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