1 /* json-node.c - JSON object model node
3 * This file is part of JSON-GLib
4 * Copyright (C) 2007 OpenedHand Ltd.
5 * Copyright (C) 2009 Intel Corp.
6 * Copyright (C) 2015 Collabora Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
22 * Emmanuele Bassi <ebassi@linux.intel.com>
23 * Philip Withnall <philip.withnall@collabora.co.uk>
30 #include "json-types.h"
31 #include "json-types-private.h"
32 #include "json-debug.h"
36 * @short_description: Node in a JSON object model
38 * A #JsonNode is a generic container of elements inside a JSON stream.
39 * It can contain fundamental types (integers, booleans, floating point
40 * numbers, strings) and complex types (arrays and objects).
42 * When parsing a JSON data stream you extract the root node and walk
43 * the node tree by retrieving the type of data contained inside the
44 * node with the %JSON_NODE_TYPE macro. If the node contains a fundamental
45 * type you can retrieve a copy of the #GValue holding it with the
46 * json_node_get_value() function, and then use the #GValue API to extract
47 * the data; if the node contains a complex type you can retrieve the
48 * #JsonObject or the #JsonArray using json_node_get_object() or
49 * json_node_get_array() respectively, and then retrieve the nodes
52 * A #JsonNode may be marked as immutable using json_node_seal(). This marks the
53 * node and all its descendents as read-only, and means that subsequent calls to
54 * setter functions (such as json_node_set_array()) on them will abort as a
55 * programmer error. By marking a node tree as immutable, it may be referenced
56 * in multiple places and its hash value cached for fast lookups, without the
57 * possibility of a value deep within the tree changing and affecting hash
58 * values. Immutable #JsonNodes may be passed to functions which retain a
59 * reference to them without needing to take a copy.
61 * #JsonNode supports two types of memory management: alloc/free semantics, and
62 * ref/unref semantics. The two may be mixed to a limited extent: nodes may be
63 * allocated (which gives them a reference count of 1), referenced zero or more
64 * times, unreferenced exactly that number of times (using json_node_unref()),
65 * then either unreferenced exactly once more or freed (using json_node_free())
66 * to destroy them. json_node_free() must not be used when a node might have a
67 * reference count not equal to 1. To this end, json-glib uses json_node_copy()
68 * and json_node_unref() internally.
71 G_DEFINE_BOXED_TYPE (JsonNode, json_node, json_node_copy, json_node_unref);
74 * json_node_get_value_type:
77 * Returns the #GType of the payload of the node.
79 * Return value: a #GType for the payload.
84 json_node_get_value_type (JsonNode *node)
86 g_return_val_if_fail (node != NULL, G_TYPE_INVALID);
90 case JSON_NODE_OBJECT:
91 return JSON_TYPE_OBJECT;
94 return JSON_TYPE_ARRAY;
97 return G_TYPE_INVALID;
100 if (node->data.value)
101 return JSON_VALUE_TYPE (node->data.value);
103 return G_TYPE_INVALID;
106 g_assert_not_reached ();
107 return G_TYPE_INVALID;
112 * json_node_alloc: (constructor)
114 * Allocates a new #JsonNode. Use json_node_init() and its variants
115 * to initialize the returned value.
117 * Return value: (transfer full): the newly allocated #JsonNode. Use
118 * json_node_free() to free the resources allocated by this function
123 json_node_alloc (void)
125 JsonNode *node = NULL;
127 node = g_slice_new0 (JsonNode);
129 node->allocated = TRUE;
135 json_node_unset (JsonNode *node)
137 /* Note: Don't use JSON_NODE_IS_VALID here because this may legitimately be
138 * called with (node->ref_count == 0) from json_node_unref(). */
139 g_assert (node != NULL);
143 case JSON_NODE_OBJECT:
144 if (node->data.object)
145 json_object_unref (node->data.object);
148 case JSON_NODE_ARRAY:
149 if (node->data.array)
150 json_array_unref (node->data.array);
153 case JSON_NODE_VALUE:
154 if (node->data.value)
155 json_value_unref (node->data.value);
165 * @node: the #JsonNode to initialize
166 * @type: the type of JSON node to initialize @node to
168 * Initializes a @node to a specific @type.
170 * If the node has already been initialized once, it will be reset to
171 * the given type, and any data contained will be cleared.
173 * Return value: (transfer none): the initialized #JsonNode
178 json_node_init (JsonNode *node,
181 g_return_val_if_fail (type >= JSON_NODE_OBJECT &&
182 type <= JSON_NODE_NULL, NULL);
183 g_return_val_if_fail (node->ref_count == 1, NULL);
185 json_node_unset (node);
193 * json_node_init_object:
194 * @node: the #JsonNode to initialize
195 * @object: (allow-none): the #JsonObject to initialize @node with, or %NULL
197 * Initializes @node to %JSON_NODE_OBJECT and sets @object into it.
199 * This function will take a reference on @object.
201 * If the node has already been initialized once, it will be reset to
202 * the given type, and any data contained will be cleared.
204 * Return value: (transfer none): the initialized #JsonNode
209 json_node_init_object (JsonNode *node,
212 g_return_val_if_fail (node != NULL, NULL);
214 json_node_init (node, JSON_NODE_OBJECT);
215 json_node_set_object (node, object);
221 * json_node_init_array:
222 * @node: the #JsonNode to initialize
223 * @array: (allow-none): the #JsonArray to initialize @node with, or %NULL
225 * Initializes @node to %JSON_NODE_ARRAY and sets @array into it.
227 * This function will take a reference on @array.
229 * If the node has already been initialized once, it will be reset to
230 * the given type, and any data contained will be cleared.
232 * Return value: (transfer none): the initialized #JsonNode
237 json_node_init_array (JsonNode *node,
240 g_return_val_if_fail (node != NULL, NULL);
242 json_node_init (node, JSON_NODE_ARRAY);
243 json_node_set_array (node, array);
249 * json_node_init_int:
250 * @node: the #JsonNode to initialize
253 * Initializes @node to %JSON_NODE_VALUE and sets @value into it.
255 * If the node has already been initialized once, it will be reset to
256 * the given type, and any data contained will be cleared.
258 * Return value: (transfer none): the initialized #JsonNode
263 json_node_init_int (JsonNode *node,
266 g_return_val_if_fail (node != NULL, NULL);
268 json_node_init (node, JSON_NODE_VALUE);
269 json_node_set_int (node, value);
275 * json_node_init_double:
276 * @node: the #JsonNode to initialize
277 * @value: a floating point value
279 * Initializes @node to %JSON_NODE_VALUE and sets @value into it.
281 * If the node has already been initialized once, it will be reset to
282 * the given type, and any data contained will be cleared.
284 * Return value: (transfer none): the initialized #JsonNode
289 json_node_init_double (JsonNode *node,
292 g_return_val_if_fail (node != NULL, NULL);
294 json_node_init (node, JSON_NODE_VALUE);
295 json_node_set_double (node, value);
301 * json_node_init_boolean:
302 * @node: the #JsonNode to initialize
303 * @value: a boolean value
305 * Initializes @node to %JSON_NODE_VALUE and sets @value into it.
307 * If the node has already been initialized once, it will be reset to
308 * the given type, and any data contained will be cleared.
310 * Return value: (transfer none): the initialized #JsonNode
315 json_node_init_boolean (JsonNode *node,
318 g_return_val_if_fail (node != NULL, NULL);
320 json_node_init (node, JSON_NODE_VALUE);
321 json_node_set_boolean (node, value);
327 * json_node_init_string:
328 * @node: the #JsonNode to initialize
329 * @value: (allow-none): a string value
331 * Initializes @node to %JSON_NODE_VALUE and sets @value into it.
333 * If the node has already been initialized once, it will be reset to
334 * the given type, and any data contained will be cleared.
336 * Return value: (transfer none): the initialized #JsonNode
341 json_node_init_string (JsonNode *node,
344 g_return_val_if_fail (node != NULL, NULL);
346 json_node_init (node, JSON_NODE_VALUE);
347 json_node_set_string (node, value);
353 * json_node_init_null:
354 * @node: the #JsonNode to initialize
356 * Initializes @node to %JSON_NODE_NULL.
358 * If the node has already been initialized once, it will be reset to
359 * the given type, and any data contained will be cleared.
361 * Return value: (transfer none): the initialized #JsonNode
366 json_node_init_null (JsonNode *node)
368 g_return_val_if_fail (node != NULL, NULL);
370 return json_node_init (node, JSON_NODE_NULL);
374 * json_node_new: (constructor)
375 * @type: a #JsonNodeType
377 * Creates a new #JsonNode of @type.
379 * This is a convenience function for json_node_alloc() and json_node_init(),
380 * and it's the equivalent of:
382 * |[<!-- language="C" -->
383 json_node_init (json_node_alloc (), type);
386 * Return value: (transfer full): the newly created #JsonNode
389 json_node_new (JsonNodeType type)
391 g_return_val_if_fail (type >= JSON_NODE_OBJECT &&
392 type <= JSON_NODE_NULL, NULL);
394 return json_node_init (json_node_alloc (), type);
401 * Copies @node. If the node contains complex data types, their reference
402 * counts are increased, regardless of whether the node is mutable or
405 * The copy will be immutable if, and only if, @node is immutable. However,
406 * there should be no need to copy an immutable node.
408 * Return value: (transfer full): the copied #JsonNode
411 json_node_copy (JsonNode *node)
415 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
417 copy = json_node_alloc ();
418 copy->type = node->type;
419 copy->immutable = node->immutable;
421 #ifdef JSON_ENABLE_DEBUG
424 JSON_NOTE (NODE, "Copying immutable JsonNode %p of type %s",
426 json_node_type_name (node));
432 case JSON_NODE_OBJECT:
433 copy->data.object = json_node_dup_object (node);
436 case JSON_NODE_ARRAY:
437 copy->data.array = json_node_dup_array (node);
440 case JSON_NODE_VALUE:
441 if (node->data.value)
442 copy->data.value = json_value_ref (node->data.value);
449 g_assert_not_reached ();
459 * Increment the reference count of @node.
462 * Returns: (transfer full): a pointer to @node
465 json_node_ref (JsonNode *node)
467 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
469 g_atomic_int_inc (&node->ref_count);
476 * @node: (transfer full): a #JsonNode
478 * Decrement the reference count of @node. If it reaches zero, the node is
484 json_node_unref (JsonNode *node)
486 g_return_if_fail (JSON_NODE_IS_VALID (node));
488 if (g_atomic_int_dec_and_test (&node->ref_count))
490 json_node_unset (node);
492 g_slice_free (JsonNode, node);
497 * json_node_set_object:
498 * @node: a #JsonNode initialized to %JSON_NODE_OBJECT
499 * @object: (nullable): a #JsonObject
501 * Sets @objects inside @node. The reference count of @object is increased.
503 * If @object is %NULL, the node’s existing object is cleared.
505 * It is an error to call this on an immutable node.
508 json_node_set_object (JsonNode *node,
511 g_return_if_fail (JSON_NODE_IS_VALID (node));
512 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT);
513 g_return_if_fail (!node->immutable);
515 if (node->data.object != NULL)
516 json_object_unref (node->data.object);
519 node->data.object = json_object_ref (object);
521 node->data.object = NULL;
525 * json_node_take_object:
526 * @node: a #JsonNode initialized to %JSON_NODE_OBJECT
527 * @object: (transfer full): a #JsonObject
529 * Sets @object inside @node. The reference count of @object is not increased.
531 * It is an error to call this on an immutable node.
534 json_node_take_object (JsonNode *node,
537 g_return_if_fail (JSON_NODE_IS_VALID (node));
538 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT);
539 g_return_if_fail (!node->immutable);
541 if (node->data.object)
543 json_object_unref (node->data.object);
544 node->data.object = NULL;
548 node->data.object = object;
552 * json_node_get_object:
555 * Retrieves the #JsonObject stored inside a #JsonNode. If the node does not
556 * hold an object value, %NULL is returned.
558 * Return value: (transfer none) (nullable): the #JsonObject
561 json_node_get_object (JsonNode *node)
563 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
564 g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL);
566 return node->data.object;
570 * json_node_dup_object:
573 * Retrieves the #JsonObject inside @node. The reference count of
574 * the returned object is increased. If the node does not hold an object value,
577 * Return value: (transfer full) (nullable): the #JsonObject
580 json_node_dup_object (JsonNode *node)
582 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
583 g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL);
585 if (node->data.object)
586 return json_object_ref (node->data.object);
592 * json_node_set_array:
593 * @node: a #JsonNode initialized to %JSON_NODE_ARRAY
594 * @array: a #JsonArray
596 * Sets @array inside @node and increases the #JsonArray reference count.
598 * It is an error to call this on an immutable node.
601 json_node_set_array (JsonNode *node,
604 g_return_if_fail (JSON_NODE_IS_VALID (node));
605 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY);
606 g_return_if_fail (!node->immutable);
608 if (node->data.array)
609 json_array_unref (node->data.array);
612 node->data.array = json_array_ref (array);
614 node->data.array = NULL;
618 * json_node_take_array:
619 * @node: a #JsonNode initialized to %JSON_NODE_ARRAY
620 * @array: (transfer full): a #JsonArray
622 * Sets @array into @node without increasing the #JsonArray reference count.
624 * It is an error to call this on an immutable node.
627 json_node_take_array (JsonNode *node,
630 g_return_if_fail (JSON_NODE_IS_VALID (node));
631 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY);
632 g_return_if_fail (!node->immutable);
634 if (node->data.array)
636 json_array_unref (node->data.array);
637 node->data.array = NULL;
641 node->data.array = array;
645 * json_node_get_array:
648 * Retrieves the #JsonArray stored inside a #JsonNode. If the node does not
649 * hold an array value, %NULL is returned.
651 * Return value: (transfer none) (nullable): the #JsonArray
654 json_node_get_array (JsonNode *node)
656 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
657 g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY, NULL);
659 return node->data.array;
663 * json_node_dup_array:
666 * Retrieves the #JsonArray stored inside a #JsonNode and returns it
667 * with its reference count increased by one. If the node does not hold an
668 * array value, %NULL is returned.
670 * Return value: (transfer full) (nullable): the #JsonArray with its reference
674 json_node_dup_array (JsonNode *node)
676 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
677 g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY, NULL);
679 if (node->data.array)
680 return json_array_ref (node->data.array);
686 * json_node_get_value:
688 * @value: (out caller-allocates): return location for an uninitialized value
690 * Retrieves a value from a #JsonNode and copies into @value. When done
691 * using it, call g_value_unset() on the #GValue. If the node does not hold a
692 * scalar value, @value is not modified.
695 json_node_get_value (JsonNode *node,
698 g_return_if_fail (JSON_NODE_IS_VALID (node));
699 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
701 if (node->data.value)
703 g_value_init (value, JSON_VALUE_TYPE (node->data.value));
704 switch (JSON_VALUE_TYPE (node->data.value))
707 g_value_set_int64 (value, json_value_get_int (node->data.value));
711 g_value_set_double (value, json_value_get_double (node->data.value));
715 g_value_set_boolean (value, json_value_get_boolean (node->data.value));
719 g_value_set_string (value, json_value_get_string (node->data.value));
729 * json_node_set_value:
730 * @node: a #JsonNode initialized to %JSON_NODE_VALUE
731 * @value: the #GValue to set
733 * Sets @value inside @node. The passed #GValue is copied into the #JsonNode.
735 * It is an error to call this on an immutable node.
738 json_node_set_value (JsonNode *node,
741 g_return_if_fail (JSON_NODE_IS_VALID (node));
742 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
743 g_return_if_fail (G_VALUE_TYPE (value) != G_TYPE_INVALID);
744 g_return_if_fail (!node->immutable);
746 if (node->data.value == NULL)
747 node->data.value = json_value_alloc ();
749 switch (G_VALUE_TYPE (value))
751 /* auto-promote machine integers to 64 bit integers */
754 json_value_init (node->data.value, JSON_VALUE_INT);
755 if (G_VALUE_TYPE (value) == G_TYPE_INT64)
756 json_value_set_int (node->data.value, g_value_get_int64 (value));
758 json_value_set_int (node->data.value, g_value_get_int (value));
762 json_value_init (node->data.value, JSON_VALUE_BOOLEAN);
763 json_value_set_boolean (node->data.value, g_value_get_boolean (value));
766 /* auto-promote single-precision floats to double precision floats */
769 json_value_init (node->data.value, JSON_VALUE_DOUBLE);
770 if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE)
771 json_value_set_double (node->data.value, g_value_get_double (value));
773 json_value_set_double (node->data.value, g_value_get_float (value));
777 json_value_init (node->data.value, JSON_VALUE_STRING);
778 json_value_set_string (node->data.value, g_value_get_string (value));
782 g_message ("Invalid value of type '%s'",
783 g_type_name (G_VALUE_TYPE (value)));
793 * Frees the resources allocated by @node.
796 json_node_free (JsonNode *node)
798 g_return_if_fail (node == NULL || JSON_NODE_IS_VALID (node));
799 g_return_if_fail (node == NULL || node->allocated);
803 if (node->ref_count > 1)
804 g_warning ("Freeing a JsonNode %p owned by other code.", node);
806 json_node_unset (node);
807 g_slice_free (JsonNode, node);
815 * Seals the #JsonNode, making it immutable to further changes. In order to be
816 * sealed, the @node must have a type and value set. The value will be
817 * recursively sealed — if the node holds an object, that #JsonObject will be
820 * If the @node is already immutable, this is a no-op.
825 json_node_seal (JsonNode *node)
827 g_return_if_fail (JSON_NODE_IS_VALID (node));
834 case JSON_NODE_OBJECT:
835 g_return_if_fail (node->data.object != NULL);
836 json_object_seal (node->data.object);
838 case JSON_NODE_ARRAY:
839 g_return_if_fail (node->data.array != NULL);
840 json_array_seal (node->data.array);
844 case JSON_NODE_VALUE:
845 g_return_if_fail (node->data.value != NULL);
846 json_value_seal (node->data.value);
849 g_assert_not_reached ();
852 node->immutable = TRUE;
856 * json_node_is_immutable:
859 * Check whether the given @node has been marked as immutable by calling
860 * json_node_seal() on it.
863 * Returns: %TRUE if the @node is immutable
866 json_node_is_immutable (JsonNode *node)
868 g_return_val_if_fail (JSON_NODE_IS_VALID (node), FALSE);
870 return node->immutable;
874 * json_node_type_name:
877 * Retrieves the user readable name of the data type contained by @node.
879 * Return value: a string containing the name of the type. The returned string
880 * is owned by the node and should never be modified or freed
883 json_node_type_name (JsonNode *node)
885 g_return_val_if_fail (node != NULL, "(null)");
889 case JSON_NODE_OBJECT:
890 case JSON_NODE_ARRAY:
892 return json_node_type_get_name (node->type);
894 case JSON_NODE_VALUE:
895 if (node->data.value)
896 return json_value_type_get_name (node->data.value->type);
903 json_node_type_get_name (JsonNodeType node_type)
907 case JSON_NODE_OBJECT:
910 case JSON_NODE_ARRAY:
916 case JSON_NODE_VALUE:
920 g_assert_not_reached ();
928 * json_node_set_parent:
930 * @parent: (transfer none): the parent #JsonNode of @node
932 * Sets the parent #JsonNode of @node.
934 * It is an error to call this with an immutable @parent. @node may be
940 json_node_set_parent (JsonNode *node,
943 g_return_if_fail (JSON_NODE_IS_VALID (node));
944 g_return_if_fail (parent == NULL ||
945 !json_node_is_immutable (parent));
947 node->parent = parent;
951 * json_node_get_parent:
954 * Retrieves the parent #JsonNode of @node.
956 * Return value: (transfer none) (nullable): the parent node, or %NULL if @node
960 json_node_get_parent (JsonNode *node)
962 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
968 * json_node_set_string:
969 * @node: a #JsonNode initialized to %JSON_NODE_VALUE
970 * @value: a string value
972 * Sets @value as the string content of the @node, replacing any existing
975 * It is an error to call this on an immutable node.
978 json_node_set_string (JsonNode *node,
981 g_return_if_fail (JSON_NODE_IS_VALID (node));
982 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
983 g_return_if_fail (!node->immutable);
985 if (node->data.value == NULL)
986 node->data.value = json_value_init (json_value_alloc (), JSON_VALUE_STRING);
988 json_value_init (node->data.value, JSON_VALUE_STRING);
990 json_value_set_string (node->data.value, value);
994 * json_node_get_string:
995 * @node: a #JsonNode of type %JSON_NODE_VALUE
997 * Gets the string value stored inside a #JsonNode. If the node does not hold a
998 * string value, %NULL is returned.
1000 * Return value: (nullable): a string value.
1003 json_node_get_string (JsonNode *node)
1005 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
1007 if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
1010 if (JSON_VALUE_HOLDS_STRING (node->data.value))
1011 return json_value_get_string (node->data.value);
1017 * json_node_dup_string:
1018 * @node: a #JsonNode of type %JSON_NODE_VALUE
1020 * Gets a copy of the string value stored inside a #JsonNode. If the node does
1021 * not hold a string value, %NULL is returned.
1023 * Return value: (transfer full) (nullable): a newly allocated string
1024 * containing a copy of the #JsonNode contents. Use g_free() to free the
1025 * allocated resources
1028 json_node_dup_string (JsonNode *node)
1030 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
1032 return g_strdup (json_node_get_string (node));
1036 * json_node_set_int:
1037 * @node: a #JsonNode of type %JSON_NODE_VALUE
1038 * @value: an integer value
1040 * Sets @value as the integer content of the @node, replacing any existing
1043 * It is an error to call this on an immutable node.
1046 json_node_set_int (JsonNode *node,
1049 g_return_if_fail (JSON_NODE_IS_VALID (node));
1050 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
1051 g_return_if_fail (!node->immutable);
1053 if (node->data.value == NULL)
1054 node->data.value = json_value_init (json_value_alloc (), JSON_VALUE_INT);
1056 json_value_init (node->data.value, JSON_VALUE_INT);
1058 json_value_set_int (node->data.value, value);
1062 * json_node_get_int:
1063 * @node: a #JsonNode of type %JSON_NODE_VALUE
1065 * Gets the integer value stored inside a #JsonNode. If the node holds a double
1066 * value, its integer component is returned. If the node holds a %FALSE boolean
1067 * value, `0` is returned; otherwise a non-zero integer is returned. If the
1068 * node holds a %JSON_NODE_NULL value or a value of another non-integer type,
1071 * Return value: an integer value.
1074 json_node_get_int (JsonNode *node)
1076 g_return_val_if_fail (JSON_NODE_IS_VALID (node), 0);
1078 if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
1081 if (JSON_VALUE_HOLDS_INT (node->data.value))
1082 return json_value_get_int (node->data.value);
1084 if (JSON_VALUE_HOLDS_DOUBLE (node->data.value))
1085 return json_value_get_double (node->data.value);
1087 if (JSON_VALUE_HOLDS_BOOLEAN (node->data.value))
1088 return json_value_get_boolean (node->data.value);
1094 * json_node_set_double:
1095 * @node: a #JsonNode of type %JSON_NODE_VALUE
1096 * @value: a double value
1098 * Sets @value as the double content of the @node, replacing any existing
1101 * It is an error to call this on an immutable node.
1104 json_node_set_double (JsonNode *node,
1107 g_return_if_fail (JSON_NODE_IS_VALID (node));
1108 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
1109 g_return_if_fail (!node->immutable);
1111 if (node->data.value == NULL)
1112 node->data.value = json_value_init (json_value_alloc (), JSON_VALUE_DOUBLE);
1114 json_value_init (node->data.value, JSON_VALUE_DOUBLE);
1116 json_value_set_double (node->data.value, value);
1120 * json_node_get_double:
1121 * @node: a #JsonNode of type %JSON_NODE_VALUE
1123 * Gets the double value stored inside a #JsonNode. If the node holds an integer
1124 * value, it is returned as a double. If the node holds a %FALSE boolean value,
1125 * `0.0` is returned; otherwise a non-zero double is returned. If the node holds
1126 * a %JSON_NODE_NULL value or a value of another non-double type, `0.0` is
1129 * Return value: a double value.
1132 json_node_get_double (JsonNode *node)
1134 g_return_val_if_fail (JSON_NODE_IS_VALID (node), 0.0);
1136 if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
1139 if (JSON_VALUE_HOLDS_DOUBLE (node->data.value))
1140 return json_value_get_double (node->data.value);
1142 if (JSON_VALUE_HOLDS_INT (node->data.value))
1143 return (gdouble) json_value_get_int (node->data.value);
1145 if (JSON_VALUE_HOLDS_BOOLEAN (node->data.value))
1146 return (gdouble) json_value_get_boolean (node->data.value);
1152 * json_node_set_boolean:
1153 * @node: a #JsonNode of type %JSON_NODE_VALUE
1154 * @value: a boolean value
1156 * Sets @value as the boolean content of the @node, replacing any existing
1159 * It is an error to call this on an immutable node.
1162 json_node_set_boolean (JsonNode *node,
1165 g_return_if_fail (JSON_NODE_IS_VALID (node));
1166 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
1167 g_return_if_fail (!node->immutable);
1169 if (node->data.value == NULL)
1170 node->data.value = json_value_init (json_value_alloc (), JSON_VALUE_BOOLEAN);
1172 json_value_init (node->data.value, JSON_VALUE_BOOLEAN);
1174 json_value_set_boolean (node->data.value, value);
1178 * json_node_get_boolean:
1179 * @node: a #JsonNode of type %JSON_NODE_VALUE
1181 * Gets the boolean value stored inside a #JsonNode. If the node holds an
1182 * integer or double value which is zero, %FALSE is returned; otherwise %TRUE
1183 * is returned. If the node holds a %JSON_NODE_NULL value or a value of another
1184 * non-boolean type, %FALSE is returned.
1186 * Return value: a boolean value.
1189 json_node_get_boolean (JsonNode *node)
1191 g_return_val_if_fail (JSON_NODE_IS_VALID (node), FALSE);
1193 if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
1196 if (JSON_VALUE_HOLDS_BOOLEAN (node->data.value))
1197 return json_value_get_boolean (node->data.value);
1199 if (JSON_VALUE_HOLDS_INT (node->data.value))
1200 return json_value_get_int (node->data.value) != 0;
1202 if (JSON_VALUE_HOLDS_DOUBLE (node->data.value))
1203 return json_value_get_double (node->data.value) != 0.0;
1209 * json_node_get_node_type:
1210 * @node: a #JsonNode
1212 * Retrieves the #JsonNodeType of @node
1214 * Return value: the type of the node
1219 json_node_get_node_type (JsonNode *node)
1221 g_return_val_if_fail (JSON_NODE_IS_VALID (node), JSON_NODE_NULL);
1227 * json_node_is_null:
1228 * @node: a #JsonNode
1230 * Checks whether @node is a %JSON_NODE_NULL.
1232 * A %JSON_NODE_NULL node is not the same as a %NULL #JsonNode; a
1233 * %JSON_NODE_NULL represents a 'null' value in the JSON tree.
1235 * Return value: %TRUE if the node is null
1240 json_node_is_null (JsonNode *node)
1242 g_return_val_if_fail (JSON_NODE_IS_VALID (node), TRUE);
1244 return node->type == JSON_NODE_NULL;
1250 * @super: super-type
1252 * Check whether @sub is a sub-type of, or equal to, @super. The only sub-type
1253 * relationship in the JSON Schema type system is that
1254 * %WBL_PRIMITIVE_TYPE_INTEGER is a sub-type of %WBL_PRIMITIVE_TYPE_NUMBER.
1256 * Formally, this function calculates: `@sub <: @super`.
1258 * Reference: http://json-schema.org/latest/json-schema-core.html#rfc.section.3.5
1260 * Returns: %TRUE if @sub is a sub-type of, or equal to, @super; %FALSE
1265 json_type_is_a (JsonNode *sub,
1268 if (super->type == JSON_NODE_VALUE && sub->type == JSON_NODE_VALUE)
1270 JsonValueType super_value_type, sub_value_type;
1272 if (super->data.value == NULL || sub->data.value == NULL)
1275 super_value_type = super->data.value->type;
1276 sub_value_type = sub->data.value->type;
1278 return (super_value_type == sub_value_type ||
1279 (super_value_type == JSON_VALUE_DOUBLE &&
1280 sub_value_type == JSON_VALUE_INT));
1283 return (super->type == sub->type);
1288 * @key: (type utf8): a JSON string to hash
1290 * Calculate a hash value for the given @key (a UTF-8 JSON string).
1292 * Note: Member names are compared byte-wise, without applying any Unicode
1293 * decomposition or normalisation. This is not explicitly mentioned in the JSON
1294 * standard (ECMA-404), but is assumed.
1296 * Returns: hash value for @key
1300 json_string_hash (gconstpointer key)
1302 return g_str_hash (key);
1306 * json_string_equal:
1307 * @a: (type utf8): a JSON string
1308 * @b: (type utf8): another JSON string
1310 * Check whether @a and @b are equal UTF-8 JSON strings.
1312 * Returns: %TRUE if @a and @b are equal; %FALSE otherwise
1316 json_string_equal (gconstpointer a,
1319 return g_str_equal (a, b);
1323 * json_string_compare:
1324 * @a: (type utf8): a JSON string
1325 * @b: (type utf8): another JSON string
1327 * Check whether @a and @b are equal UTF-8 JSON strings and return an ordering
1328 * over them in strcmp() style.
1330 * Returns: an integer less than zero if @a < @b, equal to zero if @a == @b, and
1331 * greater than zero if @a > @b
1335 json_string_compare (gconstpointer a,
1338 return g_strcmp0 (a, b);
1343 * @key: (type JsonNode): a JSON node to hash
1345 * Calculate a hash value for the given @key (a #JsonNode).
1347 * The hash is calculated over the node and its value, recursively. If the node
1348 * is immutable, this is a fast operation; otherwise, it scales proportionally
1349 * with the size of the node’s value (for example, with the number of members
1350 * in the #JsonObject if this node contains an object).
1352 * Returns: hash value for @key
1356 json_node_hash (gconstpointer key)
1358 JsonNode *node; /* unowned */
1360 /* These are all randomly generated and arbitrary. */
1361 const guint value_hash = 0xc19e75ad;
1362 const guint array_hash = 0x865acfc2;
1363 const guint object_hash = 0x3c8f3135;
1365 node = (JsonNode *) key;
1367 /* XOR the hash values with a (constant) random number depending on the node’s
1368 * type so that empty values, arrays and objects do not all collide at the
1372 case JSON_NODE_NULL:
1374 case JSON_NODE_VALUE:
1375 return value_hash ^ json_value_hash (node->data.value);
1376 case JSON_NODE_ARRAY:
1377 return array_hash ^ json_array_hash (json_node_get_array (node));
1378 case JSON_NODE_OBJECT:
1379 return object_hash ^ json_object_hash (json_node_get_object (node));
1381 g_assert_not_reached ();
1387 * @a: (type JsonNode): a JSON node
1388 * @b: (type JsonNode): another JSON node
1390 * Check whether @a and @b are equal #JsonNodes, meaning they have the same
1391 * type and same values (checked recursively). Note that integer values are
1392 * compared numerically, ignoring type, so a double value 4.0 is equal to the
1395 * Returns: %TRUE if @a and @b are equal; %FALSE otherwise
1399 json_node_equal (gconstpointer a,
1402 JsonNode *node_a, *node_b; /* unowned */
1404 node_a = (JsonNode *) a;
1405 node_b = (JsonNode *) b;
1407 /* Identity comparison. */
1408 if (node_a == node_b)
1411 /* Eliminate mismatched types rapidly. */
1412 if (!json_type_is_a (node_a, node_b) &&
1413 !json_type_is_a (node_b, node_a))
1418 switch (node_a->type)
1420 case JSON_NODE_NULL:
1421 /* Types match already. */
1423 case JSON_NODE_ARRAY:
1424 return json_array_equal (json_node_get_array (node_a),
1425 json_node_get_array (node_b));
1426 case JSON_NODE_OBJECT:
1427 return json_object_equal (json_node_get_object (node_a),
1428 json_node_get_object (node_b));
1429 case JSON_NODE_VALUE:
1430 /* Handled below. */
1433 g_assert_not_reached ();
1436 /* Handle values. */
1437 switch (node_a->data.value->type)
1439 case JSON_VALUE_NULL:
1440 /* Types already match. */
1442 case JSON_VALUE_BOOLEAN:
1443 return (json_node_get_boolean (node_a) == json_node_get_boolean (node_b));
1444 case JSON_VALUE_STRING:
1445 return json_string_equal (json_node_get_string (node_a),
1446 json_node_get_string (node_b));
1447 case JSON_VALUE_DOUBLE:
1448 case JSON_VALUE_INT: {
1449 gdouble val_a, val_b;
1450 JsonValueType value_type_a, value_type_b;
1452 value_type_a = node_a->data.value->type;
1453 value_type_b = node_b->data.value->type;
1455 /* Integer comparison doesn’t need to involve doubles… */
1456 if (value_type_a == JSON_VALUE_INT &&
1457 value_type_b == JSON_VALUE_INT)
1459 return (json_node_get_int (node_a) ==
1460 json_node_get_int (node_b));
1463 /* …but everything else does. We can use bitwise double equality here,
1464 * since we’re not doing any calculations which could introduce floating
1465 * point error. We expect that the doubles in the JSON nodes come directly
1466 * from strtod() or similar, so should be bitwise equal for equal string
1469 * Interesting background reading:
1470 * http://randomascii.wordpress.com/2012/06/26/\
1471 * doubles-are-not-floats-so-dont-compare-them/
1473 if (value_type_a == JSON_VALUE_INT)
1474 val_a = json_node_get_int (node_a);
1476 val_a = json_node_get_double (node_a);
1478 if (value_type_b == JSON_VALUE_INT)
1479 val_b = json_node_get_int (node_b);
1481 val_b = json_node_get_double (node_b);
1483 return (val_a == val_b);
1485 case JSON_VALUE_INVALID:
1487 g_assert_not_reached ();