1 /* json-node.c - JSON object model node
2 *
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.
7 *
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.
12 *
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.
17 *
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/>.
20 *
21 * Author:
22 * Emmanuele Bassi <ebassi@linux.intel.com>
23 * Philip Withnall <philip.withnall@collabora.co.uk>
24 */
25
26 #include "config.h"
27
28 #include <glib.h>
29
30 #include "json-types.h"
31 #include "json-types-private.h"
32 #include "json-debug.h"
33
34 /**
35 * SECTION:json-node
36 * @short_description: Node in a JSON object model
37 *
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).
41 *
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
50 * they contain.
51 *
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.
60 *
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.
69 */
70
71 G_DEFINE_BOXED_TYPE (JsonNode, json_node, json_node_copy, json_node_unref);
72
73 /**
74 * json_node_get_value_type:
75 * @node: a #JsonNode
76 *
77 * Returns the #GType of the payload of the node.
78 *
79 * Return value: a #GType for the payload.
80 *
81 * Since: 0.4
82 */
83 GType
json_node_get_value_type(JsonNode * node)84 json_node_get_value_type (JsonNode *node)
85 {
86 g_return_val_if_fail (node != NULL, G_TYPE_INVALID);
87
88 switch (node->type)
89 {
90 case JSON_NODE_OBJECT:
91 return JSON_TYPE_OBJECT;
92
93 case JSON_NODE_ARRAY:
94 return JSON_TYPE_ARRAY;
95
96 case JSON_NODE_NULL:
97 return G_TYPE_INVALID;
98
99 case JSON_NODE_VALUE:
100 if (node->data.value)
101 return JSON_VALUE_TYPE (node->data.value);
102 else
103 return G_TYPE_INVALID;
104
105 default:
106 g_assert_not_reached ();
107 return G_TYPE_INVALID;
108 }
109 }
110
111 /**
112 * json_node_alloc: (constructor)
113 *
114 * Allocates a new #JsonNode. Use json_node_init() and its variants
115 * to initialize the returned value.
116 *
117 * Return value: (transfer full): the newly allocated #JsonNode. Use
118 * json_node_free() to free the resources allocated by this function
119 *
120 * Since: 0.16
121 */
122 JsonNode *
json_node_alloc(void)123 json_node_alloc (void)
124 {
125 JsonNode *node = NULL;
126
127 node = g_slice_new0 (JsonNode);
128 node->ref_count = 1;
129 node->allocated = TRUE;
130
131 return node;
132 }
133
134 static void
json_node_unset(JsonNode * node)135 json_node_unset (JsonNode *node)
136 {
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);
140
141 switch (node->type)
142 {
143 case JSON_NODE_OBJECT:
144 if (node->data.object)
145 json_object_unref (node->data.object);
146 break;
147
148 case JSON_NODE_ARRAY:
149 if (node->data.array)
150 json_array_unref (node->data.array);
151 break;
152
153 case JSON_NODE_VALUE:
154 if (node->data.value)
155 json_value_unref (node->data.value);
156 break;
157
158 case JSON_NODE_NULL:
159 break;
160 }
161 }
162
163 /**
164 * json_node_init:
165 * @node: the #JsonNode to initialize
166 * @type: the type of JSON node to initialize @node to
167 *
168 * Initializes a @node to a specific @type.
169 *
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.
172 *
173 * Return value: (transfer none): the initialized #JsonNode
174 *
175 * Since: 0.16
176 */
177 JsonNode *
json_node_init(JsonNode * node,JsonNodeType type)178 json_node_init (JsonNode *node,
179 JsonNodeType type)
180 {
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);
184
185 json_node_unset (node);
186
187 node->type = type;
188
189 return node;
190 }
191
192 /**
193 * json_node_init_object:
194 * @node: the #JsonNode to initialize
195 * @object: (allow-none): the #JsonObject to initialize @node with, or %NULL
196 *
197 * Initializes @node to %JSON_NODE_OBJECT and sets @object into it.
198 *
199 * This function will take a reference on @object.
200 *
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.
203 *
204 * Return value: (transfer none): the initialized #JsonNode
205 *
206 * Since: 0.16
207 */
208 JsonNode *
json_node_init_object(JsonNode * node,JsonObject * object)209 json_node_init_object (JsonNode *node,
210 JsonObject *object)
211 {
212 g_return_val_if_fail (node != NULL, NULL);
213
214 json_node_init (node, JSON_NODE_OBJECT);
215 json_node_set_object (node, object);
216
217 return node;
218 }
219
220 /**
221 * json_node_init_array:
222 * @node: the #JsonNode to initialize
223 * @array: (allow-none): the #JsonArray to initialize @node with, or %NULL
224 *
225 * Initializes @node to %JSON_NODE_ARRAY and sets @array into it.
226 *
227 * This function will take a reference on @array.
228 *
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.
231 *
232 * Return value: (transfer none): the initialized #JsonNode
233 *
234 * Since: 0.16
235 */
236 JsonNode *
json_node_init_array(JsonNode * node,JsonArray * array)237 json_node_init_array (JsonNode *node,
238 JsonArray *array)
239 {
240 g_return_val_if_fail (node != NULL, NULL);
241
242 json_node_init (node, JSON_NODE_ARRAY);
243 json_node_set_array (node, array);
244
245 return node;
246 }
247
248 /**
249 * json_node_init_int:
250 * @node: the #JsonNode to initialize
251 * @value: an integer
252 *
253 * Initializes @node to %JSON_NODE_VALUE and sets @value into it.
254 *
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.
257 *
258 * Return value: (transfer none): the initialized #JsonNode
259 *
260 * Since: 0.16
261 */
262 JsonNode *
json_node_init_int(JsonNode * node,gint64 value)263 json_node_init_int (JsonNode *node,
264 gint64 value)
265 {
266 g_return_val_if_fail (node != NULL, NULL);
267
268 json_node_init (node, JSON_NODE_VALUE);
269 json_node_set_int (node, value);
270
271 return node;
272 }
273
274 /**
275 * json_node_init_double:
276 * @node: the #JsonNode to initialize
277 * @value: a floating point value
278 *
279 * Initializes @node to %JSON_NODE_VALUE and sets @value into it.
280 *
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.
283 *
284 * Return value: (transfer none): the initialized #JsonNode
285 *
286 * Since: 0.16
287 */
288 JsonNode *
json_node_init_double(JsonNode * node,gdouble value)289 json_node_init_double (JsonNode *node,
290 gdouble value)
291 {
292 g_return_val_if_fail (node != NULL, NULL);
293
294 json_node_init (node, JSON_NODE_VALUE);
295 json_node_set_double (node, value);
296
297 return node;
298 }
299
300 /**
301 * json_node_init_boolean:
302 * @node: the #JsonNode to initialize
303 * @value: a boolean value
304 *
305 * Initializes @node to %JSON_NODE_VALUE and sets @value into it.
306 *
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.
309 *
310 * Return value: (transfer none): the initialized #JsonNode
311 *
312 * Since: 0.16
313 */
314 JsonNode *
json_node_init_boolean(JsonNode * node,gboolean value)315 json_node_init_boolean (JsonNode *node,
316 gboolean value)
317 {
318 g_return_val_if_fail (node != NULL, NULL);
319
320 json_node_init (node, JSON_NODE_VALUE);
321 json_node_set_boolean (node, value);
322
323 return node;
324 }
325
326 /**
327 * json_node_init_string:
328 * @node: the #JsonNode to initialize
329 * @value: (allow-none): a string value
330 *
331 * Initializes @node to %JSON_NODE_VALUE and sets @value into it.
332 *
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.
335 *
336 * Return value: (transfer none): the initialized #JsonNode
337 *
338 * Since: 0.16
339 */
340 JsonNode *
json_node_init_string(JsonNode * node,const char * value)341 json_node_init_string (JsonNode *node,
342 const char *value)
343 {
344 g_return_val_if_fail (node != NULL, NULL);
345
346 json_node_init (node, JSON_NODE_VALUE);
347 json_node_set_string (node, value);
348
349 return node;
350 }
351
352 /**
353 * json_node_init_null:
354 * @node: the #JsonNode to initialize
355 *
356 * Initializes @node to %JSON_NODE_NULL.
357 *
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.
360 *
361 * Return value: (transfer none): the initialized #JsonNode
362 *
363 * Since: 0.16
364 */
365 JsonNode *
json_node_init_null(JsonNode * node)366 json_node_init_null (JsonNode *node)
367 {
368 g_return_val_if_fail (node != NULL, NULL);
369
370 return json_node_init (node, JSON_NODE_NULL);
371 }
372
373 /**
374 * json_node_new: (constructor)
375 * @type: a #JsonNodeType
376 *
377 * Creates a new #JsonNode of @type.
378 *
379 * This is a convenience function for json_node_alloc() and json_node_init(),
380 * and it's the equivalent of:
381 *
382 * |[<!-- language="C" -->
383 json_node_init (json_node_alloc (), type);
384 * ]|
385 *
386 * Return value: (transfer full): the newly created #JsonNode
387 */
388 JsonNode *
json_node_new(JsonNodeType type)389 json_node_new (JsonNodeType type)
390 {
391 g_return_val_if_fail (type >= JSON_NODE_OBJECT &&
392 type <= JSON_NODE_NULL, NULL);
393
394 return json_node_init (json_node_alloc (), type);
395 }
396
397 /**
398 * json_node_copy:
399 * @node: a #JsonNode
400 *
401 * Copies @node. If the node contains complex data types, their reference
402 * counts are increased, regardless of whether the node is mutable or
403 * immutable.
404 *
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.
407 *
408 * Return value: (transfer full): the copied #JsonNode
409 */
410 JsonNode *
json_node_copy(JsonNode * node)411 json_node_copy (JsonNode *node)
412 {
413 JsonNode *copy;
414
415 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
416
417 copy = json_node_alloc ();
418 copy->type = node->type;
419 copy->immutable = node->immutable;
420
421 #ifdef JSON_ENABLE_DEBUG
422 if (node->immutable)
423 {
424 JSON_NOTE (NODE, "Copying immutable JsonNode %p of type %s",
425 node,
426 json_node_type_name (node));
427 }
428 #endif
429
430 switch (copy->type)
431 {
432 case JSON_NODE_OBJECT:
433 copy->data.object = json_node_dup_object (node);
434 break;
435
436 case JSON_NODE_ARRAY:
437 copy->data.array = json_node_dup_array (node);
438 break;
439
440 case JSON_NODE_VALUE:
441 if (node->data.value)
442 copy->data.value = json_value_ref (node->data.value);
443 break;
444
445 case JSON_NODE_NULL:
446 break;
447
448 default:
449 g_assert_not_reached ();
450 }
451
452 return copy;
453 }
454
455 /**
456 * json_node_ref:
457 * @node: a #JsonNode
458 *
459 * Increment the reference count of @node.
460 *
461 * Since: 1.2
462 * Returns: (transfer full): a pointer to @node
463 */
464 JsonNode *
json_node_ref(JsonNode * node)465 json_node_ref (JsonNode *node)
466 {
467 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
468
469 g_atomic_int_inc (&node->ref_count);
470
471 return node;
472 }
473
474 /**
475 * json_node_unref:
476 * @node: (transfer full): a #JsonNode
477 *
478 * Decrement the reference count of @node. If it reaches zero, the node is
479 * freed.
480 *
481 * Since: 1.2
482 */
483 void
json_node_unref(JsonNode * node)484 json_node_unref (JsonNode *node)
485 {
486 g_return_if_fail (JSON_NODE_IS_VALID (node));
487
488 if (g_atomic_int_dec_and_test (&node->ref_count))
489 {
490 json_node_unset (node);
491 if (node->allocated)
492 g_slice_free (JsonNode, node);
493 }
494 }
495
496 /**
497 * json_node_set_object:
498 * @node: a #JsonNode initialized to %JSON_NODE_OBJECT
499 * @object: (nullable): a #JsonObject
500 *
501 * Sets @objects inside @node. The reference count of @object is increased.
502 *
503 * If @object is %NULL, the node’s existing object is cleared.
504 *
505 * It is an error to call this on an immutable node, or on a node which is not
506 * an object node.
507 */
508 void
json_node_set_object(JsonNode * node,JsonObject * object)509 json_node_set_object (JsonNode *node,
510 JsonObject *object)
511 {
512 g_return_if_fail (JSON_NODE_IS_VALID (node));
513 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT);
514 g_return_if_fail (!node->immutable);
515
516 if (node->data.object != NULL)
517 json_object_unref (node->data.object);
518
519 if (object)
520 node->data.object = json_object_ref (object);
521 else
522 node->data.object = NULL;
523 }
524
525 /**
526 * json_node_take_object:
527 * @node: a #JsonNode initialized to %JSON_NODE_OBJECT
528 * @object: (transfer full): a #JsonObject
529 *
530 * Sets @object inside @node. The reference count of @object is not increased.
531 *
532 * It is an error to call this on an immutable node, or on a node which is not
533 * an object node.
534 */
535 void
json_node_take_object(JsonNode * node,JsonObject * object)536 json_node_take_object (JsonNode *node,
537 JsonObject *object)
538 {
539 g_return_if_fail (JSON_NODE_IS_VALID (node));
540 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT);
541 g_return_if_fail (!node->immutable);
542
543 if (node->data.object)
544 {
545 json_object_unref (node->data.object);
546 node->data.object = NULL;
547 }
548
549 if (object)
550 node->data.object = object;
551 }
552
553 /**
554 * json_node_get_object:
555 * @node: a #JsonNode
556 *
557 * Retrieves the #JsonObject stored inside a #JsonNode. It is a programmer error
558 * to call this on a node which doesn’t hold an object value. Use
559 * %JSON_NODE_HOLDS_OBJECT first.
560 *
561 * Return value: (transfer none) (nullable): the #JsonObject
562 */
563 JsonObject *
json_node_get_object(JsonNode * node)564 json_node_get_object (JsonNode *node)
565 {
566 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
567 g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL);
568
569 return node->data.object;
570 }
571
572 /**
573 * json_node_dup_object:
574 * @node: a #JsonNode
575 *
576 * Retrieves the #JsonObject inside @node. The reference count of
577 * the returned object is increased. It is a programmer error
578 * to call this on a node which doesn’t hold an object value. Use
579 * %JSON_NODE_HOLDS_OBJECT first.
580 *
581 * Return value: (transfer full) (nullable): the #JsonObject
582 */
583 JsonObject *
json_node_dup_object(JsonNode * node)584 json_node_dup_object (JsonNode *node)
585 {
586 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
587 g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL);
588
589 if (node->data.object)
590 return json_object_ref (node->data.object);
591
592 return NULL;
593 }
594
595 /**
596 * json_node_set_array:
597 * @node: a #JsonNode initialized to %JSON_NODE_ARRAY
598 * @array: a #JsonArray
599 *
600 * Sets @array inside @node and increases the #JsonArray reference count.
601 *
602 * It is an error to call this on an immutable node, or on a node which is not
603 * an array node.
604 */
605 void
json_node_set_array(JsonNode * node,JsonArray * array)606 json_node_set_array (JsonNode *node,
607 JsonArray *array)
608 {
609 g_return_if_fail (JSON_NODE_IS_VALID (node));
610 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY);
611 g_return_if_fail (!node->immutable);
612
613 if (node->data.array)
614 json_array_unref (node->data.array);
615
616 if (array)
617 node->data.array = json_array_ref (array);
618 else
619 node->data.array = NULL;
620 }
621
622 /**
623 * json_node_take_array:
624 * @node: a #JsonNode initialized to %JSON_NODE_ARRAY
625 * @array: (transfer full): a #JsonArray
626 *
627 * Sets @array into @node without increasing the #JsonArray reference count.
628 *
629 * It is an error to call this on an immutable node, or a node which is not
630 * an array node.
631 */
632 void
json_node_take_array(JsonNode * node,JsonArray * array)633 json_node_take_array (JsonNode *node,
634 JsonArray *array)
635 {
636 g_return_if_fail (JSON_NODE_IS_VALID (node));
637 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY);
638 g_return_if_fail (!node->immutable);
639
640 if (node->data.array)
641 {
642 json_array_unref (node->data.array);
643 node->data.array = NULL;
644 }
645
646 if (array)
647 node->data.array = array;
648 }
649
650 /**
651 * json_node_get_array:
652 * @node: a #JsonNode
653 *
654 * Retrieves the #JsonArray stored inside a #JsonNode. It is a programmer error
655 * to call this on a node which doesn’t hold an array value. Use
656 * %JSON_NODE_HOLDS_ARRAY first.
657 *
658 * Return value: (transfer none) (nullable): the #JsonArray
659 */
660 JsonArray *
json_node_get_array(JsonNode * node)661 json_node_get_array (JsonNode *node)
662 {
663 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
664 g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY, NULL);
665
666 return node->data.array;
667 }
668
669 /**
670 * json_node_dup_array:
671 * @node: a #JsonNode
672 *
673 * Retrieves the #JsonArray stored inside a #JsonNode and returns it
674 * with its reference count increased by one. It is a programmer error
675 * to call this on a node which doesn’t hold an array value. Use
676 * %JSON_NODE_HOLDS_ARRAY first.
677 *
678 * Return value: (transfer full) (nullable): the #JsonArray with its reference
679 * count increased.
680 */
681 JsonArray *
json_node_dup_array(JsonNode * node)682 json_node_dup_array (JsonNode *node)
683 {
684 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
685 g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY, NULL);
686
687 if (node->data.array)
688 return json_array_ref (node->data.array);
689
690 return NULL;
691 }
692
693 /**
694 * json_node_get_value:
695 * @node: a #JsonNode
696 * @value: (out caller-allocates): return location for an uninitialized value
697 *
698 * Retrieves a value from a #JsonNode and copies into @value. When done
699 * using it, call g_value_unset() on the #GValue. It is a programmer error
700 * to call this on a node which doesn’t hold a scalar value. Use
701 * %JSON_NODE_HOLDS_VALUE first.
702 */
703 void
json_node_get_value(JsonNode * node,GValue * value)704 json_node_get_value (JsonNode *node,
705 GValue *value)
706 {
707 g_return_if_fail (JSON_NODE_IS_VALID (node));
708 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
709
710 if (node->data.value)
711 {
712 g_value_init (value, JSON_VALUE_TYPE (node->data.value));
713 switch (JSON_VALUE_TYPE (node->data.value))
714 {
715 case G_TYPE_INT64:
716 g_value_set_int64 (value, json_value_get_int (node->data.value));
717 break;
718
719 case G_TYPE_DOUBLE:
720 g_value_set_double (value, json_value_get_double (node->data.value));
721 break;
722
723 case G_TYPE_BOOLEAN:
724 g_value_set_boolean (value, json_value_get_boolean (node->data.value));
725 break;
726
727 case G_TYPE_STRING:
728 g_value_set_string (value, json_value_get_string (node->data.value));
729 break;
730
731 default:
732 break;
733 }
734 }
735 }
736
737 /**
738 * json_node_set_value:
739 * @node: a #JsonNode initialized to %JSON_NODE_VALUE
740 * @value: the #GValue to set
741 *
742 * Sets @value inside @node. The passed #GValue is copied into the #JsonNode.
743 *
744 * It is an error to call this on an immutable node, or on a node which is not
745 * a value node.
746 */
747 void
json_node_set_value(JsonNode * node,const GValue * value)748 json_node_set_value (JsonNode *node,
749 const GValue *value)
750 {
751 g_return_if_fail (JSON_NODE_IS_VALID (node));
752 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
753 g_return_if_fail (G_VALUE_TYPE (value) != G_TYPE_INVALID);
754 g_return_if_fail (!node->immutable);
755
756 if (node->data.value == NULL)
757 node->data.value = json_value_alloc ();
758
759 switch (G_VALUE_TYPE (value))
760 {
761 /* auto-promote machine integers to 64 bit integers */
762 case G_TYPE_INT64:
763 case G_TYPE_INT:
764 json_value_init (node->data.value, JSON_VALUE_INT);
765 if (G_VALUE_TYPE (value) == G_TYPE_INT64)
766 json_value_set_int (node->data.value, g_value_get_int64 (value));
767 else
768 json_value_set_int (node->data.value, g_value_get_int (value));
769 break;
770
771 case G_TYPE_BOOLEAN:
772 json_value_init (node->data.value, JSON_VALUE_BOOLEAN);
773 json_value_set_boolean (node->data.value, g_value_get_boolean (value));
774 break;
775
776 /* auto-promote single-precision floats to double precision floats */
777 case G_TYPE_DOUBLE:
778 case G_TYPE_FLOAT:
779 json_value_init (node->data.value, JSON_VALUE_DOUBLE);
780 if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE)
781 json_value_set_double (node->data.value, g_value_get_double (value));
782 else
783 json_value_set_double (node->data.value, g_value_get_float (value));
784 break;
785
786 case G_TYPE_STRING:
787 json_value_init (node->data.value, JSON_VALUE_STRING);
788 json_value_set_string (node->data.value, g_value_get_string (value));
789 break;
790
791 default:
792 g_message ("Invalid value of type '%s'",
793 g_type_name (G_VALUE_TYPE (value)));
794 return;
795 }
796
797 }
798
799 /**
800 * json_node_free:
801 * @node: a #JsonNode
802 *
803 * Frees the resources allocated by @node.
804 */
805 void
json_node_free(JsonNode * node)806 json_node_free (JsonNode *node)
807 {
808 g_return_if_fail (node == NULL || JSON_NODE_IS_VALID (node));
809 g_return_if_fail (node == NULL || node->allocated);
810
811 if (G_LIKELY (node))
812 {
813 if (node->ref_count > 1)
814 g_warning ("Freeing a JsonNode %p owned by other code.", node);
815
816 json_node_unset (node);
817 g_slice_free (JsonNode, node);
818 }
819 }
820
821 /**
822 * json_node_seal:
823 * @node: a #JsonNode
824 *
825 * Seals the #JsonNode, making it immutable to further changes. In order to be
826 * sealed, the @node must have a type and value set. The value will be
827 * recursively sealed — if the node holds an object, that #JsonObject will be
828 * sealed, etc.
829 *
830 * If the @node is already immutable, this is a no-op.
831 *
832 * Since: 1.2
833 */
834 void
json_node_seal(JsonNode * node)835 json_node_seal (JsonNode *node)
836 {
837 g_return_if_fail (JSON_NODE_IS_VALID (node));
838
839 if (node->immutable)
840 return;
841
842 switch (node->type)
843 {
844 case JSON_NODE_OBJECT:
845 g_return_if_fail (node->data.object != NULL);
846 json_object_seal (node->data.object);
847 break;
848 case JSON_NODE_ARRAY:
849 g_return_if_fail (node->data.array != NULL);
850 json_array_seal (node->data.array);
851 break;
852 case JSON_NODE_NULL:
853 break;
854 case JSON_NODE_VALUE:
855 g_return_if_fail (node->data.value != NULL);
856 json_value_seal (node->data.value);
857 break;
858 default:
859 g_assert_not_reached ();
860 }
861
862 node->immutable = TRUE;
863 }
864
865 /**
866 * json_node_is_immutable:
867 * @node: a #JsonNode
868 *
869 * Check whether the given @node has been marked as immutable by calling
870 * json_node_seal() on it.
871 *
872 * Since: 1.2
873 * Returns: %TRUE if the @node is immutable
874 */
875 gboolean
json_node_is_immutable(JsonNode * node)876 json_node_is_immutable (JsonNode *node)
877 {
878 g_return_val_if_fail (JSON_NODE_IS_VALID (node), FALSE);
879
880 return node->immutable;
881 }
882
883 /**
884 * json_node_type_name:
885 * @node: a #JsonNode
886 *
887 * Retrieves the user readable name of the data type contained by @node.
888 *
889 * Return value: a string containing the name of the type. The returned string
890 * is owned by the node and should never be modified or freed
891 */
892 const gchar *
json_node_type_name(JsonNode * node)893 json_node_type_name (JsonNode *node)
894 {
895 g_return_val_if_fail (node != NULL, "(null)");
896
897 switch (node->type)
898 {
899 case JSON_NODE_OBJECT:
900 case JSON_NODE_ARRAY:
901 case JSON_NODE_NULL:
902 return json_node_type_get_name (node->type);
903
904 case JSON_NODE_VALUE:
905 if (node->data.value)
906 return json_value_type_get_name (node->data.value->type);
907 }
908
909 return "unknown";
910 }
911
912 const gchar *
json_node_type_get_name(JsonNodeType node_type)913 json_node_type_get_name (JsonNodeType node_type)
914 {
915 switch (node_type)
916 {
917 case JSON_NODE_OBJECT:
918 return "JsonObject";
919
920 case JSON_NODE_ARRAY:
921 return "JsonArray";
922
923 case JSON_NODE_NULL:
924 return "NULL";
925
926 case JSON_NODE_VALUE:
927 return "Value";
928
929 default:
930 g_assert_not_reached ();
931 break;
932 }
933
934 return "unknown";
935 }
936
937 /**
938 * json_node_set_parent:
939 * @node: a #JsonNode
940 * @parent: (transfer none): the parent #JsonNode of @node
941 *
942 * Sets the parent #JsonNode of @node.
943 *
944 * It is an error to call this with an immutable @parent. @node may be
945 * immutable.
946 *
947 * Since: 0.8
948 */
949 void
json_node_set_parent(JsonNode * node,JsonNode * parent)950 json_node_set_parent (JsonNode *node,
951 JsonNode *parent)
952 {
953 g_return_if_fail (JSON_NODE_IS_VALID (node));
954 g_return_if_fail (parent == NULL ||
955 !json_node_is_immutable (parent));
956
957 node->parent = parent;
958 }
959
960 /**
961 * json_node_get_parent:
962 * @node: a #JsonNode
963 *
964 * Retrieves the parent #JsonNode of @node.
965 *
966 * Return value: (transfer none) (nullable): the parent node, or %NULL if @node
967 * is the root node
968 */
969 JsonNode *
json_node_get_parent(JsonNode * node)970 json_node_get_parent (JsonNode *node)
971 {
972 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
973
974 return node->parent;
975 }
976
977 /**
978 * json_node_set_string:
979 * @node: a #JsonNode initialized to %JSON_NODE_VALUE
980 * @value: a string value
981 *
982 * Sets @value as the string content of the @node, replacing any existing
983 * content.
984 *
985 * It is an error to call this on an immutable node, or on a node which is not
986 * a value node.
987 */
988 void
json_node_set_string(JsonNode * node,const gchar * value)989 json_node_set_string (JsonNode *node,
990 const gchar *value)
991 {
992 g_return_if_fail (JSON_NODE_IS_VALID (node));
993 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
994 g_return_if_fail (!node->immutable);
995
996 if (node->data.value == NULL)
997 node->data.value = json_value_init (json_value_alloc (), JSON_VALUE_STRING);
998 else
999 json_value_init (node->data.value, JSON_VALUE_STRING);
1000
1001 json_value_set_string (node->data.value, value);
1002 }
1003
1004 /**
1005 * json_node_get_string:
1006 * @node: a #JsonNode of type %JSON_NODE_VALUE
1007 *
1008 * Gets the string value stored inside a #JsonNode. If the node does not hold a
1009 * string value, %NULL is returned.
1010 *
1011 * Return value: (nullable): a string value.
1012 */
1013 const gchar *
json_node_get_string(JsonNode * node)1014 json_node_get_string (JsonNode *node)
1015 {
1016 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
1017
1018 if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
1019 return NULL;
1020
1021 if (JSON_VALUE_HOLDS_STRING (node->data.value))
1022 return json_value_get_string (node->data.value);
1023
1024 return NULL;
1025 }
1026
1027 /**
1028 * json_node_dup_string:
1029 * @node: a #JsonNode of type %JSON_NODE_VALUE
1030 *
1031 * Gets a copy of the string value stored inside a #JsonNode. If the node does
1032 * not hold a string value, %NULL is returned.
1033 *
1034 * Return value: (transfer full) (nullable): a newly allocated string
1035 * containing a copy of the #JsonNode contents. Use g_free() to free the
1036 * allocated resources
1037 */
1038 gchar *
json_node_dup_string(JsonNode * node)1039 json_node_dup_string (JsonNode *node)
1040 {
1041 g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);
1042
1043 return g_strdup (json_node_get_string (node));
1044 }
1045
1046 /**
1047 * json_node_set_int:
1048 * @node: a #JsonNode of type %JSON_NODE_VALUE
1049 * @value: an integer value
1050 *
1051 * Sets @value as the integer content of the @node, replacing any existing
1052 * content.
1053 *
1054 * It is an error to call this on an immutable node, or on a node which is not
1055 * a value node.
1056 */
1057 void
json_node_set_int(JsonNode * node,gint64 value)1058 json_node_set_int (JsonNode *node,
1059 gint64 value)
1060 {
1061 g_return_if_fail (JSON_NODE_IS_VALID (node));
1062 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
1063 g_return_if_fail (!node->immutable);
1064
1065 if (node->data.value == NULL)
1066 node->data.value = json_value_init (json_value_alloc (), JSON_VALUE_INT);
1067 else
1068 json_value_init (node->data.value, JSON_VALUE_INT);
1069
1070 json_value_set_int (node->data.value, value);
1071 }
1072
1073 /**
1074 * json_node_get_int:
1075 * @node: a #JsonNode of type %JSON_NODE_VALUE
1076 *
1077 * Gets the integer value stored inside a #JsonNode. If the node holds a double
1078 * value, its integer component is returned. If the node holds a %FALSE boolean
1079 * value, `0` is returned; otherwise a non-zero integer is returned. If the
1080 * node holds a %JSON_NODE_NULL value or a value of another non-integer type,
1081 * `0` is returned.
1082 *
1083 * Return value: an integer value.
1084 */
1085 gint64
json_node_get_int(JsonNode * node)1086 json_node_get_int (JsonNode *node)
1087 {
1088 g_return_val_if_fail (JSON_NODE_IS_VALID (node), 0);
1089
1090 if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
1091 return 0;
1092
1093 if (JSON_VALUE_HOLDS_INT (node->data.value))
1094 return json_value_get_int (node->data.value);
1095
1096 if (JSON_VALUE_HOLDS_DOUBLE (node->data.value))
1097 return json_value_get_double (node->data.value);
1098
1099 if (JSON_VALUE_HOLDS_BOOLEAN (node->data.value))
1100 return json_value_get_boolean (node->data.value);
1101
1102 return 0;
1103 }
1104
1105 /**
1106 * json_node_set_double:
1107 * @node: a #JsonNode of type %JSON_NODE_VALUE
1108 * @value: a double value
1109 *
1110 * Sets @value as the double content of the @node, replacing any existing
1111 * content.
1112 *
1113 * It is an error to call this on an immutable node, or on a node which is not
1114 * a value node.
1115 */
1116 void
json_node_set_double(JsonNode * node,gdouble value)1117 json_node_set_double (JsonNode *node,
1118 gdouble value)
1119 {
1120 g_return_if_fail (JSON_NODE_IS_VALID (node));
1121 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
1122 g_return_if_fail (!node->immutable);
1123
1124 if (node->data.value == NULL)
1125 node->data.value = json_value_init (json_value_alloc (), JSON_VALUE_DOUBLE);
1126 else
1127 json_value_init (node->data.value, JSON_VALUE_DOUBLE);
1128
1129 json_value_set_double (node->data.value, value);
1130 }
1131
1132 /**
1133 * json_node_get_double:
1134 * @node: a #JsonNode of type %JSON_NODE_VALUE
1135 *
1136 * Gets the double value stored inside a #JsonNode. If the node holds an integer
1137 * value, it is returned as a double. If the node holds a %FALSE boolean value,
1138 * `0.0` is returned; otherwise a non-zero double is returned. If the node holds
1139 * a %JSON_NODE_NULL value or a value of another non-double type, `0.0` is
1140 * returned.
1141 *
1142 * Return value: a double value.
1143 */
1144 gdouble
json_node_get_double(JsonNode * node)1145 json_node_get_double (JsonNode *node)
1146 {
1147 g_return_val_if_fail (JSON_NODE_IS_VALID (node), 0.0);
1148
1149 if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
1150 return 0;
1151
1152 if (JSON_VALUE_HOLDS_DOUBLE (node->data.value))
1153 return json_value_get_double (node->data.value);
1154
1155 if (JSON_VALUE_HOLDS_INT (node->data.value))
1156 return (gdouble) json_value_get_int (node->data.value);
1157
1158 if (JSON_VALUE_HOLDS_BOOLEAN (node->data.value))
1159 return (gdouble) json_value_get_boolean (node->data.value);
1160
1161 return 0.0;
1162 }
1163
1164 /**
1165 * json_node_set_boolean:
1166 * @node: a #JsonNode of type %JSON_NODE_VALUE
1167 * @value: a boolean value
1168 *
1169 * Sets @value as the boolean content of the @node, replacing any existing
1170 * content.
1171 *
1172 * It is an error to call this on an immutable node, or on a node which is not
1173 * a value node.
1174 */
1175 void
json_node_set_boolean(JsonNode * node,gboolean value)1176 json_node_set_boolean (JsonNode *node,
1177 gboolean value)
1178 {
1179 g_return_if_fail (JSON_NODE_IS_VALID (node));
1180 g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
1181 g_return_if_fail (!node->immutable);
1182
1183 if (node->data.value == NULL)
1184 node->data.value = json_value_init (json_value_alloc (), JSON_VALUE_BOOLEAN);
1185 else
1186 json_value_init (node->data.value, JSON_VALUE_BOOLEAN);
1187
1188 json_value_set_boolean (node->data.value, value);
1189 }
1190
1191 /**
1192 * json_node_get_boolean:
1193 * @node: a #JsonNode of type %JSON_NODE_VALUE
1194 *
1195 * Gets the boolean value stored inside a #JsonNode. If the node holds an
1196 * integer or double value which is zero, %FALSE is returned; otherwise %TRUE
1197 * is returned. If the node holds a %JSON_NODE_NULL value or a value of another
1198 * non-boolean type, %FALSE is returned.
1199 *
1200 * Return value: a boolean value.
1201 */
1202 gboolean
json_node_get_boolean(JsonNode * node)1203 json_node_get_boolean (JsonNode *node)
1204 {
1205 g_return_val_if_fail (JSON_NODE_IS_VALID (node), FALSE);
1206
1207 if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
1208 return FALSE;
1209
1210 if (JSON_VALUE_HOLDS_BOOLEAN (node->data.value))
1211 return json_value_get_boolean (node->data.value);
1212
1213 if (JSON_VALUE_HOLDS_INT (node->data.value))
1214 return json_value_get_int (node->data.value) != 0;
1215
1216 if (JSON_VALUE_HOLDS_DOUBLE (node->data.value))
1217 return json_value_get_double (node->data.value) != 0.0;
1218
1219 return FALSE;
1220 }
1221
1222 /**
1223 * json_node_get_node_type:
1224 * @node: a #JsonNode
1225 *
1226 * Retrieves the #JsonNodeType of @node
1227 *
1228 * Return value: the type of the node
1229 *
1230 * Since: 0.8
1231 */
1232 JsonNodeType
json_node_get_node_type(JsonNode * node)1233 json_node_get_node_type (JsonNode *node)
1234 {
1235 g_return_val_if_fail (JSON_NODE_IS_VALID (node), JSON_NODE_NULL);
1236
1237 return node->type;
1238 }
1239
1240 /**
1241 * json_node_is_null:
1242 * @node: a #JsonNode
1243 *
1244 * Checks whether @node is a %JSON_NODE_NULL.
1245 *
1246 * A %JSON_NODE_NULL node is not the same as a %NULL #JsonNode; a
1247 * %JSON_NODE_NULL represents a 'null' value in the JSON tree.
1248 *
1249 * Return value: %TRUE if the node is null
1250 *
1251 * Since: 0.8
1252 */
1253 gboolean
json_node_is_null(JsonNode * node)1254 json_node_is_null (JsonNode *node)
1255 {
1256 g_return_val_if_fail (JSON_NODE_IS_VALID (node), TRUE);
1257
1258 return node->type == JSON_NODE_NULL;
1259 }
1260
1261 /**
1262 * json_type_is_a:
1263 * @sub: sub-type
1264 * @super: super-type
1265 *
1266 * Check whether @sub is a sub-type of, or equal to, @super. The only sub-type
1267 * relationship in the JSON Schema type system is that
1268 * %WBL_PRIMITIVE_TYPE_INTEGER is a sub-type of %WBL_PRIMITIVE_TYPE_NUMBER.
1269 *
1270 * Formally, this function calculates: `@sub <: @super`.
1271 *
1272 * Reference: http://json-schema.org/latest/json-schema-core.html#rfc.section.3.5
1273 *
1274 * Returns: %TRUE if @sub is a sub-type of, or equal to, @super; %FALSE
1275 * otherwise
1276 * Since: 1.2
1277 */
1278 static gboolean
json_type_is_a(JsonNode * sub,JsonNode * super)1279 json_type_is_a (JsonNode *sub,
1280 JsonNode *super)
1281 {
1282 if (super->type == JSON_NODE_VALUE && sub->type == JSON_NODE_VALUE)
1283 {
1284 JsonValueType super_value_type, sub_value_type;
1285
1286 if (super->data.value == NULL || sub->data.value == NULL)
1287 return FALSE;
1288
1289 super_value_type = super->data.value->type;
1290 sub_value_type = sub->data.value->type;
1291
1292 return (super_value_type == sub_value_type ||
1293 (super_value_type == JSON_VALUE_DOUBLE &&
1294 sub_value_type == JSON_VALUE_INT));
1295 }
1296
1297 return (super->type == sub->type);
1298 }
1299
1300 /**
1301 * json_string_hash:
1302 * @key: (type utf8): a JSON string to hash
1303 *
1304 * Calculate a hash value for the given @key (a UTF-8 JSON string).
1305 *
1306 * Note: Member names are compared byte-wise, without applying any Unicode
1307 * decomposition or normalisation. This is not explicitly mentioned in the JSON
1308 * standard (ECMA-404), but is assumed.
1309 *
1310 * Returns: hash value for @key
1311 * Since: 1.2
1312 */
1313 guint
json_string_hash(gconstpointer key)1314 json_string_hash (gconstpointer key)
1315 {
1316 return g_str_hash (key);
1317 }
1318
1319 /**
1320 * json_string_equal:
1321 * @a: (type utf8): a JSON string
1322 * @b: (type utf8): another JSON string
1323 *
1324 * Check whether @a and @b are equal UTF-8 JSON strings.
1325 *
1326 * Returns: %TRUE if @a and @b are equal; %FALSE otherwise
1327 * Since: 1.2
1328 */
1329 gboolean
json_string_equal(gconstpointer a,gconstpointer b)1330 json_string_equal (gconstpointer a,
1331 gconstpointer b)
1332 {
1333 return g_str_equal (a, b);
1334 }
1335
1336 /**
1337 * json_string_compare:
1338 * @a: (type utf8): a JSON string
1339 * @b: (type utf8): another JSON string
1340 *
1341 * Check whether @a and @b are equal UTF-8 JSON strings and return an ordering
1342 * over them in strcmp() style.
1343 *
1344 * Returns: an integer less than zero if @a < @b, equal to zero if @a == @b, and
1345 * greater than zero if @a > @b
1346 * Since: 1.2
1347 */
1348 gint
json_string_compare(gconstpointer a,gconstpointer b)1349 json_string_compare (gconstpointer a,
1350 gconstpointer b)
1351 {
1352 return g_strcmp0 (a, b);
1353 }
1354
1355 /**
1356 * json_node_hash:
1357 * @key: (type JsonNode): a JSON node to hash
1358 *
1359 * Calculate a hash value for the given @key (a #JsonNode).
1360 *
1361 * The hash is calculated over the node and its value, recursively. If the node
1362 * is immutable, this is a fast operation; otherwise, it scales proportionally
1363 * with the size of the node’s value (for example, with the number of members
1364 * in the #JsonObject if this node contains an object).
1365 *
1366 * Returns: hash value for @key
1367 * Since: 1.2
1368 */
1369 guint
json_node_hash(gconstpointer key)1370 json_node_hash (gconstpointer key)
1371 {
1372 JsonNode *node; /* unowned */
1373
1374 /* These are all randomly generated and arbitrary. */
1375 const guint value_hash = 0xc19e75ad;
1376 const guint array_hash = 0x865acfc2;
1377 const guint object_hash = 0x3c8f3135;
1378
1379 node = (JsonNode *) key;
1380
1381 /* XOR the hash values with a (constant) random number depending on the node’s
1382 * type so that empty values, arrays and objects do not all collide at the
1383 * hash value 0. */
1384 switch (node->type)
1385 {
1386 case JSON_NODE_NULL:
1387 return 0;
1388 case JSON_NODE_VALUE:
1389 return value_hash ^ json_value_hash (node->data.value);
1390 case JSON_NODE_ARRAY:
1391 return array_hash ^ json_array_hash (json_node_get_array (node));
1392 case JSON_NODE_OBJECT:
1393 return object_hash ^ json_object_hash (json_node_get_object (node));
1394 default:
1395 g_assert_not_reached ();
1396 }
1397 }
1398
1399 /**
1400 * json_node_equal:
1401 * @a: (type JsonNode): a JSON node
1402 * @b: (type JsonNode): another JSON node
1403 *
1404 * Check whether @a and @b are equal #JsonNodes, meaning they have the same
1405 * type and same values (checked recursively). Note that integer values are
1406 * compared numerically, ignoring type, so a double value 4.0 is equal to the
1407 * integer value 4.
1408 *
1409 * Returns: %TRUE if @a and @b are equal; %FALSE otherwise
1410 * Since: 1.2
1411 */
1412 gboolean
json_node_equal(gconstpointer a,gconstpointer b)1413 json_node_equal (gconstpointer a,
1414 gconstpointer b)
1415 {
1416 JsonNode *node_a, *node_b; /* unowned */
1417
1418 node_a = (JsonNode *) a;
1419 node_b = (JsonNode *) b;
1420
1421 /* Identity comparison. */
1422 if (node_a == node_b)
1423 return TRUE;
1424
1425 /* Eliminate mismatched types rapidly. */
1426 if (!json_type_is_a (node_a, node_b) &&
1427 !json_type_is_a (node_b, node_a))
1428 {
1429 return FALSE;
1430 }
1431
1432 switch (node_a->type)
1433 {
1434 case JSON_NODE_NULL:
1435 /* Types match already. */
1436 return TRUE;
1437 case JSON_NODE_ARRAY:
1438 return json_array_equal (json_node_get_array (node_a),
1439 json_node_get_array (node_b));
1440 case JSON_NODE_OBJECT:
1441 return json_object_equal (json_node_get_object (node_a),
1442 json_node_get_object (node_b));
1443 case JSON_NODE_VALUE:
1444 /* Handled below. */
1445 break;
1446 default:
1447 g_assert_not_reached ();
1448 }
1449
1450 /* Handle values. */
1451 switch (node_a->data.value->type)
1452 {
1453 case JSON_VALUE_NULL:
1454 /* Types already match. */
1455 return TRUE;
1456 case JSON_VALUE_BOOLEAN:
1457 return (json_node_get_boolean (node_a) == json_node_get_boolean (node_b));
1458 case JSON_VALUE_STRING:
1459 return json_string_equal (json_node_get_string (node_a),
1460 json_node_get_string (node_b));
1461 case JSON_VALUE_DOUBLE:
1462 case JSON_VALUE_INT: {
1463 gdouble val_a, val_b;
1464 JsonValueType value_type_a, value_type_b;
1465
1466 value_type_a = node_a->data.value->type;
1467 value_type_b = node_b->data.value->type;
1468
1469 /* Integer comparison doesn’t need to involve doubles… */
1470 if (value_type_a == JSON_VALUE_INT &&
1471 value_type_b == JSON_VALUE_INT)
1472 {
1473 return (json_node_get_int (node_a) ==
1474 json_node_get_int (node_b));
1475 }
1476
1477 /* …but everything else does. We can use bitwise double equality here,
1478 * since we’re not doing any calculations which could introduce floating
1479 * point error. We expect that the doubles in the JSON nodes come directly
1480 * from strtod() or similar, so should be bitwise equal for equal string
1481 * representations.
1482 *
1483 * Interesting background reading:
1484 * http://randomascii.wordpress.com/2012/06/26/\
1485 * doubles-are-not-floats-so-dont-compare-them/
1486 */
1487 if (value_type_a == JSON_VALUE_INT)
1488 val_a = json_node_get_int (node_a);
1489 else
1490 val_a = json_node_get_double (node_a);
1491
1492 if (value_type_b == JSON_VALUE_INT)
1493 val_b = json_node_get_int (node_b);
1494 else
1495 val_b = json_node_get_double (node_b);
1496
1497 return (val_a == val_b);
1498 }
1499 case JSON_VALUE_INVALID:
1500 default:
1501 g_assert_not_reached ();
1502 }
1503 }
1504