summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--json-glib/json-generator.c125
-rw-r--r--tests/test-04.c68
2 files changed, 190 insertions, 3 deletions
diff --git a/json-glib/json-generator.c b/json-glib/json-generator.c
index df3bf55..1395ee2 100644
--- a/json-glib/json-generator.c
+++ b/json-glib/json-generator.c
@@ -53,6 +53,21 @@ enum
PROP_INDENT
};
+static gchar *dump_value (JsonGenerator *generator,
+ gint level,
+ const gchar *name,
+ JsonNode *node);
+static gchar *dump_array (JsonGenerator *generator,
+ gint level,
+ const gchar *name,
+ JsonArray *array,
+ gsize *length);
+static gchar *dump_object (JsonGenerator *generator,
+ gint level,
+ const gchar *name,
+ JsonObject *object,
+ gsize *length);
+
G_DEFINE_TYPE (JsonGenerator, json_generator, G_TYPE_OBJECT);
static void
@@ -164,6 +179,7 @@ json_generator_init (JsonGenerator *generator)
static gchar *
dump_value (JsonGenerator *generator,
gint level,
+ const gchar *name,
JsonNode *node)
{
gboolean pretty = generator->priv->pretty;
@@ -180,6 +196,9 @@ dump_value (JsonGenerator *generator,
g_string_append_c (buffer, ' ');
}
+ if (name && name[0] != '\0')
+ g_string_append_printf (buffer, "\"%s\" : ", name);
+
json_node_get_value (node, &value);
switch (G_VALUE_TYPE (&value))
@@ -213,6 +232,7 @@ dump_value (JsonGenerator *generator,
static gchar *
dump_array (JsonGenerator *generator,
gint level,
+ const gchar *name,
JsonArray *array,
gsize *length)
{
@@ -230,6 +250,9 @@ dump_array (JsonGenerator *generator,
g_string_append_c (buffer, ' ');
}
+ if (name && name[0] != '\0')
+ g_string_append_printf (buffer, "\"%s\" : ", name);
+
g_string_append_c (buffer, '[');
if (pretty)
@@ -256,16 +279,18 @@ dump_array (JsonGenerator *generator,
break;
case JSON_NODE_VALUE:
- value = dump_value (generator, sub_level, cur);
+ value = dump_value (generator, sub_level, NULL, cur);
g_string_append (buffer, value);
break;
case JSON_NODE_ARRAY:
- value = dump_array (generator, sub_level, json_node_get_array (cur), NULL);
+ value = dump_array (generator, sub_level, NULL, json_node_get_array (cur), NULL);
g_string_append (buffer, value);
break;
case JSON_NODE_OBJECT:
+ value = dump_object (generator, sub_level, NULL, json_node_get_object (cur), NULL);
+ g_string_append (buffer, value);
break;
}
@@ -292,6 +317,99 @@ dump_array (JsonGenerator *generator,
return g_string_free (buffer, FALSE);
}
+static gchar *
+dump_object (JsonGenerator *generator,
+ gint level,
+ const gchar *name,
+ JsonObject *object,
+ gsize *length)
+{
+ GList *members, *l;
+ GString *buffer;
+ gboolean pretty = generator->priv->pretty;
+ guint indent = generator->priv->indent;
+ gint i;
+
+ buffer = g_string_new ("");
+
+ if (pretty)
+ {
+ for (i = 0; i < (level * indent); i++)
+ g_string_append_c (buffer, ' ');
+ }
+
+ if (name && name[0] != '\0')
+ g_string_append_printf (buffer, "\"%s\" : ", name);
+
+ g_string_append_c (buffer, '{');
+
+ if (pretty)
+ g_string_append_c (buffer, '\n');
+ else
+ g_string_append_c (buffer, ' ');
+
+ members = json_object_get_members (object);
+
+ for (l = members; l != NULL; l = l->next)
+ {
+ const gchar *name = l->data;
+ JsonNode *cur = json_object_get_member (object, name);
+ guint sub_level = level + 1;
+ gint j;
+ gchar *value;
+
+ switch (JSON_NODE_TYPE (cur))
+ {
+ case JSON_NODE_NULL:
+ if (pretty)
+ {
+ for (j = 0; j < (sub_level * indent); j++)
+ g_string_append_c (buffer, ' ');
+ }
+ g_string_append_printf (buffer, "\"%s\" : null", name);
+ break;
+
+ case JSON_NODE_VALUE:
+ value = dump_value (generator, sub_level, name, cur);
+ g_string_append (buffer, value);
+ break;
+
+ case JSON_NODE_ARRAY:
+ value = dump_array (generator, sub_level, name, json_node_get_array (cur), NULL);
+ g_string_append (buffer, value);
+ break;
+
+ case JSON_NODE_OBJECT:
+ value = dump_object (generator, sub_level, name, json_node_get_object (cur), NULL);
+ g_string_append (buffer, value);
+ break;
+ }
+
+ if (l->next != NULL)
+ g_string_append_c (buffer, ',');
+
+ if (pretty)
+ g_string_append_c (buffer, '\n');
+ else
+ g_string_append_c (buffer, ' ');
+ }
+
+ g_list_free (members);
+
+ if (pretty)
+ {
+ for (i = 0; i < (level * indent); i++)
+ g_string_append_c (buffer, ' ');
+ }
+
+ g_string_append_c (buffer, '}');
+
+ if (length)
+ *length = buffer->len;
+
+ return g_string_free (buffer, FALSE);
+}
+
/**
* json_generator_new:
*
@@ -339,10 +457,11 @@ json_generator_to_data (JsonGenerator *generator,
switch (JSON_NODE_TYPE (root))
{
case JSON_NODE_ARRAY:
- retval = dump_array (generator, 0, json_node_get_array (root), length);
+ retval = dump_array (generator, 0, NULL, json_node_get_array (root), length);
break;
case JSON_NODE_OBJECT:
+ retval = dump_object (generator, 0, NULL, json_node_get_object (root), length);
break;
case JSON_NODE_NULL:
diff --git a/tests/test-04.c b/tests/test-04.c
index 8b70a0d..e006b48 100644
--- a/tests/test-04.c
+++ b/tests/test-04.c
@@ -143,6 +143,73 @@ test_nested (JsonGenerator *generator)
g_free (data);
}
+static void
+test_object (JsonGenerator *generator)
+{
+ JsonNode *root, *val, *nested_val;
+ JsonArray *array;
+ JsonObject *nested;
+ GValue value = { 0, };
+ gchar *data;
+ gsize len;
+
+ root = json_node_new (JSON_NODE_ARRAY);
+ array = json_array_sized_new (3);
+
+ val = json_node_new (JSON_NODE_VALUE);
+ g_value_init (&value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&value, TRUE);
+ json_node_set_value (val, &value);
+ json_array_add_element (array, val);
+ g_value_unset (&value);
+
+ {
+ val = json_node_new (JSON_NODE_OBJECT);
+ nested = json_object_new ();
+
+ nested_val = json_node_new (JSON_NODE_VALUE);
+ g_value_init (&value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&value, FALSE);
+ json_node_set_value (nested_val, &value);
+ json_object_add_member (nested, "foo", nested_val);
+ g_value_unset (&value);
+
+ nested_val = json_node_new (JSON_NODE_NULL);
+ json_object_add_member (nested, "bar", nested_val);
+
+ json_node_take_object (val, nested);
+ json_array_add_element (array, val);
+ }
+
+ {
+ val = json_node_new (JSON_NODE_OBJECT);
+ nested = json_object_new ();
+
+ nested_val = json_node_new (JSON_NODE_VALUE);
+ g_value_init (&value, G_TYPE_INT);
+ g_value_set_int (&value, 42);
+ json_node_set_value (nested_val, &value);
+ json_object_add_member (nested, "baz", nested_val);
+ g_value_unset (&value);
+
+ json_node_take_object (val, nested);
+ json_array_add_element (array, val);
+ }
+
+ json_node_take_array (root, array);
+ json_generator_set_root (generator, root);
+
+ g_object_set (generator, "pretty", FALSE, NULL);
+ data = json_generator_to_data (generator, &len);
+ g_print ("*** Nested object (len:%d): `%s'\n", len, data);
+ g_free (data);
+
+ g_object_set (generator, "pretty", TRUE, NULL);
+ data = json_generator_to_data (generator, &len);
+ g_print ("*** Nested object (pretty, len:%d):\n%s\n", len, data);
+ g_free (data);
+}
+
int
main (int argc, char *argv[])
{
@@ -155,6 +222,7 @@ main (int argc, char *argv[])
test_empty (generator);
test_simple (generator);
test_nested (generator);
+ test_object (generator);
g_object_unref (generator);