static int excavate_json_object (JsonNode *node, int *n_objects, PRN *prn) { JsonObject *obj = json_node_get_object(node); int err = 0; if (obj == NULL) { return E_DATA; } if (json_object_get_size(obj) > 0) { GList *list = json_object_get_values(obj); struct jsdata jsd = { n_objects, &err, prn }; list = json_object_get_values(obj); g_list_foreach(list, show_obj_value, &jsd); g_list_free(list); } return err; }
/** * json_reader_count_members: * @reader: a #JsonReader * * Counts the members of the current position, if @reader is * positioned on an object * * Return value: the number of members, or -1. In case of failure * the #JsonReader is set in an error state * * Since: 0.12 */ gint json_reader_count_members (JsonReader *reader) { JsonReaderPrivate *priv; g_return_val_if_fail (JSON_IS_READER (reader), -1); priv = reader->priv; if (priv->current_node == NULL) { json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE, _("No node available at the current position")); return -1; } if (!JSON_NODE_HOLDS_OBJECT (priv->current_node)) { json_reader_set_error (reader, JSON_READER_ERROR_NO_OBJECT, _("The current position holds a '%s' and not an object"), json_node_type_get_name (JSON_NODE_TYPE (priv->current_node))); return -1; } return json_object_get_size (json_node_get_object (priv->current_node)); }
/*! * Recursive function that handles converging \c JsonNode's to \c * GNode's. * * \param root \c Root JsonNode to convert. * \param node \c GNode. * \param parsing_array \c true if handling an array, else \c false. */ static void clr_oci_json_parse_aux(JsonNode* root, GNode* node, bool parsing_array) { guint i; g_assert (root); g_assert (node); if (JSON_NODE_TYPE(root) == JSON_NODE_OBJECT) { JsonObject *object = json_node_get_object(root); if (object) { guint j; guint size; GList* keys, *key = NULL; GList* values, *value = NULL; size = json_object_get_size(object); keys = json_object_get_members(object); values = json_object_get_values(object); node = g_node_append(node, g_node_new(NULL)); for (j = 0, key = keys, value = values; j < size; j++) { if (key) { node = g_node_append(node->parent, g_node_new(g_strdup(key->data))); } if (value) { clr_oci_json_parse_aux(value->data, node, false); } key = g_list_next(key); value = g_list_next(value); } if (keys) { g_list_free(keys); } if (values) { g_list_free(values); } } } else if (JSON_NODE_TYPE(root) == JSON_NODE_ARRAY) { JsonArray* array = json_node_get_array(root); guint array_size = json_array_get_length (array); JsonNode *array_element; for (i = 0; i < array_size; i++) { array_element = json_array_get_element(array, i); clr_oci_json_parse_aux(array_element, node, true); } } else if (JSON_NODE_TYPE(root) == JSON_NODE_VALUE) { node = g_node_append(node, g_node_new(clr_oci_json_string(root))); if (parsing_array) { node = g_node_append(node, g_node_new(NULL)); } } }
/** * json_reader_count_members: * @reader: a #JsonReader * * Counts the members of the current position, if @reader is * positioned on an object * * Return value: the number of members, or -1. In case of failure * the #JsonReader is set in an error state * * Since: 0.12 */ gint json_reader_count_members (JsonReader *reader) { JsonReaderPrivate *priv; g_return_val_if_fail (JSON_IS_READER (reader), -1); priv = reader->priv; if (priv->current_node == NULL) return -1; if (!JSON_NODE_HOLDS_OBJECT (priv->current_node)) return -1; return json_object_get_size (json_node_get_object (priv->current_node)); }
static GObject * json_gobject_new (GType gtype, JsonObject *object) { JsonSerializableIface *iface = NULL; JsonSerializable *serializable = NULL; gboolean find_property; gboolean deserialize_property; gboolean set_property; GList *members, *members_left, *l; guint n_members; GObjectClass *klass; GObject *retval; GArray *construct_params; gint i; klass = g_type_class_ref (gtype); n_members = json_object_get_size (object); members = json_object_get_members (object); members_left = NULL; /* first pass: construct-only properties; here we cannot use Serializable * because we don't have an instance yet; we use the default implementation * of json_deserialize_pspec() to deserialize known types * * FIXME - find a way to allow deserialization for these properties */ construct_params = g_array_sized_new (FALSE, FALSE, sizeof (GParameter), n_members); for (l = members; l != NULL; l = l->next) { const gchar *member_name = l->data; GParamSpec *pspec; GParameter param = { NULL, }; JsonNode *val; gboolean res = FALSE; pspec = g_object_class_find_property (klass, member_name); if (!pspec) goto next_member; /* we only apply construct-only properties here */ if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) == 0) goto next_member; if (!(pspec->flags & G_PARAM_WRITABLE)) goto next_member; g_value_init (¶m.value, G_PARAM_SPEC_VALUE_TYPE (pspec)); val = json_object_get_member (object, member_name); res = json_deserialize_pspec (¶m.value, pspec, val); if (!res) { g_warning ("Failed to deserialize \"%s\" property of type \"%s\" for an object of type \"%s\"", pspec->name, G_VALUE_TYPE_NAME (¶m.value), g_type_name (gtype)); g_value_unset (¶m.value); } else { param.name = g_strdup (pspec->name); g_array_append_val (construct_params, param); continue; } next_member: members_left = g_list_prepend (members_left, l->data); } retval = g_object_newv (gtype, construct_params->len, (GParameter *) construct_params->data); /* free the contents of the GArray */ for (i = 0; i < construct_params->len; i++) { GParameter *param = &g_array_index (construct_params, GParameter, i); g_free ((gchar *) param->name); g_value_unset (¶m->value); } g_array_free (construct_params, TRUE); g_list_free (members); /* we use g_list_prepend() above, but we want to maintain * the ordering of json_object_get_members() here */ members = g_list_reverse (members_left); /* do the Serializable type check once */ if (g_type_is_a (gtype, JSON_TYPE_SERIALIZABLE)) { serializable = JSON_SERIALIZABLE (retval); iface = JSON_SERIALIZABLE_GET_IFACE (serializable); find_property = (iface->find_property != NULL); deserialize_property = (iface->deserialize_property != NULL); set_property = (iface->set_property != NULL); } else { find_property = FALSE; deserialize_property = FALSE; set_property = FALSE; } g_object_freeze_notify (retval); for (l = members; l != NULL; l = l->next) { const gchar *member_name = l->data; GParamSpec *pspec; JsonNode *val; GValue value = { 0, }; gboolean res = FALSE; if (find_property) pspec = json_serializable_find_property (serializable, member_name); else pspec = g_object_class_find_property (klass, member_name); if (pspec == NULL) continue; /* we should have dealt with these above */ if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) continue; if (!(pspec->flags & G_PARAM_WRITABLE)) continue; g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); val = json_object_get_member (object, member_name); if (deserialize_property) { JSON_NOTE (GOBJECT, "Using JsonSerializable for property '%s'", pspec->name); res = json_serializable_deserialize_property (serializable, pspec->name, &value, pspec, val); } if (!res) { JSON_NOTE (GOBJECT, "Using json_deserialize_pspec for property '%s'", pspec->name); res = json_deserialize_pspec (&value, pspec, val); } if (res) { JSON_NOTE (GOBJECT, "Calling set_property('%s', '%s')", pspec->name, g_type_name (G_VALUE_TYPE (&value))); if (set_property) json_serializable_set_property (serializable, pspec, &value); else g_object_set_property (retval, pspec->name, &value); } else g_warning ("Failed to deserialize \"%s\" property of type \"%s\" for an object of type \"%s\"", pspec->name, g_type_name (G_VALUE_TYPE (&value)), g_type_name (gtype)); g_value_unset (&value); } g_list_free (members); g_object_thaw_notify (retval); g_type_class_unref (klass); return retval; }
static void _got_trending_topic_updates_cb (RestProxyCall *call, const GError *error_in, GObject *weak_object, gpointer userdata) { SwTwitterItemViewPrivate *priv = GET_PRIVATE (weak_object); SwItemView *item_view = SW_ITEM_VIEW (weak_object); SwSet *set; JsonParser *parser; JsonObject *root_o; SwService *service; GError *error = NULL; if (error_in) { g_warning (G_STRLOC ": Error getting trending topic data: %s", error_in->message); return; } service = sw_item_view_get_service (SW_ITEM_VIEW (item_view)); set = sw_item_set_new (); parser = json_parser_new (); if (!json_parser_load_from_data (parser, rest_proxy_call_get_payload (call), rest_proxy_call_get_payload_length (call), &error)) { g_warning (G_STRLOC ": error parsing json: %s", error->message); } else { JsonNode *root_n; JsonObject *trends_o; JsonArray *trends_a; GList *values; gint i; root_n = json_parser_get_root (parser); root_o = json_node_get_object (root_n); trends_o = json_object_get_object_member (root_o, "trends"); /* We have to assume just the one object member */ if (json_object_get_size (trends_o) == 1) { values = json_object_get_values (trends_o); trends_a = json_node_get_array ((JsonNode *)(values->data)); for (i = 0; i < json_array_get_length (trends_a); i++) { JsonObject *trend_o; SwItem *item; item = sw_item_new (); sw_item_set_service (item, service); trend_o = json_array_get_object_element (trends_a, i); sw_item_take (item, "date", sw_time_t_to_string (time(NULL))); sw_item_put (item, "id", json_object_get_string_member (trend_o, "name")); sw_item_put (item, "content", json_object_get_string_member (trend_o, "name")); sw_set_add (set, (GObject *)item); g_object_unref (item); } g_list_free (values); } } sw_item_view_set_from_set (SW_ITEM_VIEW (item_view), set); /* Save the results of this set to the cache */ sw_cache_save (service, priv->query, priv->params, set); sw_set_unref (set); g_object_unref (parser); }
/** * json_reader_read_element: * @reader: a #JsonReader * @index_: the index of the element * * Advances the cursor of @reader to the element @index_ of the array * or the object at the current position. * * You can use the json_reader_get_value* family of functions to retrieve * the value of the element; for instance: * * |[ * json_reader_read_element (reader, 0); * int_value = json_reader_get_int_value (reader); * ]| * * After reading the value, json_reader_end_element() should be called to * reposition the cursor inside the #JsonReader, e.g.: * * |[ * json_reader_read_element (reader, 1); * str_value = json_reader_get_string_value (reader); * json_reader_end_element (reader); * * json_reader_read_element (reader, 2); * str_value = json_reader_get_string_value (reader); * json_reader_end_element (reader); * ]| * * If @reader is not currently on an array or an object, or if the @index_ is * bigger than the size of the array or the object, the #JsonReader will be * put in an error state until json_reader_end_element() is called. * * Return value: %TRUE on success, and %FALSE otherwise * * Since: 0.12 */ gboolean json_reader_read_element (JsonReader *reader, guint index_) { JsonReaderPrivate *priv; g_return_val_if_fail (JSON_READER (reader), FALSE); json_reader_return_val_if_error_set (reader, FALSE); priv = reader->priv; if (priv->current_node == NULL) priv->current_node = priv->root; if (!(JSON_NODE_HOLDS_ARRAY (priv->current_node) || JSON_NODE_HOLDS_OBJECT (priv->current_node))) return json_reader_set_error (reader, JSON_READER_ERROR_NO_ARRAY, "The current node is of type '%s', but " "an array or an object was expected.", json_node_type_name (priv->current_node)); switch (json_node_get_node_type (priv->current_node)) { case JSON_NODE_ARRAY: { JsonArray *array = json_node_get_array (priv->current_node); if (index_ >= json_array_get_length (array)) return json_reader_set_error (reader, JSON_READER_ERROR_INVALID_INDEX, "The index '%d' is greater than the size " "of the array at the current position.", index_); priv->previous_node = priv->current_node; priv->current_node = json_array_get_element (array, index_); } break; case JSON_NODE_OBJECT: { JsonObject *object = json_node_get_object (priv->current_node); GList *members; const gchar *name; if (index_ >= json_object_get_size (object)) return json_reader_set_error (reader, JSON_READER_ERROR_INVALID_INDEX, "The index '%d' is greater than the size " "of the object at the current position.", index_); priv->previous_node = priv->current_node; g_free (priv->current_member); members = json_object_get_members (object); name = g_list_nth_data (members, index_); priv->current_node = json_object_get_member (object, name); priv->current_member = g_strdup (name); g_list_free (members); } break; default: g_assert_not_reached (); return FALSE; } return TRUE; }