Basic implementation of loading.

Add an error domain for the purpose of returning errors.
This commit is contained in:
Přemysl Eric Janouch 2011-01-16 13:36:11 +01:00
parent e9da09f196
commit 5124cf8d71
2 changed files with 129 additions and 6 deletions

View File

@ -50,6 +50,13 @@ static void ld_diagram_dispose (GObject *gobject);
static void ld_diagram_finalize (GObject *gobject); static void ld_diagram_finalize (GObject *gobject);
static gboolean write_signature (GOutputStream *stream, GError **error); 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_diagram (LdDiagram *self);
static JsonNode *serialize_object (LdDiagramObject *object); static JsonNode *serialize_object (LdDiagramObject *object);
static const gchar *get_object_class_string (GType type); 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: * ld_diagram_new:
* *
@ -243,25 +263,32 @@ ld_diagram_load_from_file (LdDiagram *self,
const gchar *filename, GError **error) const gchar *filename, GError **error)
{ {
JsonParser *parser; JsonParser *parser;
GError *json_error; GError *local_error;
g_return_val_if_fail (LD_IS_DIAGRAM (self), FALSE); g_return_val_if_fail (LD_IS_DIAGRAM (self), FALSE);
g_return_val_if_fail (filename != NULL, FALSE); g_return_val_if_fail (filename != NULL, FALSE);
/* TODO: Implement loading for real. This is just a stub. */
parser = json_parser_new (); parser = json_parser_new ();
json_error = NULL; local_error = NULL;
json_parser_load_from_file (parser, filename, &json_error); json_parser_load_from_file (parser, filename, &local_error);
if (json_error) if (local_error)
{ {
g_propagate_error (error, json_error); g_propagate_error (error, local_error);
g_object_unref (parser); g_object_unref (parser);
return FALSE; return FALSE;
} }
ld_diagram_clear (self); ld_diagram_clear (self);
local_error = NULL;
deserialize_diagram (self, json_parser_get_root (parser), &local_error);
g_object_unref (parser); g_object_unref (parser);
if (local_error)
{
g_propagate_error (error, local_error);
return FALSE;
}
return TRUE; return TRUE;
} }
@ -347,6 +374,80 @@ write_signature (GOutputStream *stream, GError **error)
return TRUE; 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 * static JsonNode *
serialize_diagram (LdDiagram *self) serialize_diagram (LdDiagram *self)
{ {

View File

@ -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; GType ld_diagram_get_type (void) G_GNUC_CONST;
LdDiagram *ld_diagram_new (void); LdDiagram *ld_diagram_new (void);