From 5124cf8d71efe0eeba0951969e587cebd46e045e Mon Sep 17 00:00:00 2001 From: Přemysl Janouch Date: Sun, 16 Jan 2011 13:36:11 +0100 Subject: Basic implementation of loading. Add an error domain for the purpose of returning errors. --- liblogdiag/ld-diagram.c | 113 +++++++++++++++++++++++++++++++++++++++++++++--- liblogdiag/ld-diagram.h | 22 ++++++++++ 2 files changed, 129 insertions(+), 6 deletions(-) diff --git a/liblogdiag/ld-diagram.c b/liblogdiag/ld-diagram.c index 817f2ea..3aae65d 100644 --- a/liblogdiag/ld-diagram.c +++ b/liblogdiag/ld-diagram.c @@ -50,6 +50,13 @@ static void ld_diagram_dispose (GObject *gobject); static void ld_diagram_finalize (GObject *gobject); static gboolean write_signature (GOutputStream *stream, GError **error); + +static gboolean check_node (JsonNode *node, JsonNodeType type, + const gchar *id, GError **error); +static gboolean deserialize_diagram (LdDiagram *self, JsonNode *root, + GError **error); +static LdDiagramObject *deserialize_object (JsonObject *object_storage); + static JsonNode *serialize_diagram (LdDiagram *self); static JsonNode *serialize_object (LdDiagramObject *object); static const gchar *get_object_class_string (GType type); @@ -181,6 +188,19 @@ ld_diagram_real_changed (LdDiagram *self) } +/** + * ld_diagram_error_quark: + * + * Registers an error quark for #LdDiagram if necessary. + * + * Return value: The error quark used for #LdDiagram errors. + */ +GQuark +ld_diagram_error_quark (void) +{ + return g_quark_from_static_string ("ld-diagram-error-quark"); +} + /** * ld_diagram_new: * @@ -243,25 +263,32 @@ ld_diagram_load_from_file (LdDiagram *self, const gchar *filename, GError **error) { JsonParser *parser; - GError *json_error; + GError *local_error; g_return_val_if_fail (LD_IS_DIAGRAM (self), FALSE); g_return_val_if_fail (filename != NULL, FALSE); - /* TODO: Implement loading for real. This is just a stub. */ parser = json_parser_new (); - json_error = NULL; - json_parser_load_from_file (parser, filename, &json_error); - if (json_error) + local_error = NULL; + json_parser_load_from_file (parser, filename, &local_error); + if (local_error) { - g_propagate_error (error, json_error); + g_propagate_error (error, local_error); g_object_unref (parser); return FALSE; } ld_diagram_clear (self); + + local_error = NULL; + deserialize_diagram (self, json_parser_get_root (parser), &local_error); g_object_unref (parser); + if (local_error) + { + g_propagate_error (error, local_error); + return FALSE; + } return TRUE; } @@ -347,6 +374,80 @@ write_signature (GOutputStream *stream, GError **error) return TRUE; } +static gboolean +check_node (JsonNode *node, JsonNodeType type, const gchar *id, GError **error) +{ + if (!node) + { + g_set_error (error, LD_DIAGRAM_ERROR, LD_DIAGRAM_ERROR_DIAGRAM_CORRUPT, + "%s is missing", id); + return FALSE; + } + if (!JSON_NODE_HOLDS (node, type)) + { + g_set_error (error, LD_DIAGRAM_ERROR, LD_DIAGRAM_ERROR_DIAGRAM_CORRUPT, + "%s is of wrong type", id); + return FALSE; + } + return TRUE; +} + +static gboolean +deserialize_diagram (LdDiagram *self, JsonNode *root, GError **error) +{ + JsonObject *root_object; + JsonNode *objects_node; + GList *iter; + + if (!check_node (root, JSON_NODE_OBJECT, "the root node", error)) + return FALSE; + + root_object = json_node_get_object (root); + objects_node = json_object_get_member (root_object, "objects"); + if (!check_node (objects_node, JSON_NODE_ARRAY, + "the `objects' array", error)) + return FALSE; + + iter = json_array_get_elements (json_node_get_array (objects_node)); + for (; iter; iter = g_list_next (iter)) + { + GError *node_error = NULL; + + check_node (iter->data, JSON_NODE_OBJECT, "object node", &node_error); + if (node_error) + { + g_warning ("%s", node_error->message); + g_error_free (node_error); + } + else + /* FIXME: Appending is slow. */ + ld_diagram_insert_object (self, + deserialize_object (json_node_get_object (iter->data)), -1); + } + return TRUE; +} + +static LdDiagramObject * +deserialize_object (JsonObject *object_storage) +{ + JsonNode *object_type_node; + const gchar *type; + + json_object_ref (object_storage); + object_type_node = json_object_get_member (object_storage, "type"); + + if (!object_type_node || !JSON_NODE_HOLDS_VALUE (object_type_node)) + goto deserialize_object_default; + + type = json_node_get_string (object_type_node); + if (!g_strcmp0 ("symbol", type)) + return LD_DIAGRAM_OBJECT (ld_diagram_symbol_new (object_storage)); + +deserialize_object_default: + /* Anything we can't identify is just an indefinite object. */ + return ld_diagram_object_new (object_storage); +} + static JsonNode * serialize_diagram (LdDiagram *self) { diff --git a/liblogdiag/ld-diagram.h b/liblogdiag/ld-diagram.h index f364189..d43408c 100644 --- a/liblogdiag/ld-diagram.h +++ b/liblogdiag/ld-diagram.h @@ -56,6 +56,28 @@ struct _LdDiagramClass }; +GQuark ld_diagram_error_quark (void); + +/** + * LD_DIAGRAM_ERROR: + * + * Uset to get the #GError quark for #LdDiagram errors. + */ +#define LD_DIAGRAM_ERROR (ld_diagram_error_quark ()) + +/** + * LdDiagramError: + * @LD_DIAGRAM_ERROR_DIAGRAM_CORRUPT: The input diagram is corrupt. + * + * These identify errors that can occur while calling #LdDiagram functions. + */ +typedef enum +{ + LD_DIAGRAM_ERROR_DIAGRAM_CORRUPT +} +LdDiagramError; + + GType ld_diagram_get_type (void) G_GNUC_CONST; LdDiagram *ld_diagram_new (void); -- cgit v1.2.3-70-g09d2