[gtk+] gsk: Add docs and error handling to serialization API



commit 4bb0c70c11c4b2af65bc66ca8a8d1c8cecbb7e92
Author: Benjamin Otte <otte redhat com>
Date:   Fri Dec 23 08:03:36 2016 +0100

    gsk: Add docs and error handling to serialization API

 docs/reference/gsk/gsk4-sections.txt |    5 +
 gsk/gskenums.h                       |   17 ++++
 gsk/gskrendernode.c                  |   46 +++++++++++-
 gsk/gskrendernode.h                  |   10 ++-
 gsk/gskrendernodeimpl.c              |  136 ++++++++++++++++++++++------------
 gsk/gskrendernodeprivate.h           |    5 +-
 tests/rendernode.c                   |    5 +-
 7 files changed, 165 insertions(+), 59 deletions(-)
---
diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt
index 1a2c526..a56cd4a 100644
--- a/docs/reference/gsk/gsk4-sections.txt
+++ b/docs/reference/gsk/gsk4-sections.txt
@@ -30,6 +30,7 @@ gsk_render_node_unref
 GskRenderNodeType
 gsk_render_node_get_node_type
 gsk_render_node_draw
+GskSerializationError
 gsk_render_node_serialize
 gsk_render_node_deserialize
 gsk_render_node_write_to_file
@@ -72,6 +73,10 @@ GskRenderNode
 GskRenderNodeClass
 gsk_render_node_get_type
 GSK_TYPE_BLEND_MODE
+<SUBSECTION Standard>
+gsk_serialization_error_quark
+GSK_SERIALIZATION_ERROR
+GSK_TYPE_SERIALIZATION_ERROR
 </SECTION>
 
 <SECTION>
diff --git a/gsk/gskenums.h b/gsk/gskenums.h
index 3b6df78..9199782 100644
--- a/gsk/gskenums.h
+++ b/gsk/gskenums.h
@@ -152,4 +152,21 @@ typedef enum {
   GSK_CORNER_BOTTOM_LEFT
 } GskCorner;
 
+/**
+ * GskSerializationError:
+ * @GSK_SERIALIZATION_UNSUPPORTED_FORMAT: The format can not be
+ *     identified
+ * @GSK_SERIALIZATION_UNSUPPORTED_VERSION: The version of the data
+ *     is not understood
+ * @GSK_SERIALIZATION_INVALID_DATA: The given data may not exist in
+ *     a proper serialization
+ *
+ * Errors that can happen during (de)serialization.
+ */
+typedef enum {
+  GSK_SERIALIZATION_UNSUPPORTED_FORMAT,
+  GSK_SERIALIZATION_UNSUPPORTED_VERSION,
+  GSK_SERIALIZATION_INVALID_DATA
+} GskSerializationError;
+
 #endif /* __GSK_TYPES_H__ */
diff --git a/gsk/gskrendernode.c b/gsk/gskrendernode.c
index 8ce7da7..f6e5a76 100644
--- a/gsk/gskrendernode.c
+++ b/gsk/gskrendernode.c
@@ -65,6 +65,8 @@ G_DEFINE_BOXED_TYPE (GskRenderNode, gsk_render_node,
                      gsk_render_node_ref,
                      gsk_render_node_unref)
 
+G_DEFINE_QUARK (gsk-serialization-error-quark, gsk_serialization_error)
+
 static void
 gsk_render_node_finalize (GskRenderNode *self)
 {
@@ -297,6 +299,22 @@ gsk_render_node_draw (GskRenderNode *node,
 #define GSK_RENDER_NODE_SERIALIZATION_VERSION 0
 #define GSK_RENDER_NODE_SERIALIZATION_ID "GskRenderNode"
 
+/**
+ * gsk_render_node_serialize:
+ * @node: a #GskRenderNode
+ *
+ * Serializes the @node for later deserialization via
+ * gsk_render_node_deserialize(). No guarantees are made about the format
+ * used other than that the same version of GTK+ will be able to deserialize
+ * the result of a call to gsk_render_node_serialize() and
+ * gsk_render_node_deserialize() will correctly reject files it cannot open
+ * that were created with previous versions of GTK+.
+ *
+ * The intended use of this functions is testing, benchmarking and debugging.
+ * The format is not meant as a permanent storage format.
+ *
+ * Returns: a #GBytes representing the node.
+ **/
 GBytes *
 gsk_render_node_serialize (GskRenderNode *node)
 {
@@ -353,8 +371,20 @@ gsk_render_node_write_to_file (GskRenderNode *node,
   return result;
 }
 
+/**
+ * gsk_render_node_deserialize:
+ * @bytes: the bytes containing the data
+ * @error: (allow-none): location to store error or %NULL
+ *
+ * Loads data previously created via gsk_render_node_serialize(). For a
+ * discussion of the supported format, see that function.
+ *
+ * Returns: (nullable) (transfer full): a new #GskRenderNode or %NULL on
+ *     error.
+ **/
 GskRenderNode *
-gsk_render_node_deserialize (GBytes *bytes)
+gsk_render_node_deserialize (GBytes  *bytes,
+                             GError **error)
 {
   char *id_string;
   guint32 version, node_type;
@@ -366,12 +396,20 @@ gsk_render_node_deserialize (GBytes *bytes)
   g_variant_get (variant, "(suuv)", &id_string, &version, &node_type, &node_variant);
 
   if (!g_str_equal (id_string, GSK_RENDER_NODE_SERIALIZATION_ID))
-    goto out;
+    {
+      g_set_error (error, GSK_SERIALIZATION_ERROR, GSK_SERIALIZATION_UNSUPPORTED_FORMAT,
+                   "Data not in GskRenderNode serialization format.");
+      goto out;
+    }
 
   if (version != GSK_RENDER_NODE_SERIALIZATION_VERSION)
-    goto out;
+    {
+      g_set_error (error, GSK_SERIALIZATION_ERROR, GSK_SERIALIZATION_UNSUPPORTED_VERSION,
+                   "Format version %u not supported.", version);
+      goto out;
+    }
 
-  node = gsk_render_node_deserialize_node (node_type, node_variant);
+  node = gsk_render_node_deserialize_node (node_type, node_variant, error);
 
 out:
   g_free (id_string);
diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h
index f36cafc..649dc69 100644
--- a/gsk/gskrendernode.h
+++ b/gsk/gskrendernode.h
@@ -32,6 +32,8 @@ G_BEGIN_DECLS
 
 #define GSK_IS_RENDER_NODE(obj) ((obj) != NULL)
 
+#define GSK_SERIALIZATION_ERROR       (gsk_serialization_error_quark ())
+
 typedef struct _GskRenderNode           GskRenderNode;
 typedef struct _GskColorStop            GskColorStop;
 typedef struct _GskShadow               GskShadow;
@@ -51,7 +53,10 @@ struct _GskShadow
 };
 
 GDK_AVAILABLE_IN_3_90
-GType gsk_render_node_get_type (void) G_GNUC_CONST;
+GType                   gsk_render_node_get_type                (void) G_GNUC_CONST;
+
+GDK_AVAILABLE_IN_3_90
+GQuark                  gsk_serialization_error_quark           (void);
 
 GDK_AVAILABLE_IN_3_90
 GskRenderNode *         gsk_render_node_ref                     (GskRenderNode *node);
@@ -181,7 +186,8 @@ gboolean                gsk_render_node_write_to_file           (GskRenderNode *
                                                                  const char    *filename,
                                                                  GError       **error);
 GDK_AVAILABLE_IN_3_90
-GskRenderNode *         gsk_render_node_deserialize             (GBytes        *bytes);
+GskRenderNode *         gsk_render_node_deserialize             (GBytes        *bytes,
+                                                                 GError       **error);
 
 G_END_DECLS
 
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index bc589d0..3cea64c 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -26,6 +26,22 @@
 #include "gskroundedrectprivate.h"
 #include "gsktextureprivate.h"
 
+static gboolean
+check_variant_type (GVariant *variant,
+                    const char *type_string,
+                    GError     **error)
+{
+  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (type_string)))
+    {
+      g_set_error (error, GSK_SERIALIZATION_ERROR, GSK_SERIALIZATION_INVALID_DATA,
+                   "Wrong variant type, got '%s' but needed '%s",
+                   g_variant_get_type_string (variant), type_string);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
 /*** GSK_COLOR_NODE ***/
 
 typedef struct _GskColorNode GskColorNode;
@@ -71,12 +87,13 @@ gsk_color_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_color_node_deserialize (GVariant *variant)
+gsk_color_node_deserialize (GVariant  *variant,
+                            GError   **error)
 {
   double x, y, w, h;
   GdkRGBA color;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_COLOR_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_COLOR_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, GSK_COLOR_NODE_VARIANT_TYPE,
@@ -213,14 +230,15 @@ gsk_linear_gradient_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_linear_gradient_node_real_deserialize (GVariant *variant,
-                                           gboolean  repeating)
+gsk_linear_gradient_node_real_deserialize (GVariant  *variant,
+                                           gboolean   repeating,
+                                           GError   **error)
 {
   GVariantIter *iter;
   double x, y, w, h, start_x, start_y, end_x, end_y;
   gsize i, n_stops;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_LINEAR_GRADIENT_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_LINEAR_GRADIENT_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, GSK_LINEAR_GRADIENT_NODE_VARIANT_TYPE,
@@ -250,15 +268,17 @@ gsk_linear_gradient_node_real_deserialize (GVariant *variant,
 }
 
 static GskRenderNode *
-gsk_linear_gradient_node_deserialize (GVariant *variant)
+gsk_linear_gradient_node_deserialize (GVariant  *variant,
+                                      GError   **error)
 {
-  return gsk_linear_gradient_node_real_deserialize (variant, FALSE);
+  return gsk_linear_gradient_node_real_deserialize (variant, FALSE, error);
 }
 
 static GskRenderNode *
-gsk_repeating_linear_gradient_node_deserialize (GVariant *variant)
+gsk_repeating_linear_gradient_node_deserialize (GVariant  *variant,
+                                                GError   **error)
 {
-  return gsk_linear_gradient_node_real_deserialize (variant, TRUE);
+  return gsk_linear_gradient_node_real_deserialize (variant, TRUE, error);
 }
 
 static const GskRenderNodeClass GSK_LINEAR_GRADIENT_NODE_CLASS = {
@@ -473,12 +493,13 @@ gsk_border_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_border_node_deserialize (GVariant *variant)
+gsk_border_node_deserialize (GVariant  *variant,
+                             GError   **error)
 {
   double doutline[12], dwidths[4];
   GdkRGBA colors[4];
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_BORDER_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_BORDER_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, GSK_BORDER_NODE_VARIANT_TYPE,
@@ -650,7 +671,8 @@ gsk_texture_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_texture_node_deserialize (GVariant *variant)
+gsk_texture_node_deserialize (GVariant  *variant,
+                              GError   **error)
 {
   GskRenderNode *node;
   GskTexture *texture;
@@ -659,7 +681,7 @@ gsk_texture_node_deserialize (GVariant *variant)
   GVariant *pixel_variant;
   gsize n_pixels;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_TEXTURE_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_TEXTURE_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, "(dddduu@au)",
@@ -1152,12 +1174,13 @@ gsk_inset_shadow_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_inset_shadow_node_deserialize (GVariant *variant)
+gsk_inset_shadow_node_deserialize (GVariant  *variant,
+                                   GError   **error)
 {
   double doutline[12], dx, dy, spread, radius;
   GdkRGBA color;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_INSET_SHADOW_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_INSET_SHADOW_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, GSK_INSET_SHADOW_NODE_VARIANT_TYPE,
@@ -1394,12 +1417,13 @@ gsk_outset_shadow_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_outset_shadow_node_deserialize (GVariant *variant)
+gsk_outset_shadow_node_deserialize (GVariant  *variant,
+                                    GError   **error)
 {
   double doutline[12], dx, dy, spread, radius;
   GdkRGBA color;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_OUTSET_SHADOW_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_OUTSET_SHADOW_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, GSK_INSET_SHADOW_NODE_VARIANT_TYPE,
@@ -1554,7 +1578,8 @@ gsk_cairo_node_serialize (GskRenderNode *node)
 const cairo_user_data_key_t gsk_surface_variant_key;
 
 static GskRenderNode *
-gsk_cairo_node_deserialize (GVariant *variant)
+gsk_cairo_node_deserialize (GVariant  *variant,
+                            GError   **error)
 {
   GskRenderNode *result;
   cairo_surface_t *surface;
@@ -1563,7 +1588,7 @@ gsk_cairo_node_deserialize (GVariant *variant)
   GVariant *pixel_variant;
   gsize n_pixels;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_CAIRO_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_CAIRO_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, "(dddduu@au)",
@@ -1821,7 +1846,8 @@ gsk_container_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_container_node_deserialize (GVariant *variant)
+gsk_container_node_deserialize (GVariant  *variant,
+                                GError   **error)
 {
   GskRenderNode *result;
   GVariantIter iter;
@@ -1829,7 +1855,7 @@ gsk_container_node_deserialize (GVariant *variant)
   guint32 child_type;
   GVariant *child_variant;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_CONTAINER_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_CONTAINER_NODE_VARIANT_TYPE, error))
     return NULL;
 
   i = 0;
@@ -1838,7 +1864,7 @@ gsk_container_node_deserialize (GVariant *variant)
 
   while (g_variant_iter_loop (&iter, "(uv)", &child_type, &child_variant))
     {
-      children[i] = gsk_render_node_deserialize_node (child_type, child_variant);
+      children[i] = gsk_render_node_deserialize_node (child_type, child_variant, error);
       if (children[i] == NULL)
         {
           guint j;
@@ -1996,7 +2022,8 @@ gsk_transform_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_transform_node_deserialize (GVariant *variant)
+gsk_transform_node_deserialize (GVariant  *variant,
+                                GError   **error)
 {
   graphene_matrix_t transform;
   double mat[16];
@@ -2004,7 +2031,7 @@ gsk_transform_node_deserialize (GVariant *variant)
   GVariant *child_variant;
   GskRenderNode *result, *child;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_TRANSFORM_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_TRANSFORM_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, GSK_TRANSFORM_NODE_VARIANT_TYPE,
@@ -2014,7 +2041,7 @@ gsk_transform_node_deserialize (GVariant *variant)
                  &mat[12], &mat[13], &mat[14], &mat[15],
                  &child_type, &child_variant);
 
-  child = gsk_render_node_deserialize_node (child_type, child_variant);
+  child = gsk_render_node_deserialize_node (child_type, child_variant, error);
   g_variant_unref (child_variant);
 
   if (child == NULL)
@@ -2163,21 +2190,22 @@ gsk_opacity_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_opacity_node_deserialize (GVariant *variant)
+gsk_opacity_node_deserialize (GVariant  *variant,
+                              GError   **error)
 {
   double opacity;
   guint32 child_type;
   GVariant *child_variant;
   GskRenderNode *result, *child;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_OPACITY_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_OPACITY_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, GSK_OPACITY_NODE_VARIANT_TYPE,
                  &opacity,
                  &child_type, &child_variant);
 
-  child = gsk_render_node_deserialize_node (child_type, child_variant);
+  child = gsk_render_node_deserialize_node (child_type, child_variant, error);
   g_variant_unref (child_variant);
 
   if (child == NULL)
@@ -2311,21 +2339,22 @@ gsk_clip_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_clip_node_deserialize (GVariant *variant)
+gsk_clip_node_deserialize (GVariant  *variant,
+                           GError   **error)
 {
   double x, y, width, height;
   guint32 child_type;
   GVariant *child_variant;
   GskRenderNode *result, *child;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_CLIP_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_CLIP_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, GSK_CLIP_NODE_VARIANT_TYPE,
                  &x, &y, &width, &height,
                  &child_type, &child_variant);
 
-  child = gsk_render_node_deserialize_node (child_type, child_variant);
+  child = gsk_render_node_deserialize_node (child_type, child_variant, error);
   g_variant_unref (child_variant);
 
   if (child == NULL)
@@ -2462,14 +2491,15 @@ gsk_rounded_clip_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_rounded_clip_node_deserialize (GVariant *variant)
+gsk_rounded_clip_node_deserialize (GVariant  *variant,
+                                   GError   **error)
 {
   double doutline[12];
   guint32 child_type;
   GVariant *child_variant;
   GskRenderNode *child, *result;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_ROUNDED_CLIP_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_ROUNDED_CLIP_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, GSK_ROUNDED_CLIP_NODE_VARIANT_TYPE,
@@ -2478,7 +2508,7 @@ gsk_rounded_clip_node_deserialize (GVariant *variant)
                  &doutline[8], &doutline[9], &doutline[10], &doutline[11],
                  &child_type, &child_variant);
 
-  child = gsk_render_node_deserialize_node (child_type, child_variant);
+  child = gsk_render_node_deserialize_node (child_type, child_variant, error);
   g_variant_unref (child_variant);
 
   if (child == NULL)
@@ -2678,7 +2708,8 @@ gsk_shadow_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_shadow_node_deserialize (GVariant *variant)
+gsk_shadow_node_deserialize (GVariant  *variant,
+                             GError   **error)
 {
   gsize n_shadows;
   guint32 child_type;
@@ -2687,13 +2718,13 @@ gsk_shadow_node_deserialize (GVariant *variant)
   GVariantIter *iter;
   gsize i;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_SHADOW_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_SHADOW_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, GSK_SHADOW_NODE_VARIANT_TYPE,
                  &child_type, &child_variant, &iter);
 
-  child = gsk_render_node_deserialize_node (child_type, child_variant);
+  child = gsk_render_node_deserialize_node (child_type, child_variant, error);
   g_variant_unref (child_variant);
 
   if (child == NULL)
@@ -2901,13 +2932,14 @@ gsk_blend_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_blend_node_deserialize (GVariant *variant)
+gsk_blend_node_deserialize (GVariant  *variant,
+                            GError   **error)
 {
   guint32 bottom_child_type, top_child_type, blend_mode;
   GVariant *bottom_child_variant, *top_child_variant;
   GskRenderNode *bottom_child, *top_child, *result;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_BLEND_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_BLEND_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, GSK_BLEND_NODE_VARIANT_TYPE,
@@ -2915,7 +2947,7 @@ gsk_blend_node_deserialize (GVariant *variant)
                  &top_child_type, &top_child_variant,
                  &blend_mode);
 
-  bottom_child = gsk_render_node_deserialize_node (bottom_child_type, bottom_child_variant);
+  bottom_child = gsk_render_node_deserialize_node (bottom_child_type, bottom_child_variant, error);
   g_variant_unref (bottom_child_variant);
   if (bottom_child == NULL)
     {
@@ -2923,7 +2955,7 @@ gsk_blend_node_deserialize (GVariant *variant)
       return NULL;
     }
 
-  top_child = gsk_render_node_deserialize_node (top_child_type, top_child_variant);
+  top_child = gsk_render_node_deserialize_node (top_child_type, top_child_variant, error);
   g_variant_unref (top_child_variant);
   if (top_child == NULL)
     {
@@ -3071,14 +3103,15 @@ gsk_cross_fade_node_serialize (GskRenderNode *node)
 }
 
 static GskRenderNode *
-gsk_cross_fade_node_deserialize (GVariant *variant)
+gsk_cross_fade_node_deserialize (GVariant  *variant,
+                                 GError   **error)
 {
   guint32 start_child_type, end_child_type;
   GVariant *start_child_variant, *end_child_variant;
   GskRenderNode *start_child, *end_child, *result;
   double progress;
 
-  if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (GSK_CROSS_FADE_NODE_VARIANT_TYPE)))
+  if (!check_variant_type (variant, GSK_CROSS_FADE_NODE_VARIANT_TYPE, error))
     return NULL;
 
   g_variant_get (variant, GSK_CROSS_FADE_NODE_VARIANT_TYPE,
@@ -3086,7 +3119,7 @@ gsk_cross_fade_node_deserialize (GVariant *variant)
                  &end_child_type, &end_child_variant,
                  &progress);
 
-  start_child = gsk_render_node_deserialize_node (start_child_type, start_child_variant);
+  start_child = gsk_render_node_deserialize_node (start_child_type, start_child_variant, error);
   g_variant_unref (start_child_variant);
   if (start_child == NULL)
     {
@@ -3094,7 +3127,7 @@ gsk_cross_fade_node_deserialize (GVariant *variant)
       return NULL;
     }
 
-  end_child = gsk_render_node_deserialize_node (end_child_type, end_child_variant);
+  end_child = gsk_render_node_deserialize_node (end_child_type, end_child_variant, error);
   g_variant_unref (end_child_variant);
   if (end_child == NULL)
     {
@@ -3204,8 +3237,9 @@ static const GskRenderNodeClass *klasses[] = {
 };
 
 GskRenderNode *
-gsk_render_node_deserialize_node (GskRenderNodeType  type,
-                                  GVariant          *variant)
+gsk_render_node_deserialize_node (GskRenderNodeType   type,
+                                  GVariant           *variant,
+                                  GError            **error)
 {
   const GskRenderNodeClass *klass;
   GskRenderNode *result;
@@ -3216,9 +3250,13 @@ gsk_render_node_deserialize_node (GskRenderNodeType  type,
     klass = NULL;
 
   if (klass == NULL)
-    return NULL;
+    {
+      g_set_error (error, GSK_SERIALIZATION_ERROR, GSK_SERIALIZATION_INVALID_DATA,
+                   "Type %u is not a valid node type", type);
+      return NULL;
+    }
 
-  result = klass->deserialize (variant);
+  result = klass->deserialize (variant, error);
 
   return result;
 }
diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h
index 25c10ea..1139e51 100644
--- a/gsk/gskrendernodeprivate.h
+++ b/gsk/gskrendernodeprivate.h
@@ -35,13 +35,14 @@ struct _GskRenderNodeClass
   void (* draw) (GskRenderNode *node,
                  cairo_t       *cr);
   GVariant * (* serialize) (GskRenderNode *node);
-  GskRenderNode * (* deserialize) (GVariant *variant);
+  GskRenderNode * (* deserialize) (GVariant  *variant,
+                                   GError   **error);
 };
 
 GskRenderNode *gsk_render_node_new (const GskRenderNodeClass *node_class, gsize extra_size);
 
 GVariant * gsk_render_node_serialize_node (GskRenderNode *node);
-GskRenderNode * gsk_render_node_deserialize_node (GskRenderNodeType type, GVariant *variant);
+GskRenderNode * gsk_render_node_deserialize_node (GskRenderNodeType type, GVariant *variant, GError **error);
 
 double gsk_opacity_node_get_opacity (GskRenderNode *node);
 
diff --git a/tests/rendernode.c b/tests/rendernode.c
index 12374df..bd10041 100644
--- a/tests/rendernode.c
+++ b/tests/rendernode.c
@@ -51,7 +51,7 @@ main(int argc, char **argv)
     }
 
   start = g_get_monotonic_time ();
-  node = gsk_render_node_deserialize (bytes);
+  node = gsk_render_node_deserialize (bytes, &error);
   end = g_get_monotonic_time ();
   if (benchmark)
     {
@@ -63,7 +63,8 @@ main(int argc, char **argv)
 
   if (node == NULL)
     {
-      g_printerr ("Invalid node file.\n");
+      g_printerr ("Invalid node file: %s\n", error->message);
+      g_clear_error (&error);
       return 1;
     }
 


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