oj 3.13.2 → 3.13.6

Sign up to get free protection for your applications and to get access to all the features.
data/ext/oj/intern.h CHANGED
@@ -21,7 +21,6 @@ extern VALUE oj_class_intern(const char * key,
21
21
  int auto_define,
22
22
  VALUE error_class);
23
23
 
24
- extern void oj_hash_print();
25
24
  extern char *oj_strndup(const char *s, size_t len);
26
25
 
27
26
  #endif /* OJ_INTERN_H */
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 oj_encode(rb_str_new_cstr(oj_default_options.create_id));
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
- 3, // cache_str
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
- if (Qnil == (rkey = oj_sym_hash_get(kval->key + 1, kval->klen - 1, &slot))) {
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
- #else
61
- if (':' == k1) {
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
- #endif
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
- rstr = rb_str_new(str, len);
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
- parent->val = rb_str_new(str, len);
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
- 3, // cache_str
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 vsalue length to cache
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] = {1.0L, 1.0e1L, 1.0e2L, 1.0e3L, 1.0e4L,
388
- 1.0e5L, 1.0e6L, 1.0e7L, 1.0e8L, 1.0e9L, // 00
389
- 1.0e10L, 1.0e11L, 1.0e12L, 1.0e13L, 1.0e14L,
390
- 1.0e15L, 1.0e16L, 1.0e17L, 1.0e18L, 1.0e19L, // 10
391
- 1.0e20L, 1.0e21L, 1.0e22L, 1.0e23L, 1.0e24L,
392
- 1.0e25L, 1.0e26L, 1.0e27L, 1.0e28L, 1.0e29L, // 20
393
- 1.0e30L, 1.0e31L, 1.0e32L, 1.0e33L, 1.0e34L,
394
- 1.0e35L, 1.0e36L, 1.0e37L, 1.0e38L, 1.0e39L, // 30
395
- 1.0e40L, 1.0e41L, 1.0e42L, 1.0e43L, 1.0e44L,
396
- 1.0e45L, 1.0e46L, 1.0e47L, 1.0e48L, 1.0e49L, // 40
397
- 1.0e50L, 1.0e51L, 1.0e52L, 1.0e53L, 1.0e54L,
398
- 1.0e55L, 1.0e56L, 1.0e57L, 1.0e58L, 1.0e59L, // 50
399
- 1.0e60L, 1.0e61L, 1.0e62L, 1.0e63L, 1.0e64L,
400
- 1.0e65L, 1.0e66L, 1.0e67L, 1.0e68L, 1.0e69L, // 60
401
- 1.0e70L, 1.0e71L, 1.0e72L, 1.0e73L, 1.0e74L,
402
- 1.0e75L, 1.0e76L, 1.0e77L, 1.0e78L, 1.0e79L, // 70
403
- 1.0e80L, 1.0e81L, 1.0e82L, 1.0e83L, 1.0e84L,
404
- 1.0e85L, 1.0e86L, 1.0e87L, 1.0e88L, 1.0e89L, // 80
405
- 1.0e90L, 1.0e91L, 1.0e92L, 1.0e93L, 1.0e94L,
406
- 1.0e95L, 1.0e96L, 1.0e97L, 1.0e98L, 1.0e99L, // 90
407
- 1.0e100L, 1.0e101L, 1.0e102L, 1.0e103L, 1.0e104L,
408
- 1.0e105L, 1.0e106L, 1.0e107L, 1.0e108L, 1.0e109L, // 100
409
- 1.0e110L, 1.0e111L, 1.0e112L, 1.0e113L, 1.0e114L,
410
- 1.0e115L, 1.0e116L, 1.0e117L, 1.0e118L, 1.0e119L, // 110
411
- 1.0e120L, 1.0e121L, 1.0e122L, 1.0e123L, 1.0e124L,
412
- 1.0e125L, 1.0e126L, 1.0e127L, 1.0e128L, 1.0e129L, // 120
413
- 1.0e130L, 1.0e131L, 1.0e132L, 1.0e133L, 1.0e134L,
414
- 1.0e135L, 1.0e136L, 1.0e137L, 1.0e138L, 1.0e139L, // 130
415
- 1.0e140L, 1.0e141L, 1.0e142L, 1.0e143L, 1.0e144L,
416
- 1.0e145L, 1.0e146L, 1.0e147L, 1.0e148L, 1.0e149L, // 140
417
- 1.0e150L, 1.0e151L, 1.0e152L, 1.0e153L, 1.0e154L,
418
- 1.0e155L, 1.0e156L, 1.0e157L, 1.0e158L, 1.0e159L, // 150
419
- 1.0e160L, 1.0e161L, 1.0e162L, 1.0e163L, 1.0e164L,
420
- 1.0e165L, 1.0e166L, 1.0e167L, 1.0e168L, 1.0e169L, // 160
421
- 1.0e170L, 1.0e171L, 1.0e172L, 1.0e173L, 1.0e174L,
422
- 1.0e175L, 1.0e176L, 1.0e177L, 1.0e178L, 1.0e179L, // 170
423
- 1.0e180L, 1.0e181L, 1.0e182L, 1.0e183L, 1.0e184L,
424
- 1.0e185L, 1.0e186L, 1.0e187L, 1.0e188L, 1.0e189L, // 180
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 = p->buf.head;
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 i;
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
- break;
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: p->map = p->next_map; break;
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 self, VALUE mode) {
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
- if (Qnil == mode) {
1199
- oj_set_parser_validator(p);
1191
+
1192
+ if (argc < 1) {
1193
+ oj_set_parser_validator(p);
1200
1194
  } else {
1201
- const char *ms = NULL;
1202
-
1203
- switch (rb_type(mode)) {
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
- rb_raise(rb_eArgError, "mode must be :validate, :usual, :saj, or :object");
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 that length are cached.
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 an positive integer less than 35. Strings shorter than that length are cached.
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
- * - _capacity=_ sets the capacity of the parser. The parser grows automatically but can be updated directly with this call.
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 element use the element value as the name of the class to create an object from instead of a Hash.
1255
- * - _decimal=_ sets the approach to how decimals are parser. If _:auto_ then the decimals with significant digits are 16 or less are Floats and long ones are BigDecimal. _:ruby_ uses a call to Ruby to convert a string to a Float. _:float_ always generates a Float. _:bigdecimal_ always results in a BigDecimal.
1256
- * - _decimal_ returns the value of the decimal conversion option which can be :auto (default), :ruby, :float, or :bigdecimal.
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 ignored on parsing in favor of creating an instance and populating directly.
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 classes on parse, :ignore which ignores and continues as a Hash (default), and :raise which raises an exception if the class is not found.
1261
- * - _omit_null=_ sets the _omit_null_ flag. If true then null values in a map or object are omitted from the resulting Hash or Object.
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
- ojParser p = ALLOC(struct _ojParser);
1431
-
1432
- memset(p, 0, sizeof(struct _ojParser));
1433
- buf_init(&p->key);
1434
- buf_init(&p->buf);
1435
- p->map = value_map;
1436
- oj_set_parser_usual(p);
1437
- usual_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
1438
- rb_gc_register_address(&usual_parser);
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
- ojParser p = ALLOC(struct _ojParser);
1454
-
1455
- memset(p, 0, sizeof(struct _ojParser));
1456
- buf_init(&p->key);
1457
- buf_init(&p->buf);
1458
- p->map = value_map;
1459
- oj_set_parser_saj(p);
1460
- saj_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
1461
- rb_gc_register_address(&saj_parser);
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
- ojParser p = ALLOC(struct _ojParser);
1494
+ ojParser p = ALLOC(struct _ojParser);
1476
1495
 
1477
- memset(p, 0, sizeof(struct _ojParser));
1478
- buf_init(&p->key);
1479
- buf_init(&p->buf);
1480
- p->map = value_map;
1481
- oj_set_parser_validator(p);
1482
- validate_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
1483
- rb_gc_register_address(&validate_parser);
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);