oj 3.13.2 → 3.13.6
Sign up to get free protection for your applications and to get access to all the features.
- 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);
|