|
Packit Service |
ca3877 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
|
Packit Service |
ca3877 |
/*
|
|
Packit Service |
ca3877 |
* soup-message-body.c: SoupMessage request/response bodies
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Copyright (C) 2000-2003, Ximian, Inc.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#ifdef HAVE_CONFIG_H
|
|
Packit Service |
ca3877 |
#include <config.h>
|
|
Packit Service |
ca3877 |
#endif
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#include <string.h>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#include "soup-message-body.h"
|
|
Packit Service |
ca3877 |
#include "soup.h"
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SECTION:soup-message-body
|
|
Packit Service |
ca3877 |
* @short_description: HTTP message body
|
|
Packit Service |
ca3877 |
* @see_also: #SoupMessage
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* #SoupMessageBody represents the request or response body of a
|
|
Packit Service |
ca3877 |
* #SoupMessage.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* In addition to #SoupMessageBody, libsoup also defines a "smaller"
|
|
Packit Service |
ca3877 |
* data buffer type, #SoupBuffer, which is primarily used as a
|
|
Packit Service |
ca3877 |
* component of #SoupMessageBody. In particular, when using chunked
|
|
Packit Service |
ca3877 |
* encoding to transmit or receive a message, each chunk is
|
|
Packit Service |
ca3877 |
* represented as a #SoupBuffer.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SoupMemoryUse:
|
|
Packit Service |
ca3877 |
* @SOUP_MEMORY_STATIC: The memory is statically allocated and
|
|
Packit Service |
ca3877 |
* constant; libsoup can use the passed-in buffer directly and not
|
|
Packit Service |
ca3877 |
* need to worry about it being modified or freed.
|
|
Packit Service |
ca3877 |
* @SOUP_MEMORY_TAKE: The caller has allocated the memory for the
|
|
Packit Service |
ca3877 |
* #SoupBuffer's use; libsoup will assume ownership of it and free it
|
|
Packit Service |
ca3877 |
* (with g_free()) when it is done with it.
|
|
Packit Service |
ca3877 |
* @SOUP_MEMORY_COPY: The passed-in data belongs to the caller; the
|
|
Packit Service |
ca3877 |
* #SoupBuffer will copy it into new memory, leaving the caller free
|
|
Packit Service |
ca3877 |
* to reuse the original memory.
|
|
Packit Service |
ca3877 |
* @SOUP_MEMORY_TEMPORARY: The passed-in data belongs to the caller,
|
|
Packit Service |
ca3877 |
* but will remain valid for the lifetime of the #SoupBuffer. The
|
|
Packit Service |
ca3877 |
* difference between this and @SOUP_MEMORY_STATIC is that if you copy
|
|
Packit Service |
ca3877 |
* a @SOUP_MEMORY_TEMPORARY buffer, it will make a copy of the memory
|
|
Packit Service |
ca3877 |
* as well, rather than reusing the original memory.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Describes how #SoupBuffer should use the data passed in by the
|
|
Packit Service |
ca3877 |
* caller.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* See also soup_buffer_new_with_owner(), which allows to you create a
|
|
Packit Service |
ca3877 |
* buffer containing data which is owned by another object.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* Internal SoupMemoryUse values */
|
|
Packit Service |
ca3877 |
enum {
|
|
Packit Service |
ca3877 |
SOUP_MEMORY_SUBBUFFER = SOUP_MEMORY_TEMPORARY + 1,
|
|
Packit Service |
ca3877 |
SOUP_MEMORY_OWNED
|
|
Packit Service |
ca3877 |
};
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SoupBuffer:
|
|
Packit Service |
ca3877 |
* @data: (type gpointer): the data
|
|
Packit Service |
ca3877 |
* @length: length of @data
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* A data buffer, generally used to represent a chunk of a
|
|
Packit Service |
ca3877 |
* #SoupMessageBody.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* @data is a #char because that's generally convenient; in some
|
|
Packit Service |
ca3877 |
* situations you may need to cast it to #guchar or another type.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
typedef struct {
|
|
Packit Service |
ca3877 |
SoupBuffer buffer;
|
|
Packit Service |
ca3877 |
SoupMemoryUse use;
|
|
Packit Service |
ca3877 |
guint refcount;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
gpointer owner;
|
|
Packit Service |
ca3877 |
GDestroyNotify owner_dnotify;
|
|
Packit Service |
ca3877 |
} SoupBufferPrivate;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_buffer_new:
|
|
Packit Service |
ca3877 |
* @use: how @data is to be used by the buffer
|
|
Packit Service |
ca3877 |
* @data: (array length=length) (element-type guint8): data
|
|
Packit Service |
ca3877 |
* @length: length of @data
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Creates a new #SoupBuffer containing @length bytes from @data.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: the new #SoupBuffer.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupBuffer *
|
|
Packit Service |
ca3877 |
soup_buffer_new (SoupMemoryUse use, gconstpointer data, gsize length)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupBufferPrivate *priv = g_slice_new0 (SoupBufferPrivate);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (use == SOUP_MEMORY_COPY) {
|
|
Packit Service |
ca3877 |
data = g_memdup (data, length);
|
|
Packit Service |
ca3877 |
use = SOUP_MEMORY_TAKE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
priv->buffer.data = data;
|
|
Packit Service |
ca3877 |
priv->buffer.length = length;
|
|
Packit Service |
ca3877 |
priv->use = use;
|
|
Packit Service |
ca3877 |
priv->refcount = 1;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (use == SOUP_MEMORY_TAKE) {
|
|
Packit Service |
ca3877 |
priv->owner = (gpointer)data;
|
|
Packit Service |
ca3877 |
priv->owner_dnotify = g_free;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return (SoupBuffer *)priv;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_buffer_new_take: (rename-to soup_buffer_new)
|
|
Packit Service |
ca3877 |
* @data: (array length=length) (transfer full): data
|
|
Packit Service |
ca3877 |
* @length: length of @data
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Creates a new #SoupBuffer containing @length bytes from @data.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* This function is exactly equivalent to soup_buffer_new() with
|
|
Packit Service |
ca3877 |
* %SOUP_MEMORY_TAKE as first argument; it exists mainly for
|
|
Packit Service |
ca3877 |
* convenience and simplifying language bindings.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: the new #SoupBuffer.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.32
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupBuffer *
|
|
Packit Service |
ca3877 |
soup_buffer_new_take (guchar *data, gsize length)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return soup_buffer_new (SOUP_MEMORY_TAKE, data, length);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_buffer_new_subbuffer:
|
|
Packit Service |
ca3877 |
* @parent: the parent #SoupBuffer
|
|
Packit Service |
ca3877 |
* @offset: offset within @parent to start at
|
|
Packit Service |
ca3877 |
* @length: number of bytes to copy from @parent
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Creates a new #SoupBuffer containing @length bytes "copied" from
|
|
Packit Service |
ca3877 |
* @parent starting at @offset. (Normally this will not actually copy
|
|
Packit Service |
ca3877 |
* any data, but will instead simply reference the same data as
|
|
Packit Service |
ca3877 |
* @parent does.)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: the new #SoupBuffer.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupBuffer *
|
|
Packit Service |
ca3877 |
soup_buffer_new_subbuffer (SoupBuffer *parent, gsize offset, gsize length)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupBufferPrivate *priv;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* Normally this is just a ref, but if @parent is TEMPORARY,
|
|
Packit Service |
ca3877 |
* it will do an actual copy.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
parent = soup_buffer_copy (parent);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
priv = g_slice_new0 (SoupBufferPrivate);
|
|
Packit Service |
ca3877 |
priv->buffer.data = parent->data + offset;
|
|
Packit Service |
ca3877 |
priv->buffer.length = length;
|
|
Packit Service |
ca3877 |
priv->use = SOUP_MEMORY_SUBBUFFER;
|
|
Packit Service |
ca3877 |
priv->owner = parent;
|
|
Packit Service |
ca3877 |
priv->owner_dnotify = (GDestroyNotify)soup_buffer_free;
|
|
Packit Service |
ca3877 |
priv->refcount = 1;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return (SoupBuffer *)priv;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_buffer_new_with_owner:
|
|
Packit Service |
ca3877 |
* @data: (array length=length) (element-type guint8): data
|
|
Packit Service |
ca3877 |
* @length: length of @data
|
|
Packit Service |
ca3877 |
* @owner: pointer to an object that owns @data
|
|
Packit Service |
ca3877 |
* @owner_dnotify: (allow-none): a function to free/unref @owner when
|
|
Packit Service |
ca3877 |
* the buffer is freed
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Creates a new #SoupBuffer containing @length bytes from @data. When
|
|
Packit Service |
ca3877 |
* the #SoupBuffer is freed, it will call @owner_dnotify, passing
|
|
Packit Service |
ca3877 |
* @owner to it. You must ensure that @data will remain valid until
|
|
Packit Service |
ca3877 |
* @owner_dnotify is called.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* For example, you could use this to create a buffer containing data
|
|
Packit Service |
ca3877 |
* returned from libxml without needing to do an extra copy:
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* <informalexample><programlisting>
|
|
Packit Service |
ca3877 |
* xmlDocDumpMemory (doc, &xmlbody, &len;;
|
|
Packit Service |
ca3877 |
* return soup_buffer_new_with_owner (xmlbody, len, xmlbody,
|
|
Packit Service |
ca3877 |
* (GDestroyNotify)xmlFree);
|
|
Packit Service |
ca3877 |
* </programlisting></informalexample>
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* In this example, @data and @owner are the same, but in other cases
|
|
Packit Service |
ca3877 |
* they would be different (eg, @owner would be a object, and @data
|
|
Packit Service |
ca3877 |
* would be a pointer to one of the object's fields).
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: the new #SoupBuffer.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupBuffer *
|
|
Packit Service |
ca3877 |
soup_buffer_new_with_owner (gconstpointer data, gsize length,
|
|
Packit Service |
ca3877 |
gpointer owner, GDestroyNotify owner_dnotify)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupBufferPrivate *priv = g_slice_new0 (SoupBufferPrivate);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
priv->buffer.data = data;
|
|
Packit Service |
ca3877 |
priv->buffer.length = length;
|
|
Packit Service |
ca3877 |
priv->use = SOUP_MEMORY_OWNED;
|
|
Packit Service |
ca3877 |
priv->owner = owner;
|
|
Packit Service |
ca3877 |
priv->owner_dnotify = owner_dnotify;
|
|
Packit Service |
ca3877 |
priv->refcount = 1;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return (SoupBuffer *)priv;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_buffer_get_owner:
|
|
Packit Service |
ca3877 |
* @buffer: a #SoupBuffer created with soup_buffer_new_with_owner()
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets the "owner" object for a buffer created with
|
|
Packit Service |
ca3877 |
* soup_buffer_new_with_owner().
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: (transfer none): the owner pointer
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
gpointer
|
|
Packit Service |
ca3877 |
soup_buffer_get_owner (SoupBuffer *buffer)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupBufferPrivate *priv = (SoupBufferPrivate *)buffer;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_return_val_if_fail ((int)priv->use == (int)SOUP_MEMORY_OWNED, NULL);
|
|
Packit Service |
ca3877 |
return priv->owner;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_buffer_get_data:
|
|
Packit Service |
ca3877 |
* @buffer: a #SoupBuffer
|
|
Packit Service |
ca3877 |
* @data: (out) (array length=length) (transfer none): the pointer
|
|
Packit Service |
ca3877 |
* to the buffer data is stored here
|
|
Packit Service |
ca3877 |
* @length: (out): the length of the buffer data is stored here
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* This function exists for use by language bindings, because it's not
|
|
Packit Service |
ca3877 |
* currently possible to get the right effect by annotating the fields
|
|
Packit Service |
ca3877 |
* of #SoupBuffer.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.32
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_buffer_get_data (SoupBuffer *buffer,
|
|
Packit Service |
ca3877 |
const guint8 **data,
|
|
Packit Service |
ca3877 |
gsize *length)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
*data = (const guint8 *)buffer->data;
|
|
Packit Service |
ca3877 |
*length = buffer->length;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_buffer_copy:
|
|
Packit Service |
ca3877 |
* @buffer: a #SoupBuffer
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Makes a copy of @buffer. In reality, #SoupBuffer is a refcounted
|
|
Packit Service |
ca3877 |
* type, and calling soup_buffer_copy() will normally just increment
|
|
Packit Service |
ca3877 |
* the refcount on @buffer and return it. However, if @buffer was
|
|
Packit Service |
ca3877 |
* created with #SOUP_MEMORY_TEMPORARY memory, then soup_buffer_copy()
|
|
Packit Service |
ca3877 |
* will actually return a copy of it, so that the data in the copy
|
|
Packit Service |
ca3877 |
* will remain valid after the temporary buffer is freed.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: the new (or newly-reffed) buffer
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupBuffer *
|
|
Packit Service |
ca3877 |
soup_buffer_copy (SoupBuffer *buffer)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupBufferPrivate *priv = (SoupBufferPrivate *)buffer;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* For non-TEMPORARY buffers, this is just a ref */
|
|
Packit Service |
ca3877 |
if (priv->use != SOUP_MEMORY_TEMPORARY) {
|
|
Packit Service |
ca3877 |
g_atomic_int_inc (&priv->refcount);
|
|
Packit Service |
ca3877 |
return buffer;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* For TEMPORARY buffers, we need to do a real copy the first
|
|
Packit Service |
ca3877 |
* time, and then after that, we just keep returning the copy.
|
|
Packit Service |
ca3877 |
* We store the copy in priv->owner, which is technically
|
|
Packit Service |
ca3877 |
* backwards, but it saves us from having to keep an extra
|
|
Packit Service |
ca3877 |
* pointer in SoupBufferPrivate.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!priv->owner) {
|
|
Packit Service |
ca3877 |
priv->owner = soup_buffer_new (SOUP_MEMORY_COPY,
|
|
Packit Service |
ca3877 |
buffer->data,
|
|
Packit Service |
ca3877 |
buffer->length);
|
|
Packit Service |
ca3877 |
priv->owner_dnotify = (GDestroyNotify)soup_buffer_free;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
return soup_buffer_copy (priv->owner);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_buffer_free:
|
|
Packit Service |
ca3877 |
* @buffer: a #SoupBuffer
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Frees @buffer. (In reality, as described in the documentation for
|
|
Packit Service |
ca3877 |
* soup_buffer_copy(), this is actually an "unref" operation, and may
|
|
Packit Service |
ca3877 |
* or may not actually free @buffer.)
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_buffer_free (SoupBuffer *buffer)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupBufferPrivate *priv = (SoupBufferPrivate *)buffer;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!g_atomic_int_dec_and_test (&priv->refcount))
|
|
Packit Service |
ca3877 |
return;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (priv->owner_dnotify)
|
|
Packit Service |
ca3877 |
priv->owner_dnotify (priv->owner);
|
|
Packit Service |
ca3877 |
g_slice_free (SoupBufferPrivate, priv);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_buffer_get_as_bytes:
|
|
Packit Service |
ca3877 |
* @buffer: a #SoupBuffer
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Creates a #GBytes pointing to the same memory as @buffer. The
|
|
Packit Service |
ca3877 |
* #GBytes will hold a reference on @buffer to ensure that it is not
|
|
Packit Service |
ca3877 |
* freed while the #GBytes is still valid.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Returns: (transfer full): a new #GBytes which has the same content
|
|
Packit Service |
ca3877 |
* as the #SoupBuffer.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.40
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
GBytes *
|
|
Packit Service |
ca3877 |
soup_buffer_get_as_bytes (SoupBuffer *buffer)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupBuffer *copy;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
copy = soup_buffer_copy (buffer);
|
|
Packit Service |
ca3877 |
return g_bytes_new_with_free_func (copy->data, copy->length,
|
|
Packit Service |
ca3877 |
(GDestroyNotify)soup_buffer_free,
|
|
Packit Service |
ca3877 |
copy);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
G_DEFINE_BOXED_TYPE (SoupBuffer, soup_buffer, soup_buffer_copy, soup_buffer_free)
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SoupMessageBody:
|
|
Packit Service |
ca3877 |
* @data: the data
|
|
Packit Service |
ca3877 |
* @length: length of @data
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* A #SoupMessage request or response body.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Note that while @length always reflects the full length of the
|
|
Packit Service |
ca3877 |
* message body, @data is normally %NULL, and will only be filled in
|
|
Packit Service |
ca3877 |
* after soup_message_body_flatten() is called. For client-side
|
|
Packit Service |
ca3877 |
* messages, this automatically happens for the response body after it
|
|
Packit Service |
ca3877 |
* has been fully read, unless you set the
|
|
Packit Service |
ca3877 |
* %SOUP_MESSAGE_OVERWRITE_CHUNKS flags. Likewise, for server-side
|
|
Packit Service |
ca3877 |
* messages, the request body is automatically filled in after being
|
|
Packit Service |
ca3877 |
* read.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* As an added bonus, when @data is filled in, it is always terminated
|
|
Packit Service |
ca3877 |
* with a '\0' byte (which is not reflected in @length).
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
typedef struct {
|
|
Packit Service |
ca3877 |
SoupMessageBody body;
|
|
Packit Service |
ca3877 |
GSList *chunks, *last;
|
|
Packit Service |
ca3877 |
SoupBuffer *flattened;
|
|
Packit Service |
ca3877 |
gboolean accumulate;
|
|
Packit Service |
ca3877 |
goffset base_offset;
|
|
Packit Service |
ca3877 |
int ref_count;
|
|
Packit Service |
ca3877 |
} SoupMessageBodyPrivate;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_body_new:
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Creates a new #SoupMessageBody. #SoupMessage uses this internally; you
|
|
Packit Service |
ca3877 |
* will not normally need to call it yourself.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: a new #SoupMessageBody.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupMessageBody *
|
|
Packit Service |
ca3877 |
soup_message_body_new (void)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageBodyPrivate *priv;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
priv = g_slice_new0 (SoupMessageBodyPrivate);
|
|
Packit Service |
ca3877 |
priv->accumulate = TRUE;
|
|
Packit Service |
ca3877 |
priv->ref_count = 1;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return (SoupMessageBody *)priv;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_body_set_accumulate:
|
|
Packit Service |
ca3877 |
* @body: a #SoupMessageBody
|
|
Packit Service |
ca3877 |
* @accumulate: whether or not to accumulate body chunks in @body
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Sets or clears the accumulate flag on @body. (The default value is
|
|
Packit Service |
ca3877 |
* %TRUE.) If set to %FALSE, @body's %data field will not be filled in
|
|
Packit Service |
ca3877 |
* after the body is fully sent/received, and the chunks that make up
|
|
Packit Service |
ca3877 |
* @body may be discarded when they are no longer needed.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* In particular, if you set this flag to %FALSE on an "incoming"
|
|
Packit Service |
ca3877 |
* message body (that is, the #SoupMessage:response_body of a
|
|
Packit Service |
ca3877 |
* client-side message, or #SoupMessage:request_body of a server-side
|
|
Packit Service |
ca3877 |
* message), this will cause each chunk of the body to be discarded
|
|
Packit Service |
ca3877 |
* after its corresponding #SoupMessage::got_chunk signal is emitted.
|
|
Packit Service |
ca3877 |
* (This is equivalent to setting the deprecated
|
|
Packit Service |
ca3877 |
* %SOUP_MESSAGE_OVERWRITE_CHUNKS flag on the message.)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* If you set this flag to %FALSE on the #SoupMessage:response_body of
|
|
Packit Service |
ca3877 |
* a server-side message, it will cause each chunk of the body to be
|
|
Packit Service |
ca3877 |
* discarded after its corresponding #SoupMessage::wrote_chunk signal
|
|
Packit Service |
ca3877 |
* is emitted.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* If you set the flag to %FALSE on the #SoupMessage:request_body of a
|
|
Packit Service |
ca3877 |
* client-side message, it will block the accumulation of chunks into
|
|
Packit Service |
ca3877 |
* @body's %data field, but it will not normally cause the chunks to
|
|
Packit Service |
ca3877 |
* be discarded after being written like in the server-side
|
|
Packit Service |
ca3877 |
* #SoupMessage:response_body case, because the request body needs to
|
|
Packit Service |
ca3877 |
* be kept around in case the request needs to be sent a second time
|
|
Packit Service |
ca3877 |
* due to redirection or authentication. However, if you set the
|
|
Packit Service |
ca3877 |
* %SOUP_MESSAGE_CAN_REBUILD flag on the message, then the chunks will
|
|
Packit Service |
ca3877 |
* be discarded, and you will be responsible for recreating the
|
|
Packit Service |
ca3877 |
* request body after the #SoupMessage::restarted signal is emitted.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.24
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_body_set_accumulate (SoupMessageBody *body,
|
|
Packit Service |
ca3877 |
gboolean accumulate)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
priv->accumulate = accumulate;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_body_get_accumulate:
|
|
Packit Service |
ca3877 |
* @body: a #SoupMessageBody
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets the accumulate flag on @body; see
|
|
Packit Service |
ca3877 |
* soup_message_body_set_accumulate() for details.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: the accumulate flag for @body.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.24
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
gboolean
|
|
Packit Service |
ca3877 |
soup_message_body_get_accumulate (SoupMessageBody *body)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return priv->accumulate;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
append_buffer (SoupMessageBody *body, SoupBuffer *buffer)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (priv->last) {
|
|
Packit Service |
ca3877 |
priv->last = g_slist_append (priv->last, buffer);
|
|
Packit Service |
ca3877 |
priv->last = priv->last->next;
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
priv->chunks = priv->last = g_slist_append (NULL, buffer);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (priv->flattened) {
|
|
Packit Service |
ca3877 |
soup_buffer_free (priv->flattened);
|
|
Packit Service |
ca3877 |
priv->flattened = NULL;
|
|
Packit Service |
ca3877 |
body->data = NULL;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
body->length += buffer->length;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_body_append:
|
|
Packit Service |
ca3877 |
* @body: a #SoupMessageBody
|
|
Packit Service |
ca3877 |
* @use: how to use @data
|
|
Packit Service |
ca3877 |
* @data: (array length=length) (element-type guint8): data to append
|
|
Packit Service |
ca3877 |
* @length: length of @data
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Appends @length bytes from @data to @body according to @use.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_body_append (SoupMessageBody *body, SoupMemoryUse use,
|
|
Packit Service |
ca3877 |
gconstpointer data, gsize length)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
if (length > 0)
|
|
Packit Service |
ca3877 |
append_buffer (body, soup_buffer_new (use, data, length));
|
|
Packit Service |
ca3877 |
else if (use == SOUP_MEMORY_TAKE)
|
|
Packit Service |
ca3877 |
g_free ((gpointer)data);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_body_append_take: (rename-to soup_message_body_append)
|
|
Packit Service |
ca3877 |
* @body: a #SoupMessageBody
|
|
Packit Service |
ca3877 |
* @data: (array length=length) (transfer full): data to append
|
|
Packit Service |
ca3877 |
* @length: length of @data
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Appends @length bytes from @data to @body.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* This function is exactly equivalent to soup_message_body_append()
|
|
Packit Service |
ca3877 |
* with %SOUP_MEMORY_TAKE as second argument; it exists mainly for
|
|
Packit Service |
ca3877 |
* convenience and simplifying language bindings.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.32
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_body_append_take (SoupMessageBody *body,
|
|
Packit Service |
ca3877 |
guchar *data, gsize length)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
soup_message_body_append(body, SOUP_MEMORY_TAKE, data, length);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_body_append_buffer:
|
|
Packit Service |
ca3877 |
* @body: a #SoupMessageBody
|
|
Packit Service |
ca3877 |
* @buffer: a #SoupBuffer
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Appends the data from @buffer to @body. (#SoupMessageBody uses
|
|
Packit Service |
ca3877 |
* #SoupBuffers internally, so this is normally a constant-time
|
|
Packit Service |
ca3877 |
* operation that doesn't actually require copying the data in
|
|
Packit Service |
ca3877 |
* @buffer.)
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_body_append_buffer (SoupMessageBody *body, SoupBuffer *buffer)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
g_return_if_fail (buffer->length > 0);
|
|
Packit Service |
ca3877 |
append_buffer (body, soup_buffer_copy (buffer));
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_body_truncate:
|
|
Packit Service |
ca3877 |
* @body: a #SoupMessageBody
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Deletes all of the data in @body.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_body_truncate (SoupMessageBody *body)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_slist_free_full (priv->chunks, (GDestroyNotify)soup_buffer_free);
|
|
Packit Service |
ca3877 |
priv->chunks = priv->last = NULL;
|
|
Packit Service |
ca3877 |
priv->base_offset = 0;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (priv->flattened) {
|
|
Packit Service |
ca3877 |
soup_buffer_free (priv->flattened);
|
|
Packit Service |
ca3877 |
priv->flattened = NULL;
|
|
Packit Service |
ca3877 |
body->data = NULL;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
body->length = 0;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_body_complete:
|
|
Packit Service |
ca3877 |
* @body: a #SoupMessageBody
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Tags @body as being complete; Call this when using chunked encoding
|
|
Packit Service |
ca3877 |
* after you have appended the last chunk.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_body_complete (SoupMessageBody *body)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
append_buffer (body, soup_buffer_new (SOUP_MEMORY_STATIC, NULL, 0));
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_body_flatten:
|
|
Packit Service |
ca3877 |
* @body: a #SoupMessageBody
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Fills in @body's data field with a buffer containing all of the
|
|
Packit Service |
ca3877 |
* data in @body (plus an additional '\0' byte not counted by @body's
|
|
Packit Service |
ca3877 |
* length field).
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: a #SoupBuffer containing the same data as @body.
|
|
Packit Service |
ca3877 |
* (You must free this buffer if you do not want it.)
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupBuffer *
|
|
Packit Service |
ca3877 |
soup_message_body_flatten (SoupMessageBody *body)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body;
|
|
Packit Service |
ca3877 |
char *buf, *ptr;
|
|
Packit Service |
ca3877 |
GSList *iter;
|
|
Packit Service |
ca3877 |
SoupBuffer *chunk;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_return_val_if_fail (priv->accumulate == TRUE, NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!priv->flattened) {
|
|
Packit Service |
ca3877 |
#if GLIB_SIZEOF_SIZE_T < 8
|
|
Packit Service |
ca3877 |
g_return_val_if_fail (body->length < G_MAXSIZE, NULL);
|
|
Packit Service |
ca3877 |
#endif
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
buf = ptr = g_malloc (body->length + 1);
|
|
Packit Service |
ca3877 |
for (iter = priv->chunks; iter; iter = iter->next) {
|
|
Packit Service |
ca3877 |
chunk = iter->data;
|
|
Packit Service |
ca3877 |
memcpy (ptr, chunk->data, chunk->length);
|
|
Packit Service |
ca3877 |
ptr += chunk->length;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
*ptr = '\0';
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
priv->flattened = soup_buffer_new (SOUP_MEMORY_TAKE,
|
|
Packit Service |
ca3877 |
buf, body->length);
|
|
Packit Service |
ca3877 |
body->data = priv->flattened->data;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return soup_buffer_copy (priv->flattened);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_body_get_chunk:
|
|
Packit Service |
ca3877 |
* @body: a #SoupMessageBody
|
|
Packit Service |
ca3877 |
* @offset: an offset
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets a #SoupBuffer containing data from @body starting at @offset.
|
|
Packit Service |
ca3877 |
* The size of the returned chunk is unspecified. You can iterate
|
|
Packit Service |
ca3877 |
* through the entire body by first calling
|
|
Packit Service |
ca3877 |
* soup_message_body_get_chunk() with an offset of 0, and then on each
|
|
Packit Service |
ca3877 |
* successive call, increment the offset by the length of the
|
|
Packit Service |
ca3877 |
* previously-returned chunk.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* If @offset is greater than or equal to the total length of @body,
|
|
Packit Service |
ca3877 |
* then the return value depends on whether or not
|
|
Packit Service |
ca3877 |
* soup_message_body_complete() has been called or not; if it has,
|
|
Packit Service |
ca3877 |
* then soup_message_body_get_chunk() will return a 0-length chunk
|
|
Packit Service |
ca3877 |
* (indicating the end of @body). If it has not, then
|
|
Packit Service |
ca3877 |
* soup_message_body_get_chunk() will return %NULL (indicating that
|
|
Packit Service |
ca3877 |
* @body may still potentially have more data, but that data is not
|
|
Packit Service |
ca3877 |
* currently available).
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: (nullable): a #SoupBuffer, or %NULL.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupBuffer *
|
|
Packit Service |
ca3877 |
soup_message_body_get_chunk (SoupMessageBody *body, goffset offset)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body;
|
|
Packit Service |
ca3877 |
GSList *iter;
|
|
Packit Service |
ca3877 |
SoupBuffer *chunk = NULL;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
offset -= priv->base_offset;
|
|
Packit Service |
ca3877 |
for (iter = priv->chunks; iter; iter = iter->next) {
|
|
Packit Service |
ca3877 |
chunk = iter->data;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (offset < chunk->length || offset == 0)
|
|
Packit Service |
ca3877 |
break;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
offset -= chunk->length;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!iter)
|
|
Packit Service |
ca3877 |
return NULL;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (offset == 0)
|
|
Packit Service |
ca3877 |
return soup_buffer_copy (chunk);
|
|
Packit Service |
ca3877 |
else {
|
|
Packit Service |
ca3877 |
return soup_buffer_new_subbuffer (chunk, offset,
|
|
Packit Service |
ca3877 |
chunk->length - offset);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_body_got_chunk:
|
|
Packit Service |
ca3877 |
* @body: a #SoupMessageBody
|
|
Packit Service |
ca3877 |
* @chunk: a #SoupBuffer received from the network
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Handles the #SoupMessageBody part of receiving a chunk of data from
|
|
Packit Service |
ca3877 |
* the network. Normally this means appending @chunk to @body, exactly
|
|
Packit Service |
ca3877 |
* as with soup_message_body_append_buffer(), but if you have set
|
|
Packit Service |
ca3877 |
* @body's accumulate flag to %FALSE, then that will not happen.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* This is a low-level method which you should not normally need to
|
|
Packit Service |
ca3877 |
* use.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.24
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_body_got_chunk (SoupMessageBody *body, SoupBuffer *chunk)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!priv->accumulate)
|
|
Packit Service |
ca3877 |
return;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
soup_message_body_append_buffer (body, chunk);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_body_wrote_chunk:
|
|
Packit Service |
ca3877 |
* @body: a #SoupMessageBody
|
|
Packit Service |
ca3877 |
* @chunk: a #SoupBuffer returned from soup_message_body_get_chunk()
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Handles the #SoupMessageBody part of writing a chunk of data to the
|
|
Packit Service |
ca3877 |
* network. Normally this is a no-op, but if you have set @body's
|
|
Packit Service |
ca3877 |
* accumulate flag to %FALSE, then this will cause @chunk to be
|
|
Packit Service |
ca3877 |
* discarded to free up memory.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* This is a low-level method which you should not need to use, and
|
|
Packit Service |
ca3877 |
* there are further restrictions on its proper use which are not
|
|
Packit Service |
ca3877 |
* documented here.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.24
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_body_wrote_chunk (SoupMessageBody *body, SoupBuffer *chunk)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body;
|
|
Packit Service |
ca3877 |
SoupBuffer *chunk2;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (priv->accumulate)
|
|
Packit Service |
ca3877 |
return;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
chunk2 = priv->chunks->data;
|
|
Packit Service |
ca3877 |
g_return_if_fail (chunk->length == chunk2->length);
|
|
Packit Service |
ca3877 |
g_return_if_fail (chunk == chunk2 || ((SoupBufferPrivate *)chunk2)->use == SOUP_MEMORY_TEMPORARY);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
priv->chunks = g_slist_remove (priv->chunks, chunk2);
|
|
Packit Service |
ca3877 |
if (!priv->chunks)
|
|
Packit Service |
ca3877 |
priv->last = NULL;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
priv->base_offset += chunk2->length;
|
|
Packit Service |
ca3877 |
soup_buffer_free (chunk2);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static SoupMessageBody *
|
|
Packit Service |
ca3877 |
soup_message_body_copy (SoupMessageBody *body)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_atomic_int_inc (&priv->ref_count);
|
|
Packit Service |
ca3877 |
return body;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_body_free:
|
|
Packit Service |
ca3877 |
* @body: a #SoupMessageBody
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Frees @body. You will not normally need to use this, as
|
|
Packit Service |
ca3877 |
* #SoupMessage frees its associated message bodies automatically.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_body_free (SoupMessageBody *body)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!g_atomic_int_dec_and_test (&priv->ref_count))
|
|
Packit Service |
ca3877 |
return;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
soup_message_body_truncate (body);
|
|
Packit Service |
ca3877 |
g_slice_free (SoupMessageBodyPrivate, priv);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
G_DEFINE_BOXED_TYPE (SoupMessageBody, soup_message_body, soup_message_body_copy, soup_message_body_free)
|