GMemoryInputStream: Add API to accept GBytes

And s/Chunk/GBytes/ internally.  GBytes is really a perfect match for
GMemoryInputStream.

https://bugzilla.gnome.org/show_bug.cgi?id=672102
This commit is contained in:
Colin Walters 2012-05-17 14:36:15 -04:00
parent 6e32f0a601
commit 1bedf24879
3 changed files with 78 additions and 41 deletions

View File

@ -548,6 +548,8 @@ g_loadable_icon_load_finish
g_memory_input_stream_get_type g_memory_input_stream_get_type
g_memory_input_stream_new g_memory_input_stream_new
g_memory_input_stream_new_from_data g_memory_input_stream_new_from_data
g_memory_input_stream_new_from_bytes
g_memory_input_stream_add_bytes
g_memory_input_stream_add_data g_memory_input_stream_add_data
g_memory_output_stream_get_type g_memory_output_stream_get_type
g_memory_output_stream_new g_memory_output_stream_new

View File

@ -44,14 +44,6 @@
* #GPollableInputStream. * #GPollableInputStream.
*/ */
typedef struct _Chunk Chunk;
struct _Chunk {
guint8 *data;
gsize len;
GDestroyNotify destroy;
};
struct _GMemoryInputStreamPrivate { struct _GMemoryInputStreamPrivate {
GSList *chunks; GSList *chunks;
gsize len; gsize len;
@ -139,17 +131,6 @@ g_memory_input_stream_class_init (GMemoryInputStreamClass *klass)
istream_class->close_finish = g_memory_input_stream_close_finish; istream_class->close_finish = g_memory_input_stream_close_finish;
} }
static void
free_chunk (gpointer data)
{
Chunk *chunk = data;
if (chunk->destroy)
chunk->destroy (chunk->data);
g_slice_free (Chunk, chunk);
}
static void static void
g_memory_input_stream_finalize (GObject *object) g_memory_input_stream_finalize (GObject *object)
{ {
@ -159,7 +140,7 @@ g_memory_input_stream_finalize (GObject *object)
stream = G_MEMORY_INPUT_STREAM (object); stream = G_MEMORY_INPUT_STREAM (object);
priv = stream->priv; priv = stream->priv;
g_slist_free_full (priv->chunks, free_chunk); g_slist_free_full (priv->chunks, (GDestroyNotify)g_bytes_unref);
G_OBJECT_CLASS (g_memory_input_stream_parent_class)->finalize (object); G_OBJECT_CLASS (g_memory_input_stream_parent_class)->finalize (object);
} }
@ -231,6 +212,29 @@ g_memory_input_stream_new_from_data (const void *data,
return stream; return stream;
} }
/**
* g_memory_input_stream_new_from_bytes:
* @bytes: a #GBytes
*
* Creates a new #GMemoryInputStream with data from the given @bytes.
*
* Returns: new #GInputStream read from @bytes
* Since: 2.34
**/
GInputStream *
g_memory_input_stream_new_from_bytes (GBytes *bytes)
{
GInputStream *stream;
stream = g_memory_input_stream_new ();
g_memory_input_stream_add_bytes (G_MEMORY_INPUT_STREAM (stream),
bytes);
return stream;
}
/** /**
* g_memory_input_stream_add_data: * g_memory_input_stream_add_data:
* @stream: a #GMemoryInputStream * @stream: a #GMemoryInputStream
@ -246,24 +250,43 @@ g_memory_input_stream_add_data (GMemoryInputStream *stream,
gssize len, gssize len,
GDestroyNotify destroy) GDestroyNotify destroy)
{ {
GMemoryInputStreamPrivate *priv; GBytes *bytes;
Chunk *chunk;
g_return_if_fail (G_IS_MEMORY_INPUT_STREAM (stream));
g_return_if_fail (data != NULL);
priv = stream->priv;
if (len == -1) if (len == -1)
len = strlen (data); len = strlen (data);
chunk = g_slice_new (Chunk);
chunk->data = (guint8 *)data;
chunk->len = len;
chunk->destroy = destroy;
priv->chunks = g_slist_append (priv->chunks, chunk); /* It's safe to discard the const here because we're chaining the
priv->len += chunk->len; * destroy callback.
*/
bytes = g_bytes_new_with_free_func (data, len, destroy, (void*)data);
g_memory_input_stream_add_bytes (stream, bytes);
g_bytes_unref (bytes);
}
/**
* g_memory_input_stream_add_bytes:
* @stream: a #GMemoryInputStream
* @bytes: input data
*
* Appends @bytes to data that can be read from the input stream.
*
* Since: 2.34
*/
void
g_memory_input_stream_add_bytes (GMemoryInputStream *stream,
GBytes *bytes)
{
GMemoryInputStreamPrivate *priv;
g_return_if_fail (G_IS_MEMORY_INPUT_STREAM (stream));
g_return_if_fail (bytes != NULL);
priv = stream->priv;
priv->chunks = g_slist_append (priv->chunks, g_bytes_ref (bytes));
priv->len += g_bytes_get_size (bytes);
} }
static gssize static gssize
@ -276,7 +299,8 @@ g_memory_input_stream_read (GInputStream *stream,
GMemoryInputStream *memory_stream; GMemoryInputStream *memory_stream;
GMemoryInputStreamPrivate *priv; GMemoryInputStreamPrivate *priv;
GSList *l; GSList *l;
Chunk *chunk; GBytes *chunk;
gsize len;
gsize offset, start, rest, size; gsize offset, start, rest, size;
memory_stream = G_MEMORY_INPUT_STREAM (stream); memory_stream = G_MEMORY_INPUT_STREAM (stream);
@ -287,12 +311,13 @@ g_memory_input_stream_read (GInputStream *stream,
offset = 0; offset = 0;
for (l = priv->chunks; l; l = l->next) for (l = priv->chunks; l; l = l->next)
{ {
chunk = (Chunk *)l->data; chunk = (GBytes *)l->data;
len = g_bytes_get_size (chunk);
if (offset + chunk->len > priv->pos) if (offset + len > priv->pos)
break; break;
offset += chunk->len; offset += len;
} }
start = priv->pos - offset; start = priv->pos - offset;
@ -300,10 +325,14 @@ g_memory_input_stream_read (GInputStream *stream,
for (; l && rest > 0; l = l->next) for (; l && rest > 0; l = l->next)
{ {
chunk = (Chunk *)l->data; const guint8* chunk_data;
size = MIN (rest, chunk->len - start); chunk = (GBytes *)l->data;
memcpy ((guint8 *)buffer + (count - rest), chunk->data + start, size); chunk_data = g_bytes_get_data (chunk, &len);
size = MIN (rest, len - start);
memcpy ((guint8 *)buffer + (count - rest), chunk_data + start, size);
rest -= size; rest -= size;
start = 0; start = 0;

View File

@ -72,10 +72,16 @@ GInputStream * g_memory_input_stream_new (void);
GInputStream * g_memory_input_stream_new_from_data (const void *data, GInputStream * g_memory_input_stream_new_from_data (const void *data,
gssize len, gssize len,
GDestroyNotify destroy); GDestroyNotify destroy);
GLIB_AVAILABLE_IN_2_34
GInputStream * g_memory_input_stream_new_from_bytes (GBytes *bytes);
void g_memory_input_stream_add_data (GMemoryInputStream *stream, void g_memory_input_stream_add_data (GMemoryInputStream *stream,
const void *data, const void *data,
gssize len, gssize len,
GDestroyNotify destroy); GDestroyNotify destroy);
GLIB_AVAILABLE_IN_2_34
void g_memory_input_stream_add_bytes (GMemoryInputStream *stream,
GBytes *bytes);
G_END_DECLS G_END_DECLS