"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.
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 }