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.
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);