Add g_memory_input_stream_new_from_data_full/add_data_full() apis

Add an extra state pointer and an extra GDestroyNotify function
to the 'Chunk' definition... allowing bindings to attach some extra
state to memory chunks (to get memory management correctly from
language bindings).
Bug #589887
This commit is contained in:
Tristan Van Berkom 2011-09-16 13:46:01 +02:00 committed by Murray Cumming
parent b7051e8da8
commit 42738469d1
2 changed files with 88 additions and 11 deletions

View File

@ -47,6 +47,8 @@ struct _Chunk {
guint8 *data;
gsize len;
GDestroyNotify destroy;
gpointer user_data;
GDestroyNotify user_data_destroy;
};
struct _GMemoryInputStreamPrivate {
@ -148,6 +150,9 @@ free_chunk (gpointer data,
if (chunk->destroy)
chunk->destroy (chunk->data);
if (chunk->user_data_destroy)
chunk->user_data_destroy (chunk->user_data);
g_slice_free (Chunk, chunk);
}
@ -215,13 +220,43 @@ GInputStream *
g_memory_input_stream_new_from_data (const void *data,
gssize len,
GDestroyNotify destroy)
{
return g_memory_input_stream_new_from_data_full (data, len, destroy, NULL, NULL);
}
/**
* g_memory_input_stream_new_from_data_full:
* @data: (array length=len) (element-type guint8): input data
* @len: length of the data, may be -1 if @data is a nul-terminated string
* @destroy: (allow-none): function that is called to free @data, or %NULL
* @user_data: extra state pointer related to the chunk of data
* @user_data_destroy: function that is called to free @user_data, or %NULL
*
* Creates a new #GMemoryInputStream with data in memory of a given size.
*
* This function differs from g_memory_input_stream_new_from_data() only
* because it allows a pointer to some additional state related to
* the data chunk to be stored (this can be used to properly manage
* the life cycle of data chunks from language bindings).
*
* Returns: new #GInputStream read from @data of @len bytes.
*
* Since: 2.30
**/
GInputStream *
g_memory_input_stream_new_from_data_full (const void *data,
gssize len,
GDestroyNotify destroy,
gpointer user_data,
GDestroyNotify user_data_destroy)
{
GInputStream *stream;
stream = g_memory_input_stream_new ();
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream),
data, len, destroy);
g_memory_input_stream_add_data_full (G_MEMORY_INPUT_STREAM (stream),
data, len, destroy,
user_data, user_data_destroy);
return stream;
}
@ -240,6 +275,35 @@ g_memory_input_stream_add_data (GMemoryInputStream *stream,
const void *data,
gssize len,
GDestroyNotify destroy)
{
g_memory_input_stream_add_data_full (stream, data, len, destroy, NULL, NULL);
}
/**
* g_memory_input_stream_add_data_full:
* @stream: a #GMemoryInputStream
* @data: (array length=len) (element-type guint8): input data
* @len: length of the data, may be -1 if @data is a nul-terminated string
* @destroy: (allow-none): function that is called to free @data, or %NULL
* @user_data: extra state pointer related to the chunk of data
* @user_data_destroy: function that is called to free @user_data, or %NULL
*
* Appends @data to data that can be read from the input stream
*
* This function differs from g_memory_input_stream_add_data() only
* because it allows a pointer to some additional state related to
* the data chunk to be stored (this can be used to properly manage
* the life cycle of data chunks from language bindings).
*
* Since: 2.30
*/
void
g_memory_input_stream_add_data_full (GMemoryInputStream *stream,
const void *data,
gssize len,
GDestroyNotify destroy,
gpointer user_data,
GDestroyNotify user_data_destroy)
{
GMemoryInputStreamPrivate *priv;
Chunk *chunk;
@ -256,6 +320,8 @@ g_memory_input_stream_add_data (GMemoryInputStream *stream,
chunk->data = (guint8 *)data;
chunk->len = len;
chunk->destroy = destroy;
chunk->user_data = user_data;
chunk->user_data_destroy = user_data_destroy;
priv->chunks = g_slist_append (priv->chunks, chunk);
priv->len += chunk->len;

View File

@ -67,15 +67,26 @@ struct _GMemoryInputStreamClass
};
GType g_memory_input_stream_get_type (void) G_GNUC_CONST;
GInputStream * g_memory_input_stream_new (void);
GInputStream * g_memory_input_stream_new_from_data (const void *data,
gssize len,
GDestroyNotify destroy);
void g_memory_input_stream_add_data (GMemoryInputStream *stream,
const void *data,
gssize len,
GDestroyNotify destroy);
GType g_memory_input_stream_get_type (void) G_GNUC_CONST;
GInputStream * g_memory_input_stream_new (void);
GInputStream * g_memory_input_stream_new_from_data (const void *data,
gssize len,
GDestroyNotify destroy);
GInputStream * g_memory_input_stream_new_from_data_full (const void *data,
gssize len,
GDestroyNotify destroy,
gpointer user_data,
GDestroyNotify user_data_destroy);
void g_memory_input_stream_add_data (GMemoryInputStream *stream,
const void *data,
gssize len,
GDestroyNotify destroy);
void g_memory_input_stream_add_data_full (GMemoryInputStream *stream,
const void *data,
gssize len,
GDestroyNotify destroy,
gpointer user_data,
GDestroyNotify user_data_destroy);
G_END_DECLS