oj 3.13.2 → 3.13.6
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 +1280 -0
- data/README.md +1 -1
- data/RELEASE_NOTES.md +55 -0
- data/ext/oj/cache.c +240 -107
- data/ext/oj/cache.h +2 -1
- data/ext/oj/compat.c +1 -2
- data/ext/oj/custom.c +4 -7
- data/ext/oj/extconf.rb +1 -0
- data/ext/oj/intern.c +106 -216
- data/ext/oj/intern.h +0 -1
- data/ext/oj/mimic_json.c +2 -2
- data/ext/oj/object.c +10 -39
- data/ext/oj/oj.c +8 -5
- data/ext/oj/parser.c +167 -148
- data/ext/oj/saj2.c +3 -3
- data/ext/oj/strict.c +2 -3
- data/ext/oj/usual.c +55 -31
- data/ext/oj/wab.c +6 -3
- data/lib/oj/state.rb +8 -7
- data/lib/oj/version.rb +1 -1
- data/pages/Options.md +12 -2
- data/test/bar.rb +9 -28
- data/test/foo.rb +8 -8
- data/test/mem.rb +33 -0
- data/test/perf_once.rb +58 -0
- data/test/perf_parser.rb +6 -1
- data/test/test_parser_usual.rb +9 -5
- metadata +11 -2
data/ext/oj/intern.h
CHANGED
data/ext/oj/mimic_json.c
CHANGED
@@ -682,7 +682,7 @@ static VALUE mimic_set_create_id(VALUE self, VALUE id) {
|
|
682
682
|
*/
|
683
683
|
static VALUE mimic_create_id(VALUE self) {
|
684
684
|
if (NULL != oj_default_options.create_id) {
|
685
|
-
return
|
685
|
+
return rb_utf8_str_new(oj_default_options.create_id, oj_default_options.create_id_len);
|
686
686
|
}
|
687
687
|
return rb_str_new_cstr(oj_json_class);
|
688
688
|
}
|
@@ -714,7 +714,7 @@ static struct _options mimic_object_to_json_options = {0, // indent
|
|
714
714
|
false, // sec_prec_set
|
715
715
|
No, // ignore_under
|
716
716
|
Yes, // cache_keys
|
717
|
-
|
717
|
+
0, // cache_str
|
718
718
|
0, // int_range_min
|
719
719
|
0, // int_range_max
|
720
720
|
oj_json_class, // create_id
|
data/ext/oj/object.c
CHANGED
@@ -30,46 +30,19 @@ inline static long read_long(const char *str, size_t len) {
|
|
30
30
|
|
31
31
|
static VALUE calc_hash_key(ParseInfo pi, Val kval, char k1) {
|
32
32
|
volatile VALUE rkey;
|
33
|
-
#if 0
|
34
|
-
VALUE *slot;
|
35
33
|
|
36
34
|
if (':' == k1) {
|
37
|
-
|
38
|
-
rkey = rb_str_new(kval->key + 1, kval->klen - 1);
|
39
|
-
rkey = oj_encode(rkey);
|
40
|
-
rkey = rb_str_intern(rkey);
|
41
|
-
*slot = rkey;
|
42
|
-
rb_gc_register_address(slot);
|
43
|
-
}
|
44
|
-
} else if (Yes == pi->options.sym_key) {
|
45
|
-
if (Qnil == (rkey = oj_sym_hash_get(kval->key, kval->klen, &slot))) {
|
46
|
-
rkey = rb_str_new(kval->key, kval->klen);
|
47
|
-
rkey = oj_encode(rkey);
|
48
|
-
rkey = rb_str_intern(rkey);
|
49
|
-
*slot = rkey;
|
50
|
-
rb_gc_register_address(slot);
|
51
|
-
}
|
52
|
-
} else {
|
53
|
-
if (Qnil == (rkey = oj_str_hash_get(kval->key, kval->klen, &slot))) {
|
54
|
-
rkey = rb_str_new(kval->key, kval->klen);
|
55
|
-
rkey = oj_encode(rkey);
|
56
|
-
*slot = rkey;
|
57
|
-
rb_gc_register_address(slot);
|
58
|
-
}
|
35
|
+
return ID2SYM(rb_intern3(kval->key + 1, kval->klen - 1, oj_utf8_encoding));
|
59
36
|
}
|
60
|
-
|
61
|
-
|
62
|
-
rkey = ID2SYM(rb_intern3(kval->key + 1, kval->klen - 1, oj_utf8_encoding));
|
63
|
-
} else {
|
64
|
-
if (Yes == pi->options.sym_key) {
|
65
|
-
rkey = ID2SYM(rb_intern3(kval->key, kval->klen, oj_utf8_encoding));
|
66
|
-
} else {
|
67
|
-
rkey = rb_str_new(kval->key, kval->klen);
|
68
|
-
rkey = oj_encode(rkey);
|
69
|
-
}
|
37
|
+
if (Yes == pi->options.sym_key) {
|
38
|
+
return ID2SYM(rb_intern3(kval->key, kval->klen, oj_utf8_encoding));
|
70
39
|
}
|
71
|
-
#
|
40
|
+
#if HAVE_RB_ENC_INTERNED_STR
|
41
|
+
rkey = rb_enc_interned_str(kval->key, kval->klen, oj_utf8_encoding);
|
42
|
+
#else
|
43
|
+
rkey = rb_utf8_str_new(kval->key, kval->klen);
|
72
44
|
OBJ_FREEZE(rkey);
|
45
|
+
#endif
|
73
46
|
return rkey;
|
74
47
|
}
|
75
48
|
|
@@ -87,8 +60,7 @@ static VALUE str_to_value(ParseInfo pi, const char *str, size_t len, const char
|
|
87
60
|
}
|
88
61
|
rstr = oj_circ_array_get(pi->circ_array, i);
|
89
62
|
} else {
|
90
|
-
|
91
|
-
rstr = oj_encode(rstr);
|
63
|
+
rstr = rb_utf8_str_new(str, len);
|
92
64
|
}
|
93
65
|
return rstr;
|
94
66
|
}
|
@@ -259,8 +231,7 @@ static int hat_cstr(ParseInfo pi, Val parent, Val kval, const char *str, size_t
|
|
259
231
|
parent->val = ID2SYM(rb_intern3(str + 1, len - 1, oj_utf8_encoding));
|
260
232
|
break;
|
261
233
|
case 's':
|
262
|
-
|
263
|
-
parent->val = oj_encode(parent->val);
|
234
|
+
parent->val = rb_utf8_str_new(str, len);
|
264
235
|
break;
|
265
236
|
case 'c': // class
|
266
237
|
{
|
data/ext/oj/oj.c
CHANGED
@@ -107,6 +107,7 @@ static VALUE bigdecimal_load_sym;
|
|
107
107
|
static VALUE bigdecimal_sym;
|
108
108
|
static VALUE cache_keys_sym;
|
109
109
|
static VALUE cache_str_sym;
|
110
|
+
static VALUE cache_string_sym;
|
110
111
|
static VALUE circular_sym;
|
111
112
|
static VALUE class_cache_sym;
|
112
113
|
static VALUE compat_bigdecimal_sym;
|
@@ -190,7 +191,7 @@ struct _options oj_default_options = {
|
|
190
191
|
false, // sec_prec_set
|
191
192
|
No, // ignore_under
|
192
193
|
Yes, // cache_keys
|
193
|
-
|
194
|
+
0, // cache_str
|
194
195
|
0, // int_range_min
|
195
196
|
0, // int_range_max
|
196
197
|
oj_json_class, // create_id
|
@@ -287,8 +288,8 @@ struct _options oj_default_options = {
|
|
287
288
|
* - *:ignore* [_nil_|_Array_] either nil or an Array of classes to ignore when dumping
|
288
289
|
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when dumping in
|
289
290
|
*object or custom mode.
|
290
|
-
* - *:cache_keys* [_Boolean_] if true then hash keys are cached
|
291
|
-
* - *:cache_str* [_Fixnum_] maximum string value length to cache
|
291
|
+
* - *:cache_keys* [_Boolean_] if true then hash keys are cached if less than 35 bytes.
|
292
|
+
* - *:cache_str* [_Fixnum_] maximum string value length to cache (strings less than this are cached)
|
292
293
|
* - *:integer_range* [_Range_] Dump integers outside range as strings.
|
293
294
|
* - *:trace* [_true,_|_false_] Trace all load and dump calls, default is false (trace is off)
|
294
295
|
* - *:safe* [_true,_|_false_] Safe mimic breaks JSON mimic to be safer, default is false (safe is
|
@@ -571,7 +572,7 @@ static VALUE get_def_opts(VALUE self) {
|
|
571
572
|
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when
|
572
573
|
*dumping in object or custom mode.
|
573
574
|
* - *:cache_keys* [_Boolean_] if true then hash keys are cached
|
574
|
-
* - *:cache_str* [_Fixnum_] maximum string
|
575
|
+
* - *:cache_str* [_Fixnum_] maximum string value length to cache (strings less than this are cached)
|
575
576
|
* - *:integer_range* [_Range_] Dump integers outside range as strings.
|
576
577
|
* - *:trace* [_Boolean_] turn trace on or off.
|
577
578
|
* - *:safe* [_Boolean_] turn safe mimic on or off.
|
@@ -692,7 +693,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts)
|
|
692
693
|
sprintf(copts->float_fmt, "%%0.%dg", n);
|
693
694
|
copts->float_prec = n;
|
694
695
|
}
|
695
|
-
} else if (cache_str_sym == k) {
|
696
|
+
} else if (cache_str_sym == k || cache_string_sym == k) {
|
696
697
|
int n;
|
697
698
|
|
698
699
|
#ifdef RUBY_INTEGER_UNIFICATION
|
@@ -1920,6 +1921,8 @@ void Init_oj() {
|
|
1920
1921
|
rb_gc_register_address(&cache_keys_sym);
|
1921
1922
|
cache_str_sym = ID2SYM(rb_intern("cache_str"));
|
1922
1923
|
rb_gc_register_address(&cache_str_sym);
|
1924
|
+
cache_string_sym = ID2SYM(rb_intern("cache_string"));
|
1925
|
+
rb_gc_register_address(&cache_string_sym);
|
1923
1926
|
circular_sym = ID2SYM(rb_intern("circular"));
|
1924
1927
|
rb_gc_register_address(&circular_sym);
|
1925
1928
|
class_cache_sym = ID2SYM(rb_intern("class_cache"));
|
data/ext/oj/parser.c
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
// Copyright (c) 2020, 2021, Peter Ohler, All rights reserved.
|
2
2
|
|
3
|
+
#include "parser.h"
|
4
|
+
|
3
5
|
#include <fcntl.h>
|
4
6
|
|
5
|
-
#include "parser.h"
|
6
7
|
#include "oj.h"
|
7
8
|
|
8
9
|
#define DEBUG 0
|
@@ -384,87 +385,44 @@ static const byte hex_map[256] = "\
|
|
384
385
|
................................\
|
385
386
|
................................";
|
386
387
|
|
387
|
-
static long double pow_map[401] = {
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
1.0e190L, 1.0e191L, 1.0e192L, 1.0e193L, 1.0e194L,
|
426
|
-
1.0e195L, 1.0e196L, 1.0e197L, 1.0e198L, 1.0e199L, // 190
|
427
|
-
1.0e200L, 1.0e201L, 1.0e202L, 1.0e203L, 1.0e204L,
|
428
|
-
1.0e205L, 1.0e206L, 1.0e207L, 1.0e208L, 1.0e209L, // 200
|
429
|
-
1.0e210L, 1.0e211L, 1.0e212L, 1.0e213L, 1.0e214L,
|
430
|
-
1.0e215L, 1.0e216L, 1.0e217L, 1.0e218L, 1.0e219L, // 210
|
431
|
-
1.0e220L, 1.0e221L, 1.0e222L, 1.0e223L, 1.0e224L,
|
432
|
-
1.0e225L, 1.0e226L, 1.0e227L, 1.0e228L, 1.0e229L, // 220
|
433
|
-
1.0e230L, 1.0e231L, 1.0e232L, 1.0e233L, 1.0e234L,
|
434
|
-
1.0e235L, 1.0e236L, 1.0e237L, 1.0e238L, 1.0e239L, // 230
|
435
|
-
1.0e240L, 1.0e241L, 1.0e242L, 1.0e243L, 1.0e244L,
|
436
|
-
1.0e245L, 1.0e246L, 1.0e247L, 1.0e248L, 1.0e249L, // 240
|
437
|
-
1.0e250L, 1.0e251L, 1.0e252L, 1.0e253L, 1.0e254L,
|
438
|
-
1.0e255L, 1.0e256L, 1.0e257L, 1.0e258L, 1.0e259L, // 250
|
439
|
-
1.0e260L, 1.0e261L, 1.0e262L, 1.0e263L, 1.0e264L,
|
440
|
-
1.0e265L, 1.0e266L, 1.0e267L, 1.0e268L, 1.0e269L, // 260
|
441
|
-
1.0e270L, 1.0e271L, 1.0e272L, 1.0e273L, 1.0e274L,
|
442
|
-
1.0e275L, 1.0e276L, 1.0e277L, 1.0e278L, 1.0e279L, // 270
|
443
|
-
1.0e280L, 1.0e281L, 1.0e282L, 1.0e283L, 1.0e284L,
|
444
|
-
1.0e285L, 1.0e286L, 1.0e287L, 1.0e288L, 1.0e289L, // 280
|
445
|
-
1.0e290L, 1.0e291L, 1.0e292L, 1.0e293L, 1.0e294L,
|
446
|
-
1.0e295L, 1.0e296L, 1.0e297L, 1.0e298L, 1.0e299L, // 290
|
447
|
-
1.0e300L, 1.0e301L, 1.0e302L, 1.0e303L, 1.0e304L,
|
448
|
-
1.0e305L, 1.0e306L, 1.0e307L, 1.0e308L, 1.0e309L, // 300
|
449
|
-
1.0e310L, 1.0e311L, 1.0e312L, 1.0e313L, 1.0e314L,
|
450
|
-
1.0e315L, 1.0e316L, 1.0e317L, 1.0e318L, 1.0e319L, // 310
|
451
|
-
1.0e320L, 1.0e321L, 1.0e322L, 1.0e323L, 1.0e324L,
|
452
|
-
1.0e325L, 1.0e326L, 1.0e327L, 1.0e328L, 1.0e329L, // 320
|
453
|
-
1.0e330L, 1.0e331L, 1.0e332L, 1.0e333L, 1.0e334L,
|
454
|
-
1.0e335L, 1.0e336L, 1.0e337L, 1.0e338L, 1.0e339L, // 330
|
455
|
-
1.0e340L, 1.0e341L, 1.0e342L, 1.0e343L, 1.0e344L,
|
456
|
-
1.0e345L, 1.0e346L, 1.0e347L, 1.0e348L, 1.0e349L, // 340
|
457
|
-
1.0e350L, 1.0e351L, 1.0e352L, 1.0e353L, 1.0e354L,
|
458
|
-
1.0e355L, 1.0e356L, 1.0e357L, 1.0e358L, 1.0e359L, // 350
|
459
|
-
1.0e360L, 1.0e361L, 1.0e362L, 1.0e363L, 1.0e364L,
|
460
|
-
1.0e365L, 1.0e366L, 1.0e367L, 1.0e368L, 1.0e369L, // 360
|
461
|
-
1.0e370L, 1.0e371L, 1.0e372L, 1.0e373L, 1.0e374L,
|
462
|
-
1.0e375L, 1.0e376L, 1.0e377L, 1.0e378L, 1.0e379L, // 370
|
463
|
-
1.0e380L, 1.0e381L, 1.0e382L, 1.0e383L, 1.0e384L,
|
464
|
-
1.0e385L, 1.0e386L, 1.0e387L, 1.0e388L, 1.0e389L, // 380
|
465
|
-
1.0e390L, 1.0e391L, 1.0e392L, 1.0e393L, 1.0e394L,
|
466
|
-
1.0e395L, 1.0e396L, 1.0e397L, 1.0e398L, 1.0e399L, // 390
|
467
|
-
1.0e400L};
|
388
|
+
static long double pow_map[401] = {
|
389
|
+
1.0L, 1.0e1L, 1.0e2L, 1.0e3L, 1.0e4L, 1.0e5L, 1.0e6L, 1.0e7L, 1.0e8L, 1.0e9L, 1.0e10L,
|
390
|
+
1.0e11L, 1.0e12L, 1.0e13L, 1.0e14L, 1.0e15L, 1.0e16L, 1.0e17L, 1.0e18L, 1.0e19L, 1.0e20L, 1.0e21L,
|
391
|
+
1.0e22L, 1.0e23L, 1.0e24L, 1.0e25L, 1.0e26L, 1.0e27L, 1.0e28L, 1.0e29L, 1.0e30L, 1.0e31L, 1.0e32L,
|
392
|
+
1.0e33L, 1.0e34L, 1.0e35L, 1.0e36L, 1.0e37L, 1.0e38L, 1.0e39L, 1.0e40L, 1.0e41L, 1.0e42L, 1.0e43L,
|
393
|
+
1.0e44L, 1.0e45L, 1.0e46L, 1.0e47L, 1.0e48L, 1.0e49L, 1.0e50L, 1.0e51L, 1.0e52L, 1.0e53L, 1.0e54L,
|
394
|
+
1.0e55L, 1.0e56L, 1.0e57L, 1.0e58L, 1.0e59L, 1.0e60L, 1.0e61L, 1.0e62L, 1.0e63L, 1.0e64L, 1.0e65L,
|
395
|
+
1.0e66L, 1.0e67L, 1.0e68L, 1.0e69L, 1.0e70L, 1.0e71L, 1.0e72L, 1.0e73L, 1.0e74L, 1.0e75L, 1.0e76L,
|
396
|
+
1.0e77L, 1.0e78L, 1.0e79L, 1.0e80L, 1.0e81L, 1.0e82L, 1.0e83L, 1.0e84L, 1.0e85L, 1.0e86L, 1.0e87L,
|
397
|
+
1.0e88L, 1.0e89L, 1.0e90L, 1.0e91L, 1.0e92L, 1.0e93L, 1.0e94L, 1.0e95L, 1.0e96L, 1.0e97L, 1.0e98L,
|
398
|
+
1.0e99L, 1.0e100L, 1.0e101L, 1.0e102L, 1.0e103L, 1.0e104L, 1.0e105L, 1.0e106L, 1.0e107L, 1.0e108L, 1.0e109L,
|
399
|
+
1.0e110L, 1.0e111L, 1.0e112L, 1.0e113L, 1.0e114L, 1.0e115L, 1.0e116L, 1.0e117L, 1.0e118L, 1.0e119L, 1.0e120L,
|
400
|
+
1.0e121L, 1.0e122L, 1.0e123L, 1.0e124L, 1.0e125L, 1.0e126L, 1.0e127L, 1.0e128L, 1.0e129L, 1.0e130L, 1.0e131L,
|
401
|
+
1.0e132L, 1.0e133L, 1.0e134L, 1.0e135L, 1.0e136L, 1.0e137L, 1.0e138L, 1.0e139L, 1.0e140L, 1.0e141L, 1.0e142L,
|
402
|
+
1.0e143L, 1.0e144L, 1.0e145L, 1.0e146L, 1.0e147L, 1.0e148L, 1.0e149L, 1.0e150L, 1.0e151L, 1.0e152L, 1.0e153L,
|
403
|
+
1.0e154L, 1.0e155L, 1.0e156L, 1.0e157L, 1.0e158L, 1.0e159L, 1.0e160L, 1.0e161L, 1.0e162L, 1.0e163L, 1.0e164L,
|
404
|
+
1.0e165L, 1.0e166L, 1.0e167L, 1.0e168L, 1.0e169L, 1.0e170L, 1.0e171L, 1.0e172L, 1.0e173L, 1.0e174L, 1.0e175L,
|
405
|
+
1.0e176L, 1.0e177L, 1.0e178L, 1.0e179L, 1.0e180L, 1.0e181L, 1.0e182L, 1.0e183L, 1.0e184L, 1.0e185L, 1.0e186L,
|
406
|
+
1.0e187L, 1.0e188L, 1.0e189L, 1.0e190L, 1.0e191L, 1.0e192L, 1.0e193L, 1.0e194L, 1.0e195L, 1.0e196L, 1.0e197L,
|
407
|
+
1.0e198L, 1.0e199L, 1.0e200L, 1.0e201L, 1.0e202L, 1.0e203L, 1.0e204L, 1.0e205L, 1.0e206L, 1.0e207L, 1.0e208L,
|
408
|
+
1.0e209L, 1.0e210L, 1.0e211L, 1.0e212L, 1.0e213L, 1.0e214L, 1.0e215L, 1.0e216L, 1.0e217L, 1.0e218L, 1.0e219L,
|
409
|
+
1.0e220L, 1.0e221L, 1.0e222L, 1.0e223L, 1.0e224L, 1.0e225L, 1.0e226L, 1.0e227L, 1.0e228L, 1.0e229L, 1.0e230L,
|
410
|
+
1.0e231L, 1.0e232L, 1.0e233L, 1.0e234L, 1.0e235L, 1.0e236L, 1.0e237L, 1.0e238L, 1.0e239L, 1.0e240L, 1.0e241L,
|
411
|
+
1.0e242L, 1.0e243L, 1.0e244L, 1.0e245L, 1.0e246L, 1.0e247L, 1.0e248L, 1.0e249L, 1.0e250L, 1.0e251L, 1.0e252L,
|
412
|
+
1.0e253L, 1.0e254L, 1.0e255L, 1.0e256L, 1.0e257L, 1.0e258L, 1.0e259L, 1.0e260L, 1.0e261L, 1.0e262L, 1.0e263L,
|
413
|
+
1.0e264L, 1.0e265L, 1.0e266L, 1.0e267L, 1.0e268L, 1.0e269L, 1.0e270L, 1.0e271L, 1.0e272L, 1.0e273L, 1.0e274L,
|
414
|
+
1.0e275L, 1.0e276L, 1.0e277L, 1.0e278L, 1.0e279L, 1.0e280L, 1.0e281L, 1.0e282L, 1.0e283L, 1.0e284L, 1.0e285L,
|
415
|
+
1.0e286L, 1.0e287L, 1.0e288L, 1.0e289L, 1.0e290L, 1.0e291L, 1.0e292L, 1.0e293L, 1.0e294L, 1.0e295L, 1.0e296L,
|
416
|
+
1.0e297L, 1.0e298L, 1.0e299L, 1.0e300L, 1.0e301L, 1.0e302L, 1.0e303L, 1.0e304L, 1.0e305L, 1.0e306L, 1.0e307L,
|
417
|
+
1.0e308L, 1.0e309L, 1.0e310L, 1.0e311L, 1.0e312L, 1.0e313L, 1.0e314L, 1.0e315L, 1.0e316L, 1.0e317L, 1.0e318L,
|
418
|
+
1.0e319L, 1.0e320L, 1.0e321L, 1.0e322L, 1.0e323L, 1.0e324L, 1.0e325L, 1.0e326L, 1.0e327L, 1.0e328L, 1.0e329L,
|
419
|
+
1.0e330L, 1.0e331L, 1.0e332L, 1.0e333L, 1.0e334L, 1.0e335L, 1.0e336L, 1.0e337L, 1.0e338L, 1.0e339L, 1.0e340L,
|
420
|
+
1.0e341L, 1.0e342L, 1.0e343L, 1.0e344L, 1.0e345L, 1.0e346L, 1.0e347L, 1.0e348L, 1.0e349L, 1.0e350L, 1.0e351L,
|
421
|
+
1.0e352L, 1.0e353L, 1.0e354L, 1.0e355L, 1.0e356L, 1.0e357L, 1.0e358L, 1.0e359L, 1.0e360L, 1.0e361L, 1.0e362L,
|
422
|
+
1.0e363L, 1.0e364L, 1.0e365L, 1.0e366L, 1.0e367L, 1.0e368L, 1.0e369L, 1.0e370L, 1.0e371L, 1.0e372L, 1.0e373L,
|
423
|
+
1.0e374L, 1.0e375L, 1.0e376L, 1.0e377L, 1.0e378L, 1.0e379L, 1.0e380L, 1.0e381L, 1.0e382L, 1.0e383L, 1.0e384L,
|
424
|
+
1.0e385L, 1.0e386L, 1.0e387L, 1.0e388L, 1.0e389L, 1.0e390L, 1.0e391L, 1.0e392L, 1.0e393L, 1.0e394L, 1.0e395L,
|
425
|
+
1.0e396L, 1.0e397L, 1.0e398L, 1.0e399L, 1.0e400L};
|
468
426
|
|
469
427
|
static VALUE parser_class;
|
470
428
|
|
@@ -591,7 +549,7 @@ static void big_change(ojParser p) {
|
|
591
549
|
int len = 0;
|
592
550
|
|
593
551
|
buf[sizeof(buf) - 1] = '\0';
|
594
|
-
p->buf.tail
|
552
|
+
p->buf.tail = p->buf.head;
|
595
553
|
switch (p->type) {
|
596
554
|
case OJ_INT:
|
597
555
|
// If an int then it will fit in the num.raw so no need to check length;
|
@@ -646,12 +604,15 @@ static void big_change(ojParser p) {
|
|
646
604
|
static void parse(ojParser p, const byte *json) {
|
647
605
|
const byte *start;
|
648
606
|
const byte *b = json;
|
649
|
-
int
|
607
|
+
int i;
|
650
608
|
|
651
609
|
#if DEBUG
|
652
610
|
printf("*** parse - mode: %c %s\n", p->map[256], (const char *)json);
|
653
611
|
#endif
|
654
612
|
for (; '\0' != *b; b++) {
|
613
|
+
#if DEBUG
|
614
|
+
printf("*** parse - mode: %c %02x %s => %c\n", p->map[256], *b, b, p->map[*b]);
|
615
|
+
#endif
|
655
616
|
switch (p->map[*b]) {
|
656
617
|
case SKIP_NEWLINE:
|
657
618
|
p->line++;
|
@@ -890,7 +851,7 @@ static void parse(ojParser p, const byte *json) {
|
|
890
851
|
}
|
891
852
|
buf_append_string(&p->buf, (const char *)start, b - start);
|
892
853
|
b--;
|
893
|
-
|
854
|
+
break;
|
894
855
|
case BIG_E:
|
895
856
|
buf_append(&p->buf, *b);
|
896
857
|
p->map = big_exp_sign_map;
|
@@ -929,13 +890,17 @@ static void parse(ojParser p, const byte *json) {
|
|
929
890
|
buf_append_string(&p->buf, (const char *)start, b - start);
|
930
891
|
}
|
931
892
|
if ('"' == *b) {
|
893
|
+
p->funcs[p->stack[p->depth]].add_str(p);
|
932
894
|
p->map = p->next_map;
|
933
895
|
break;
|
934
896
|
}
|
935
897
|
b--;
|
936
898
|
break;
|
937
899
|
case STR_SLASH: p->map = esc_map; break;
|
938
|
-
case STR_QUOTE:
|
900
|
+
case STR_QUOTE:
|
901
|
+
p->funcs[p->stack[p->depth]].add_str(p);
|
902
|
+
p->map = p->next_map;
|
903
|
+
break;
|
939
904
|
case ESC_U:
|
940
905
|
p->map = u_map;
|
941
906
|
p->ri = 0;
|
@@ -1177,13 +1142,42 @@ extern void oj_set_parser_saj(ojParser p);
|
|
1177
1142
|
extern void oj_set_parser_usual(ojParser p);
|
1178
1143
|
extern void oj_set_parser_debug(ojParser p);
|
1179
1144
|
|
1145
|
+
static int opt_cb(VALUE rkey, VALUE value, VALUE ptr) {
|
1146
|
+
ojParser p = (ojParser)ptr;
|
1147
|
+
const char *key = NULL;
|
1148
|
+
char set_key[64];
|
1149
|
+
long klen;
|
1150
|
+
|
1151
|
+
switch (rb_type(rkey)) {
|
1152
|
+
case RUBY_T_SYMBOL:
|
1153
|
+
rkey = rb_sym2str(rkey);
|
1154
|
+
// fall through
|
1155
|
+
case RUBY_T_STRING:
|
1156
|
+
key = rb_string_value_ptr(&rkey);
|
1157
|
+
klen = RSTRING_LEN(rkey);
|
1158
|
+
break;
|
1159
|
+
default: rb_raise(rb_eArgError, "option keys must be a symbol or string");
|
1160
|
+
}
|
1161
|
+
if ((long)sizeof(set_key) - 1 <= klen) {
|
1162
|
+
return ST_CONTINUE;
|
1163
|
+
}
|
1164
|
+
memcpy(set_key, key, klen);
|
1165
|
+
set_key[klen] = '=';
|
1166
|
+
set_key[klen + 1] = '\0';
|
1167
|
+
p->option(p, set_key, value);
|
1168
|
+
|
1169
|
+
return ST_CONTINUE;
|
1170
|
+
}
|
1171
|
+
|
1180
1172
|
/* Document-method: new
|
1181
1173
|
* call-seq: new(mode=nil)
|
1182
1174
|
*
|
1183
1175
|
* Creates a new Parser with the specified mode. If no mode is provided
|
1184
|
-
* validation is assumed.
|
1176
|
+
* validation is assumed. Optional arguments can be provided that match the
|
1177
|
+
* mode. For example with the :usual mode the call might look like
|
1178
|
+
* Oj::Parser.new(:usual, cache_keys: true).
|
1185
1179
|
*/
|
1186
|
-
static VALUE parser_new(VALUE
|
1180
|
+
static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
|
1187
1181
|
ojParser p = ALLOC(struct _ojParser);
|
1188
1182
|
|
1189
1183
|
#if HAVE_RB_EXT_RACTOR_SAFE
|
@@ -1193,34 +1187,45 @@ static VALUE parser_new(VALUE self, VALUE mode) {
|
|
1193
1187
|
memset(p, 0, sizeof(struct _ojParser));
|
1194
1188
|
buf_init(&p->key);
|
1195
1189
|
buf_init(&p->buf);
|
1196
|
-
|
1197
1190
|
p->map = value_map;
|
1198
|
-
|
1199
|
-
|
1191
|
+
|
1192
|
+
if (argc < 1) {
|
1193
|
+
oj_set_parser_validator(p);
|
1200
1194
|
} else {
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
case RUBY_T_SYMBOL:
|
1205
|
-
mode = rb_sym2str(mode);
|
1206
|
-
// fall through
|
1207
|
-
case RUBY_T_STRING: ms = RSTRING_PTR(mode); break;
|
1208
|
-
default:
|
1209
|
-
rb_raise(rb_eArgError, "mode must be :validate, :usual, :saj, or :object");
|
1210
|
-
}
|
1211
|
-
if (0 == strcmp("usual", ms) || 0 == strcmp("standard", ms) || 0 == strcmp("strict", ms) ||
|
1212
|
-
0 == strcmp("compat", ms)) {
|
1213
|
-
oj_set_parser_usual(p);
|
1214
|
-
} else if (0 == strcmp("object", ms)) {
|
1215
|
-
// TBD
|
1216
|
-
} else if (0 == strcmp("saj", ms)) {
|
1217
|
-
oj_set_parser_saj(p);
|
1218
|
-
} else if (0 == strcmp("validate", ms)) {
|
1195
|
+
VALUE mode = argv[0];
|
1196
|
+
|
1197
|
+
if (Qnil == mode) {
|
1219
1198
|
oj_set_parser_validator(p);
|
1220
|
-
} else if (0 == strcmp("debug", ms)) {
|
1221
|
-
oj_set_parser_debug(p);
|
1222
1199
|
} else {
|
1223
|
-
|
1200
|
+
const char *ms = NULL;
|
1201
|
+
|
1202
|
+
switch (rb_type(mode)) {
|
1203
|
+
case RUBY_T_SYMBOL:
|
1204
|
+
mode = rb_sym2str(mode);
|
1205
|
+
// fall through
|
1206
|
+
case RUBY_T_STRING: ms = RSTRING_PTR(mode); break;
|
1207
|
+
default: rb_raise(rb_eArgError, "mode must be :validate, :usual, :saj, or :object");
|
1208
|
+
}
|
1209
|
+
if (0 == strcmp("usual", ms) || 0 == strcmp("standard", ms) || 0 == strcmp("strict", ms) ||
|
1210
|
+
0 == strcmp("compat", ms)) {
|
1211
|
+
oj_set_parser_usual(p);
|
1212
|
+
} else if (0 == strcmp("object", ms)) {
|
1213
|
+
// TBD
|
1214
|
+
} else if (0 == strcmp("saj", ms)) {
|
1215
|
+
oj_set_parser_saj(p);
|
1216
|
+
} else if (0 == strcmp("validate", ms)) {
|
1217
|
+
oj_set_parser_validator(p);
|
1218
|
+
} else if (0 == strcmp("debug", ms)) {
|
1219
|
+
oj_set_parser_debug(p);
|
1220
|
+
} else {
|
1221
|
+
rb_raise(rb_eArgError, "mode must be :validate, :usual, :saj, or :object");
|
1222
|
+
}
|
1223
|
+
}
|
1224
|
+
if (1 < argc) {
|
1225
|
+
VALUE ropts = argv[1];
|
1226
|
+
|
1227
|
+
Check_Type(ropts, T_HASH);
|
1228
|
+
rb_hash_foreach(ropts, opt_cb, (VALUE)p);
|
1224
1229
|
}
|
1225
1230
|
}
|
1226
1231
|
return Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
|
@@ -1238,7 +1243,8 @@ static VALUE parser_new(VALUE self, VALUE mode) {
|
|
1238
1243
|
* - *:saj*
|
1239
1244
|
* - _cache_keys=_ sets the value of the _cache_keys_ flag.
|
1240
1245
|
* - _cache_keys_ returns the value of the _cache_keys_ flag.
|
1241
|
-
* - _cache_strings=_ sets the value of the _cache_strings_ to an positive integer less than 35. Strings shorter than
|
1246
|
+
* - _cache_strings=_ sets the value of the _cache_strings_ to an positive integer less than 35. Strings shorter than
|
1247
|
+
* that length are cached.
|
1242
1248
|
* - _cache_strings_ returns the value of the _cache_strings_ integer value.
|
1243
1249
|
* - _handler=_ sets the SAJ handler
|
1244
1250
|
* - _handler_ returns the SAJ handler
|
@@ -1246,19 +1252,32 @@ static VALUE parser_new(VALUE self, VALUE mode) {
|
|
1246
1252
|
* - *:usual*
|
1247
1253
|
* - _cache_keys=_ sets the value of the _cache_keys_ flag.
|
1248
1254
|
* - _cache_keys_ returns the value of the _cache_keys_ flag.
|
1249
|
-
* - _cache_strings=_ sets the value of the _cache_strings_ to
|
1255
|
+
* - _cache_strings=_ sets the value of the _cache_strings_ to a positive integer less than 35. Strings shorter than
|
1256
|
+
* that length are cached.
|
1250
1257
|
* - _cache_strings_ returns the value of the _cache_strings_ integer value.
|
1251
|
-
* -
|
1258
|
+
* - _cache_expunge=_ sets the value of the _cache_expunge_ where 0 never expunges, 1 expunges slowly, 2 expunges
|
1259
|
+
* faster, and 3 or higher expunges agressively.
|
1260
|
+
* - _cache_expunge_ returns the value of the _cache_expunge_ integer value.
|
1261
|
+
* - _capacity=_ sets the capacity of the parser. The parser grows automatically but can be updated directly with this
|
1262
|
+
* call.
|
1252
1263
|
* - _capacity_ returns the current capacity of the parser's internal stack.
|
1253
1264
|
* - _create_id_ returns the value _create_id_ or _nil_ if there is no _create_id_.
|
1254
|
-
* - _create_id=_ sets the value _create_id_ or if _nil_ unsets it. Parsed JSON objects that include the specified
|
1255
|
-
*
|
1256
|
-
* -
|
1265
|
+
* - _create_id=_ sets the value _create_id_ or if _nil_ unsets it. Parsed JSON objects that include the specified
|
1266
|
+
* element use the element value as the name of the class to create an object from instead of a Hash.
|
1267
|
+
* - _decimal=_ sets the approach to how decimals are parser. If _:auto_ then the decimals with significant digits are
|
1268
|
+
* 16 or less are Floats and long ones are BigDecimal. _:ruby_ uses a call to Ruby to convert a string to a Float.
|
1269
|
+
* _:float_ always generates a Float. _:bigdecimal_ always results in a BigDecimal.
|
1270
|
+
* - _decimal_ returns the value of the decimal conversion option which can be :auto (default), :ruby, :float, or
|
1271
|
+
* :bigdecimal.
|
1257
1272
|
* - _ignore_json_create_ returns the value of the _ignore_json_create_ flag.
|
1258
|
-
* - _ignore_json_create=_ sets the value of the _ignore_json_create_ flag. When set the class json_create method is
|
1273
|
+
* - _ignore_json_create=_ sets the value of the _ignore_json_create_ flag. When set the class json_create method is
|
1274
|
+
* ignored on parsing in favor of creating an instance and populating directly.
|
1259
1275
|
* - _missing_class_ return the value of the _missing_class_ indicator.
|
1260
|
-
* - _missing_class=_ sets the value of the _missing_class_ flag. Valid values are _:auto_ which creates any missing
|
1261
|
-
*
|
1276
|
+
* - _missing_class=_ sets the value of the _missing_class_ flag. Valid values are _:auto_ which creates any missing
|
1277
|
+
* classes on parse, :ignore which ignores and continues as a Hash (default), and :raise which raises an exception if
|
1278
|
+
* the class is not found.
|
1279
|
+
* - _omit_null=_ sets the _omit_null_ flag. If true then null values in a map or object are omitted from the
|
1280
|
+
* resulting Hash or Object.
|
1262
1281
|
* - _omit_null_ returns the value of the _omit_null_ flag.
|
1263
1282
|
* - _symbol_keys=_ sets the flag that indicates Hash keys should be parsed to Symbols versus Strings.
|
1264
1283
|
* - _symbol_keys_ returns the value of the _symbol_keys_ flag.
|
@@ -1427,15 +1446,15 @@ static VALUE usual_parser = Qundef;
|
|
1427
1446
|
*/
|
1428
1447
|
static VALUE parser_usual(VALUE self) {
|
1429
1448
|
if (Qundef == usual_parser) {
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1449
|
+
ojParser p = ALLOC(struct _ojParser);
|
1450
|
+
|
1451
|
+
memset(p, 0, sizeof(struct _ojParser));
|
1452
|
+
buf_init(&p->key);
|
1453
|
+
buf_init(&p->buf);
|
1454
|
+
p->map = value_map;
|
1455
|
+
oj_set_parser_usual(p);
|
1456
|
+
usual_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
|
1457
|
+
rb_gc_register_address(&usual_parser);
|
1439
1458
|
}
|
1440
1459
|
return usual_parser;
|
1441
1460
|
}
|
@@ -1450,15 +1469,15 @@ static VALUE saj_parser = Qundef;
|
|
1450
1469
|
*/
|
1451
1470
|
static VALUE parser_saj(VALUE self) {
|
1452
1471
|
if (Qundef == saj_parser) {
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1472
|
+
ojParser p = ALLOC(struct _ojParser);
|
1473
|
+
|
1474
|
+
memset(p, 0, sizeof(struct _ojParser));
|
1475
|
+
buf_init(&p->key);
|
1476
|
+
buf_init(&p->buf);
|
1477
|
+
p->map = value_map;
|
1478
|
+
oj_set_parser_saj(p);
|
1479
|
+
saj_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
|
1480
|
+
rb_gc_register_address(&saj_parser);
|
1462
1481
|
}
|
1463
1482
|
return saj_parser;
|
1464
1483
|
}
|
@@ -1472,15 +1491,15 @@ static VALUE validate_parser = Qundef;
|
|
1472
1491
|
*/
|
1473
1492
|
static VALUE parser_validate(VALUE self) {
|
1474
1493
|
if (Qundef == validate_parser) {
|
1475
|
-
|
1494
|
+
ojParser p = ALLOC(struct _ojParser);
|
1476
1495
|
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1496
|
+
memset(p, 0, sizeof(struct _ojParser));
|
1497
|
+
buf_init(&p->key);
|
1498
|
+
buf_init(&p->buf);
|
1499
|
+
p->map = value_map;
|
1500
|
+
oj_set_parser_validator(p);
|
1501
|
+
validate_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
|
1502
|
+
rb_gc_register_address(&validate_parser);
|
1484
1503
|
}
|
1485
1504
|
return validate_parser;
|
1486
1505
|
}
|
@@ -1498,7 +1517,7 @@ static VALUE parser_validate(VALUE self) {
|
|
1498
1517
|
*/
|
1499
1518
|
void oj_parser_init() {
|
1500
1519
|
parser_class = rb_define_class_under(Oj, "Parser", rb_cObject);
|
1501
|
-
rb_define_module_function(parser_class, "new", parser_new, 1);
|
1520
|
+
rb_define_module_function(parser_class, "new", parser_new, -1);
|
1502
1521
|
rb_define_method(parser_class, "parse", parser_parse, 1);
|
1503
1522
|
rb_define_method(parser_class, "load", parser_load, 1);
|
1504
1523
|
rb_define_method(parser_class, "file", parser_file, 1);
|