"Fossies" - the Fresh Open Source Software Archive 
Member "jansson-2.14/src/value.c" (19 Nov 2020, 25626 Bytes) of package /linux/www/jansson-2.14.tar.bz2:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "value.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.13.1_vs_2.14.
1 /*
2 * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>
3 *
4 * Jansson is free software; you can redistribute it and/or modify
5 * it under the terms of the MIT license. See LICENSE for details.
6 */
7
8 #ifndef _GNU_SOURCE
9 #define _GNU_SOURCE
10 #endif
11
12 #ifdef HAVE_CONFIG_H
13 #include <jansson_private_config.h>
14 #endif
15
16 #include <math.h>
17 #include <stddef.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 #ifdef HAVE_STDINT_H
22 #include <stdint.h>
23 #endif
24
25 #include "hashtable.h"
26 #include "jansson.h"
27 #include "jansson_private.h"
28 #include "utf.h"
29
30 /* Work around nonstandard isnan() and isinf() implementations */
31 #ifndef isnan
32 #ifndef __sun
33 static JSON_INLINE int isnan(double x) { return x != x; }
34 #endif
35 #endif
36 #ifndef isinf
37 static JSON_INLINE int isinf(double x) { return !isnan(x) && isnan(x - x); }
38 #endif
39
40 json_t *do_deep_copy(const json_t *json, hashtable_t *parents);
41
42 static JSON_INLINE void json_init(json_t *json, json_type type) {
43 json->type = type;
44 json->refcount = 1;
45 }
46
47 int jsonp_loop_check(hashtable_t *parents, const json_t *json, char *key, size_t key_size,
48 size_t *key_len_out) {
49 size_t key_len = snprintf(key, key_size, "%p", json);
50
51 if (key_len_out)
52 *key_len_out = key_len;
53
54 if (hashtable_get(parents, key, key_len))
55 return -1;
56
57 return hashtable_set(parents, key, key_len, json_null());
58 }
59
60 /*** object ***/
61
62 extern volatile uint32_t hashtable_seed;
63
64 json_t *json_object(void) {
65 json_object_t *object = jsonp_malloc(sizeof(json_object_t));
66 if (!object)
67 return NULL;
68
69 if (!hashtable_seed) {
70 /* Autoseed */
71 json_object_seed(0);
72 }
73
74 json_init(&object->json, JSON_OBJECT);
75
76 if (hashtable_init(&object->hashtable)) {
77 jsonp_free(object);
78 return NULL;
79 }
80
81 return &object->json;
82 }
83
84 static void json_delete_object(json_object_t *object) {
85 hashtable_close(&object->hashtable);
86 jsonp_free(object);
87 }
88
89 size_t json_object_size(const json_t *json) {
90 json_object_t *object;
91
92 if (!json_is_object(json))
93 return 0;
94
95 object = json_to_object(json);
96 return object->hashtable.size;
97 }
98
99 json_t *json_object_get(const json_t *json, const char *key) {
100 if (!key)
101 return NULL;
102
103 return json_object_getn(json, key, strlen(key));
104 }
105
106 json_t *json_object_getn(const json_t *json, const char *key, size_t key_len) {
107 json_object_t *object;
108
109 if (!key || !json_is_object(json))
110 return NULL;
111
112 object = json_to_object(json);
113 return hashtable_get(&object->hashtable, key, key_len);
114 }
115
116 int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value) {
117 if (!key) {
118 json_decref(value);
119 return -1;
120 }
121 return json_object_setn_new_nocheck(json, key, strlen(key), value);
122 }
123
124 int json_object_setn_new_nocheck(json_t *json, const char *key, size_t key_len,
125 json_t *value) {
126 json_object_t *object;
127
128 if (!value)
129 return -1;
130
131 if (!key || !json_is_object(json) || json == value) {
132 json_decref(value);
133 return -1;
134 }
135 object = json_to_object(json);
136
137 if (hashtable_set(&object->hashtable, key, key_len, value)) {
138 json_decref(value);
139 return -1;
140 }
141
142 return 0;
143 }
144
145 int json_object_set_new(json_t *json, const char *key, json_t *value) {
146 if (!key) {
147 json_decref(value);
148 return -1;
149 }
150
151 return json_object_setn_new(json, key, strlen(key), value);
152 }
153
154 int json_object_setn_new(json_t *json, const char *key, size_t key_len, json_t *value) {
155 if (!key || !utf8_check_string(key, key_len)) {
156 json_decref(value);
157 return -1;
158 }
159
160 return json_object_setn_new_nocheck(json, key, key_len, value);
161 }
162
163 int json_object_del(json_t *json, const char *key) {
164 if (!key)
165 return -1;
166
167 return json_object_deln(json, key, strlen(key));
168 }
169
170 int json_object_deln(json_t *json, const char *key, size_t key_len) {
171 json_object_t *object;
172
173 if (!key || !json_is_object(json))
174 return -1;
175
176 object = json_to_object(json);
177 return hashtable_del(&object->hashtable, key, key_len);
178 }
179
180 int json_object_clear(json_t *json) {
181 json_object_t *object;
182
183 if (!json_is_object(json))
184 return -1;
185
186 object = json_to_object(json);
187 hashtable_clear(&object->hashtable);
188
189 return 0;
190 }
191
192 int json_object_update(json_t *object, json_t *other) {
193 const char *key;
194 json_t *value;
195
196 if (!json_is_object(object) || !json_is_object(other))
197 return -1;
198
199 json_object_foreach(other, key, value) {
200 if (json_object_set_nocheck(object, key, value))
201 return -1;
202 }
203
204 return 0;
205 }
206
207 int json_object_update_existing(json_t *object, json_t *other) {
208 const char *key;
209 size_t key_len;
210 json_t *value;
211
212 if (!json_is_object(object) || !json_is_object(other))
213 return -1;
214
215 json_object_keylen_foreach(other, key, key_len, value) {
216 if (json_object_getn(object, key, key_len))
217 json_object_setn_nocheck(object, key, key_len, value);
218 }
219
220 return 0;
221 }
222
223 int json_object_update_missing(json_t *object, json_t *other) {
224 const char *key;
225 json_t *value;
226
227 if (!json_is_object(object) || !json_is_object(other))
228 return -1;
229
230 json_object_foreach(other, key, value) {
231 if (!json_object_get(object, key))
232 json_object_set_nocheck(object, key, value);
233 }
234
235 return 0;
236 }
237
238 int do_object_update_recursive(json_t *object, json_t *other, hashtable_t *parents) {
239 const char *key;
240 size_t key_len;
241 json_t *value;
242 char loop_key[LOOP_KEY_LEN];
243 int res = 0;
244 size_t loop_key_len;
245
246 if (!json_is_object(object) || !json_is_object(other))
247 return -1;
248
249 if (jsonp_loop_check(parents, other, loop_key, sizeof(loop_key), &loop_key_len))
250 return -1;
251
252 json_object_keylen_foreach(other, key, key_len, value) {
253 json_t *v = json_object_get(object, key);
254
255 if (json_is_object(v) && json_is_object(value)) {
256 if (do_object_update_recursive(v, value, parents)) {
257 res = -1;
258 break;
259 }
260 } else {
261 if (json_object_setn_nocheck(object, key, key_len, value)) {
262 res = -1;
263 break;
264 }
265 }
266 }
267
268 hashtable_del(parents, loop_key, loop_key_len);
269
270 return res;
271 }
272
273 int json_object_update_recursive(json_t *object, json_t *other) {
274 int res;
275 hashtable_t parents_set;
276
277 if (hashtable_init(&parents_set))
278 return -1;
279 res = do_object_update_recursive(object, other, &parents_set);
280 hashtable_close(&parents_set);
281
282 return res;
283 }
284
285 void *json_object_iter(json_t *json) {
286 json_object_t *object;
287
288 if (!json_is_object(json))
289 return NULL;
290
291 object = json_to_object(json);
292 return hashtable_iter(&object->hashtable);
293 }
294
295 void *json_object_iter_at(json_t *json, const char *key) {
296 json_object_t *object;
297
298 if (!key || !json_is_object(json))
299 return NULL;
300
301 object = json_to_object(json);
302 return hashtable_iter_at(&object->hashtable, key, strlen(key));
303 }
304
305 void *json_object_iter_next(json_t *json, void *iter) {
306 json_object_t *object;
307
308 if (!json_is_object(json) || iter == NULL)
309 return NULL;
310
311 object = json_to_object(json);
312 return hashtable_iter_next(&object->hashtable, iter);
313 }
314
315 const char *json_object_iter_key(void *iter) {
316 if (!iter)
317 return NULL;
318
319 return hashtable_iter_key(iter);
320 }
321
322 size_t json_object_iter_key_len(void *iter) {
323 if (!iter)
324 return 0;
325
326 return hashtable_iter_key_len(iter);
327 }
328
329 json_t *json_object_iter_value(void *iter) {
330 if (!iter)
331 return NULL;
332
333 return (json_t *)hashtable_iter_value(iter);
334 }
335
336 int json_object_iter_set_new(json_t *json, void *iter, json_t *value) {
337 if (!json_is_object(json) || !iter || !value) {
338 json_decref(value);
339 return -1;
340 }
341
342 hashtable_iter_set(iter, value);
343 return 0;
344 }
345
346 void *json_object_key_to_iter(const char *key) {
347 if (!key)
348 return NULL;
349
350 return hashtable_key_to_iter(key);
351 }
352
353 static int json_object_equal(const json_t *object1, const json_t *object2) {
354 const char *key;
355 const json_t *value1, *value2;
356
357 if (json_object_size(object1) != json_object_size(object2))
358 return 0;
359
360 json_object_foreach((json_t *)object1, key, value1) {
361 value2 = json_object_get(object2, key);
362
363 if (!json_equal(value1, value2))
364 return 0;
365 }
366
367 return 1;
368 }
369
370 static json_t *json_object_copy(json_t *object) {
371 json_t *result;
372
373 const char *key;
374 json_t *value;
375
376 result = json_object();
377 if (!result)
378 return NULL;
379
380 json_object_foreach(object, key, value) json_object_set_nocheck(result, key, value);
381
382 return result;
383 }
384
385 static json_t *json_object_deep_copy(const json_t *object, hashtable_t *parents) {
386 json_t *result;
387 void *iter;
388 char loop_key[LOOP_KEY_LEN];
389 size_t loop_key_len;
390
391 if (jsonp_loop_check(parents, object, loop_key, sizeof(loop_key), &loop_key_len))
392 return NULL;
393
394 result = json_object();
395 if (!result)
396 goto out;
397
398 /* Cannot use json_object_foreach because object has to be cast
399 non-const */
400 iter = json_object_iter((json_t *)object);
401 while (iter) {
402 const char *key;
403 const json_t *value;
404 key = json_object_iter_key(iter);
405 value = json_object_iter_value(iter);
406
407 if (json_object_set_new_nocheck(result, key, do_deep_copy(value, parents))) {
408 json_decref(result);
409 result = NULL;
410 break;
411 }
412 iter = json_object_iter_next((json_t *)object, iter);
413 }
414
415 out:
416 hashtable_del(parents, loop_key, loop_key_len);
417
418 return result;
419 }
420
421 /*** array ***/
422
423 json_t *json_array(void) {
424 json_array_t *array = jsonp_malloc(sizeof(json_array_t));
425 if (!array)
426 return NULL;
427 json_init(&array->json, JSON_ARRAY);
428
429 array->entries = 0;
430 array->size = 8;
431
432 array->table = jsonp_malloc(array->size * sizeof(json_t *));
433 if (!array->table) {
434 jsonp_free(array);
435 return NULL;
436 }
437
438 return &array->json;
439 }
440
441 static void json_delete_array(json_array_t *array) {
442 size_t i;
443
444 for (i = 0; i < array->entries; i++)
445 json_decref(array->table[i]);
446
447 jsonp_free(array->table);
448 jsonp_free(array);
449 }
450
451 size_t json_array_size(const json_t *json) {
452 if (!json_is_array(json))
453 return 0;
454
455 return json_to_array(json)->entries;
456 }
457
458 json_t *json_array_get(const json_t *json, size_t index) {
459 json_array_t *array;
460 if (!json_is_array(json))
461 return NULL;
462 array = json_to_array(json);
463
464 if (index >= array->entries)
465 return NULL;
466
467 return array->table[index];
468 }
469
470 int json_array_set_new(json_t *json, size_t index, json_t *value) {
471 json_array_t *array;
472
473 if (!value)
474 return -1;
475
476 if (!json_is_array(json) || json == value) {
477 json_decref(value);
478 return -1;
479 }
480 array = json_to_array(json);
481
482 if (index >= array->entries) {
483 json_decref(value);
484 return -1;
485 }
486
487 json_decref(array->table[index]);
488 array->table[index] = value;
489
490 return 0;
491 }
492
493 static void array_move(json_array_t *array, size_t dest, size_t src, size_t count) {
494 memmove(&array->table[dest], &array->table[src], count * sizeof(json_t *));
495 }
496
497 static void array_copy(json_t **dest, size_t dpos, json_t **src, size_t spos,
498 size_t count) {
499 memcpy(&dest[dpos], &src[spos], count * sizeof(json_t *));
500 }
501
502 static json_t **json_array_grow(json_array_t *array, size_t amount, int copy) {
503 size_t new_size;
504 json_t **old_table, **new_table;
505
506 if (array->entries + amount <= array->size)
507 return array->table;
508
509 old_table = array->table;
510
511 new_size = max(array->size + amount, array->size * 2);
512 new_table = jsonp_malloc(new_size * sizeof(json_t *));
513 if (!new_table)
514 return NULL;
515
516 array->size = new_size;
517 array->table = new_table;
518
519 if (copy) {
520 array_copy(array->table, 0, old_table, 0, array->entries);
521 jsonp_free(old_table);
522 return array->table;
523 }
524
525 return old_table;
526 }
527
528 int json_array_append_new(json_t *json, json_t *value) {
529 json_array_t *array;
530
531 if (!value)
532 return -1;
533
534 if (!json_is_array(json) || json == value) {
535 json_decref(value);
536 return -1;
537 }
538 array = json_to_array(json);
539
540 if (!json_array_grow(array, 1, 1)) {
541 json_decref(value);
542 return -1;
543 }
544
545 array->table[array->entries] = value;
546 array->entries++;
547
548 return 0;
549 }
550
551 int json_array_insert_new(json_t *json, size_t index, json_t *value) {
552 json_array_t *array;
553 json_t **old_table;
554
555 if (!value)
556 return -1;
557
558 if (!json_is_array(json) || json == value) {
559 json_decref(value);
560 return -1;
561 }
562 array = json_to_array(json);
563
564 if (index > array->entries) {
565 json_decref(value);
566 return -1;
567 }
568
569 old_table = json_array_grow(array, 1, 0);
570 if (!old_table) {
571 json_decref(value);
572 return -1;
573 }
574
575 if (old_table != array->table) {
576 array_copy(array->table, 0, old_table, 0, index);
577 array_copy(array->table, index + 1, old_table, index, array->entries - index);
578 jsonp_free(old_table);
579 } else
580 array_move(array, index + 1, index, array->entries - index);
581
582 array->table[index] = value;
583 array->entries++;
584
585 return 0;
586 }
587
588 int json_array_remove(json_t *json, size_t index) {
589 json_array_t *array;
590
591 if (!json_is_array(json))
592 return -1;
593 array = json_to_array(json);
594
595 if (index >= array->entries)
596 return -1;
597
598 json_decref(array->table[index]);
599
600 /* If we're removing the last element, nothing has to be moved */
601 if (index < array->entries - 1)
602 array_move(array, index, index + 1, array->entries - index - 1);
603
604 array->entries--;
605
606 return 0;
607 }
608
609 int json_array_clear(json_t *json) {
610 json_array_t *array;
611 size_t i;
612
613 if (!json_is_array(json))
614 return -1;
615 array = json_to_array(json);
616
617 for (i = 0; i < array->entries; i++)
618 json_decref(array->table[i]);
619
620 array->entries = 0;
621 return 0;
622 }
623
624 int json_array_extend(json_t *json, json_t *other_json) {
625 json_array_t *array, *other;
626 size_t i;
627
628 if (!json_is_array(json) || !json_is_array(other_json))
629 return -1;
630 array = json_to_array(json);
631 other = json_to_array(other_json);
632
633 if (!json_array_grow(array, other->entries, 1))
634 return -1;
635
636 for (i = 0; i < other->entries; i++)
637 json_incref(other->table[i]);
638
639 array_copy(array->table, array->entries, other->table, 0, other->entries);
640
641 array->entries += other->entries;
642 return 0;
643 }
644
645 static int json_array_equal(const json_t *array1, const json_t *array2) {
646 size_t i, size;
647
648 size = json_array_size(array1);
649 if (size != json_array_size(array2))
650 return 0;
651
652 for (i = 0; i < size; i++) {
653 json_t *value1, *value2;
654
655 value1 = json_array_get(array1, i);
656 value2 = json_array_get(array2, i);
657
658 if (!json_equal(value1, value2))
659 return 0;
660 }
661
662 return 1;
663 }
664
665 static json_t *json_array_copy(json_t *array) {
666 json_t *result;
667 size_t i;
668
669 result = json_array();
670 if (!result)
671 return NULL;
672
673 for (i = 0; i < json_array_size(array); i++)
674 json_array_append(result, json_array_get(array, i));
675
676 return result;
677 }
678
679 static json_t *json_array_deep_copy(const json_t *array, hashtable_t *parents) {
680 json_t *result;
681 size_t i;
682 char loop_key[LOOP_KEY_LEN];
683 size_t loop_key_len;
684
685 if (jsonp_loop_check(parents, array, loop_key, sizeof(loop_key), &loop_key_len))
686 return NULL;
687
688 result = json_array();
689 if (!result)
690 goto out;
691
692 for (i = 0; i < json_array_size(array); i++) {
693 if (json_array_append_new(result,
694 do_deep_copy(json_array_get(array, i), parents))) {
695 json_decref(result);
696 result = NULL;
697 break;
698 }
699 }
700
701 out:
702 hashtable_del(parents, loop_key, loop_key_len);
703
704 return result;
705 }
706
707 /*** string ***/
708
709 static json_t *string_create(const char *value, size_t len, int own) {
710 char *v;
711 json_string_t *string;
712
713 if (!value)
714 return NULL;
715
716 if (own)
717 v = (char *)value;
718 else {
719 v = jsonp_strndup(value, len);
720 if (!v)
721 return NULL;
722 }
723
724 string = jsonp_malloc(sizeof(json_string_t));
725 if (!string) {
726 jsonp_free(v);
727 return NULL;
728 }
729 json_init(&string->json, JSON_STRING);
730 string->value = v;
731 string->length = len;
732
733 return &string->json;
734 }
735
736 json_t *json_string_nocheck(const char *value) {
737 if (!value)
738 return NULL;
739
740 return string_create(value, strlen(value), 0);
741 }
742
743 json_t *json_stringn_nocheck(const char *value, size_t len) {
744 return string_create(value, len, 0);
745 }
746
747 /* this is private; "steal" is not a public API concept */
748 json_t *jsonp_stringn_nocheck_own(const char *value, size_t len) {
749 return string_create(value, len, 1);
750 }
751
752 json_t *json_string(const char *value) {
753 if (!value)
754 return NULL;
755
756 return json_stringn(value, strlen(value));
757 }
758
759 json_t *json_stringn(const char *value, size_t len) {
760 if (!value || !utf8_check_string(value, len))
761 return NULL;
762
763 return json_stringn_nocheck(value, len);
764 }
765
766 const char *json_string_value(const json_t *json) {
767 if (!json_is_string(json))
768 return NULL;
769
770 return json_to_string(json)->value;
771 }
772
773 size_t json_string_length(const json_t *json) {
774 if (!json_is_string(json))
775 return 0;
776
777 return json_to_string(json)->length;
778 }
779
780 int json_string_set_nocheck(json_t *json, const char *value) {
781 if (!value)
782 return -1;
783
784 return json_string_setn_nocheck(json, value, strlen(value));
785 }
786
787 int json_string_setn_nocheck(json_t *json, const char *value, size_t len) {
788 char *dup;
789 json_string_t *string;
790
791 if (!json_is_string(json) || !value)
792 return -1;
793
794 dup = jsonp_strndup(value, len);
795 if (!dup)
796 return -1;
797
798 string = json_to_string(json);
799 jsonp_free(string->value);
800 string->value = dup;
801 string->length = len;
802
803 return 0;
804 }
805
806 int json_string_set(json_t *json, const char *value) {
807 if (!value)
808 return -1;
809
810 return json_string_setn(json, value, strlen(value));
811 }
812
813 int json_string_setn(json_t *json, const char *value, size_t len) {
814 if (!value || !utf8_check_string(value, len))
815 return -1;
816
817 return json_string_setn_nocheck(json, value, len);
818 }
819
820 static void json_delete_string(json_string_t *string) {
821 jsonp_free(string->value);
822 jsonp_free(string);
823 }
824
825 static int json_string_equal(const json_t *string1, const json_t *string2) {
826 json_string_t *s1, *s2;
827
828 s1 = json_to_string(string1);
829 s2 = json_to_string(string2);
830 return s1->length == s2->length && !memcmp(s1->value, s2->value, s1->length);
831 }
832
833 static json_t *json_string_copy(const json_t *string) {
834 json_string_t *s;
835
836 s = json_to_string(string);
837 return json_stringn_nocheck(s->value, s->length);
838 }
839
840 json_t *json_vsprintf(const char *fmt, va_list ap) {
841 json_t *json = NULL;
842 int length;
843 char *buf;
844 va_list aq;
845 va_copy(aq, ap);
846
847 length = vsnprintf(NULL, 0, fmt, ap);
848 if (length < 0)
849 goto out;
850 if (length == 0) {
851 json = json_string("");
852 goto out;
853 }
854
855 buf = jsonp_malloc((size_t)length + 1);
856 if (!buf)
857 goto out;
858
859 vsnprintf(buf, (size_t)length + 1, fmt, aq);
860 if (!utf8_check_string(buf, length)) {
861 jsonp_free(buf);
862 goto out;
863 }
864
865 json = jsonp_stringn_nocheck_own(buf, length);
866
867 out:
868 va_end(aq);
869 return json;
870 }
871
872 json_t *json_sprintf(const char *fmt, ...) {
873 json_t *result;
874 va_list ap;
875
876 va_start(ap, fmt);
877 result = json_vsprintf(fmt, ap);
878 va_end(ap);
879
880 return result;
881 }
882
883 /*** integer ***/
884
885 json_t *json_integer(json_int_t value) {
886 json_integer_t *integer = jsonp_malloc(sizeof(json_integer_t));
887 if (!integer)
888 return NULL;
889 json_init(&integer->json, JSON_INTEGER);
890
891 integer->value = value;
892 return &integer->json;
893 }
894
895 json_int_t json_integer_value(const json_t *json) {
896 if (!json_is_integer(json))
897 return 0;
898
899 return json_to_integer(json)->value;
900 }
901
902 int json_integer_set(json_t *json, json_int_t value) {
903 if (!json_is_integer(json))
904 return -1;
905
906 json_to_integer(json)->value = value;
907
908 return 0;
909 }
910
911 static void json_delete_integer(json_integer_t *integer) { jsonp_free(integer); }
912
913 static int json_integer_equal(const json_t *integer1, const json_t *integer2) {
914 return json_integer_value(integer1) == json_integer_value(integer2);
915 }
916
917 static json_t *json_integer_copy(const json_t *integer) {
918 return json_integer(json_integer_value(integer));
919 }
920
921 /*** real ***/
922
923 json_t *json_real(double value) {
924 json_real_t *real;
925
926 if (isnan(value) || isinf(value))
927 return NULL;
928
929 real = jsonp_malloc(sizeof(json_real_t));
930 if (!real)
931 return NULL;
932 json_init(&real->json, JSON_REAL);
933
934 real->value = value;
935 return &real->json;
936 }
937
938 double json_real_value(const json_t *json) {
939 if (!json_is_real(json))
940 return 0;
941
942 return json_to_real(json)->value;
943 }
944
945 int json_real_set(json_t *json, double value) {
946 if (!json_is_real(json) || isnan(value) || isinf(value))
947 return -1;
948
949 json_to_real(json)->value = value;
950
951 return 0;
952 }
953
954 static void json_delete_real(json_real_t *real) { jsonp_free(real); }
955
956 static int json_real_equal(const json_t *real1, const json_t *real2) {
957 return json_real_value(real1) == json_real_value(real2);
958 }
959
960 static json_t *json_real_copy(const json_t *real) {
961 return json_real(json_real_value(real));
962 }
963
964 /*** number ***/
965
966 double json_number_value(const json_t *json) {
967 if (json_is_integer(json))
968 return (double)json_integer_value(json);
969 else if (json_is_real(json))
970 return json_real_value(json);
971 else
972 return 0.0;
973 }
974
975 /*** simple values ***/
976
977 json_t *json_true(void) {
978 static json_t the_true = {JSON_TRUE, (size_t)-1};
979 return &the_true;
980 }
981
982 json_t *json_false(void) {
983 static json_t the_false = {JSON_FALSE, (size_t)-1};
984 return &the_false;
985 }
986
987 json_t *json_null(void) {
988 static json_t the_null = {JSON_NULL, (size_t)-1};
989 return &the_null;
990 }
991
992 /*** deletion ***/
993
994 void json_delete(json_t *json) {
995 if (!json)
996 return;
997
998 switch (json_typeof(json)) {
999 case JSON_OBJECT:
1000 json_delete_object(json_to_object(json));
1001 break;
1002 case JSON_ARRAY:
1003 json_delete_array(json_to_array(json));
1004 break;
1005 case JSON_STRING:
1006 json_delete_string(json_to_string(json));
1007 break;
1008 case JSON_INTEGER:
1009 json_delete_integer(json_to_integer(json));
1010 break;
1011 case JSON_REAL:
1012 json_delete_real(json_to_real(json));
1013 break;
1014 default:
1015 return;
1016 }
1017
1018 /* json_delete is not called for true, false or null */
1019 }
1020
1021 /*** equality ***/
1022
1023 int json_equal(const json_t *json1, const json_t *json2) {
1024 if (!json1 || !json2)
1025 return 0;
1026
1027 if (json_typeof(json1) != json_typeof(json2))
1028 return 0;
1029
1030 /* this covers true, false and null as they are singletons */
1031 if (json1 == json2)
1032 return 1;
1033
1034 switch (json_typeof(json1)) {
1035 case JSON_OBJECT:
1036 return json_object_equal(json1, json2);
1037 case JSON_ARRAY:
1038 return json_array_equal(json1, json2);
1039 case JSON_STRING:
1040 return json_string_equal(json1, json2);
1041 case JSON_INTEGER:
1042 return json_integer_equal(json1, json2);
1043 case JSON_REAL:
1044 return json_real_equal(json1, json2);
1045 default:
1046 return 0;
1047 }
1048 }
1049
1050 /*** copying ***/
1051
1052 json_t *json_copy(json_t *json) {
1053 if (!json)
1054 return NULL;
1055
1056 switch (json_typeof(json)) {
1057 case JSON_OBJECT:
1058 return json_object_copy(json);
1059 case JSON_ARRAY:
1060 return json_array_copy(json);
1061 case JSON_STRING:
1062 return json_string_copy(json);
1063 case JSON_INTEGER:
1064 return json_integer_copy(json);
1065 case JSON_REAL:
1066 return json_real_copy(json);
1067 case JSON_TRUE:
1068 case JSON_FALSE:
1069 case JSON_NULL:
1070 return json;
1071 default:
1072 return NULL;
1073 }
1074 }
1075
1076 json_t *json_deep_copy(const json_t *json) {
1077 json_t *res;
1078 hashtable_t parents_set;
1079
1080 if (hashtable_init(&parents_set))
1081 return NULL;
1082 res = do_deep_copy(json, &parents_set);
1083 hashtable_close(&parents_set);
1084
1085 return res;
1086 }
1087
1088 json_t *do_deep_copy(const json_t *json, hashtable_t *parents) {
1089 if (!json)
1090 return NULL;
1091
1092 switch (json_typeof(json)) {
1093 case JSON_OBJECT:
1094 return json_object_deep_copy(json, parents);
1095 case JSON_ARRAY:
1096 return json_array_deep_copy(json, parents);
1097 /* for the rest of the types, deep copying doesn't differ from
1098 shallow copying */
1099 case JSON_STRING:
1100 return json_string_copy(json);
1101 case JSON_INTEGER:
1102 return json_integer_copy(json);
1103 case JSON_REAL:
1104 return json_real_copy(json);
1105 case JSON_TRUE:
1106 case JSON_FALSE:
1107 case JSON_NULL:
1108 return (json_t *)json;
1109 default:
1110 return NULL;
1111 }
1112 }