diff options
author | Dan Winship <danw@src.gnome.org> | 2008-04-05 19:35:35 +0000 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2008-04-05 19:35:35 +0000 |
commit | 797462000d2e977db154d3eae120a308f18a8085 (patch) | |
tree | d80a3ae1ef6c2247e6e253246820aa559742c184 /libsoup/soup-message-body.c | |
parent | 69bac3aac055b260f3ba0590f05a35298fb33908 (diff) | |
download | libsoup-797462000d2e977db154d3eae120a308f18a8085.tar.gz |
New, replaces SOUP_MESSAGE_OVERWRITE_CHUNKS, but can be set on either the
* libsoup/soup-message-body.c (soup_message_body_set_accumulate)
(soup_message_body_get_accumulate): New, replaces
SOUP_MESSAGE_OVERWRITE_CHUNKS, but can be set on either the
incoming or outgoing message body.
(soup_message_body_get_chunk): update to still dtrt if !accumulate
(soup_message_body_got_chunk, soup_message_body_wrote_chunk): New
methods to handle accumulating/discarding chunks.
* libsoup/soup-message-io.c (read_body_chunk): Use
soup_message_body_got_chunk.
(io_write): Use soup_message_body_wrote_chunk, to discard unneeded
chunks after writing them. Fixes most of #522146.
* libsoup/soup-message.c (soup_message_class_init): add a new
flag, "server-side", to indicate whether the message is
client-side or server-side, and update several methods to use it.
(got_body): Update for accumulate
(soup_message_set_flags): If the caller changes OVERWRITE_CHUNKS,
update the corresponding accumulate flag.
* libsoup/soup-message.h (SOUP_MESSAGE_OVERWRITE_CHUNKS):
deprecated now
* tests/chunk-test.c (do_request_test): Use
soup_message_body_set_accumulate() now, and verify that the chunks
are being discarded appropriately.
(do_response_test): Use
soup_message_body_set_accumulate() instead of OVERWRITE_CHUNKS.
* tests/pull-api.c (do_fully_async_test)
(do_synchronously_async_test): Use
soup_message_body_set_accumulate().
svn path=/trunk/; revision=1126
Diffstat (limited to 'libsoup/soup-message-body.c')
-rw-r--r-- | libsoup/soup-message-body.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/libsoup/soup-message-body.c b/libsoup/soup-message-body.c index de8ac801..f83b883f 100644 --- a/libsoup/soup-message-body.c +++ b/libsoup/soup-message-body.c @@ -304,6 +304,8 @@ typedef struct { SoupMessageBody body; GSList *chunks, *last; SoupBuffer *flattened; + gboolean accumulate; + goffset base_offset; int ref_count; } SoupMessageBodyPrivate; @@ -321,11 +323,63 @@ soup_message_body_new (void) SoupMessageBodyPrivate *priv; priv = g_slice_new0 (SoupMessageBodyPrivate); + priv->accumulate = TRUE; priv->ref_count = 1; return (SoupMessageBody *)priv; } +/** + * soup_message_body_set_accumulate: + * @body: a #SoupMessageBody + * @accumulate: whether or not to accumulate body chunks in @body + * + * Sets or clears the accumulate flag on @body. (The default value + * is %TRUE.) + * + * If you set this flag to %FALSE on an "incoming" message body (that + * is, the %response_body of a client-side message, or %request_body + * of a server-side message), this will cause each chunk of the body + * to be discarded after its corresponding #SoupMessage::got_chunk + * signal is emitted. (This is equivalent to setting the deprecated + * %SOUP_MESSAGE_OVERWRITE_CHUNKS flag on the message.) + * + * If you set this flag to %FALSE on an "outgoing" message body (the + * %request_body of a client-side message, or %response_body of a + * server-side message), it will cause each chunk of the body to be + * discarded after its corresponding #SoupMessage::wrote_chunk signal + * is emitted. + * + * In either case, @body's %data field will not be filled in after the + * body is fully sent/received, since the body data will no longer be + * available + **/ +void +soup_message_body_set_accumulate (SoupMessageBody *body, + gboolean accumulate) +{ + SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body; + + priv->accumulate = accumulate; +} + +/** + * soup_message_body_get_accumulate: + * @body: a #SoupMessageBody + * + * Gets the accumulate flag on @body; see + * soup_message_body_set_accumulate() for details. + * + * Return value: the accumulate flag for @body. + **/ +gboolean +soup_message_body_get_accumulate (SoupMessageBody *body) +{ + SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body; + + return priv->accumulate; +} + static void append_buffer (SoupMessageBody *body, SoupBuffer *buffer) { @@ -438,6 +492,8 @@ soup_message_body_flatten (SoupMessageBody *body) GSList *iter; SoupBuffer *chunk; + g_return_val_if_fail (priv->accumulate == TRUE, NULL); + if (!priv->flattened) { #if GLIB_SIZEOF_SIZE_T < 8 g_return_val_if_fail (body->length < G_MAXSIZE, NULL); @@ -489,6 +545,7 @@ soup_message_body_get_chunk (SoupMessageBody *body, goffset offset) GSList *iter; SoupBuffer *chunk = NULL; + offset -= priv->base_offset; for (iter = priv->chunks; iter; iter = iter->next) { chunk = iter->data; @@ -509,6 +566,63 @@ soup_message_body_get_chunk (SoupMessageBody *body, goffset offset) } } +/** + * soup_message_body_got_chunk: + * @body: a #SoupMessageBody + * @chunk: a #SoupBuffer 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 + * @body's accumulate flag to %FALSE, then that will not happen. + * + * This is a low-level method which you should not normally need to + * use. + **/ +void +soup_message_body_got_chunk (SoupMessageBody *body, SoupBuffer *chunk) +{ + SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body; + + if (!priv->accumulate) + return; + + soup_message_body_append_buffer (body, chunk); +} + +/** + * soup_message_body_wrote_chunk: + * @body: a #SoupMessageBody + * @chunk: a #SoupBuffer received from the network + * + * 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 + * accumulate flag to %FALSE, then this will cause @chunk (and any + * chunks preceding it in @body) to be discarded to free up memory. + * + * This is a low-level method which you should not normally need to + * use. + **/ +void +soup_message_body_wrote_chunk (SoupMessageBody *body, SoupBuffer *chunk) +{ + SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body; + SoupBuffer *chunk2; + + if (priv->accumulate) + return; + + do { + chunk2 = priv->chunks->data; + priv->chunks = g_slist_remove (priv->chunks, chunk2); + priv->base_offset += chunk2->length; + soup_buffer_free (chunk2); + } while (priv->chunks && chunk2 != chunk); + + if (!priv->chunks) + priv->last = NULL; +} + static SoupMessageBody * soup_message_body_copy (SoupMessageBody *body) { |