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