[librsvg] rsvg-load.c: Accumulate to a GByteArray, not a GMemoryInputStream
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] rsvg-load.c: Accumulate to a GByteArray, not a GMemoryInputStream
- Date: Mon, 10 Dec 2018 20:54:33 +0000 (UTC)
commit a4b3e21334536a3b60115714a97d0c9af2035791
Author: Federico Mena Quintero <federico gnome org>
Date: Mon Dec 10 14:06:23 2018 -0600
rsvg-load.c: Accumulate to a GByteArray, not a GMemoryInputStream
The latter has O(n^2) behavior when appending lots of small buffers;
it's simply a GSList of GBytes (!).
So, now we use a GByteArray as a buffer, which we pass on in one chunk
at the end to the stream reader.
librsvg/rsvg-load.c | 45 ++++++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 21 deletions(-)
---
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index 0a6dff22..43d3c557 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -60,8 +60,7 @@ struct RsvgLoad {
RsvgHandle *handle;
LoadState state;
-
- GInputStream *stream;
+ GByteArray *buffer;
RsvgXmlState *rust_state;
};
@@ -73,7 +72,7 @@ rsvg_load_new (RsvgHandle *handle)
load->handle = handle;
load->state = LOAD_STATE_START;
- load->stream = NULL;
+ load->buffer = NULL;
load->rust_state = rsvg_xml_state_new (handle);
@@ -83,7 +82,10 @@ rsvg_load_new (RsvgHandle *handle)
void
rsvg_load_free (RsvgLoad *load)
{
- g_clear_object (&load->stream);
+ if (load->buffer) {
+ g_byte_array_free (load->buffer, TRUE);
+ }
+
g_clear_pointer (&load->rust_state, rsvg_xml_state_free);
g_free (load);
}
@@ -140,30 +142,21 @@ rsvg_load_read_stream_sync (RsvgLoad *load,
return res;
}
-static void
-create_stream (RsvgLoad *load)
-{
- g_assert (load->stream == NULL);
-
- load->stream = g_memory_input_stream_new ();
-}
-
gboolean
rsvg_load_write (RsvgLoad *load, const guchar *buf, gsize count, GError **error)
{
switch (load->state) {
case LOAD_STATE_START:
- g_assert (load->stream == NULL);
+ g_assert (load->buffer == NULL);
+
+ load->buffer = g_byte_array_new();
+ g_byte_array_append (load->buffer, buf, count);
- create_stream (load);
- g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (load->stream),
- g_memdup (buf, count), count, (GDestroyNotify) g_free);
load->state = LOAD_STATE_READING;
break;
case LOAD_STATE_READING:
- g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (load->stream),
- g_memdup (buf, count), count, (GDestroyNotify) g_free);
+ g_byte_array_append (load->buffer, buf, count);
break;
default:
@@ -183,10 +176,20 @@ rsvg_load_close (RsvgLoad *load, GError **error)
case LOAD_STATE_CLOSED:
return TRUE;
- case LOAD_STATE_READING:
- res = rsvg_load_read_stream_sync (load, load->stream, NULL, error);
- g_clear_object (&load->stream);
+ case LOAD_STATE_READING: {
+ GInputStream *stream;
+ GBytes *bytes;
+
+ bytes = g_byte_array_free_to_bytes (load->buffer);
+ load->buffer = NULL;
+
+ stream = g_memory_input_stream_new_from_bytes (bytes);
+ g_bytes_unref (bytes);
+
+ res = rsvg_load_read_stream_sync (load, stream, NULL, error);
+ g_clear_object (&stream);
break;
+ }
default:
g_assert_not_reached();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]