diff options
author | Patrick Griffis <pgriffis@igalia.com> | 2020-08-31 17:24:21 -0500 |
---|---|---|
committer | Patrick Griffis <pgriffis@igalia.com> | 2020-09-19 15:41:25 -0700 |
commit | 4b43e158799689666bcbe186045ddee356601f1c (patch) | |
tree | 7034aeb51657f2326ce1d7de3876a974b76fb711 /libsoup | |
parent | 73cd3c7dc4207cacf5eb4311584201bf7133ff0f (diff) | |
download | libsoup-4b43e158799689666bcbe186045ddee356601f1c.tar.gz |
Replace SoupBuffer with GBytes
Diffstat (limited to 'libsoup')
-rw-r--r-- | libsoup/Soup-2.4-custom.vala | 7 | ||||
-rw-r--r-- | libsoup/Soup-2.4.metadata | 4 | ||||
-rw-r--r-- | libsoup/cache/soup-cache-input-stream.c | 28 | ||||
-rw-r--r-- | libsoup/content-sniffer/soup-content-sniffer-stream.c | 6 | ||||
-rw-r--r-- | libsoup/content-sniffer/soup-content-sniffer.c | 44 | ||||
-rw-r--r-- | libsoup/content-sniffer/soup-content-sniffer.h | 4 | ||||
-rw-r--r-- | libsoup/soup-directory-input-stream.c | 42 | ||||
-rw-r--r-- | libsoup/soup-directory-input-stream.h | 2 | ||||
-rw-r--r-- | libsoup/soup-form.c | 12 | ||||
-rw-r--r-- | libsoup/soup-form.h | 2 | ||||
-rw-r--r-- | libsoup/soup-logger.c | 4 | ||||
-rw-r--r-- | libsoup/soup-message-body.c | 438 | ||||
-rw-r--r-- | libsoup/soup-message-body.h | 53 | ||||
-rw-r--r-- | libsoup/soup-message-io.c | 52 | ||||
-rw-r--r-- | libsoup/soup-message-server-io.c | 30 | ||||
-rw-r--r-- | libsoup/soup-message.c | 30 | ||||
-rw-r--r-- | libsoup/soup-message.h | 6 | ||||
-rw-r--r-- | libsoup/soup-multipart.c | 57 | ||||
-rw-r--r-- | libsoup/soup-multipart.h | 6 | ||||
-rw-r--r-- | libsoup/soup-server.c | 2 |
20 files changed, 223 insertions, 606 deletions
diff --git a/libsoup/Soup-2.4-custom.vala b/libsoup/Soup-2.4-custom.vala index 619bd027..ffd1849f 100644 --- a/libsoup/Soup-2.4-custom.vala +++ b/libsoup/Soup-2.4-custom.vala @@ -1,11 +1,4 @@ namespace Soup { - [Compact] - [CCode (copy_function = "g_boxed_copy", free_function = "g_boxed_free", type_id = "soup_buffer_get_type ()", cheader_filename = "libsoup/soup.h")] - public class Buffer { - [CCode (has_construct_function = false)] - public Buffer.subbuffer (Soup.Buffer parent, size_t offset, size_t length); - } - [Version (deprecated_since = "vala-0.22", replacement = "Status.get_phrase")] public static unowned string status_get_phrase (uint status_code); [Version (deprecated_since = "vala-0.22", replacement = "Status.proxify")] diff --git a/libsoup/Soup-2.4.metadata b/libsoup/Soup-2.4.metadata index 3fd48166..da138e39 100644 --- a/libsoup/Soup-2.4.metadata +++ b/libsoup/Soup-2.4.metadata @@ -15,7 +15,6 @@ AuthDomain .accepts#method name="accepts_authorization" AuthDomainBasic.new skip=false AuthDomainDigest.new skip=false -Buffer.new_subbuffer skip ContentSniffer.sniff.params nullable form_* skip=false Message @@ -35,14 +34,11 @@ URI // uri_host_*.* type="Soup.URI" // Not enough GIR information -Buffer.data type="uint8[]" array_length_field="length" MessageBody.data type="uint8[]" array_length_field="length" Date .new_from_time_t.when type="time_t" .to_time_t type="time_t" // Simplify memory management -Buffer - .new deprecated_since="2.32" replacement="Buffer.take" MessageBody .append deprecated_since="2.32" replacement="MessageBody.append_take" diff --git a/libsoup/cache/soup-cache-input-stream.c b/libsoup/cache/soup-cache-input-stream.c index e93b43fd..649d23fc 100644 --- a/libsoup/cache/soup-cache-input-stream.c +++ b/libsoup/cache/soup-cache-input-stream.c @@ -35,7 +35,7 @@ struct _SoupCacheInputStreamPrivate gsize bytes_written; gboolean read_finished; - SoupBuffer *current_writing_buffer; + GBytes *current_writing_buffer; GQueue *buffer_queue; }; @@ -148,8 +148,8 @@ soup_cache_input_stream_finalize (GObject *object) g_clear_object (&priv->cancellable); g_clear_object (&priv->output_stream); - g_clear_pointer (&priv->current_writing_buffer, soup_buffer_free); - g_queue_free_full (priv->buffer_queue, (GDestroyNotify) soup_buffer_free); + g_clear_pointer (&priv->current_writing_buffer, g_bytes_unref); + g_queue_free_full (priv->buffer_queue, (GDestroyNotify) g_bytes_unref); G_OBJECT_CLASS (soup_cache_input_stream_parent_class)->finalize (object); } @@ -171,15 +171,15 @@ write_ready_cb (GObject *source, GAsyncResult *result, SoupCacheInputStream *ist } /* Check that we have written everything */ - pending = priv->current_writing_buffer->length - write_size; + pending = g_bytes_get_size (priv->current_writing_buffer) - write_size; if (pending) { - SoupBuffer *subbuffer = soup_buffer_new_subbuffer (priv->current_writing_buffer, - write_size, pending); - g_queue_push_head (priv->buffer_queue, subbuffer); + GBytes *subbuffer = g_bytes_new_from_bytes (priv->current_writing_buffer, + write_size, pending); + g_queue_push_head (priv->buffer_queue, g_steal_pointer (&subbuffer)); } priv->bytes_written += write_size; - g_clear_pointer (&priv->current_writing_buffer, soup_buffer_free); + g_clear_pointer (&priv->current_writing_buffer, g_bytes_unref); try_write_next_buffer (istream); g_object_unref (istream); @@ -189,12 +189,12 @@ static void soup_cache_input_stream_write_next_buffer (SoupCacheInputStream *istream) { SoupCacheInputStreamPrivate *priv = istream->priv; - SoupBuffer *buffer = g_queue_pop_head (priv->buffer_queue); + GBytes *buffer = g_queue_pop_head (priv->buffer_queue); int priority; g_assert (priv->output_stream && !g_output_stream_is_closed (priv->output_stream)); - g_clear_pointer (&priv->current_writing_buffer, soup_buffer_free); + g_clear_pointer (&priv->current_writing_buffer, g_bytes_unref); priv->current_writing_buffer = buffer; if (priv->buffer_queue->length > 10) @@ -202,7 +202,9 @@ soup_cache_input_stream_write_next_buffer (SoupCacheInputStream *istream) else priority = G_PRIORITY_LOW; - g_output_stream_write_async (priv->output_stream, buffer->data, buffer->length, + g_output_stream_write_async (priv->output_stream, + g_bytes_get_data (buffer, NULL), + g_bytes_get_size (buffer), priority, priv->cancellable, (GAsyncReadyCallback) write_ready_cb, g_object_ref (istream)); @@ -234,8 +236,8 @@ read_internal (GInputStream *stream, if (priv->current_writing_buffer == NULL && priv->output_stream) notify_and_clear (istream, NULL); } else { - SoupBuffer *soup_buffer = soup_buffer_new (SOUP_MEMORY_COPY, buffer, nread); - g_queue_push_tail (priv->buffer_queue, soup_buffer); + GBytes *local_buffer = g_bytes_new (buffer, nread); + g_queue_push_tail (priv->buffer_queue, g_steal_pointer (&local_buffer)); if (priv->current_writing_buffer == NULL && priv->output_stream) soup_cache_input_stream_write_next_buffer (istream); diff --git a/libsoup/content-sniffer/soup-content-sniffer-stream.c b/libsoup/content-sniffer/soup-content-sniffer-stream.c index 4b026e01..465648e5 100644 --- a/libsoup/content-sniffer/soup-content-sniffer-stream.c +++ b/libsoup/content-sniffer/soup-content-sniffer-stream.c @@ -112,7 +112,7 @@ read_and_sniff (GInputStream *stream, gboolean blocking, SoupContentSnifferStreamPrivate *priv = soup_content_sniffer_stream_get_instance_private (sniffer); gssize nread; GError *my_error = NULL; - SoupBuffer *buf; + GBytes *buf; do { nread = g_pollable_stream_read (G_FILTER_INPUT_STREAM (stream)->base_stream, @@ -140,11 +140,11 @@ read_and_sniff (GInputStream *stream, gboolean blocking, } /* Sniff, then return the data */ - buf = soup_buffer_new (SOUP_MEMORY_TEMPORARY, priv->buffer, priv->buffer_nread); + buf = g_bytes_new (priv->buffer, priv->buffer_nread); priv->sniffed_type = soup_content_sniffer_sniff (priv->sniffer, priv->msg, buf, &priv->sniffed_params); - soup_buffer_free (buf); + g_bytes_unref (buf); priv->sniffing = FALSE; return priv->buffer_nread; diff --git a/libsoup/content-sniffer/soup-content-sniffer.c b/libsoup/content-sniffer/soup-content-sniffer.c index 14ff38ae..f5653417 100644 --- a/libsoup/content-sniffer/soup-content-sniffer.c +++ b/libsoup/content-sniffer/soup-content-sniffer.c @@ -86,12 +86,14 @@ typedef struct { static char* sniff_media (SoupContentSniffer *sniffer, - SoupBuffer *buffer, + GBytes *buffer, SoupContentSnifferMediaPattern table[], int table_length) { - const guchar *resource = (const guchar *)buffer->data; - guint resource_length = MIN (512, buffer->length); + + gsize resource_length; + const guchar *resource = g_bytes_get_data (buffer, &resource_length); + resource_length = MIN (512, resource_length); int i; for (i = 0; i < table_length; i++) { @@ -168,7 +170,7 @@ static SoupContentSnifferMediaPattern image_types_table[] = { }; static char* -sniff_images (SoupContentSniffer *sniffer, SoupBuffer *buffer) +sniff_images (SoupContentSniffer *sniffer, GBytes *buffer) { return sniff_media (sniffer, buffer, @@ -223,10 +225,11 @@ static SoupContentSnifferMediaPattern audio_video_types_table[] = { }; static gboolean -sniff_mp4 (SoupContentSniffer *sniffer, SoupBuffer *buffer) +sniff_mp4 (SoupContentSniffer *sniffer, GBytes *buffer) { - const char *resource = (const char *)buffer->data; - guint resource_length = MIN (512, buffer->length); + gsize resource_length; + const char *resource = g_bytes_get_data (buffer, &resource_length); + resource_length = MIN (512, resource_length); guint32 box_size = *((guint32*)resource); guint i; @@ -255,7 +258,7 @@ sniff_mp4 (SoupContentSniffer *sniffer, SoupBuffer *buffer) } static char* -sniff_audio_video (SoupContentSniffer *sniffer, SoupBuffer *buffer) +sniff_audio_video (SoupContentSniffer *sniffer, GBytes *buffer) { char *sniffed_type; @@ -485,12 +488,13 @@ static char byte_looks_binary[] = { /* HTML5: 2.7.4 Content-Type sniffing: unknown type */ static char* -sniff_unknown (SoupContentSniffer *sniffer, SoupBuffer *buffer, +sniff_unknown (SoupContentSniffer *sniffer, GBytes *buffer, gboolean sniff_scriptable) { char *sniffed_type = NULL; - const guchar *resource = (const guchar *)buffer->data; - guint resource_length = MIN (512, buffer->length); + gsize resource_length; + const guchar *resource = g_bytes_get_data (buffer, &resource_length); + resource_length = MIN (512, resource_length); guint i; for (i = 0; i < G_N_ELEMENTS (types_table); i++) { @@ -574,10 +578,11 @@ sniff_unknown (SoupContentSniffer *sniffer, SoupBuffer *buffer, /* MIMESNIFF: 7.2 Sniffing a mislabeled binary resource */ static char* -sniff_text_or_binary (SoupContentSniffer *sniffer, SoupBuffer *buffer) +sniff_text_or_binary (SoupContentSniffer *sniffer, GBytes *buffer) { - const guchar *resource = (const guchar *)buffer->data; - int resource_length = MIN (512, buffer->length); + gsize resource_length; + const guchar *resource = g_bytes_get_data (buffer, &resource_length); + resource_length = MIN (512, resource_length); gboolean looks_binary = FALSE; int i; @@ -628,10 +633,11 @@ skip_insignificant_space (const char *resource, int *pos, int resource_length) } static char* -sniff_feed_or_html (SoupContentSniffer *sniffer, SoupBuffer *buffer) +sniff_feed_or_html (SoupContentSniffer *sniffer, GBytes *buffer) { - const char *resource = (const char *)buffer->data; - int resource_length = MIN (512, buffer->length); + gsize resource_length; + const char *resource = g_bytes_get_data (buffer, &resource_length); + resource_length = MIN (512, resource_length); int pos = 0; if (resource_length < 3) @@ -762,7 +768,7 @@ sniff_feed_or_html (SoupContentSniffer *sniffer, SoupBuffer *buffer) static char * soup_content_sniffer_real_sniff (SoupContentSniffer *sniffer, SoupMessage *msg, - SoupBuffer *buffer, GHashTable **params) + GBytes *buffer, GHashTable **params) { const char *content_type; const char *x_content_type_options; @@ -915,7 +921,7 @@ soup_content_sniffer_new (void) */ char * soup_content_sniffer_sniff (SoupContentSniffer *sniffer, - SoupMessage *msg, SoupBuffer *buffer, + SoupMessage *msg, GBytes *buffer, GHashTable **params) { g_return_val_if_fail (SOUP_IS_CONTENT_SNIFFER (sniffer), NULL); diff --git a/libsoup/content-sniffer/soup-content-sniffer.h b/libsoup/content-sniffer/soup-content-sniffer.h index cc9aa2b9..6931b6e4 100644 --- a/libsoup/content-sniffer/soup-content-sniffer.h +++ b/libsoup/content-sniffer/soup-content-sniffer.h @@ -19,7 +19,7 @@ struct _SoupContentSnifferClass { char* (*sniff) (SoupContentSniffer *sniffer, SoupMessage *msg, - SoupBuffer *buffer, + GBytes *buffer, GHashTable **params); gsize (*get_buffer_size) (SoupContentSniffer *sniffer); @@ -32,7 +32,7 @@ SoupContentSniffer *soup_content_sniffer_new (void); SOUP_AVAILABLE_IN_2_28 char *soup_content_sniffer_sniff (SoupContentSniffer *sniffer, SoupMessage *msg, - SoupBuffer *buffer, + GBytes *buffer, GHashTable **params); SOUP_AVAILABLE_IN_2_28 gsize soup_content_sniffer_get_buffer_size (SoupContentSniffer *sniffer); diff --git a/libsoup/soup-directory-input-stream.c b/libsoup/soup-directory-input-stream.c index 572f167e..5c24883f 100644 --- a/libsoup/soup-directory-input-stream.c +++ b/libsoup/soup-directory-input-stream.c @@ -35,11 +35,10 @@ G_DEFINE_TYPE (SoupDirectoryInputStream, soup_directory_input_stream, G_TYPE_INPUT_STREAM) -static SoupBuffer * +static GBytes * soup_directory_input_stream_parse_info (SoupDirectoryInputStream *stream, GFileInfo *info) { - SoupBuffer *buffer; GString *string; const char *file_name; char *escaped, *path, *xml_string, *size, *date, *time, *name; @@ -90,7 +89,6 @@ soup_directory_input_stream_parse_info (SoupDirectoryInputStream *stream, g_string_append_printf (string, ROW_FORMAT, name, path, xml_string, raw_size, size, timestamp, time, date); g_string_append (string, "</tr>\n"); - buffer = soup_buffer_new (SOUP_MEMORY_TAKE, string->str, string->len); g_free (time); g_free (date); @@ -98,18 +96,17 @@ soup_directory_input_stream_parse_info (SoupDirectoryInputStream *stream, g_free (size); g_free (path); g_free (xml_string); - g_string_free (string, FALSE); - return buffer; + return g_string_free_to_bytes (string); } -static SoupBuffer * +static GBytes * soup_directory_input_stream_read_next_file (SoupDirectoryInputStream *stream, GCancellable *cancellable, GError **error) { GFileInfo *info; - SoupBuffer *buffer; + GBytes *buffer; GError *err = NULL; do { @@ -120,9 +117,7 @@ soup_directory_input_stream_read_next_file (SoupDirectoryInputStream *stream, return NULL; } else if (!stream->done) { stream->done = TRUE; - return soup_buffer_new (SOUP_MEMORY_STATIC, - EXIT_STRING, - sizeof (EXIT_STRING)); + return g_bytes_new_static (EXIT_STRING, sizeof (EXIT_STRING)); } else { return NULL; } @@ -156,16 +151,16 @@ soup_directory_input_stream_read (GInputStream *input, } } - size = MIN (stream->buffer->length, count - total); - memcpy ((char *)buffer + total, stream->buffer->data, size); - if (size == stream->buffer->length) { - soup_buffer_free (stream->buffer); - stream->buffer = NULL; + gsize buffer_len = g_bytes_get_size (stream->buffer); + size = MIN (buffer_len, count - total); + memcpy ((char *)buffer + total, g_bytes_get_data (stream->buffer, NULL), size); + if (size == buffer_len) { + g_clear_pointer (&stream->buffer, g_bytes_unref); } else { - SoupBuffer *sub = soup_buffer_new_subbuffer (stream->buffer, - size, - stream->buffer->length - size); - soup_buffer_free (stream->buffer); + GBytes *sub = g_bytes_new_from_bytes (stream->buffer, + size, + buffer_len - size); + g_bytes_unref (stream->buffer); stream->buffer = sub; } } @@ -181,10 +176,7 @@ soup_directory_input_stream_close (GInputStream *input, SoupDirectoryInputStream *stream = SOUP_DIRECTORY_INPUT_STREAM (input); gboolean result; - if (stream->buffer) { - soup_buffer_free (stream->buffer); - stream->buffer = NULL; - } + g_clear_pointer (&stream->buffer, g_bytes_unref); result = g_file_enumerator_close (stream->enumerator, cancellable, @@ -244,9 +236,7 @@ soup_directory_input_stream_setup_buffer (SoupDirectoryInputStream *stream) { char *init = soup_directory_input_stream_create_header (stream); - stream->buffer = soup_buffer_new (SOUP_MEMORY_TAKE, - init, - strlen (init)); + stream->buffer = g_bytes_new_take (init, strlen (init)); } GInputStream * diff --git a/libsoup/soup-directory-input-stream.h b/libsoup/soup-directory-input-stream.h index 4c83e355..1ffb84eb 100644 --- a/libsoup/soup-directory-input-stream.h +++ b/libsoup/soup-directory-input-stream.h @@ -43,7 +43,7 @@ struct _SoupDirectoryInputStream { GFileEnumerator *enumerator; char *uri; - SoupBuffer *buffer; + GBytes *buffer; gboolean done; }; diff --git a/libsoup/soup-form.c b/libsoup/soup-form.c index aa0974f2..1de391d1 100644 --- a/libsoup/soup-form.c +++ b/libsoup/soup-form.c @@ -133,7 +133,7 @@ soup_form_decode (const char *encoded_form) * care about those fields. soup_form_decode_multipart() may also * return %NULL in those fields if the client did not provide that * information. You must free the returned filename and content-type - * with g_free(), and the returned file data with soup_buffer_free(). + * with g_free(), and the returned file data with g_bytes_unref(). * * If you have a form with more than one file upload control, you will * need to decode it manually, using soup_multipart_new_from_message() @@ -149,12 +149,12 @@ soup_form_decode (const char *encoded_form) GHashTable * soup_form_decode_multipart (SoupMessage *msg, const char *file_control_name, char **filename, char **content_type, - SoupBuffer **file) + GBytes **file) { SoupMultipart *multipart; GHashTable *form_data_set, *params; SoupMessageHeaders *part_headers; - SoupBuffer *part_body; + GBytes *part_body; char *disposition, *name; int i; @@ -193,12 +193,12 @@ soup_form_decode_multipart (SoupMessage *msg, const char *file_control_name, if (content_type) *content_type = g_strdup (soup_message_headers_get_content_type (part_headers, NULL)); if (file) - *file = soup_buffer_copy (part_body); + *file = g_bytes_ref (part_body); } else { g_hash_table_insert (form_data_set, g_strdup (name), - g_strndup (part_body->data, - part_body->length)); + g_strndup (g_bytes_get_data (part_body, NULL), + g_bytes_get_size (part_body))); } g_free (disposition); diff --git a/libsoup/soup-form.h b/libsoup/soup-form.h index 6774f5d8..4880e7be 100644 --- a/libsoup/soup-form.h +++ b/libsoup/soup-form.h @@ -21,7 +21,7 @@ GHashTable *soup_form_decode_multipart (SoupMessage *msg, const char *file_control_name, char **filename, char **content_type, - SoupBuffer **file); + GBytes **file); SOUP_AVAILABLE_IN_2_4 char *soup_form_encode (const char *first_field, diff --git a/libsoup/soup-logger.c b/libsoup/soup-logger.c index 50297dc8..d76701a2 100644 --- a/libsoup/soup-logger.c +++ b/libsoup/soup-logger.c @@ -602,11 +602,11 @@ print_request (SoupLogger *logger, SoupMessage *msg, if (msg->request_body->length && soup_message_body_get_accumulate (msg->request_body)) { - SoupBuffer *request; + GBytes *request; request = soup_message_body_flatten (msg->request_body); g_return_if_fail (request != NULL); - soup_buffer_free (request); + g_bytes_unref (request); if (soup_message_headers_get_expectations (msg->request_headers) != SOUP_EXPECTATION_CONTINUE) { soup_logger_print (logger, SOUP_LOGGER_LOG_BODY, '>', diff --git a/libsoup/soup-message-body.c b/libsoup/soup-message-body.c index eb6d5f5a..82c6b887 100644 --- a/libsoup/soup-message-body.c +++ b/libsoup/soup-message-body.c @@ -21,12 +21,6 @@ * * #SoupMessageBody represents the request or response body of a * #SoupMessage. - * - * In addition to #SoupMessageBody, libsoup also defines a "smaller" - * data buffer type, #SoupBuffer, which is primarily used as a - * component of #SoupMessageBody. In particular, when using chunked - * encoding to transmit or receive a message, each chunk is - * represented as a #SoupBuffer. **/ /** @@ -34,311 +28,12 @@ * @SOUP_MEMORY_STATIC: The memory is statically allocated and * constant; libsoup can use the passed-in buffer directly and not * need to worry about it being modified or freed. - * @SOUP_MEMORY_TAKE: The caller has allocated the memory for the - * #SoupBuffer's use; libsoup will assume ownership of it and free it - * (with g_free()) when it is done with it. - * @SOUP_MEMORY_COPY: The passed-in data belongs to the caller; the - * #SoupBuffer will copy it into new memory, leaving the caller free + * @SOUP_MEMORY_TAKE: The caller has allocated the memory and libsoup + * will assume ownership of it and free it with g_free(). + * @SOUP_MEMORY_COPY: The passed-in data belongs to the caller and + * libsoup will copy it into new memory leaving the caller free * to reuse the original memory. - * @SOUP_MEMORY_TEMPORARY: The passed-in data belongs to the caller, - * but will remain valid for the lifetime of the #SoupBuffer. The - * difference between this and @SOUP_MEMORY_STATIC is that if you copy - * a @SOUP_MEMORY_TEMPORARY buffer, it will make a copy of the memory - * as well, rather than reusing the original memory. - * - * Describes how #SoupBuffer should use the data passed in by the - * caller. - * - * See also soup_buffer_new_with_owner(), which allows to you create a - * buffer containing data which is owned by another object. - **/ - -/* Internal SoupMemoryUse values */ -enum { - SOUP_MEMORY_SUBBUFFER = SOUP_MEMORY_TEMPORARY + 1, - SOUP_MEMORY_OWNED -}; - -/** - * SoupBuffer: - * @data: (type gpointer): the data - * @length: length of @data - * - * A data buffer, generally used to represent a chunk of a - * #SoupMessageBody. - * - * @data is a #char because that's generally convenient; in some - * situations you may need to cast it to #guchar or another type. - **/ - -typedef struct { - SoupBuffer buffer; - SoupMemoryUse use; - guint refcount; - - gpointer owner; - GDestroyNotify owner_dnotify; -} SoupBufferPrivate; - -/** - * soup_buffer_new: - * @use: how @data is to be used by the buffer - * @data: (array length=length) (element-type guint8): data - * @length: length of @data - * - * Creates a new #SoupBuffer containing @length bytes from @data. - * - * Return value: the new #SoupBuffer. - **/ -SoupBuffer * -soup_buffer_new (SoupMemoryUse use, gconstpointer data, gsize length) -{ - SoupBufferPrivate *priv = g_slice_new0 (SoupBufferPrivate); - - if (use == SOUP_MEMORY_COPY) { - data = g_memdup (data, length); - use = SOUP_MEMORY_TAKE; - } - - priv->buffer.data = data; - priv->buffer.length = length; - priv->use = use; - priv->refcount = 1; - - if (use == SOUP_MEMORY_TAKE) { - priv->owner = (gpointer)data; - priv->owner_dnotify = g_free; - } - - return (SoupBuffer *)priv; -} - -/** - * soup_buffer_new_take: (rename-to soup_buffer_new) - * @data: (array length=length) (transfer full): data - * @length: length of @data - * - * Creates a new #SoupBuffer containing @length bytes from @data. - * - * This function is exactly equivalent to soup_buffer_new() with - * %SOUP_MEMORY_TAKE as first argument; it exists mainly for - * convenience and simplifying language bindings. - * - * Return value: the new #SoupBuffer. - * - * Since: 2.32 - **/ -SoupBuffer * -soup_buffer_new_take (guchar *data, gsize length) -{ - return soup_buffer_new (SOUP_MEMORY_TAKE, data, length); -} - -/** - * soup_buffer_new_subbuffer: - * @parent: the parent #SoupBuffer - * @offset: offset within @parent to start at - * @length: number of bytes to copy from @parent - * - * Creates a new #SoupBuffer containing @length bytes "copied" from - * @parent starting at @offset. (Normally this will not actually copy - * any data, but will instead simply reference the same data as - * @parent does.) - * - * Return value: the new #SoupBuffer. - **/ -SoupBuffer * -soup_buffer_new_subbuffer (SoupBuffer *parent, gsize offset, gsize length) -{ - SoupBufferPrivate *priv; - - /* Normally this is just a ref, but if @parent is TEMPORARY, - * it will do an actual copy. - */ - parent = soup_buffer_copy (parent); - - priv = g_slice_new0 (SoupBufferPrivate); - priv->buffer.data = parent->data + offset; - priv->buffer.length = length; - priv->use = SOUP_MEMORY_SUBBUFFER; - priv->owner = parent; - priv->owner_dnotify = (GDestroyNotify)soup_buffer_free; - priv->refcount = 1; - - return (SoupBuffer *)priv; -} - -/** - * soup_buffer_new_with_owner: - * @data: (array length=length) (element-type guint8): data - * @length: length of @data - * @owner: pointer to an object that owns @data - * @owner_dnotify: (allow-none): a function to free/unref @owner when - * the buffer is freed - * - * Creates a new #SoupBuffer containing @length bytes from @data. When - * the #SoupBuffer is freed, it will call @owner_dnotify, passing - * @owner to it. You must ensure that @data will remain valid until - * @owner_dnotify is called. - * - * For example, you could use this to create a buffer containing data - * returned from libxml without needing to do an extra copy: - * - * <informalexample><programlisting> - * xmlDocDumpMemory (doc, &xmlbody, &len); - * return soup_buffer_new_with_owner (xmlbody, len, xmlbody, - * (GDestroyNotify)xmlFree); - * </programlisting></informalexample> - * - * In this example, @data and @owner are the same, but in other cases - * they would be different (eg, @owner would be a object, and @data - * would be a pointer to one of the object's fields). - * - * Return value: the new #SoupBuffer. - **/ -SoupBuffer * -soup_buffer_new_with_owner (gconstpointer data, gsize length, - gpointer owner, GDestroyNotify owner_dnotify) -{ - SoupBufferPrivate *priv = g_slice_new0 (SoupBufferPrivate); - - priv->buffer.data = data; - priv->buffer.length = length; - priv->use = SOUP_MEMORY_OWNED; - priv->owner = owner; - priv->owner_dnotify = owner_dnotify; - priv->refcount = 1; - - return (SoupBuffer *)priv; -} - -/** - * soup_buffer_get_owner: - * @buffer: a #SoupBuffer created with soup_buffer_new_with_owner() - * - * Gets the "owner" object for a buffer created with - * soup_buffer_new_with_owner(). - * - * Return value: (transfer none): the owner pointer - **/ -gpointer -soup_buffer_get_owner (SoupBuffer *buffer) -{ - SoupBufferPrivate *priv = (SoupBufferPrivate *)buffer; - - g_return_val_if_fail ((int)priv->use == (int)SOUP_MEMORY_OWNED, NULL); - return priv->owner; -} - -/** - * soup_buffer_get_data: - * @buffer: a #SoupBuffer - * @data: (out) (array length=length) (transfer none): the pointer - * to the buffer data is stored here - * @length: (out): the length of the buffer data is stored here - * - * This function exists for use by language bindings, because it's not - * currently possible to get the right effect by annotating the fields - * of #SoupBuffer. - * - * Since: 2.32 - */ -void -soup_buffer_get_data (SoupBuffer *buffer, - const guint8 **data, - gsize *length) -{ - *data = (const guint8 *)buffer->data; - *length = buffer->length; -} - -/** - * soup_buffer_copy: - * @buffer: a #SoupBuffer - * - * Makes a copy of @buffer. In reality, #SoupBuffer is a refcounted - * type, and calling soup_buffer_copy() will normally just increment - * the refcount on @buffer and return it. However, if @buffer was - * created with #SOUP_MEMORY_TEMPORARY memory, then soup_buffer_copy() - * will actually return a copy of it, so that the data in the copy - * will remain valid after the temporary buffer is freed. - * - * Return value: the new (or newly-reffed) buffer - **/ -SoupBuffer * -soup_buffer_copy (SoupBuffer *buffer) -{ - SoupBufferPrivate *priv = (SoupBufferPrivate *)buffer; - - /* For non-TEMPORARY buffers, this is just a ref */ - if (priv->use != SOUP_MEMORY_TEMPORARY) { - g_atomic_int_inc (&priv->refcount); - return buffer; - } - - /* For TEMPORARY buffers, we need to do a real copy the first - * time, and then after that, we just keep returning the copy. - * We store the copy in priv->owner, which is technically - * backwards, but it saves us from having to keep an extra - * pointer in SoupBufferPrivate. - */ - - if (!priv->owner) { - priv->owner = soup_buffer_new (SOUP_MEMORY_COPY, - buffer->data, - buffer->length); - priv->owner_dnotify = (GDestroyNotify)soup_buffer_free; - } - return soup_buffer_copy (priv->owner); -} - -/** - * soup_buffer_free: - * @buffer: a #SoupBuffer - * - * Frees @buffer. (In reality, as described in the documentation for - * soup_buffer_copy(), this is actually an "unref" operation, and may - * or may not actually free @buffer.) **/ -void -soup_buffer_free (SoupBuffer *buffer) -{ - SoupBufferPrivate *priv = (SoupBufferPrivate *)buffer; - - if (!g_atomic_int_dec_and_test (&priv->refcount)) - return; - - if (priv->owner_dnotify) - priv->owner_dnotify (priv->owner); - g_slice_free (SoupBufferPrivate, priv); -} - -/** - * soup_buffer_get_as_bytes: - * @buffer: a #SoupBuffer - * - * Creates a #GBytes pointing to the same memory as @buffer. The - * #GBytes will hold a reference on @buffer to ensure that it is not - * freed while the #GBytes is still valid. - * - * Returns: (transfer full): a new #GBytes which has the same content - * as the #SoupBuffer. - * - * Since: 2.40 - */ -GBytes * -soup_buffer_get_as_bytes (SoupBuffer *buffer) -{ - SoupBuffer *copy; - - copy = soup_buffer_copy (buffer); - return g_bytes_new_with_free_func (copy->data, copy->length, - (GDestroyNotify)soup_buffer_free, - copy); -} - -G_DEFINE_BOXED_TYPE (SoupBuffer, soup_buffer, soup_buffer_copy, soup_buffer_free) - /** * SoupMessageBody: @@ -362,7 +57,7 @@ G_DEFINE_BOXED_TYPE (SoupBuffer, soup_buffer, soup_buffer_copy, soup_buffer_free typedef struct { SoupMessageBody body; GSList *chunks, *last; - SoupBuffer *flattened; + GBytes *flattened; gboolean accumulate; goffset base_offset; int ref_count; @@ -451,7 +146,7 @@ soup_message_body_get_accumulate (SoupMessageBody *body) } static void -append_buffer (SoupMessageBody *body, SoupBuffer *buffer) +append_buffer (SoupMessageBody *body, GBytes *buffer) { SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body; @@ -461,12 +156,9 @@ append_buffer (SoupMessageBody *body, SoupBuffer *buffer) } else priv->chunks = priv->last = g_slist_append (NULL, buffer); - if (priv->flattened) { - soup_buffer_free (priv->flattened); - priv->flattened = NULL; - body->data = NULL; - } - body->length += buffer->length; + g_clear_pointer (&priv->flattened, g_bytes_unref); + body->data = NULL; + body->length += g_bytes_get_size (buffer); } /** @@ -482,8 +174,16 @@ void soup_message_body_append (SoupMessageBody *body, SoupMemoryUse use, gconstpointer data, gsize length) { - if (length > 0) - append_buffer (body, soup_buffer_new (use, data, length)); + GBytes *bytes; + if (length > 0) { + if (use == SOUP_MEMORY_TAKE) + bytes = g_bytes_new_take ((guchar*)data, length); + else if (use == SOUP_MEMORY_STATIC) + bytes = g_bytes_new_static (data, length); + else + bytes = g_bytes_new (data, length); + append_buffer (body, g_steal_pointer (&bytes)); + } else if (use == SOUP_MEMORY_TAKE) g_free ((gpointer)data); } @@ -510,20 +210,17 @@ soup_message_body_append_take (SoupMessageBody *body, } /** - * soup_message_body_append_buffer: + * soup_message_body_append_bytes: * @body: a #SoupMessageBody - * @buffer: a #SoupBuffer + * @buffer: a #GBytes * - * Appends the data from @buffer to @body. (#SoupMessageBody uses - * #SoupBuffers internally, so this is normally a constant-time - * operation that doesn't actually require copying the data in - * @buffer.) + * Appends the data from @buffer to @body. **/ void -soup_message_body_append_buffer (SoupMessageBody *body, SoupBuffer *buffer) +soup_message_body_append_bytes (SoupMessageBody *body, GBytes *buffer) { - g_return_if_fail (buffer->length > 0); - append_buffer (body, soup_buffer_copy (buffer)); + g_return_if_fail (g_bytes_get_size (buffer) > 0); + append_buffer (body, g_bytes_ref (buffer)); } /** @@ -537,15 +234,11 @@ soup_message_body_truncate (SoupMessageBody *body) { SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body; - g_slist_free_full (priv->chunks, (GDestroyNotify)soup_buffer_free); + g_slist_free_full (priv->chunks, (GDestroyNotify)g_bytes_unref); priv->chunks = priv->last = NULL; priv->base_offset = 0; - - if (priv->flattened) { - soup_buffer_free (priv->flattened); - priv->flattened = NULL; - body->data = NULL; - } + g_clear_pointer (&priv->flattened, g_bytes_unref); + body->data = NULL; body->length = 0; } @@ -559,7 +252,7 @@ soup_message_body_truncate (SoupMessageBody *body) void soup_message_body_complete (SoupMessageBody *body) { - append_buffer (body, soup_buffer_new (SOUP_MEMORY_STATIC, NULL, 0)); + append_buffer (body, g_bytes_new_static (NULL, 0)); } /** @@ -570,16 +263,13 @@ soup_message_body_complete (SoupMessageBody *body) * data in @body (plus an additional '\0' byte not counted by @body's * length field). * - * Return value: a #SoupBuffer containing the same data as @body. - * (You must free this buffer if you do not want it.) + * Return: (transfer full): a #GBytes containing the same data as @body. + * (You must g_bytes_unref() this if you do not want it.) **/ -SoupBuffer * +GBytes * soup_message_body_flatten (SoupMessageBody *body) { SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body; - char *buf, *ptr; - GSList *iter; - SoupBuffer *chunk; g_return_val_if_fail (priv->accumulate == TRUE, NULL); @@ -588,20 +278,22 @@ soup_message_body_flatten (SoupMessageBody *body) g_return_val_if_fail (body->length < G_MAXSIZE, NULL); #endif - buf = ptr = g_malloc (body->length + 1); - for (iter = priv->chunks; iter; iter = iter->next) { - chunk = iter->data; - memcpy (ptr, chunk->data, chunk->length); - ptr += chunk->length; + GByteArray *array = g_byte_array_sized_new (body->length + 1); + for (GSList *iter = priv->chunks; iter; iter = iter->next) { + GBytes *chunk = iter->data; + gsize chunk_size; + const guchar *chunk_data = g_bytes_get_data (chunk, &chunk_size); + g_byte_array_append (array, chunk_data, chunk_size); } - *ptr = '\0'; + // NUL terminate the array but don't reflect that in the length + g_byte_array_append (array, (guchar*)"\0", 1); + array->len -= 1; - priv->flattened = soup_buffer_new (SOUP_MEMORY_TAKE, - buf, body->length); - body->data = priv->flattened->data; + priv->flattened = g_byte_array_free_to_bytes (array); + body->data = g_bytes_get_data (priv->flattened, NULL); } - return soup_buffer_copy (priv->flattened); + return g_bytes_ref (priv->flattened); } /** @@ -609,7 +301,7 @@ soup_message_body_flatten (SoupMessageBody *body) * @body: a #SoupMessageBody * @offset: an offset * - * Gets a #SoupBuffer containing data from @body starting at @offset. + * Gets a #GBytes containing data from @body starting at @offset. * The size of the returned chunk is unspecified. You can iterate * through the entire body by first calling * soup_message_body_get_chunk() with an offset of 0, and then on each @@ -625,44 +317,40 @@ soup_message_body_flatten (SoupMessageBody *body) * @body may still potentially have more data, but that data is not * currently available). * - * Return value: (nullable): a #SoupBuffer, or %NULL. + * Return value: (nullable): a #GBytes, or %NULL. **/ -SoupBuffer * +GBytes * soup_message_body_get_chunk (SoupMessageBody *body, goffset offset) { SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body; GSList *iter; - SoupBuffer *chunk = NULL; + GBytes *chunk = NULL; offset -= priv->base_offset; for (iter = priv->chunks; iter; iter = iter->next) { chunk = iter->data; + gsize chunk_length = g_bytes_get_size (chunk); - if (offset < chunk->length || offset == 0) + if (offset < chunk_length || offset == 0) break; - offset -= chunk->length; + offset -= chunk_length; } if (!iter) return NULL; - if (offset == 0) - return soup_buffer_copy (chunk); - else { - return soup_buffer_new_subbuffer (chunk, offset, - chunk->length - offset); - } + return g_bytes_new_from_bytes (chunk, offset, g_bytes_get_size (chunk) - offset); } /** * soup_message_body_got_chunk: * @body: a #SoupMessageBody - * @chunk: a #SoupBuffer received from the network + * @chunk: a #GBytes received from the network * * Handles the #SoupMessageBody part of receiving a chunk of data from * the network. Normally this means appending @chunk to @body, exactly - * as with soup_message_body_append_buffer(), but if you have set + * as with soup_message_body_append_bytes(), but if you have set * @body's accumulate flag to %FALSE, then that will not happen. * * This is a low-level method which you should not normally need to @@ -671,20 +359,20 @@ soup_message_body_get_chunk (SoupMessageBody *body, goffset offset) * Since: 2.24 **/ void -soup_message_body_got_chunk (SoupMessageBody *body, SoupBuffer *chunk) +soup_message_body_got_chunk (SoupMessageBody *body, GBytes *chunk) { SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body; if (!priv->accumulate) return; - soup_message_body_append_buffer (body, chunk); + soup_message_body_append_bytes (body, chunk); } /** * soup_message_body_wrote_chunk: * @body: a #SoupMessageBody - * @chunk: a #SoupBuffer returned from soup_message_body_get_chunk() + * @chunk: a #GBytes returned from soup_message_body_get_chunk() * * Handles the #SoupMessageBody part of writing a chunk of data to the * network. Normally this is a no-op, but if you have set @body's @@ -698,24 +386,24 @@ soup_message_body_got_chunk (SoupMessageBody *body, SoupBuffer *chunk) * Since: 2.24 **/ void -soup_message_body_wrote_chunk (SoupMessageBody *body, SoupBuffer *chunk) +soup_message_body_wrote_chunk (SoupMessageBody *body, GBytes *chunk) { SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body; - SoupBuffer *chunk2; + GBytes *chunk2; if (priv->accumulate) return; chunk2 = priv->chunks->data; - g_return_if_fail (chunk->length == chunk2->length); - g_return_if_fail (chunk == chunk2 || ((SoupBufferPrivate *)chunk2)->use == SOUP_MEMORY_TEMPORARY); + g_return_if_fail (g_bytes_get_size (chunk) == g_bytes_get_size (chunk2)); + g_return_if_fail (chunk == chunk2); priv->chunks = g_slist_remove (priv->chunks, chunk2); if (!priv->chunks) priv->last = NULL; - priv->base_offset += chunk2->length; - soup_buffer_free (chunk2); + priv->base_offset += g_bytes_get_size (chunk2); + g_bytes_unref (chunk2); } static SoupMessageBody * diff --git a/libsoup/soup-message-body.h b/libsoup/soup-message-body.h index c08e26ae..4b757af9 100644 --- a/libsoup/soup-message-body.h +++ b/libsoup/soup-message-body.h @@ -18,46 +18,6 @@ typedef enum { typedef struct { const char *data; - gsize length; -} SoupBuffer; - -SOUP_AVAILABLE_IN_2_4 -GType soup_buffer_get_type (void); -#define SOUP_TYPE_BUFFER (soup_buffer_get_type ()) - -SOUP_AVAILABLE_IN_2_4 -SoupBuffer *soup_buffer_new (SoupMemoryUse use, - gconstpointer data, - gsize length); -SOUP_AVAILABLE_IN_2_32 -SoupBuffer *soup_buffer_new_take (guchar *data, - gsize length); -SOUP_AVAILABLE_IN_2_4 -SoupBuffer *soup_buffer_new_subbuffer (SoupBuffer *parent, - gsize offset, - gsize length); - -SOUP_AVAILABLE_IN_2_4 -SoupBuffer *soup_buffer_new_with_owner (gconstpointer data, - gsize length, - gpointer owner, - GDestroyNotify owner_dnotify); -SOUP_AVAILABLE_IN_2_4 -gpointer soup_buffer_get_owner (SoupBuffer *buffer); -SOUP_AVAILABLE_IN_2_32 -void soup_buffer_get_data (SoupBuffer *buffer, - const guint8 **data, - gsize *length); -SOUP_AVAILABLE_IN_2_40 -GBytes *soup_buffer_get_as_bytes (SoupBuffer *buffer); - -SOUP_AVAILABLE_IN_2_4 -SoupBuffer *soup_buffer_copy (SoupBuffer *buffer); -SOUP_AVAILABLE_IN_2_4 -void soup_buffer_free (SoupBuffer *buffer); - -typedef struct { - const char *data; goffset length; } SoupMessageBody; @@ -84,31 +44,30 @@ void soup_message_body_append_take (SoupMessageBody *body, guchar *data, gsize length); SOUP_AVAILABLE_IN_2_4 -void soup_message_body_append_buffer (SoupMessageBody *body, - SoupBuffer *buffer); +void soup_message_body_append_bytes (SoupMessageBody *body, + GBytes *buffer); SOUP_AVAILABLE_IN_2_4 void soup_message_body_truncate (SoupMessageBody *body); SOUP_AVAILABLE_IN_2_4 void soup_message_body_complete (SoupMessageBody *body); SOUP_AVAILABLE_IN_2_4 -SoupBuffer *soup_message_body_flatten (SoupMessageBody *body); +GBytes *soup_message_body_flatten (SoupMessageBody *body); SOUP_AVAILABLE_IN_2_4 -SoupBuffer *soup_message_body_get_chunk (SoupMessageBody *body, +GBytes *soup_message_body_get_chunk (SoupMessageBody *body, goffset offset); SOUP_AVAILABLE_IN_2_24 void soup_message_body_got_chunk (SoupMessageBody *body, - SoupBuffer *chunk); + GBytes *chunk); SOUP_AVAILABLE_IN_2_24 void soup_message_body_wrote_chunk (SoupMessageBody *body, - SoupBuffer *chunk); + GBytes *chunk); SOUP_AVAILABLE_IN_2_4 void soup_message_body_free (SoupMessageBody *body); -G_DEFINE_AUTOPTR_CLEANUP_FUNC (SoupBuffer, soup_buffer_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (SoupMessageBody, soup_message_body_free) G_END_DECLS diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c index 302630ba..f9da4a9b 100644 --- a/libsoup/soup-message-io.c +++ b/libsoup/soup-message-io.c @@ -76,7 +76,7 @@ typedef struct { SoupEncoding write_encoding; GString *write_buf; SoupMessageBody *write_body; - SoupBuffer *write_chunk; + GBytes *write_chunk; goffset write_body_offset; goffset write_length; goffset written; @@ -130,8 +130,7 @@ soup_message_io_cleanup (SoupMessage *msg) g_byte_array_free (io->read_header_buf, TRUE); g_string_free (io->write_buf, TRUE); - if (io->write_chunk) - soup_buffer_free (io->write_chunk); + g_clear_pointer (&io->write_chunk, g_bytes_unref); if (io->async_close_wait) { g_cancellable_cancel (io->async_close_wait); @@ -388,7 +387,7 @@ io_write (SoupMessage *msg, gboolean blocking, GCancellable *cancellable, GError **error) { SoupMessageIOData *io = soup_message_get_io_data (msg); - SoupBuffer *chunk; + GBytes *chunk; gssize nwrote; if (io->async_close_error) { @@ -513,37 +512,36 @@ io_write (SoupMessage *msg, gboolean blocking, soup_message_io_pause (msg); return FALSE; } - if (!io->write_chunk->length) { + if (!g_bytes_get_size (io->write_chunk)) { io->write_state = SOUP_MESSAGE_IO_STATE_BODY_FLUSH; break; } } nwrote = g_pollable_stream_write (io->body_ostream, - io->write_chunk->data + io->written, - io->write_chunk->length - io->written, + (guchar*)g_bytes_get_data (io->write_chunk, NULL) + io->written, + g_bytes_get_size (io->write_chunk) - io->written, blocking, cancellable, error); if (nwrote == -1) return FALSE; - chunk = soup_buffer_new_subbuffer (io->write_chunk, - io->written, nwrote); + chunk = g_bytes_new_from_bytes (io->write_chunk, io->written, nwrote); io->written += nwrote; if (io->write_length) io->write_length -= nwrote; - if (io->written == io->write_chunk->length) + if (io->written == g_bytes_get_size (io->write_chunk)) io->write_state = SOUP_MESSAGE_IO_STATE_BODY_DATA; soup_message_wrote_body_data (msg, chunk); - soup_buffer_free (chunk); + g_bytes_unref (chunk); break; case SOUP_MESSAGE_IO_STATE_BODY_DATA: io->written = 0; - if (io->write_chunk->length == 0) { + if (g_bytes_get_size (io->write_chunk) == 0) { io->write_state = SOUP_MESSAGE_IO_STATE_BODY_FLUSH; break; } @@ -551,9 +549,8 @@ io_write (SoupMessage *msg, gboolean blocking, if (io->mode == SOUP_MESSAGE_IO_SERVER || soup_message_get_flags (msg) & SOUP_MESSAGE_CAN_REBUILD) soup_message_body_wrote_chunk (io->write_body, io->write_chunk); - io->write_body_offset += io->write_chunk->length; - soup_buffer_free (io->write_chunk); - io->write_chunk = NULL; + io->write_body_offset += g_bytes_get_size (io->write_chunk); + g_clear_pointer (&io->write_chunk, g_bytes_unref); io->write_state = SOUP_MESSAGE_IO_STATE_BODY; soup_message_wrote_chunk (msg); @@ -612,9 +609,7 @@ io_read (SoupMessage *msg, gboolean blocking, GCancellable *cancellable, GError **error) { SoupMessageIOData *io = soup_message_get_io_data (msg); - guchar *stack_buf = NULL; gssize nread; - SoupBuffer *buffer; guint status; switch (io->read_state) { @@ -749,34 +744,29 @@ io_read (SoupMessage *msg, gboolean blocking, break; - case SOUP_MESSAGE_IO_STATE_BODY: - if (!stack_buf) - stack_buf = alloca (RESPONSE_BLOCK_SIZE); - buffer = soup_buffer_new (SOUP_MEMORY_TEMPORARY, - stack_buf, - RESPONSE_BLOCK_SIZE); + case SOUP_MESSAGE_IO_STATE_BODY: { + guchar buf[RESPONSE_BLOCK_SIZE]; nread = g_pollable_stream_read (io->body_istream, - (guchar *)buffer->data, - buffer->length, + buf, + RESPONSE_BLOCK_SIZE, blocking, cancellable, error); if (nread > 0) { - buffer->length = nread; - soup_message_body_got_chunk (io->read_body, buffer); - soup_message_got_chunk (msg, buffer); - soup_buffer_free (buffer); + GBytes *bytes = g_bytes_new (buf, nread); + soup_message_body_got_chunk (io->read_body, bytes); + soup_message_got_chunk (msg, bytes); + g_bytes_unref (bytes); break; } - soup_buffer_free (buffer); if (nread == -1) return FALSE; /* else nread == 0 */ io->read_state = SOUP_MESSAGE_IO_STATE_BODY_DONE; break; - + } case SOUP_MESSAGE_IO_STATE_BODY_DONE: io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING; diff --git a/libsoup/soup-message-server-io.c b/libsoup/soup-message-server-io.c index 3e00f3ea..2c0ee91c 100644 --- a/libsoup/soup-message-server-io.c +++ b/libsoup/soup-message-server-io.c @@ -144,7 +144,7 @@ handle_partial_get (SoupMessage *msg) { SoupRange *ranges; int nranges; - SoupBuffer *full_response; + GBytes *full_response; guint status; /* Make sure the message is set up right for us to return a @@ -185,23 +185,23 @@ handle_partial_get (SoupMessage *msg) soup_message_body_truncate (msg->response_body); if (nranges == 1) { - SoupBuffer *range_buf; + GBytes *range_buf; /* Single range, so just set Content-Range and fix the body. */ soup_message_headers_set_content_range (msg->response_headers, ranges[0].start, ranges[0].end, - full_response->length); - range_buf = soup_buffer_new_subbuffer (full_response, - ranges[0].start, - ranges[0].end - ranges[0].start + 1); - soup_message_body_append_buffer (msg->response_body, range_buf); - soup_buffer_free (range_buf); + g_bytes_get_size (full_response)); + range_buf = g_bytes_new_from_bytes (full_response, + ranges[0].start, + ranges[0].end - ranges[0].start + 1); + soup_message_body_append_bytes (msg->response_body, range_buf); + g_bytes_unref (range_buf); } else { SoupMultipart *multipart; SoupMessageHeaders *part_headers; - SoupBuffer *part_body; + GBytes *part_body; const char *content_type; int i; @@ -222,14 +222,14 @@ handle_partial_get (SoupMessage *msg) soup_message_headers_set_content_range (part_headers, ranges[i].start, ranges[i].end, - full_response->length); - part_body = soup_buffer_new_subbuffer (full_response, - ranges[i].start, - ranges[i].end - ranges[i].start + 1); + g_bytes_get_size (full_response)); + part_body = g_bytes_new_from_bytes (full_response, + ranges[i].start, + ranges[i].end - ranges[i].start + 1); soup_multipart_append_part (multipart, part_headers, part_body); soup_message_headers_free (part_headers); - soup_buffer_free (part_body); + g_bytes_unref (part_body); } soup_multipart_to_message (multipart, msg->response_headers, @@ -237,7 +237,7 @@ handle_partial_get (SoupMessage *msg) soup_multipart_free (multipart); } - soup_buffer_free (full_response); + g_bytes_unref (full_response); soup_message_headers_free_ranges (msg->request_headers, ranges); } diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c index cf494709..6ff46e5d 100644 --- a/libsoup/soup-message.c +++ b/libsoup/soup-message.c @@ -267,7 +267,7 @@ soup_message_get_property (GObject *object, guint prop_id, { SoupMessage *msg = SOUP_MESSAGE (object); SoupMessagePrivate *priv = soup_message_get_instance_private (msg); - SoupBuffer *buf; + GBytes *buf; switch (prop_id) { case PROP_METHOD: @@ -305,8 +305,7 @@ soup_message_get_property (GObject *object, guint prop_id, break; case PROP_REQUEST_BODY_DATA: buf = soup_message_body_flatten (msg->request_body); - g_value_take_boxed (value, soup_buffer_get_as_bytes (buf)); - soup_buffer_free (buf); + g_value_take_boxed (value, buf); break; case PROP_REQUEST_HEADERS: g_value_set_boxed (value, msg->request_headers); @@ -316,8 +315,7 @@ soup_message_get_property (GObject *object, guint prop_id, break; case PROP_RESPONSE_BODY_DATA: buf = soup_message_body_flatten (msg->response_body); - g_value_take_boxed (value, soup_buffer_get_as_bytes (buf)); - soup_buffer_free (buf); + g_value_take_boxed (value, buf); break; case PROP_RESPONSE_HEADERS: g_value_set_boxed (value, msg->response_headers); @@ -345,10 +343,8 @@ soup_message_real_got_body (SoupMessage *msg) body = priv->server_side ? msg->request_body : msg->response_body; if (soup_message_body_get_accumulate (body)) { - SoupBuffer *buffer; - - buffer = soup_message_body_flatten (body); - soup_buffer_free (buffer); + GBytes *buffer = soup_message_body_flatten (body); + g_bytes_unref (buffer); } } @@ -410,7 +406,7 @@ soup_message_class_init (SoupMessageClass *message_class) * Note that this signal is not parallel to * #SoupMessage::got_chunk; it is emitted only when a complete * chunk (added with soup_message_body_append() or - * soup_message_body_append_buffer()) has been written. To get + * soup_message_body_append_bytes()) has been written. To get * more useful continuous progress information, use * #SoupMessage::wrote_body_data. **/ @@ -445,7 +441,7 @@ soup_message_class_init (SoupMessageClass *message_class) NULL, NULL, NULL, G_TYPE_NONE, 1, - SOUP_TYPE_BUFFER); + G_TYPE_BYTES); /** * SoupMessage::wrote-body: @@ -544,13 +540,7 @@ soup_message_class_init (SoupMessageClass *message_class) NULL, NULL, NULL, G_TYPE_NONE, 1, - /* Use %G_SIGNAL_TYPE_STATIC_SCOPE so that - * the %SOUP_MEMORY_TEMPORARY buffers used - * by soup-message-io.c when emitting this - * signal don't get forcibly copied by - * g_signal_emit(). - */ - SOUP_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE); + G_TYPE_BYTES); /** * SoupMessage::got-body: @@ -1160,7 +1150,7 @@ soup_message_wrote_chunk (SoupMessage *msg) } void -soup_message_wrote_body_data (SoupMessage *msg, SoupBuffer *chunk) +soup_message_wrote_body_data (SoupMessage *msg, GBytes *chunk) { g_signal_emit (msg, signals[WROTE_BODY_DATA], 0, chunk); } @@ -1184,7 +1174,7 @@ soup_message_got_headers (SoupMessage *msg) } void -soup_message_got_chunk (SoupMessage *msg, SoupBuffer *chunk) +soup_message_got_chunk (SoupMessage *msg, GBytes *chunk) { g_signal_emit (msg, signals[GOT_CHUNK], 0, chunk); } diff --git a/libsoup/soup-message.h b/libsoup/soup-message.h index c4cd49e8..70a0becb 100644 --- a/libsoup/soup-message.h +++ b/libsoup/soup-message.h @@ -46,7 +46,7 @@ typedef struct { void (*wrote_body) (SoupMessage *msg); void (*got_informational) (SoupMessage *msg); void (*got_headers) (SoupMessage *msg); - void (*got_chunk) (SoupMessage *msg, SoupBuffer *chunk); + void (*got_chunk) (SoupMessage *msg, GBytes *chunk); void (*got_body) (SoupMessage *msg); void (*restarted) (SoupMessage *msg); void (*finished) (SoupMessage *msg); @@ -228,7 +228,7 @@ void soup_message_wrote_headers (SoupMessage *msg); SOUP_AVAILABLE_IN_2_4 void soup_message_wrote_chunk (SoupMessage *msg); SOUP_AVAILABLE_IN_2_4 -void soup_message_wrote_body_data (SoupMessage *msg, SoupBuffer *chunk); +void soup_message_wrote_body_data (SoupMessage *msg, GBytes *chunk); SOUP_AVAILABLE_IN_2_4 void soup_message_wrote_body (SoupMessage *msg); SOUP_AVAILABLE_IN_2_4 @@ -236,7 +236,7 @@ void soup_message_got_informational (SoupMessage *msg); SOUP_AVAILABLE_IN_2_4 void soup_message_got_headers (SoupMessage *msg); SOUP_AVAILABLE_IN_2_4 -void soup_message_got_chunk (SoupMessage *msg, SoupBuffer *chunk); +void soup_message_got_chunk (SoupMessage *msg, GBytes *chunk); SOUP_AVAILABLE_IN_2_4 void soup_message_got_body (SoupMessage *msg); SOUP_AVAILABLE_IN_2_4 diff --git a/libsoup/soup-multipart.c b/libsoup/soup-multipart.c index 1844de98..67df98fa 100644 --- a/libsoup/soup-multipart.c +++ b/libsoup/soup-multipart.c @@ -54,7 +54,7 @@ soup_multipart_new_internal (char *mime_type, char *boundary) multipart->mime_type = mime_type; multipart->boundary = boundary; multipart->headers = g_ptr_array_new_with_free_func ((GDestroyNotify)soup_message_headers_free); - multipart->bodies = g_ptr_array_new_with_free_func ((GDestroyNotify)soup_buffer_free); + multipart->bodies = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref); return multipart; } @@ -140,10 +140,10 @@ soup_multipart_new_from_message (SoupMessageHeaders *headers, const char *content_type, *boundary; GHashTable *params; int boundary_len; - SoupBuffer *flattened; + GBytes *flattened; const char *start, *split, *end, *body_end; SoupMessageHeaders *part_headers; - SoupBuffer *part_body; + GBytes *part_body; content_type = soup_message_headers_get_content_type (headers, ¶ms); if (!content_type) @@ -160,16 +160,18 @@ soup_multipart_new_from_message (SoupMessageHeaders *headers, g_hash_table_destroy (params); flattened = soup_message_body_flatten (body); - body_end = flattened->data + flattened->length; + gsize flattened_size; + const char *flattened_data = g_bytes_get_data (flattened, &flattened_size); + body_end = flattened_data + flattened_size; boundary = multipart->boundary; boundary_len = strlen (boundary); /* skip preamble */ - start = find_boundary (flattened->data, body_end, + start = find_boundary (flattened_data, body_end, boundary, boundary_len); if (!start) { soup_multipart_free (multipart); - soup_buffer_free (flattened); + g_bytes_unref (flattened); return NULL; } @@ -178,14 +180,14 @@ soup_multipart_new_from_message (SoupMessageHeaders *headers, boundary, boundary_len); if (!end) { soup_multipart_free (multipart); - soup_buffer_free (flattened); + g_bytes_unref (flattened); return NULL; } split = strstr (start, "\r\n\r\n"); if (!split || split > end) { soup_multipart_free (multipart); - soup_buffer_free (flattened); + g_bytes_unref (flattened); return NULL; } split += 4; @@ -204,7 +206,7 @@ soup_multipart_new_from_message (SoupMessageHeaders *headers, if (!soup_headers_parse (start, split - 2 - start, part_headers)) { soup_multipart_free (multipart); - soup_buffer_free (flattened); + g_bytes_unref (flattened); return NULL; } @@ -213,15 +215,15 @@ soup_multipart_new_from_message (SoupMessageHeaders *headers, * the following boundary line, which is to say 2 bytes * after the end of the body. */ - part_body = soup_buffer_new_subbuffer (flattened, - split - flattened->data, - end - 2 - split); + part_body = g_bytes_new_from_bytes (flattened, // FIXME + split - flattened_data, + end - 2 - split); g_ptr_array_add (multipart->bodies, part_body); start = end; } - soup_buffer_free (flattened); + g_bytes_unref (flattened); return multipart; } @@ -259,7 +261,7 @@ soup_multipart_get_length (SoupMultipart *multipart) **/ gboolean soup_multipart_get_part (SoupMultipart *multipart, int part, - SoupMessageHeaders **headers, SoupBuffer **body) + SoupMessageHeaders **headers, GBytes **body) { if (part < 0 || part >= multipart->bodies->len) return FALSE; @@ -284,7 +286,7 @@ soup_multipart_get_part (SoupMultipart *multipart, int part, void soup_multipart_append_part (SoupMultipart *multipart, SoupMessageHeaders *headers, - SoupBuffer *body) + GBytes *body) { SoupMessageHeaders *headers_copy; SoupMessageHeadersIter iter; @@ -307,7 +309,7 @@ soup_multipart_append_part (SoupMultipart *multipart, * 3) We don't want to steal the reference to @headers, * because then we'd have to either also steal the * reference to @body (which would be inconsistent with - * other SoupBuffer methods), or NOT steal the reference to + * other GBytes methods), or NOT steal the reference to * @body, in which case there'd be inconsistency just * between the two arguments of this method! */ @@ -317,7 +319,7 @@ soup_multipart_append_part (SoupMultipart *multipart, soup_message_headers_append (headers_copy, name, value); g_ptr_array_add (multipart->headers, headers_copy); - g_ptr_array_add (multipart->bodies, soup_buffer_copy (body)); + g_ptr_array_add (multipart->bodies, g_bytes_ref (body)); } /** @@ -337,12 +339,12 @@ void soup_multipart_append_form_string (SoupMultipart *multipart, const char *control_name, const char *data) { - SoupBuffer *body; + GBytes *body; - body = soup_buffer_new (SOUP_MEMORY_COPY, data, strlen (data)); + body = g_bytes_new (data, strlen (data)); soup_multipart_append_form_file (multipart, control_name, NULL, NULL, body); - soup_buffer_free (body); + g_bytes_unref (body); } /** @@ -363,7 +365,7 @@ soup_multipart_append_form_string (SoupMultipart *multipart, void soup_multipart_append_form_file (SoupMultipart *multipart, const char *control_name, const char *filename, - const char *content_type, SoupBuffer *body) + const char *content_type, GBytes *body) { SoupMessageHeaders *headers; GString *disposition; @@ -385,7 +387,7 @@ soup_multipart_append_form_file (SoupMultipart *multipart, } g_ptr_array_add (multipart->headers, headers); - g_ptr_array_add (multipart->bodies, soup_buffer_copy (body)); + g_ptr_array_add (multipart->bodies, g_bytes_ref (body)); } /** @@ -404,7 +406,7 @@ soup_multipart_to_message (SoupMultipart *multipart, SoupMessageBody *dest_body) { SoupMessageHeaders *part_headers; - SoupBuffer *part_body; + GBytes *part_body; SoupMessageHeadersIter iter; const char *name, *value; GString *str; @@ -430,11 +432,12 @@ soup_multipart_to_message (SoupMultipart *multipart, while (soup_message_headers_iter_next (&iter, &name, &value)) g_string_append_printf (str, "%s: %s\r\n", name, value); g_string_append (str, "\r\n"); - soup_message_body_append (dest_body, SOUP_MEMORY_TAKE, - str->str, str->len); - g_string_free (str, FALSE); - soup_message_body_append_buffer (dest_body, part_body); + GBytes *buffer = g_string_free_to_bytes (str); + soup_message_body_append_bytes (dest_body, buffer); + g_bytes_unref (buffer); + + soup_message_body_append_bytes (dest_body, part_body); } str = g_string_new ("\r\n--"); diff --git a/libsoup/soup-multipart.h b/libsoup/soup-multipart.h index 22675c39..e5a46c24 100644 --- a/libsoup/soup-multipart.h +++ b/libsoup/soup-multipart.h @@ -29,12 +29,12 @@ SOUP_AVAILABLE_IN_2_26 gboolean soup_multipart_get_part (SoupMultipart *multipart, int part, SoupMessageHeaders **headers, - SoupBuffer **body); + GBytes **body); SOUP_AVAILABLE_IN_2_26 void soup_multipart_append_part (SoupMultipart *multipart, SoupMessageHeaders *headers, - SoupBuffer *body); + GBytes *body); SOUP_AVAILABLE_IN_2_26 void soup_multipart_append_form_string (SoupMultipart *multipart, @@ -45,7 +45,7 @@ void soup_multipart_append_form_file (SoupMultipart *multipart, const char *control_name, const char *filename, const char *content_type, - SoupBuffer *body); + GBytes *body); SOUP_AVAILABLE_IN_2_26 void soup_multipart_to_message (SoupMultipart *multipart, diff --git a/libsoup/soup-server.c b/libsoup/soup-server.c index ae2301d4..2aa4a7e2 100644 --- a/libsoup/soup-server.c +++ b/libsoup/soup-server.c @@ -2020,7 +2020,7 @@ get_or_create_handler (SoupServer *server, const char *exact_path) * To send the response body a bit at a time using "chunked" encoding, * first call soup_message_headers_set_encoding() to set * %SOUP_ENCODING_CHUNKED on the #SoupMessage:response-headers. Then call - * soup_message_body_append() (or soup_message_body_append_buffer()) + * soup_message_body_append() (or soup_message_body_append_bytes)) * to append each chunk as it becomes ready, and * soup_server_unpause_message() to make sure it's running. (The * server will automatically pause the message if it is using chunked |