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