[librsvg/librsvg-2.40] Allow loading one byte at a time with rsvg_handle_write()
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/librsvg-2.40] Allow loading one byte at a time with rsvg_handle_write()
- Date: Wed, 4 Oct 2017 01:05:40 +0000 (UTC)
commit 20bab7fb4a181419617b5bbbf539b1e00f94a344
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Oct 3 14:45:37 2017 -0500
Allow loading one byte at a time with rsvg_handle_write()
This hadn't worked for a long time for compressed files, since we
weren't holding the state of reading the gzip header. Now we have a
test for it.
rsvg-base.c | 57 ++++++++++++++++++++++++++++++++++++++++++------------
rsvg-private.h | 1 +
tests/loading.c | 9 ++++++-
3 files changed, 52 insertions(+), 15 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index 2ae8528..4a20306 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -1748,27 +1748,58 @@ rsvg_handle_write (RsvgHandle * handle, const guchar * buf, gsize count, GError
priv = handle->priv;
rsvg_return_val_if_fail (priv->state == RSVG_HANDLE_STATE_START
+ || priv->state == RSVG_HANDLE_STATE_EXPECTING_GZ_1
|| priv->state == RSVG_HANDLE_STATE_READING,
FALSE,
error);
- if (priv->state == RSVG_HANDLE_STATE_START) {
- priv->state = RSVG_HANDLE_STATE_READING;
+ while (count > 0) {
+ switch (priv->state) {
+ case RSVG_HANDLE_STATE_START:
+ if (buf[0] == GZ_MAGIC_0) {
+ priv->state = RSVG_HANDLE_STATE_EXPECTING_GZ_1;
+ buf++;
+ count--;
+ } else {
+ priv->state = RSVG_HANDLE_STATE_READING;
+ return rsvg_handle_write_impl (handle, buf, count, error);
+ }
- /* test for GZ marker. todo: store the first 2 bytes in the odd circumstance that someone calls
- * write() in 1 byte increments */
- if ((count >= 2) && (buf[0] == GZ_MAGIC_0) && (buf[1] == GZ_MAGIC_1)) {
- priv->data_input_stream = g_memory_input_stream_new ();
- }
- }
+ break;
- if (priv->data_input_stream) {
- g_memory_input_stream_add_data ((GMemoryInputStream *) priv->data_input_stream,
- g_memdup (buf, count), count, (GDestroyNotify) g_free);
- return TRUE;
+ case RSVG_HANDLE_STATE_EXPECTING_GZ_1:
+ if (buf[0] == GZ_MAGIC_1) {
+ static const guchar gz_magic[2] = { GZ_MAGIC_0, GZ_MAGIC_1 };
+
+ priv->data_input_stream = g_memory_input_stream_new ();
+ g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (priv->data_input_stream), gz_magic,
2, NULL);
+
+ priv->state = RSVG_HANDLE_STATE_READING;
+ buf++;
+ count--;
+ } else {
+ priv->state = RSVG_HANDLE_STATE_READING;
+ return rsvg_handle_write_impl (handle, buf, count, error);
+ }
+
+ break;
+
+ case RSVG_HANDLE_STATE_READING:
+ if (priv->data_input_stream) {
+ g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (priv->data_input_stream),
+ g_memdup (buf, count), count, (GDestroyNotify) g_free);
+ return TRUE;
+ } else {
+ return rsvg_handle_write_impl (handle, buf, count, error);
+ }
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
}
- return rsvg_handle_write_impl (handle, buf, count, error);
+ return TRUE;
}
/**
diff --git a/rsvg-private.h b/rsvg-private.h
index 899a815..4803b93 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -131,6 +131,7 @@ typedef enum {
/* Reading state for an RsvgHandle */
typedef enum {
RSVG_HANDLE_STATE_START,
+ RSVG_HANDLE_STATE_EXPECTING_GZ_1,
RSVG_HANDLE_STATE_READING,
RSVG_HANDLE_STATE_CLOSED_OK,
RSVG_HANDLE_STATE_CLOSED_ERROR
diff --git a/tests/loading.c b/tests/loading.c
index 3f68dd8..46b8801 100644
--- a/tests/loading.c
+++ b/tests/loading.c
@@ -28,8 +28,12 @@ load_one_byte_at_a_time (gconstpointer data)
done = FALSE;
do {
- if (fread (buf, 1, 1, file) == 1) {
- g_assert (rsvg_handle_write (handle, buf, 1, NULL) != FALSE);
+ size_t num_read;
+
+ num_read = fread (buf, 1, 1, file);
+
+ if (num_read > 0) {
+ g_assert (rsvg_handle_write (handle, buf, num_read, NULL) != FALSE);
} else {
g_assert (ferror (file) == 0);
@@ -53,6 +57,7 @@ main (int argc, char **argv)
g_test_init (&argc, &argv, NULL);
g_test_add_data_func ("/load-one-byte-at-a-time", "loading/gnome-cool.svg", load_one_byte_at_a_time);
+ g_test_add_data_func ("/load-compressed-one-byte-at-a-time", "loading/gnome-cool.svgz",
load_one_byte_at_a_time);
result = g_test_run ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]