static void consume_array_member (JsonBuilder *bob, const char* elm, JsonArray *arr) { JsonNode *node; if (!arr) return; /* nothing to do */ node = json_node_new (JSON_NODE_ARRAY); json_node_init_array (node, arr); json_array_unref (arr); bob = json_builder_set_member_name (bob, elm); bob = json_builder_add_value (bob, node); /* consumes */ }
/** * json_array_add_array_element: * @array: a #JsonArray * @value: (allow-none) (transfer full): a #JsonArray * * Conveniently adds an array into @array. The @array takes ownership * of the newly added #JsonArray * * See also: json_array_add_element(), json_node_take_array() * * Since: 0.8 */ void json_array_add_array_element (JsonArray *array, JsonArray *value) { JsonNode *node; g_return_if_fail (array != NULL); node = json_node_alloc (); if (value != NULL) { json_node_init_array (node, value); json_array_unref (value); } else json_node_init_null (node); g_ptr_array_add (array->elements, node); }
/** * json_object_set_array_member: * @object: a #JsonObject * @member_name: the name of the member * @value: (transfer full): the value of the member * * Convenience function for setting an array @value of * @member_name inside @object. * * The @object will take ownership of the passed #JsonArray * * See also: json_object_set_member() * * Since: 0.8 */ void json_object_set_array_member (JsonObject *object, const gchar *member_name, JsonArray *value) { JsonNode *node; g_return_if_fail (object != NULL); g_return_if_fail (member_name != NULL); node = json_node_alloc (); if (value != NULL) { json_node_init_array (node, value); json_array_unref (value); } else json_node_init_null (node); object_set_member_internal (object, member_name, node); }
JsonNode * json_serialize_pspec (const GValue *real_value, GParamSpec *pspec) { JsonNode *retval = NULL; JsonNodeType node_type; switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (real_value))) { /* JSON native types */ case G_TYPE_INT64: retval = json_node_init_int (json_node_alloc (), g_value_get_int64 (real_value)); break; case G_TYPE_BOOLEAN: retval = json_node_init_boolean (json_node_alloc (), g_value_get_boolean (real_value)); break; case G_TYPE_DOUBLE: retval = json_node_init_double (json_node_alloc (), g_value_get_double (real_value)); break; case G_TYPE_STRING: retval = json_node_init_string (json_node_alloc (), g_value_get_string (real_value)); break; /* auto-promoted types */ case G_TYPE_INT: retval = json_node_init_int (json_node_alloc (), g_value_get_int (real_value)); break; case G_TYPE_UINT: retval = json_node_init_int (json_node_alloc (), g_value_get_uint (real_value)); break; case G_TYPE_LONG: retval = json_node_init_int (json_node_alloc (), g_value_get_long (real_value)); break; case G_TYPE_ULONG: retval = json_node_init_int (json_node_alloc (), g_value_get_ulong (real_value)); break; case G_TYPE_UINT64: retval = json_node_init_int (json_node_alloc (), g_value_get_uint64 (real_value)); break; case G_TYPE_FLOAT: retval = json_node_init_double (json_node_alloc (), g_value_get_float (real_value)); break; case G_TYPE_CHAR: retval = json_node_alloc (); json_node_init_int (retval, g_value_get_schar (real_value)); break; case G_TYPE_UCHAR: retval = json_node_init_int (json_node_alloc (), g_value_get_uchar (real_value)); break; case G_TYPE_ENUM: retval = json_node_init_int (json_node_alloc (), g_value_get_enum (real_value)); break; case G_TYPE_FLAGS: retval = json_node_init_int (json_node_alloc (), g_value_get_flags (real_value)); break; /* complex types */ case G_TYPE_BOXED: if (G_VALUE_HOLDS (real_value, G_TYPE_STRV)) { gchar **strv = g_value_get_boxed (real_value); gint i, strv_len; JsonArray *array; strv_len = g_strv_length (strv); array = json_array_sized_new (strv_len); for (i = 0; i < strv_len; i++) { JsonNode *str = json_node_new (JSON_NODE_VALUE); json_node_set_string (str, strv[i]); json_array_add_element (array, str); } retval = json_node_init_array (json_node_alloc (), array); json_array_unref (array); } else if (json_boxed_can_serialize (G_VALUE_TYPE (real_value), &node_type)) { gpointer boxed = g_value_get_boxed (real_value); retval = json_boxed_serialize (G_VALUE_TYPE (real_value), boxed); } else g_warning ("Boxed type '%s' is not handled by JSON-GLib", g_type_name (G_VALUE_TYPE (real_value))); break; case G_TYPE_OBJECT: { GObject *object = g_value_get_object (real_value); retval = json_node_alloc (); if (object != NULL) { json_node_init (retval, JSON_NODE_OBJECT); json_node_take_object (retval, json_gobject_dump (object)); } else json_node_init_null (retval); } break; case G_TYPE_NONE: retval = json_node_new (JSON_NODE_NULL); break; default: g_warning ("Unsupported type `%s'", g_type_name (G_VALUE_TYPE (real_value))); break; } return retval; }
JsonNode * js_util_tojsonnode(js_State *state, int idx) { const char *s; JsonNode *node; JsonNode *tmp; JsonObject *object; JsonArray *array; unsigned int i, length; node = json_node_alloc(); if (js_isstring(state, idx)) { json_node_init_string(node, js_tostring(state, idx)); } else if (js_isnumber(state, idx)) { json_node_init_int(node, js_tointeger(state, idx)); } else if (js_isboolean(state, idx)) { json_node_init_boolean(node, js_toboolean(state, idx)); } else if (js_isarray(state, idx)) { length = js_getlength(state, idx); array = json_array_new(); json_node_init_array(node, array); for (i = 0; i < length; i++) { js_getindex(state, idx, i); tmp = js_util_tojsonnode(state, -1); if (tmp) json_array_add_element(array, tmp); js_pop(state, 1); } json_array_unref(array); } else if (js_isobject(state, idx)) { object = json_object_new(); json_node_init_object(node, object); js_pushiterator(state, idx, 1); while((s = js_nextiterator(state, -1)) != NULL) { if (idx > 0) js_getproperty(state, idx, s); else js_getproperty(state, idx - 1, s); tmp = js_util_tojsonnode(state, -1); if (tmp) json_object_set_member(object, s, tmp); js_pop(state, 1); } js_pop(state, 1); json_object_unref(object); } else { json_node_free(node); return NULL; } return node; }
static guint json_parse_array (JsonParser *parser, JsonScanner *scanner, JsonNode **node) { JsonParserPrivate *priv = parser->priv; JsonNode *old_current; JsonArray *array; guint token; gint idx; old_current = priv->current_node; priv->current_node = json_node_init_array (json_node_alloc (), NULL); array = json_array_new (); token = json_scanner_get_next_token (scanner); g_assert (token == G_TOKEN_LEFT_BRACE); g_signal_emit (parser, parser_signals[ARRAY_START], 0); idx = 0; while (token != G_TOKEN_RIGHT_BRACE) { guint next_token = json_scanner_peek_next_token (scanner); JsonNode *element = NULL; /* parse the element */ switch (next_token) { case G_TOKEN_LEFT_BRACE: JSON_NOTE (PARSER, "Nested array at index %d", idx); token = json_parse_array (parser, scanner, &element); break; case G_TOKEN_LEFT_CURLY: JSON_NOTE (PARSER, "Nested object at index %d", idx); token = json_parse_object (parser, scanner, &element); break; case G_TOKEN_RIGHT_BRACE: goto array_done; default: token = json_scanner_get_next_token (scanner); token = json_parse_value (parser, scanner, token, &element); break; } if (token != G_TOKEN_NONE || element == NULL) { /* the json_parse_* functions will have set the error code */ json_array_unref (array); json_node_free (priv->current_node); priv->current_node = old_current; return token; } next_token = json_scanner_peek_next_token (scanner); if (next_token == G_TOKEN_COMMA) { token = json_scanner_get_next_token (scanner); next_token = json_scanner_peek_next_token (scanner); /* look for trailing commas */ if (next_token == G_TOKEN_RIGHT_BRACE) { priv->error_code = JSON_PARSER_ERROR_TRAILING_COMMA; json_array_unref (array); json_node_free (priv->current_node); json_node_free (element); priv->current_node = old_current; return G_TOKEN_RIGHT_BRACE; } } JSON_NOTE (PARSER, "Array element %d completed", idx + 1); json_node_set_parent (element, priv->current_node); json_array_add_element (array, element); g_signal_emit (parser, parser_signals[ARRAY_ELEMENT], 0, array, idx); token = next_token; } array_done: json_scanner_get_next_token (scanner); json_node_take_array (priv->current_node, array); json_node_set_parent (priv->current_node, old_current); g_signal_emit (parser, parser_signals[ARRAY_END], 0, array); if (node != NULL && *node == NULL) *node = priv->current_node; priv->current_node = old_current; return G_TOKEN_NONE; }