1 /* json-object.c - JSON object implementation
3 * This file is part of JSON-GLib
4 * Copyright (C) 2007 OpenedHand Ltd.
5 * Copyright (C) 2009 Intel Corp.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21 * Emmanuele Bassi <ebassi@linux.intel.com>
32 #include "json-types-private.h"
36 * @short_description: a JSON object representation
38 * #JsonObject is the representation of the object type inside JSON. It contains
39 * #JsonNode<!-- -->s, which may contain fundamental types, arrays or other
40 * objects. Each member of an object is accessed using its name.
42 * Since objects can be expensive, they are reference counted. You can control
43 * the lifetime of a #JsonObject using json_object_ref() and json_object_unref().
45 * To add or overwrite a member with a given name, use json_object_set_member().
46 * To extract a member with a given name, use json_object_get_member().
47 * To retrieve the list of members, use json_object_get_members().
48 * To retrieve the size of the object (that is, the number of members it has),
49 * use json_object_get_size().
52 G_DEFINE_BOXED_TYPE (JsonObject, json_object, json_object_ref, json_object_unref);
57 * Creates a new #JsonObject, an JSON object type representation.
59 * Return value: the newly created #JsonObject
62 json_object_new (void)
66 object = g_slice_new (JsonObject);
68 object->ref_count = 1;
69 object->members = g_hash_table_new_full (g_str_hash, g_str_equal,
71 (GDestroyNotify) json_node_free);
72 object->members_ordered = NULL;
79 * @object: a #JsonObject
81 * Increase by one the reference count of a #JsonObject.
83 * Return value: the passed #JsonObject, with the reference count
87 json_object_ref (JsonObject *object)
89 g_return_val_if_fail (object != NULL, NULL);
90 g_return_val_if_fail (object->ref_count > 0, NULL);
92 g_atomic_int_add (&object->ref_count, 1);
99 * @object: a #JsonObject
101 * Decreases by one the reference count of a #JsonObject. If the
102 * reference count reaches zero, the object is destroyed and all
103 * its allocated resources are freed.
106 json_object_unref (JsonObject *object)
108 g_return_if_fail (object != NULL);
109 g_return_if_fail (object->ref_count > 0);
111 if (g_atomic_int_dec_and_test (&object->ref_count))
113 g_list_free (object->members_ordered);
114 g_hash_table_destroy (object->members);
115 object->members_ordered = NULL;
116 object->members = NULL;
118 g_slice_free (JsonObject, object);
123 object_set_member_internal (JsonObject *object,
124 const gchar *member_name,
127 gchar *name = g_strdup (member_name);
129 if (g_hash_table_lookup (object->members, name) == NULL)
130 object->members_ordered = g_list_prepend (object->members_ordered, name);
135 /* if the member already exists then we need to replace the
136 * pointer to its name, to avoid keeping invalid pointers
137 * once we replace the key in the hash table
139 l = g_list_find_custom (object->members_ordered, name, (GCompareFunc) strcmp);
144 g_hash_table_replace (object->members, name, node);
148 * json_object_add_member:
149 * @object: a #JsonObject
150 * @member_name: the name of the member
151 * @node: (transfer full): the value of the member
153 * Adds a member named @member_name and containing @node into a #JsonObject.
154 * The object will take ownership of the #JsonNode.
156 * This function will return if the @object already contains a member
159 * Deprecated: 0.8: Use json_object_set_member() instead
162 json_object_add_member (JsonObject *object,
163 const gchar *member_name,
166 g_return_if_fail (object != NULL);
167 g_return_if_fail (member_name != NULL);
168 g_return_if_fail (node != NULL);
170 if (json_object_has_member (object, member_name))
172 g_warning ("JsonObject already has a `%s' member of type `%s'",
174 json_node_type_name (node));
178 object_set_member_internal (object, member_name, node);
182 * json_object_set_member:
183 * @object: a #JsonObject
184 * @member_name: the name of the member
185 * @node: (transfer full): the value of the member
187 * Sets @node as the value of @member_name inside @object.
189 * If @object already contains a member called @member_name then
190 * the member's current value is overwritten. Otherwise, a new
191 * member is added to @object.
196 json_object_set_member (JsonObject *object,
197 const gchar *member_name,
202 g_return_if_fail (object != NULL);
203 g_return_if_fail (member_name != NULL);
204 g_return_if_fail (node != NULL);
206 old_node = g_hash_table_lookup (object->members, member_name);
207 if (old_node == NULL)
210 if (old_node == node)
214 object_set_member_internal (object, member_name, node);
218 * json_object_set_int_member:
219 * @object: a #JsonObject
220 * @member_name: the name of the member
221 * @value: the value of the member
223 * Convenience function for setting an integer @value of
224 * @member_name inside @object.
226 * See also: json_object_set_member()
231 json_object_set_int_member (JsonObject *object,
232 const gchar *member_name,
237 g_return_if_fail (object != NULL);
238 g_return_if_fail (member_name != NULL);
240 node = json_node_new (JSON_NODE_VALUE);
241 json_node_set_int (node, value);
242 object_set_member_internal (object, member_name, node);
246 * json_object_set_double_member:
247 * @object: a #JsonObject
248 * @member_name: the name of the member
249 * @value: the value of the member
251 * Convenience function for setting a floating point @value
252 * of @member_name inside @object.
254 * See also: json_object_set_member()
259 json_object_set_double_member (JsonObject *object,
260 const gchar *member_name,
265 g_return_if_fail (object != NULL);
266 g_return_if_fail (member_name != NULL);
268 node = json_node_new (JSON_NODE_VALUE);
269 json_node_set_double (node, value);
270 object_set_member_internal (object, member_name, node);
274 * json_object_set_boolean_member:
275 * @object: a #JsonObject
276 * @member_name: the name of the member
277 * @value: the value of the member
279 * Convenience function for setting a boolean @value of
280 * @member_name inside @object.
282 * See also: json_object_set_member()
287 json_object_set_boolean_member (JsonObject *object,
288 const gchar *member_name,
293 g_return_if_fail (object != NULL);
294 g_return_if_fail (member_name != NULL);
296 node = json_node_new (JSON_NODE_VALUE);
297 json_node_set_boolean (node, value);
298 object_set_member_internal (object, member_name, node);
302 * json_object_set_string_member:
303 * @object: a #JsonObject
304 * @member_name: the name of the member
305 * @value: the value of the member
307 * Convenience function for setting a string @value of
308 * @member_name inside @object.
310 * See also: json_object_set_member()
315 json_object_set_string_member (JsonObject *object,
316 const gchar *member_name,
321 g_return_if_fail (object != NULL);
322 g_return_if_fail (member_name != NULL);
326 node = json_node_new (JSON_NODE_VALUE);
327 json_node_set_string (node, value);
330 node = json_node_new (JSON_NODE_NULL);
332 object_set_member_internal (object, member_name, node);
336 * json_object_set_null_member:
337 * @object: a #JsonObject
338 * @member_name: the name of the member
340 * Convenience function for setting a null @value of
341 * @member_name inside @object.
343 * See also: json_object_set_member()
348 json_object_set_null_member (JsonObject *object,
349 const gchar *member_name)
353 g_return_if_fail (object != NULL);
354 g_return_if_fail (member_name != NULL);
356 node = json_node_new (JSON_NODE_NULL);
357 object_set_member_internal (object, member_name, node);
361 * json_object_set_array_member:
362 * @object: a #JsonObject
363 * @member_name: the name of the member
364 * @value: (transfer full): the value of the member
366 * Convenience function for setting an array @value of
367 * @member_name inside @object.
369 * The @object will take ownership of the passed #JsonArray
371 * See also: json_object_set_member()
376 json_object_set_array_member (JsonObject *object,
377 const gchar *member_name,
382 g_return_if_fail (object != NULL);
383 g_return_if_fail (member_name != NULL);
387 node = json_node_new (JSON_NODE_ARRAY);
388 json_node_take_array (node, value);
391 node = json_node_new (JSON_NODE_NULL);
393 object_set_member_internal (object, member_name, node);
397 * json_object_set_object_member:
398 * @object: a #JsonObject
399 * @member_name: the name of the member
400 * @value: (transfer full): the value of the member
402 * Convenience function for setting an object @value of
403 * @member_name inside @object.
405 * The @object will take ownership of the passed #JsonObject
407 * See also: json_object_set_member()
412 json_object_set_object_member (JsonObject *object,
413 const gchar *member_name,
418 g_return_if_fail (object != NULL);
419 g_return_if_fail (member_name != NULL);
423 node = json_node_new (JSON_NODE_OBJECT);
424 json_node_take_object (node, value);
427 node = json_node_new (JSON_NODE_NULL);
429 object_set_member_internal (object, member_name, node);
433 * json_object_get_members:
434 * @object: a #JsonObject
436 * Retrieves all the names of the members of a #JsonObject. You can
437 * obtain the value for each member using json_object_get_member().
439 * Return value: (element-type utf8) (transfer container): a #GList
440 * of member names. The content of the list is owned by the #JsonObject
441 * and should never be modified or freed. When you have finished using
442 * the returned list, use g_list_free() to free the resources it has
446 json_object_get_members (JsonObject *object)
450 g_return_val_if_fail (object != NULL, NULL);
452 copy = g_list_copy (object->members_ordered);
454 return g_list_reverse (copy);
458 * json_object_get_values:
459 * @object: a #JsonObject
461 * Retrieves all the values of the members of a #JsonObject.
463 * Return value: (element-type JsonNode) (transfer container): a #GList of
464 * #JsonNode<!-- -->s. The content of the list is owned by the #JsonObject
465 * and should never be modified or freed. When you have finished using the
466 * returned list, use g_list_free() to free the resources it has allocated.
469 json_object_get_values (JsonObject *object)
473 g_return_val_if_fail (object != NULL, NULL);
476 for (l = object->members_ordered; l != NULL; l = l->next)
477 values = g_list_prepend (values, g_hash_table_lookup (object->members, l->data));
483 * json_object_dup_member:
484 * @object: a #JsonObject
485 * @member_name: the name of the JSON object member to access
487 * Retrieves a copy of the #JsonNode containing the value of @member_name
488 * inside a #JsonObject
490 * Return value: (transfer full): a copy of the node for the requested
491 * object member or %NULL. Use json_node_free() when done.
496 json_object_dup_member (JsonObject *object,
497 const gchar *member_name)
501 g_return_val_if_fail (object != NULL, NULL);
502 g_return_val_if_fail (member_name != NULL, NULL);
504 retval = json_object_get_member (object, member_name);
508 return json_node_copy (retval);
511 static inline JsonNode *
512 object_get_member_internal (JsonObject *object,
513 const gchar *member_name)
515 return g_hash_table_lookup (object->members, member_name);
519 * json_object_get_member:
520 * @object: a #JsonObject
521 * @member_name: the name of the JSON object member to access
523 * Retrieves the #JsonNode containing the value of @member_name inside
526 * Return value: (transfer none): a pointer to the node for the requested object
530 json_object_get_member (JsonObject *object,
531 const gchar *member_name)
533 g_return_val_if_fail (object != NULL, NULL);
534 g_return_val_if_fail (member_name != NULL, NULL);
536 return object_get_member_internal (object, member_name);
540 * json_object_get_int_member:
541 * @object: a #JsonObject
542 * @member_name: the name of the member
544 * Convenience function that retrieves the integer value
545 * stored in @member_name of @object
547 * See also: json_object_get_member()
549 * Return value: the integer value of the object's member
554 json_object_get_int_member (JsonObject *object,
555 const gchar *member_name)
559 g_return_val_if_fail (object != NULL, 0);
560 g_return_val_if_fail (member_name != NULL, 0);
562 node = object_get_member_internal (object, member_name);
563 g_return_val_if_fail (node != NULL, 0);
564 g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0);
566 return json_node_get_int (node);
570 * json_object_get_double_member:
571 * @object: a #JsonObject
572 * @member_name: the name of the member
574 * Convenience function that retrieves the floating point value
575 * stored in @member_name of @object
577 * See also: json_object_get_member()
579 * Return value: the floating point value of the object's member
584 json_object_get_double_member (JsonObject *object,
585 const gchar *member_name)
589 g_return_val_if_fail (object != NULL, 0.0);
590 g_return_val_if_fail (member_name != NULL, 0.0);
592 node = object_get_member_internal (object, member_name);
593 g_return_val_if_fail (node != NULL, 0.0);
594 g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0.0);
596 return json_node_get_double (node);
600 * json_object_get_boolean_member:
601 * @object: a #JsonObject
602 * @member_name: the name of the member
604 * Convenience function that retrieves the boolean value
605 * stored in @member_name of @object
607 * See also: json_object_get_member()
609 * Return value: the boolean value of the object's member
614 json_object_get_boolean_member (JsonObject *object,
615 const gchar *member_name)
619 g_return_val_if_fail (object != NULL, FALSE);
620 g_return_val_if_fail (member_name != NULL, FALSE);
622 node = object_get_member_internal (object, member_name);
623 g_return_val_if_fail (node != NULL, FALSE);
624 g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, FALSE);
626 return json_node_get_boolean (node);
630 * json_object_get_null_member:
631 * @object: a #JsonObject
632 * @member_name: the name of the member
634 * Convenience function that checks whether the value
635 * stored in @member_name of @object is null
637 * See also: json_object_get_member()
639 * Return value: %TRUE if the value is null
644 json_object_get_null_member (JsonObject *object,
645 const gchar *member_name)
649 g_return_val_if_fail (object != NULL, FALSE);
650 g_return_val_if_fail (member_name != NULL, FALSE);
652 node = object_get_member_internal (object, member_name);
653 g_return_val_if_fail (node != NULL, FALSE);
655 return JSON_NODE_TYPE (node) == JSON_NODE_NULL;
659 * json_object_get_string_member:
660 * @object: a #JsonObject
661 * @member_name: the name of the member
663 * Convenience function that retrieves the string value
664 * stored in @member_name of @object
666 * See also: json_object_get_member()
668 * Return value: the string value of the object's member
673 json_object_get_string_member (JsonObject *object,
674 const gchar *member_name)
678 g_return_val_if_fail (object != NULL, NULL);
679 g_return_val_if_fail (member_name != NULL, NULL);
681 node = object_get_member_internal (object, member_name);
682 g_return_val_if_fail (node != NULL, NULL);
683 g_return_val_if_fail (JSON_NODE_HOLDS_VALUE (node) || JSON_NODE_HOLDS_NULL (node), NULL);
685 if (JSON_NODE_HOLDS_NULL (node))
688 return json_node_get_string (node);
692 * json_object_get_array_member:
693 * @object: a #JsonObject
694 * @member_name: the name of the member
696 * Convenience function that retrieves the array
697 * stored in @member_name of @object
699 * See also: json_object_get_member()
701 * Return value: (transfer none): the array inside the object's member
706 json_object_get_array_member (JsonObject *object,
707 const gchar *member_name)
711 g_return_val_if_fail (object != NULL, NULL);
712 g_return_val_if_fail (member_name != NULL, NULL);
714 node = object_get_member_internal (object, member_name);
715 g_return_val_if_fail (node != NULL, NULL);
716 g_return_val_if_fail (JSON_NODE_HOLDS_ARRAY (node) || JSON_NODE_HOLDS_NULL (node), NULL);
718 if (JSON_NODE_HOLDS_NULL (node))
721 return json_node_get_array (node);
725 * json_object_get_object_member:
726 * @object: a #JsonObject
727 * @member_name: the name of the member
729 * Convenience function that retrieves the object
730 * stored in @member_name of @object
732 * See also: json_object_get_member()
734 * Return value: (transfer none): the object inside the object's member
739 json_object_get_object_member (JsonObject *object,
740 const gchar *member_name)
744 g_return_val_if_fail (object != NULL, NULL);
745 g_return_val_if_fail (member_name != NULL, NULL);
747 node = object_get_member_internal (object, member_name);
748 g_return_val_if_fail (node != NULL, NULL);
749 g_return_val_if_fail (JSON_NODE_HOLDS_OBJECT (node) || JSON_NODE_HOLDS_NULL (node), NULL);
751 if (JSON_NODE_HOLDS_NULL (node))
754 return json_node_get_object (node);
758 * json_object_has_member:
759 * @object: a #JsonObject
760 * @member_name: the name of a JSON object member
762 * Checks whether @object has a member named @member_name.
764 * Return value: %TRUE if the JSON object has the requested member
767 json_object_has_member (JsonObject *object,
768 const gchar *member_name)
770 g_return_val_if_fail (object != NULL, FALSE);
771 g_return_val_if_fail (member_name != NULL, FALSE);
773 return (g_hash_table_lookup (object->members, member_name) != NULL);
777 * json_object_get_size:
778 * @object: a #JsonObject
780 * Retrieves the number of members of a #JsonObject.
782 * Return value: the number of members
785 json_object_get_size (JsonObject *object)
787 g_return_val_if_fail (object != NULL, 0);
789 return g_hash_table_size (object->members);
793 * json_object_remove_member:
794 * @object: a #JsonObject
795 * @member_name: the name of the member to remove
797 * Removes @member_name from @object, freeing its allocated resources.
800 json_object_remove_member (JsonObject *object,
801 const gchar *member_name)
805 g_return_if_fail (object != NULL);
806 g_return_if_fail (member_name != NULL);
808 for (l = object->members_ordered; l != NULL; l = l->next)
810 const gchar *name = l->data;
812 if (g_strcmp0 (name, member_name) == 0)
814 object->members_ordered = g_list_delete_link (object->members_ordered, l);
819 g_hash_table_remove (object->members, member_name);
823 * json_object_foreach_member:
824 * @object: a #JsonObject
825 * @func: (scope call): the function to be called on each member
826 * @data: (closure): data to be passed to the function
828 * Iterates over all members of @object and calls @func on
831 * It is safe to change the value of a #JsonNode of the @object
832 * from within the iterator @func, but it is not safe to add or
833 * remove members from the @object.
838 json_object_foreach_member (JsonObject *object,
839 JsonObjectForeach func,
844 g_return_if_fail (object != NULL);
845 g_return_if_fail (func != NULL);
847 /* the list is stored in reverse order to have constant time additions */
848 members = g_list_last (object->members_ordered);
849 for (l = members; l != NULL; l = l->prev)
851 const gchar *member_name = l->data;
852 JsonNode *member_node = g_hash_table_lookup (object->members, member_name);
854 func (object, member_name, member_node, data);