oj 3.13.7 → 3.13.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +75 -0
- data/README.md +11 -0
- data/ext/oj/buf.h +4 -0
- data/ext/oj/circarray.c +1 -1
- data/ext/oj/code.c +15 -22
- data/ext/oj/compat.c +10 -10
- data/ext/oj/custom.c +66 -112
- data/ext/oj/dump.c +147 -184
- data/ext/oj/dump.h +25 -8
- data/ext/oj/dump_compat.c +47 -89
- data/ext/oj/dump_leaf.c +14 -58
- data/ext/oj/dump_object.c +72 -188
- data/ext/oj/dump_strict.c +19 -31
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/extconf.rb +5 -4
- data/ext/oj/fast.c +36 -24
- data/ext/oj/intern.c +22 -12
- data/ext/oj/intern.h +1 -1
- data/ext/oj/mimic_json.c +74 -73
- data/ext/oj/object.c +54 -72
- data/ext/oj/odd.c +83 -63
- data/ext/oj/odd.h +13 -13
- data/ext/oj/oj.c +166 -175
- data/ext/oj/oj.h +25 -3
- data/ext/oj/parse.c +123 -79
- data/ext/oj/parse.h +2 -0
- data/ext/oj/parser.c +77 -21
- data/ext/oj/parser.h +12 -0
- data/ext/oj/rails.c +46 -70
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +2 -0
- data/ext/oj/saj.c +11 -23
- data/ext/oj/saj2.c +333 -85
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/sparse.c +4 -0
- data/ext/oj/stream_writer.c +3 -1
- data/ext/oj/strict.c +13 -13
- data/ext/oj/string_writer.c +12 -5
- data/ext/oj/usual.c +86 -131
- data/ext/oj/usual.h +68 -0
- data/ext/oj/val_stack.c +1 -1
- data/ext/oj/validate.c +21 -26
- data/ext/oj/wab.c +22 -27
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +1 -1
- data/lib/oj/version.rb +1 -1
- data/pages/Compatibility.md +1 -1
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +6 -3
- data/pages/Options.md +6 -0
- data/pages/Rails.md +12 -0
- data/test/activesupport7/abstract_unit.rb +49 -0
- data/test/activesupport7/decoding_test.rb +125 -0
- data/test/activesupport7/encoding_test.rb +486 -0
- data/test/activesupport7/encoding_test_cases.rb +104 -0
- data/test/activesupport7/time_zone_test_helpers.rb +47 -0
- data/test/bar.rb +3 -8
- data/test/bug.rb +16 -0
- data/test/foo.rb +71 -7
- data/test/helper.rb +8 -2
- data/test/json_gem/json_generator_test.rb +5 -4
- data/test/json_gem/json_parser_test.rb +8 -1
- data/test/json_gem/test_helper.rb +7 -3
- data/test/perf_dump.rb +50 -0
- data/test/test_compat.rb +25 -0
- data/test/test_custom.rb +13 -2
- data/test/test_fast.rb +37 -7
- data/test/test_file.rb +23 -7
- data/test/test_gc.rb +11 -0
- data/test/test_object.rb +8 -10
- data/test/test_parser.rb +3 -19
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +92 -2
- data/test/test_saj.rb +1 -1
- data/test/test_scp.rb +2 -4
- data/test/test_strict.rb +2 -0
- data/test/test_various.rb +32 -2
- data/test/test_wab.rb +2 -0
- data/test/tests.rb +9 -1
- data/test/tests_mimic.rb +9 -0
- data/test/tests_mimic_addition.rb +9 -0
- metadata +15 -115
data/ext/oj/usual.c
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
#include "cache.h"
|
4
4
|
#include "oj.h"
|
5
5
|
#include "parser.h"
|
6
|
+
#include "usual.h"
|
6
7
|
|
7
8
|
// The Usual delegate builds Ruby objects during parsing. It makes use of
|
8
9
|
// three stacks. The first is the value stack. This is where parsed values are
|
@@ -28,61 +29,6 @@
|
|
28
29
|
|
29
30
|
#define DEBUG 0
|
30
31
|
|
31
|
-
// Used to mark the start of each Hash, Array, or Object. The members point at
|
32
|
-
// positions of the start in the value stack and if not an Array into the key
|
33
|
-
// stack.
|
34
|
-
typedef struct _col {
|
35
|
-
long vi; // value stack index
|
36
|
-
long ki; // key stack index if an hash else -1 for an array
|
37
|
-
} * Col;
|
38
|
-
|
39
|
-
typedef union _key {
|
40
|
-
struct {
|
41
|
-
int16_t len;
|
42
|
-
char buf[30];
|
43
|
-
};
|
44
|
-
struct {
|
45
|
-
int16_t xlen; // should be the same as len
|
46
|
-
char * key;
|
47
|
-
};
|
48
|
-
} * Key;
|
49
|
-
|
50
|
-
#define MISS_AUTO 'A'
|
51
|
-
#define MISS_RAISE 'R'
|
52
|
-
#define MISS_IGNORE 'I'
|
53
|
-
|
54
|
-
typedef struct _delegate {
|
55
|
-
VALUE *vhead;
|
56
|
-
VALUE *vtail;
|
57
|
-
VALUE *vend;
|
58
|
-
|
59
|
-
Col chead;
|
60
|
-
Col ctail;
|
61
|
-
Col cend;
|
62
|
-
|
63
|
-
Key khead;
|
64
|
-
Key ktail;
|
65
|
-
Key kend;
|
66
|
-
|
67
|
-
VALUE (*get_key)(ojParser p, Key kp);
|
68
|
-
struct _cache *key_cache; // same as str_cache or sym_cache
|
69
|
-
struct _cache *str_cache;
|
70
|
-
struct _cache *sym_cache;
|
71
|
-
struct _cache *class_cache;
|
72
|
-
struct _cache *attr_cache;
|
73
|
-
|
74
|
-
VALUE array_class;
|
75
|
-
VALUE hash_class;
|
76
|
-
|
77
|
-
char * create_id;
|
78
|
-
uint8_t create_id_len;
|
79
|
-
uint8_t cache_str;
|
80
|
-
uint8_t cache_xrate;
|
81
|
-
uint8_t miss_class;
|
82
|
-
bool cache_keys;
|
83
|
-
bool ignore_json_create;
|
84
|
-
} * Delegate;
|
85
|
-
|
86
32
|
static ID to_f_id = 0;
|
87
33
|
static ID ltlt_id = 0;
|
88
34
|
static ID hset_id = 0;
|
@@ -178,7 +124,7 @@ static VALUE form_class_auto(const char *str, size_t len) {
|
|
178
124
|
return resolve_classpath(str, len, true);
|
179
125
|
}
|
180
126
|
|
181
|
-
static void assure_cstack(
|
127
|
+
static void assure_cstack(Usual d) {
|
182
128
|
if (d->cend <= d->ctail + 1) {
|
183
129
|
size_t cap = d->cend - d->chead;
|
184
130
|
long pos = d->ctail - d->chead;
|
@@ -191,7 +137,7 @@ static void assure_cstack(Delegate d) {
|
|
191
137
|
}
|
192
138
|
|
193
139
|
static void push(ojParser p, VALUE v) {
|
194
|
-
|
140
|
+
Usual d = (Usual)p->ctx;
|
195
141
|
|
196
142
|
if (d->vend <= d->vtail) {
|
197
143
|
size_t cap = d->vend - d->vhead;
|
@@ -207,7 +153,7 @@ static void push(ojParser p, VALUE v) {
|
|
207
153
|
}
|
208
154
|
|
209
155
|
static VALUE cache_key(ojParser p, Key kp) {
|
210
|
-
|
156
|
+
Usual d = (Usual)p->ctx;
|
211
157
|
|
212
158
|
if ((size_t)kp->len < sizeof(kp->buf)) {
|
213
159
|
return cache_intern(d->key_cache, kp->buf, kp->len);
|
@@ -230,7 +176,7 @@ static VALUE sym_key(ojParser p, Key kp) {
|
|
230
176
|
}
|
231
177
|
|
232
178
|
static ID get_attr_id(ojParser p, Key kp) {
|
233
|
-
|
179
|
+
Usual d = (Usual)p->ctx;
|
234
180
|
|
235
181
|
if ((size_t)kp->len < sizeof(kp->buf)) {
|
236
182
|
return (ID)cache_intern(d->attr_cache, kp->buf, kp->len);
|
@@ -239,7 +185,7 @@ static ID get_attr_id(ojParser p, Key kp) {
|
|
239
185
|
}
|
240
186
|
|
241
187
|
static void push_key(ojParser p) {
|
242
|
-
|
188
|
+
Usual d = (Usual)p->ctx;
|
243
189
|
size_t klen = buf_len(&p->key);
|
244
190
|
const char *key = buf_str(&p->key);
|
245
191
|
|
@@ -263,7 +209,7 @@ static void push_key(ojParser p) {
|
|
263
209
|
}
|
264
210
|
|
265
211
|
static void push2(ojParser p, VALUE v) {
|
266
|
-
|
212
|
+
Usual d = (Usual)p->ctx;
|
267
213
|
|
268
214
|
if (d->vend <= d->vtail + 1) {
|
269
215
|
size_t cap = d->vend - d->vhead;
|
@@ -281,7 +227,7 @@ static void push2(ojParser p, VALUE v) {
|
|
281
227
|
}
|
282
228
|
|
283
229
|
static void open_object(ojParser p) {
|
284
|
-
|
230
|
+
Usual d = (Usual)p->ctx;
|
285
231
|
|
286
232
|
assure_cstack(d);
|
287
233
|
d->ctail->vi = d->vtail - d->vhead;
|
@@ -291,7 +237,7 @@ static void open_object(ojParser p) {
|
|
291
237
|
}
|
292
238
|
|
293
239
|
static void open_object_key(ojParser p) {
|
294
|
-
|
240
|
+
Usual d = (Usual)p->ctx;
|
295
241
|
|
296
242
|
push_key(p);
|
297
243
|
assure_cstack(d);
|
@@ -302,7 +248,7 @@ static void open_object_key(ojParser p) {
|
|
302
248
|
}
|
303
249
|
|
304
250
|
static void open_array(ojParser p) {
|
305
|
-
|
251
|
+
Usual d = (Usual)p->ctx;
|
306
252
|
|
307
253
|
assure_cstack(d);
|
308
254
|
d->ctail->vi = d->vtail - d->vhead;
|
@@ -312,7 +258,7 @@ static void open_array(ojParser p) {
|
|
312
258
|
}
|
313
259
|
|
314
260
|
static void open_array_key(ojParser p) {
|
315
|
-
|
261
|
+
Usual d = (Usual)p->ctx;
|
316
262
|
|
317
263
|
push_key(p);
|
318
264
|
assure_cstack(d);
|
@@ -324,7 +270,7 @@ static void open_array_key(ojParser p) {
|
|
324
270
|
|
325
271
|
static void close_object(ojParser p) {
|
326
272
|
VALUE * vp;
|
327
|
-
|
273
|
+
Usual d = (Usual)p->ctx;
|
328
274
|
|
329
275
|
d->ctail--;
|
330
276
|
|
@@ -357,7 +303,7 @@ static void close_object(ojParser p) {
|
|
357
303
|
|
358
304
|
static void close_object_class(ojParser p) {
|
359
305
|
VALUE * vp;
|
360
|
-
|
306
|
+
Usual d = (Usual)p->ctx;
|
361
307
|
|
362
308
|
d->ctail--;
|
363
309
|
|
@@ -380,7 +326,7 @@ static void close_object_class(ojParser p) {
|
|
380
326
|
|
381
327
|
static void close_object_create(ojParser p) {
|
382
328
|
VALUE * vp;
|
383
|
-
|
329
|
+
Usual d = (Usual)p->ctx;
|
384
330
|
|
385
331
|
d->ctail--;
|
386
332
|
|
@@ -459,7 +405,7 @@ static void close_object_create(ojParser p) {
|
|
459
405
|
}
|
460
406
|
|
461
407
|
static void close_array(ojParser p) {
|
462
|
-
|
408
|
+
Usual d = (Usual)p->ctx;
|
463
409
|
|
464
410
|
d->ctail--;
|
465
411
|
VALUE * head = d->vhead + d->ctail->vi + 1;
|
@@ -472,7 +418,7 @@ static void close_array(ojParser p) {
|
|
472
418
|
|
473
419
|
static void close_array_class(ojParser p) {
|
474
420
|
VALUE * vp;
|
475
|
-
|
421
|
+
Usual d = (Usual)p->ctx;
|
476
422
|
|
477
423
|
d->ctail--;
|
478
424
|
VALUE * head = d->vhead + d->ctail->vi + 1;
|
@@ -537,7 +483,7 @@ static void add_float_key(ojParser p) {
|
|
537
483
|
static void add_float_as_big(ojParser p) {
|
538
484
|
char buf[64];
|
539
485
|
|
540
|
-
// fails on ubuntu
|
486
|
+
// snprintf fails on ubuntu and macOS for long double
|
541
487
|
// snprintf(buf, sizeof(buf), "%Lg", p->num.dub);
|
542
488
|
sprintf(buf, "%Lg", p->num.dub);
|
543
489
|
push(p, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(buf)));
|
@@ -546,7 +492,9 @@ static void add_float_as_big(ojParser p) {
|
|
546
492
|
static void add_float_as_big_key(ojParser p) {
|
547
493
|
char buf[64];
|
548
494
|
|
549
|
-
snprintf
|
495
|
+
// snprintf fails on ubuntu and macOS for long double
|
496
|
+
// snprintf(buf, sizeof(buf), "%Lg", p->num.dub);
|
497
|
+
sprintf(buf, "%Lg", p->num.dub);
|
550
498
|
push_key(p);
|
551
499
|
push2(p, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(buf)));
|
552
500
|
}
|
@@ -583,7 +531,7 @@ static void add_big_as_ruby_key(ojParser p) {
|
|
583
531
|
}
|
584
532
|
|
585
533
|
static void add_str(ojParser p) {
|
586
|
-
|
534
|
+
Usual d = (Usual)p->ctx;
|
587
535
|
volatile VALUE rstr;
|
588
536
|
const char * str = buf_str(&p->buf);
|
589
537
|
size_t len = buf_len(&p->buf);
|
@@ -597,7 +545,7 @@ static void add_str(ojParser p) {
|
|
597
545
|
}
|
598
546
|
|
599
547
|
static void add_str_key(ojParser p) {
|
600
|
-
|
548
|
+
Usual d = (Usual)p->ctx;
|
601
549
|
volatile VALUE rstr;
|
602
550
|
const char * str = buf_str(&p->buf);
|
603
551
|
size_t len = buf_len(&p->buf);
|
@@ -612,7 +560,7 @@ static void add_str_key(ojParser p) {
|
|
612
560
|
}
|
613
561
|
|
614
562
|
static void add_str_key_create(ojParser p) {
|
615
|
-
|
563
|
+
Usual d = (Usual)p->ctx;
|
616
564
|
volatile VALUE rstr;
|
617
565
|
const char * str = buf_str(&p->buf);
|
618
566
|
size_t len = buf_len(&p->buf);
|
@@ -646,7 +594,7 @@ static void add_str_key_create(ojParser p) {
|
|
646
594
|
}
|
647
595
|
|
648
596
|
static VALUE result(ojParser p) {
|
649
|
-
|
597
|
+
Usual d = (Usual)p->ctx;
|
650
598
|
|
651
599
|
if (d->vhead < d->vtail) {
|
652
600
|
return *d->vhead;
|
@@ -655,7 +603,7 @@ static VALUE result(ojParser p) {
|
|
655
603
|
}
|
656
604
|
|
657
605
|
static void start(ojParser p) {
|
658
|
-
|
606
|
+
Usual d = (Usual)p->ctx;
|
659
607
|
|
660
608
|
d->vtail = d->vhead;
|
661
609
|
d->ctail = d->chead;
|
@@ -663,7 +611,7 @@ static void start(ojParser p) {
|
|
663
611
|
}
|
664
612
|
|
665
613
|
static void dfree(ojParser p) {
|
666
|
-
|
614
|
+
Usual d = (Usual)p->ctx;
|
667
615
|
|
668
616
|
cache_free(d->str_cache);
|
669
617
|
cache_free(d->attr_cache);
|
@@ -682,10 +630,10 @@ static void dfree(ojParser p) {
|
|
682
630
|
}
|
683
631
|
|
684
632
|
static void mark(ojParser p) {
|
685
|
-
if (NULL == p->ctx) {
|
633
|
+
if (NULL == p || NULL == p->ctx) {
|
686
634
|
return;
|
687
635
|
}
|
688
|
-
|
636
|
+
Usual d = (Usual)p->ctx;
|
689
637
|
VALUE * vp;
|
690
638
|
|
691
639
|
if (NULL == d) {
|
@@ -718,13 +666,13 @@ struct opt {
|
|
718
666
|
};
|
719
667
|
|
720
668
|
static VALUE opt_array_class(ojParser p, VALUE value) {
|
721
|
-
|
669
|
+
Usual d = (Usual)p->ctx;
|
722
670
|
|
723
671
|
return d->array_class;
|
724
672
|
}
|
725
673
|
|
726
674
|
static VALUE opt_array_class_set(ojParser p, VALUE value) {
|
727
|
-
|
675
|
+
Usual d = (Usual)p->ctx;
|
728
676
|
|
729
677
|
if (Qnil == value) {
|
730
678
|
p->funcs[TOP_FUN].close_array = close_array;
|
@@ -745,13 +693,13 @@ static VALUE opt_array_class_set(ojParser p, VALUE value) {
|
|
745
693
|
}
|
746
694
|
|
747
695
|
static VALUE opt_cache_keys(ojParser p, VALUE value) {
|
748
|
-
|
696
|
+
Usual d = (Usual)p->ctx;
|
749
697
|
|
750
698
|
return d->cache_keys ? Qtrue : Qfalse;
|
751
699
|
}
|
752
700
|
|
753
701
|
static VALUE opt_cache_keys_set(ojParser p, VALUE value) {
|
754
|
-
|
702
|
+
Usual d = (Usual)p->ctx;
|
755
703
|
|
756
704
|
if (Qtrue == value) {
|
757
705
|
d->cache_keys = true;
|
@@ -773,13 +721,13 @@ static VALUE opt_cache_keys_set(ojParser p, VALUE value) {
|
|
773
721
|
}
|
774
722
|
|
775
723
|
static VALUE opt_cache_strings(ojParser p, VALUE value) {
|
776
|
-
|
724
|
+
Usual d = (Usual)p->ctx;
|
777
725
|
|
778
726
|
return INT2NUM((int)d->cache_str);
|
779
727
|
}
|
780
728
|
|
781
729
|
static VALUE opt_cache_strings_set(ojParser p, VALUE value) {
|
782
|
-
|
730
|
+
Usual d = (Usual)p->ctx;
|
783
731
|
int limit = NUM2INT(value);
|
784
732
|
|
785
733
|
if (CACHE_MAX_KEY < limit) {
|
@@ -793,13 +741,13 @@ static VALUE opt_cache_strings_set(ojParser p, VALUE value) {
|
|
793
741
|
}
|
794
742
|
|
795
743
|
static VALUE opt_cache_expunge(ojParser p, VALUE value) {
|
796
|
-
|
744
|
+
Usual d = (Usual)p->ctx;
|
797
745
|
|
798
746
|
return INT2NUM((int)d->cache_xrate);
|
799
747
|
}
|
800
748
|
|
801
749
|
static VALUE opt_cache_expunge_set(ojParser p, VALUE value) {
|
802
|
-
|
750
|
+
Usual d = (Usual)p->ctx;
|
803
751
|
int rate = NUM2INT(value);
|
804
752
|
|
805
753
|
if (rate < 0) {
|
@@ -817,13 +765,13 @@ static VALUE opt_cache_expunge_set(ojParser p, VALUE value) {
|
|
817
765
|
}
|
818
766
|
|
819
767
|
static VALUE opt_capacity(ojParser p, VALUE value) {
|
820
|
-
|
768
|
+
Usual d = (Usual)p->ctx;
|
821
769
|
|
822
770
|
return ULONG2NUM(d->vend - d->vhead);
|
823
771
|
}
|
824
772
|
|
825
773
|
static VALUE opt_capacity_set(ojParser p, VALUE value) {
|
826
|
-
|
774
|
+
Usual d = (Usual)p->ctx;
|
827
775
|
long cap = NUM2LONG(value);
|
828
776
|
|
829
777
|
if (d->vend - d->vhead < cap) {
|
@@ -844,13 +792,13 @@ static VALUE opt_capacity_set(ojParser p, VALUE value) {
|
|
844
792
|
}
|
845
793
|
|
846
794
|
static VALUE opt_class_cache(ojParser p, VALUE value) {
|
847
|
-
|
795
|
+
Usual d = (Usual)p->ctx;
|
848
796
|
|
849
797
|
return (NULL != d->class_cache) ? Qtrue : Qfalse;
|
850
798
|
}
|
851
799
|
|
852
800
|
static VALUE opt_class_cache_set(ojParser p, VALUE value) {
|
853
|
-
|
801
|
+
Usual d = (Usual)p->ctx;
|
854
802
|
|
855
803
|
if (Qtrue == value) {
|
856
804
|
if (NULL == d->class_cache) {
|
@@ -864,7 +812,7 @@ static VALUE opt_class_cache_set(ojParser p, VALUE value) {
|
|
864
812
|
}
|
865
813
|
|
866
814
|
static VALUE opt_create_id(ojParser p, VALUE value) {
|
867
|
-
|
815
|
+
Usual d = (Usual)p->ctx;
|
868
816
|
|
869
817
|
if (NULL == d->create_id) {
|
870
818
|
return Qnil;
|
@@ -873,7 +821,7 @@ static VALUE opt_create_id(ojParser p, VALUE value) {
|
|
873
821
|
}
|
874
822
|
|
875
823
|
static VALUE opt_create_id_set(ojParser p, VALUE value) {
|
876
|
-
|
824
|
+
Usual d = (Usual)p->ctx;
|
877
825
|
|
878
826
|
if (Qnil == value) {
|
879
827
|
d->create_id = NULL;
|
@@ -983,13 +931,13 @@ static VALUE opt_decimal_set(ojParser p, VALUE value) {
|
|
983
931
|
}
|
984
932
|
|
985
933
|
static VALUE opt_hash_class(ojParser p, VALUE value) {
|
986
|
-
|
934
|
+
Usual d = (Usual)p->ctx;
|
987
935
|
|
988
936
|
return d->hash_class;
|
989
937
|
}
|
990
938
|
|
991
939
|
static VALUE opt_hash_class_set(ojParser p, VALUE value) {
|
992
|
-
|
940
|
+
Usual d = (Usual)p->ctx;
|
993
941
|
|
994
942
|
if (Qnil != value) {
|
995
943
|
rb_check_type(value, T_CLASS);
|
@@ -1013,13 +961,13 @@ static VALUE opt_hash_class_set(ojParser p, VALUE value) {
|
|
1013
961
|
}
|
1014
962
|
|
1015
963
|
static VALUE opt_ignore_json_create(ojParser p, VALUE value) {
|
1016
|
-
|
964
|
+
Usual d = (Usual)p->ctx;
|
1017
965
|
|
1018
966
|
return d->ignore_json_create ? Qtrue : Qfalse;
|
1019
967
|
}
|
1020
968
|
|
1021
969
|
static VALUE opt_ignore_json_create_set(ojParser p, VALUE value) {
|
1022
|
-
|
970
|
+
Usual d = (Usual)p->ctx;
|
1023
971
|
|
1024
972
|
d->ignore_json_create = (Qtrue == value);
|
1025
973
|
|
@@ -1027,7 +975,7 @@ static VALUE opt_ignore_json_create_set(ojParser p, VALUE value) {
|
|
1027
975
|
}
|
1028
976
|
|
1029
977
|
static VALUE opt_missing_class(ojParser p, VALUE value) {
|
1030
|
-
|
978
|
+
Usual d = (Usual)p->ctx;
|
1031
979
|
|
1032
980
|
switch (d->miss_class) {
|
1033
981
|
case MISS_AUTO: return ID2SYM(rb_intern("auto"));
|
@@ -1038,7 +986,7 @@ static VALUE opt_missing_class(ojParser p, VALUE value) {
|
|
1038
986
|
}
|
1039
987
|
|
1040
988
|
static VALUE opt_missing_class_set(ojParser p, VALUE value) {
|
1041
|
-
|
989
|
+
Usual d = (Usual)p->ctx;
|
1042
990
|
const char * mode;
|
1043
991
|
volatile VALUE s;
|
1044
992
|
|
@@ -1089,13 +1037,13 @@ static VALUE opt_omit_null_set(ojParser p, VALUE value) {
|
|
1089
1037
|
}
|
1090
1038
|
|
1091
1039
|
static VALUE opt_symbol_keys(ojParser p, VALUE value) {
|
1092
|
-
|
1040
|
+
Usual d = (Usual)p->ctx;
|
1093
1041
|
|
1094
1042
|
return (NULL != d->sym_cache) ? Qtrue : Qfalse;
|
1095
1043
|
}
|
1096
1044
|
|
1097
1045
|
static VALUE opt_symbol_keys_set(ojParser p, VALUE value) {
|
1098
|
-
|
1046
|
+
Usual d = (Usual)p->ctx;
|
1099
1047
|
|
1100
1048
|
if (Qtrue == value) {
|
1101
1049
|
d->sym_cache = cache_create(0, form_sym, true, false);
|
@@ -1119,33 +1067,33 @@ static VALUE opt_symbol_keys_set(ojParser p, VALUE value) {
|
|
1119
1067
|
static VALUE option(ojParser p, const char *key, VALUE value) {
|
1120
1068
|
struct opt *op;
|
1121
1069
|
struct opt opts[] = {
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1070
|
+
{.name = "array_class", .func = opt_array_class},
|
1071
|
+
{.name = "array_class=", .func = opt_array_class_set},
|
1072
|
+
{.name = "cache_keys", .func = opt_cache_keys},
|
1073
|
+
{.name = "cache_keys=", .func = opt_cache_keys_set},
|
1074
|
+
{.name = "cache_strings", .func = opt_cache_strings},
|
1075
|
+
{.name = "cache_strings=", .func = opt_cache_strings_set},
|
1076
|
+
{.name = "cache_expunge", .func = opt_cache_expunge},
|
1077
|
+
{.name = "cache_expunge=", .func = opt_cache_expunge_set},
|
1078
|
+
{.name = "capacity", .func = opt_capacity},
|
1079
|
+
{.name = "capacity=", .func = opt_capacity_set},
|
1080
|
+
{.name = "class_cache", .func = opt_class_cache},
|
1081
|
+
{.name = "class_cache=", .func = opt_class_cache_set},
|
1082
|
+
{.name = "create_id", .func = opt_create_id},
|
1083
|
+
{.name = "create_id=", .func = opt_create_id_set},
|
1084
|
+
{.name = "decimal", .func = opt_decimal},
|
1085
|
+
{.name = "decimal=", .func = opt_decimal_set},
|
1086
|
+
{.name = "hash_class", .func = opt_hash_class},
|
1087
|
+
{.name = "hash_class=", .func = opt_hash_class_set},
|
1088
|
+
{.name = "ignore_json_create", .func = opt_ignore_json_create},
|
1089
|
+
{.name = "ignore_json_create=", .func = opt_ignore_json_create_set},
|
1090
|
+
{.name = "missing_class", .func = opt_missing_class},
|
1091
|
+
{.name = "missing_class=", .func = opt_missing_class_set},
|
1092
|
+
{.name = "omit_null", .func = opt_omit_null},
|
1093
|
+
{.name = "omit_null=", .func = opt_omit_null_set},
|
1094
|
+
{.name = "symbol_keys", .func = opt_symbol_keys},
|
1095
|
+
{.name = "symbol_keys=", .func = opt_symbol_keys_set},
|
1096
|
+
{.name = NULL},
|
1149
1097
|
};
|
1150
1098
|
|
1151
1099
|
for (op = opts; NULL != op->name; op++) {
|
@@ -1160,8 +1108,7 @@ static VALUE option(ojParser p, const char *key, VALUE value) {
|
|
1160
1108
|
|
1161
1109
|
///// the set up //////////////////////////////////////////////////////////////
|
1162
1110
|
|
1163
|
-
void
|
1164
|
-
Delegate d = ALLOC(struct _delegate);
|
1111
|
+
void oj_init_usual(ojParser p, Usual d) {
|
1165
1112
|
int cap = 4096;
|
1166
1113
|
|
1167
1114
|
d->vhead = ALLOC_N(VALUE, cap);
|
@@ -1233,6 +1180,8 @@ void oj_set_parser_usual(ojParser p) {
|
|
1233
1180
|
d->class_cache = NULL;
|
1234
1181
|
d->key_cache = d->str_cache;
|
1235
1182
|
|
1183
|
+
// The parser fields are set but the functions can be replaced by a
|
1184
|
+
// delegate that wraps the usual delegate.
|
1236
1185
|
p->ctx = (void *)d;
|
1237
1186
|
p->option = option;
|
1238
1187
|
p->result = result;
|
@@ -1250,3 +1199,9 @@ void oj_set_parser_usual(ojParser p) {
|
|
1250
1199
|
hset_id = rb_intern("[]=");
|
1251
1200
|
}
|
1252
1201
|
}
|
1202
|
+
|
1203
|
+
void oj_set_parser_usual(ojParser p) {
|
1204
|
+
Usual d = ALLOC(struct _usual);
|
1205
|
+
|
1206
|
+
oj_init_usual(p, d);
|
1207
|
+
}
|
data/ext/oj/usual.h
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
// Copyright (c) 2022, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#include <ruby.h>
|
4
|
+
#include <stdbool.h>
|
5
|
+
#include <stdint.h>
|
6
|
+
|
7
|
+
struct _cache;
|
8
|
+
struct _ojParser;
|
9
|
+
|
10
|
+
// Used to mark the start of each Hash, Array, or Object. The members point at
|
11
|
+
// positions of the start in the value stack and if not an Array into the key
|
12
|
+
// stack.
|
13
|
+
typedef struct _col {
|
14
|
+
long vi; // value stack index
|
15
|
+
long ki; // key stack index if an hash else -1 for an array
|
16
|
+
} * Col;
|
17
|
+
|
18
|
+
typedef union _key {
|
19
|
+
struct {
|
20
|
+
int16_t len;
|
21
|
+
char buf[30];
|
22
|
+
};
|
23
|
+
struct {
|
24
|
+
int16_t xlen; // should be the same as len
|
25
|
+
char * key;
|
26
|
+
};
|
27
|
+
} * Key;
|
28
|
+
|
29
|
+
#define MISS_AUTO 'A'
|
30
|
+
#define MISS_RAISE 'R'
|
31
|
+
#define MISS_IGNORE 'I'
|
32
|
+
|
33
|
+
typedef struct _usual {
|
34
|
+
VALUE *vhead;
|
35
|
+
VALUE *vtail;
|
36
|
+
VALUE *vend;
|
37
|
+
|
38
|
+
Col chead;
|
39
|
+
Col ctail;
|
40
|
+
Col cend;
|
41
|
+
|
42
|
+
Key khead;
|
43
|
+
Key ktail;
|
44
|
+
Key kend;
|
45
|
+
|
46
|
+
VALUE (*get_key)(ojParser p, Key kp);
|
47
|
+
struct _cache *key_cache; // same as str_cache or sym_cache
|
48
|
+
struct _cache *str_cache;
|
49
|
+
struct _cache *sym_cache;
|
50
|
+
struct _cache *class_cache;
|
51
|
+
struct _cache *attr_cache;
|
52
|
+
|
53
|
+
VALUE array_class;
|
54
|
+
VALUE hash_class;
|
55
|
+
|
56
|
+
char * create_id;
|
57
|
+
uint8_t create_id_len;
|
58
|
+
uint8_t cache_str;
|
59
|
+
uint8_t cache_xrate;
|
60
|
+
uint8_t miss_class;
|
61
|
+
bool cache_keys;
|
62
|
+
bool ignore_json_create;
|
63
|
+
} * Usual;
|
64
|
+
|
65
|
+
// Initialize the parser with the usual delegate. If the usual delegate is
|
66
|
+
// wrapped then this function is called first and then the parser functions
|
67
|
+
// can be replaced.
|
68
|
+
extern void oj_init_usual(struct _ojParser *p, Usual d);
|
data/ext/oj/val_stack.c
CHANGED
data/ext/oj/validate.c
CHANGED
@@ -2,50 +2,45 @@
|
|
2
2
|
|
3
3
|
#include "parser.h"
|
4
4
|
|
5
|
-
static void
|
6
|
-
noop(ojParser p) {
|
5
|
+
static void noop(ojParser p) {
|
7
6
|
}
|
8
7
|
|
9
|
-
static VALUE
|
10
|
-
option(ojParser p, const char *key, VALUE value) {
|
8
|
+
static VALUE option(ojParser p, const char *key, VALUE value) {
|
11
9
|
rb_raise(rb_eArgError, "%s is not an option for the validate delegate", key);
|
12
10
|
return Qnil;
|
13
11
|
}
|
14
12
|
|
15
|
-
static VALUE
|
16
|
-
result(ojParser p) {
|
13
|
+
static VALUE result(ojParser p) {
|
17
14
|
return Qnil;
|
18
15
|
}
|
19
16
|
|
20
|
-
static void
|
21
|
-
dfree(ojParser p) {
|
17
|
+
static void dfree(ojParser p) {
|
22
18
|
}
|
23
19
|
|
24
|
-
static void
|
25
|
-
mark(ojParser p) {
|
20
|
+
static void mark(ojParser p) {
|
26
21
|
}
|
27
22
|
|
28
23
|
void oj_set_parser_validator(ojParser p) {
|
29
|
-
p->
|
30
|
-
Funcs end = p->funcs + 3;
|
24
|
+
Funcs end = p->funcs + 3;
|
31
25
|
Funcs f;
|
26
|
+
p->ctx = NULL;
|
32
27
|
|
33
28
|
for (f = p->funcs; f < end; f++) {
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
29
|
+
f->add_null = noop;
|
30
|
+
f->add_true = noop;
|
31
|
+
f->add_false = noop;
|
32
|
+
f->add_int = noop;
|
33
|
+
f->add_float = noop;
|
34
|
+
f->add_big = noop;
|
35
|
+
f->add_str = noop;
|
36
|
+
f->open_array = noop;
|
37
|
+
f->close_array = noop;
|
38
|
+
f->open_object = noop;
|
39
|
+
f->close_object = noop;
|
45
40
|
}
|
46
41
|
p->option = option;
|
47
42
|
p->result = result;
|
48
|
-
p->free
|
49
|
-
p->mark
|
50
|
-
p->start
|
43
|
+
p->free = dfree;
|
44
|
+
p->mark = mark;
|
45
|
+
p->start = noop;
|
51
46
|
}
|