[librsvg/librsvg-2.40] RsvgHandle: use a state field instead of finished/is_closed/first_write flags



commit 623308dbe268af00aee5d9adc294cac941cd48c6
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Aug 8 13:08:41 2017 -0500

    RsvgHandle: use a state field instead of finished/is_closed/first_write flags
    
    This makes it easier to see, well, which reading state we are in.

 rsvg-base.c         |   39 ++++++++++++++++++++++++++++-----------
 rsvg-cairo-render.c |    2 +-
 rsvg-gobject.c      |    3 +--
 rsvg-private.h      |   14 ++++++++++----
 rsvg.c              |    2 +-
 5 files changed, 41 insertions(+), 19 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index 90815d0..c6ded51 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -1194,8 +1194,6 @@ rsvg_handle_close_impl (RsvgHandle * handle, GError ** error)
 {
     GError *real_error = NULL;
 
-       handle->priv->is_closed = TRUE;
-
     handle->priv->error = &real_error;
 
     if (handle->priv->ctxt != NULL) {
@@ -1211,7 +1209,6 @@ rsvg_handle_close_impl (RsvgHandle * handle, GError ** error)
         handle->priv->ctxt = rsvg_free_xml_parser_and_doc (handle->priv->ctxt);
     }
 
-    handle->priv->finished = TRUE;
     handle->priv->error = NULL;
 
     if (real_error != NULL) {
@@ -1732,10 +1729,13 @@ rsvg_handle_write (RsvgHandle * handle, const guchar * buf, gsize count, GError
     rsvg_return_val_if_fail (handle, FALSE, error);
     priv = handle->priv;
 
-    rsvg_return_val_if_fail (!priv->is_closed, FALSE, error);
+    rsvg_return_val_if_fail (priv->state == RSVG_HANDLE_STATE_START
+                             || priv->state == RSVG_HANDLE_STATE_READING,
+                             FALSE,
+                             error);
 
-    if (priv->first_write) {
-        priv->first_write = FALSE;
+    if (priv->state == RSVG_HANDLE_STATE_START) {
+        priv->state = RSVG_HANDLE_STATE_READING;
 
         /* test for GZ marker. todo: store the first 2 bytes in the odd circumstance that someone calls
          * write() in 1 byte increments */
@@ -1768,12 +1768,16 @@ gboolean
 rsvg_handle_close (RsvgHandle * handle, GError ** error)
 {
     RsvgHandlePrivate *priv;
+    gboolean result;
 
     rsvg_return_val_if_fail (handle, FALSE, error);
     priv = handle->priv;
 
-    if (priv->is_closed)
-          return TRUE;
+    if (priv->state == RSVG_HANDLE_STATE_CLOSED_OK
+        || priv->state == RSVG_HANDLE_STATE_CLOSED_ERROR) {
+        /* closing is idempotent */
+        return TRUE;
+    }
 
     if (priv->data_input_stream) {
         gboolean ret;
@@ -1785,7 +1789,15 @@ rsvg_handle_close (RsvgHandle * handle, GError ** error)
         return ret;
     }
 
-    return rsvg_handle_close_impl (handle, error);
+    result = rsvg_handle_close_impl (handle, error);
+
+    if (result) {
+        priv->state = RSVG_HANDLE_STATE_CLOSED_OK;
+    } else {
+        priv->state = RSVG_HANDLE_STATE_CLOSED_ERROR;
+    }
+
+    return result;
 }
 
 /**
@@ -1832,6 +1844,7 @@ rsvg_handle_read_stream_sync (RsvgHandle   *handle,
     stream = g_buffered_input_stream_new (stream);
     if (g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (stream), 2, cancellable, error) != 2) {
         g_object_unref (stream);
+        priv->state = RSVG_HANDLE_STATE_CLOSED_ERROR;
         return FALSE;
     }
     buf = g_buffered_input_stream_peek_buffer (G_BUFFERED_INPUT_STREAM (stream), NULL);
@@ -1877,8 +1890,6 @@ rsvg_handle_read_stream_sync (RsvgHandle   *handle,
 
     priv->ctxt = rsvg_free_xml_parser_and_doc (priv->ctxt);
 
-    priv->finished = TRUE;
-
     res = TRUE;
 
   out:
@@ -1888,6 +1899,12 @@ rsvg_handle_read_stream_sync (RsvgHandle   *handle,
     priv->error = NULL;
     g_clear_object (&priv->cancellable);
 
+    if (res) {
+        priv->state = RSVG_HANDLE_STATE_CLOSED_OK;
+    } else {
+        priv->state = RSVG_HANDLE_STATE_CLOSED_ERROR;
+    }
+
     return res;
 }
 
diff --git a/rsvg-cairo-render.c b/rsvg-cairo-render.c
index 4285fe8..e06a65a 100644
--- a/rsvg-cairo-render.c
+++ b/rsvg-cairo-render.c
@@ -198,7 +198,7 @@ rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id)
 
     g_return_val_if_fail (handle != NULL, FALSE);
 
-    if (!handle->priv->finished)
+    if (handle->priv->state != RSVG_HANDLE_STATE_CLOSED_OK)
         return FALSE;
 
     if (id && *id)
diff --git a/rsvg-gobject.c b/rsvg-gobject.c
index 8adb5cd..888c403 100644
--- a/rsvg-gobject.c
+++ b/rsvg-gobject.c
@@ -68,6 +68,7 @@ rsvg_handle_init (RsvgHandle * self)
     self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, RSVG_TYPE_HANDLE, RsvgHandlePrivate);
 
     self->priv->flags = RSVG_HANDLE_FLAGS_NONE;
+    self->priv->state = RSVG_HANDLE_STATE_START;
     self->priv->load_policy = RSVG_LOAD_POLICY_DEFAULT;
     self->priv->defs = rsvg_defs_new (self);
     self->priv->handler_nest = 0;
@@ -87,9 +88,7 @@ rsvg_handle_init (RsvgHandle * self)
     self->priv->currentnode = NULL;
     self->priv->treebase = NULL;
 
-    self->priv->finished = FALSE;
     self->priv->data_input_stream = NULL;
-    self->priv->first_write = TRUE;
     self->priv->cancellable = NULL;
 
     self->priv->is_disposed = FALSE;
diff --git a/rsvg-private.h b/rsvg-private.h
index 1433247..899a815 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -128,13 +128,22 @@ typedef enum {
 
 #define RSVG_LOAD_POLICY_DEFAULT (RSVG_LOAD_POLICY_STRICT)
 
+/* Reading state for an RsvgHandle */
+typedef enum {
+    RSVG_HANDLE_STATE_START,
+    RSVG_HANDLE_STATE_READING,
+    RSVG_HANDLE_STATE_CLOSED_OK,
+    RSVG_HANDLE_STATE_CLOSED_ERROR
+} RsvgHandleState;
+
 struct RsvgHandlePrivate {
     RsvgHandleFlags flags;
 
+    RsvgHandleState state;
+
     RsvgLoadPolicy load_policy;
 
     gboolean is_disposed;
-    gboolean is_closed;
 
     RsvgSizeFunc size_func;
     gpointer user_data;
@@ -173,11 +182,8 @@ struct RsvgHandlePrivate {
     gchar *base_uri;
     GFile *base_gfile;
 
-    gboolean finished;
-
     gboolean in_loop;          /* see get_dimension() */
 
-    gboolean first_write;
     GInputStream *data_input_stream; /* for rsvg_handle_write of svgz data */
 };
 
diff --git a/rsvg.c b/rsvg.c
index 31c4baf..e1d85c7 100644
--- a/rsvg.c
+++ b/rsvg.c
@@ -71,7 +71,7 @@ rsvg_handle_get_pixbuf_sub (RsvgHandle * handle, const char *id)
 
     g_return_val_if_fail (handle != NULL, NULL);
 
-    if (!handle->priv->finished)
+    if (handle->priv->state != RSVG_HANDLE_STATE_CLOSED_OK)
         return NULL;
 
     rsvg_handle_get_dimensions (handle, &dimensions);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]