json 1.8.6 → 2.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +5 -5
  2. data/{CHANGES → CHANGES.md} +292 -96
  3. data/LICENSE +56 -0
  4. data/README.md +185 -114
  5. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  6. data/ext/json/ext/generator/generator.c +328 -117
  7. data/ext/json/ext/generator/generator.h +8 -8
  8. data/ext/json/ext/parser/extconf.rb +29 -0
  9. data/ext/json/ext/parser/parser.c +540 -569
  10. data/ext/json/ext/parser/parser.h +10 -6
  11. data/ext/json/ext/parser/parser.rl +269 -261
  12. data/ext/json/extconf.rb +1 -1
  13. data/json.gemspec +0 -0
  14. data/lib/json/add/bigdecimal.rb +40 -10
  15. data/lib/json/add/complex.rb +32 -9
  16. data/lib/json/add/core.rb +1 -0
  17. data/lib/json/add/date.rb +27 -7
  18. data/lib/json/add/date_time.rb +26 -9
  19. data/lib/json/add/exception.rb +25 -7
  20. data/lib/json/add/ostruct.rb +32 -9
  21. data/lib/json/add/range.rb +33 -8
  22. data/lib/json/add/rational.rb +30 -8
  23. data/lib/json/add/regexp.rb +28 -10
  24. data/lib/json/add/set.rb +48 -0
  25. data/lib/json/add/struct.rb +29 -7
  26. data/lib/json/add/symbol.rb +28 -5
  27. data/lib/json/add/time.rb +27 -6
  28. data/lib/json/common.rb +402 -188
  29. data/lib/json/ext.rb +0 -6
  30. data/lib/json/generic_object.rb +11 -6
  31. data/lib/json/pure/generator.rb +120 -137
  32. data/lib/json/pure/parser.rb +64 -86
  33. data/lib/json/pure.rb +2 -8
  34. data/lib/json/version.rb +2 -1
  35. data/lib/json.rb +559 -29
  36. metadata +18 -129
  37. data/.gitignore +0 -17
  38. data/.travis.yml +0 -18
  39. data/Gemfile +0 -7
  40. data/README-json-jruby.markdown +0 -33
  41. data/Rakefile +0 -402
  42. data/TODO +0 -1
  43. data/VERSION +0 -1
  44. data/data/example.json +0 -1
  45. data/data/index.html +0 -38
  46. data/data/prototype.js +0 -4184
  47. data/diagrams/.keep +0 -0
  48. data/install.rb +0 -23
  49. data/java/src/json/ext/ByteListTranscoder.java +0 -166
  50. data/java/src/json/ext/Generator.java +0 -446
  51. data/java/src/json/ext/GeneratorMethods.java +0 -231
  52. data/java/src/json/ext/GeneratorService.java +0 -42
  53. data/java/src/json/ext/GeneratorState.java +0 -542
  54. data/java/src/json/ext/OptionsReader.java +0 -113
  55. data/java/src/json/ext/Parser.java +0 -2644
  56. data/java/src/json/ext/Parser.rl +0 -968
  57. data/java/src/json/ext/ParserService.java +0 -34
  58. data/java/src/json/ext/RuntimeInfo.java +0 -120
  59. data/java/src/json/ext/StringDecoder.java +0 -166
  60. data/java/src/json/ext/StringEncoder.java +0 -111
  61. data/java/src/json/ext/Utils.java +0 -88
  62. data/json-java.gemspec +0 -38
  63. data/json_pure.gemspec +0 -37
  64. data/lib/json/ext/.keep +0 -0
  65. data/tests/fixtures/fail1.json +0 -1
  66. data/tests/fixtures/fail10.json +0 -1
  67. data/tests/fixtures/fail11.json +0 -1
  68. data/tests/fixtures/fail12.json +0 -1
  69. data/tests/fixtures/fail13.json +0 -1
  70. data/tests/fixtures/fail14.json +0 -1
  71. data/tests/fixtures/fail18.json +0 -1
  72. data/tests/fixtures/fail19.json +0 -1
  73. data/tests/fixtures/fail2.json +0 -1
  74. data/tests/fixtures/fail20.json +0 -1
  75. data/tests/fixtures/fail21.json +0 -1
  76. data/tests/fixtures/fail22.json +0 -1
  77. data/tests/fixtures/fail23.json +0 -1
  78. data/tests/fixtures/fail24.json +0 -1
  79. data/tests/fixtures/fail25.json +0 -1
  80. data/tests/fixtures/fail27.json +0 -2
  81. data/tests/fixtures/fail28.json +0 -2
  82. data/tests/fixtures/fail3.json +0 -1
  83. data/tests/fixtures/fail4.json +0 -1
  84. data/tests/fixtures/fail5.json +0 -1
  85. data/tests/fixtures/fail6.json +0 -1
  86. data/tests/fixtures/fail7.json +0 -1
  87. data/tests/fixtures/fail8.json +0 -1
  88. data/tests/fixtures/fail9.json +0 -1
  89. data/tests/fixtures/pass1.json +0 -56
  90. data/tests/fixtures/pass15.json +0 -1
  91. data/tests/fixtures/pass16.json +0 -1
  92. data/tests/fixtures/pass17.json +0 -1
  93. data/tests/fixtures/pass2.json +0 -1
  94. data/tests/fixtures/pass26.json +0 -1
  95. data/tests/fixtures/pass3.json +0 -6
  96. data/tests/setup_variant.rb +0 -11
  97. data/tests/test_json.rb +0 -519
  98. data/tests/test_json_addition.rb +0 -196
  99. data/tests/test_json_encoding.rb +0 -65
  100. data/tests/test_json_fixtures.rb +0 -35
  101. data/tests/test_json_generate.rb +0 -348
  102. data/tests/test_json_generic_object.rb +0 -75
  103. data/tests/test_json_string_matching.rb +0 -39
  104. data/tests/test_json_unicode.rb +0 -72
  105. data/tools/diff.sh +0 -18
  106. data/tools/fuzz.rb +0 -139
  107. data/tools/server.rb +0 -62
@@ -1,10 +1,10 @@
1
-
1
+ /* This file is automatically generated from parser.rl by using ragel */
2
2
  #line 1 "parser.rl"
3
3
  #include "../fbuffer/fbuffer.h"
4
4
  #include "parser.h"
5
5
 
6
6
  #if defined HAVE_RUBY_ENCODING_H
7
- # define EXC_ENCODING UTF_8,
7
+ # define EXC_ENCODING rb_utf8_encoding(),
8
8
  # ifndef HAVE_RB_ENC_RAISE
9
9
  static void
10
10
  enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
@@ -27,7 +27,7 @@ enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
27
27
 
28
28
  /* unicode */
29
29
 
30
- static const char digit_values[256] = {
30
+ static const signed char digit_values[256] = {
31
31
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
32
32
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
33
33
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
@@ -46,7 +46,7 @@ static const char digit_values[256] = {
46
46
 
47
47
  static UTF32 unescape_unicode(const unsigned char *p)
48
48
  {
49
- char b;
49
+ signed char b;
50
50
  UTF32 result = 0;
51
51
  b = digit_values[p[0]];
52
52
  if (b < 0) return UNI_REPLACEMENT_CHAR;
@@ -89,57 +89,52 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
89
89
  return len;
90
90
  }
91
91
 
92
- #ifdef HAVE_RUBY_ENCODING_H
93
- static rb_encoding *UTF_8, *UTF_16BE, *UTF_16LE, *UTF_32BE, *UTF_32LE;
94
- #else
95
- static ID i_iconv;
96
- #endif
97
-
98
92
  static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
99
93
  static VALUE CNaN, CInfinity, CMinusInfinity;
100
94
 
101
95
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
102
- i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
103
- i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
104
- i_match_string, i_aset, i_aref, i_leftshift;
96
+ i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
97
+ i_object_class, i_array_class, i_decimal_class, i_key_p,
98
+ i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
99
+ i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
105
100
 
106
101
 
107
- #line 130 "parser.rl"
102
+ #line 125 "parser.rl"
108
103
 
109
104
 
110
105
 
111
- #line 112 "parser.c"
112
- static const int JSON_object_start = 1;
113
- static const int JSON_object_first_final = 27;
114
- static const int JSON_object_error = 0;
106
+ #line 107 "parser.c"
107
+ enum {JSON_object_start = 1};
108
+ enum {JSON_object_first_final = 27};
109
+ enum {JSON_object_error = 0};
115
110
 
116
- static const int JSON_object_en_main = 1;
111
+ enum {JSON_object_en_main = 1};
117
112
 
118
113
 
119
- #line 171 "parser.rl"
114
+ #line 167 "parser.rl"
120
115
 
121
116
 
122
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
117
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
123
118
  {
124
119
  int cs = EVIL;
125
120
  VALUE last_name = Qnil;
126
121
  VALUE object_class = json->object_class;
127
122
 
128
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
129
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
123
+ if (json->max_nesting && current_nesting > json->max_nesting) {
124
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
130
125
  }
131
126
 
132
127
  *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
133
128
 
134
129
 
135
- #line 136 "parser.c"
130
+ #line 131 "parser.c"
136
131
  {
137
132
  cs = JSON_object_start;
138
133
  }
139
134
 
140
- #line 186 "parser.rl"
135
+ #line 182 "parser.rl"
141
136
 
142
- #line 143 "parser.c"
137
+ #line 138 "parser.c"
143
138
  {
144
139
  if ( p == pe )
145
140
  goto _test_eof;
@@ -167,7 +162,7 @@ case 2:
167
162
  goto st2;
168
163
  goto st0;
169
164
  tr2:
170
- #line 153 "parser.rl"
165
+ #line 149 "parser.rl"
171
166
  {
172
167
  char *np;
173
168
  json->parsing_name = 1;
@@ -180,7 +175,7 @@ st3:
180
175
  if ( ++p == pe )
181
176
  goto _test_eof3;
182
177
  case 3:
183
- #line 184 "parser.c"
178
+ #line 179 "parser.c"
184
179
  switch( (*p) ) {
185
180
  case 13: goto st3;
186
181
  case 32: goto st3;
@@ -247,14 +242,15 @@ case 8:
247
242
  goto st8;
248
243
  goto st0;
249
244
  tr11:
250
- #line 138 "parser.rl"
245
+ #line 133 "parser.rl"
251
246
  {
252
247
  VALUE v = Qnil;
253
- char *np = JSON_parse_value(json, p, pe, &v);
248
+ char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
254
249
  if (np == NULL) {
255
250
  p--; {p++; cs = 9; goto _out;}
256
251
  } else {
257
252
  if (NIL_P(json->object_class)) {
253
+ OBJ_FREEZE(last_name);
258
254
  rb_hash_aset(*result, last_name, v);
259
255
  } else {
260
256
  rb_funcall(*result, i_aset, 2, last_name, v);
@@ -267,7 +263,7 @@ st9:
267
263
  if ( ++p == pe )
268
264
  goto _test_eof9;
269
265
  case 9:
270
- #line 271 "parser.c"
266
+ #line 267 "parser.c"
271
267
  switch( (*p) ) {
272
268
  case 13: goto st9;
273
269
  case 32: goto st9;
@@ -356,14 +352,14 @@ case 18:
356
352
  goto st9;
357
353
  goto st18;
358
354
  tr4:
359
- #line 161 "parser.rl"
355
+ #line 157 "parser.rl"
360
356
  { p--; {p++; cs = 27; goto _out;} }
361
357
  goto st27;
362
358
  st27:
363
359
  if ( ++p == pe )
364
360
  goto _test_eof27;
365
361
  case 27:
366
- #line 367 "parser.c"
362
+ #line 363 "parser.c"
367
363
  goto st0;
368
364
  st19:
369
365
  if ( ++p == pe )
@@ -461,7 +457,7 @@ case 26:
461
457
  _out: {}
462
458
  }
463
459
 
464
- #line 187 "parser.rl"
460
+ #line 183 "parser.rl"
465
461
 
466
462
  if (cs >= JSON_object_first_final) {
467
463
  if (json->create_additions) {
@@ -486,281 +482,358 @@ case 26:
486
482
 
487
483
 
488
484
 
489
- #line 490 "parser.c"
490
- static const int JSON_value_start = 1;
491
- static const int JSON_value_first_final = 21;
492
- static const int JSON_value_error = 0;
485
+ #line 486 "parser.c"
486
+ enum {JSON_value_start = 1};
487
+ enum {JSON_value_first_final = 29};
488
+ enum {JSON_value_error = 0};
493
489
 
494
- static const int JSON_value_en_main = 1;
490
+ enum {JSON_value_en_main = 1};
495
491
 
496
492
 
497
- #line 291 "parser.rl"
493
+ #line 283 "parser.rl"
498
494
 
499
495
 
500
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
496
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
501
497
  {
502
498
  int cs = EVIL;
503
499
 
504
500
 
505
- #line 506 "parser.c"
501
+ #line 502 "parser.c"
506
502
  {
507
503
  cs = JSON_value_start;
508
504
  }
509
505
 
510
- #line 298 "parser.rl"
506
+ #line 290 "parser.rl"
511
507
 
512
- #line 513 "parser.c"
508
+ #line 509 "parser.c"
513
509
  {
514
510
  if ( p == pe )
515
511
  goto _test_eof;
516
512
  switch ( cs )
517
513
  {
514
+ st1:
515
+ if ( ++p == pe )
516
+ goto _test_eof1;
518
517
  case 1:
519
518
  switch( (*p) ) {
520
- case 34: goto tr0;
521
- case 45: goto tr2;
522
- case 73: goto st2;
523
- case 78: goto st9;
524
- case 91: goto tr5;
525
- case 102: goto st11;
526
- case 110: goto st15;
527
- case 116: goto st18;
528
- case 123: goto tr9;
519
+ case 13: goto st1;
520
+ case 32: goto st1;
521
+ case 34: goto tr2;
522
+ case 45: goto tr3;
523
+ case 47: goto st6;
524
+ case 73: goto st10;
525
+ case 78: goto st17;
526
+ case 91: goto tr7;
527
+ case 102: goto st19;
528
+ case 110: goto st23;
529
+ case 116: goto st26;
530
+ case 123: goto tr11;
529
531
  }
530
- if ( 48 <= (*p) && (*p) <= 57 )
531
- goto tr2;
532
+ if ( (*p) > 10 ) {
533
+ if ( 48 <= (*p) && (*p) <= 57 )
534
+ goto tr3;
535
+ } else if ( (*p) >= 9 )
536
+ goto st1;
532
537
  goto st0;
533
538
  st0:
534
539
  cs = 0;
535
540
  goto _out;
536
- tr0:
537
- #line 239 "parser.rl"
541
+ tr2:
542
+ #line 235 "parser.rl"
538
543
  {
539
544
  char *np = JSON_parse_string(json, p, pe, result);
540
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
545
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
541
546
  }
542
- goto st21;
543
- tr2:
544
- #line 244 "parser.rl"
547
+ goto st29;
548
+ tr3:
549
+ #line 240 "parser.rl"
545
550
  {
546
551
  char *np;
547
- if(pe > p + 9 - json->quirks_mode && !strncmp(MinusInfinity, p, 9)) {
552
+ if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
548
553
  if (json->allow_nan) {
549
554
  *result = CMinusInfinity;
550
555
  {p = (( p + 10))-1;}
551
- p--; {p++; cs = 21; goto _out;}
556
+ p--; {p++; cs = 29; goto _out;}
552
557
  } else {
553
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
558
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
554
559
  }
555
560
  }
556
561
  np = JSON_parse_float(json, p, pe, result);
557
562
  if (np != NULL) {p = (( np))-1;}
558
563
  np = JSON_parse_integer(json, p, pe, result);
559
564
  if (np != NULL) {p = (( np))-1;}
560
- p--; {p++; cs = 21; goto _out;}
565
+ p--; {p++; cs = 29; goto _out;}
561
566
  }
562
- goto st21;
563
- tr5:
564
- #line 262 "parser.rl"
567
+ goto st29;
568
+ tr7:
569
+ #line 258 "parser.rl"
565
570
  {
566
571
  char *np;
567
- json->current_nesting++;
568
- np = JSON_parse_array(json, p, pe, result);
569
- json->current_nesting--;
570
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
572
+ np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
573
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
571
574
  }
572
- goto st21;
573
- tr9:
574
- #line 270 "parser.rl"
575
+ goto st29;
576
+ tr11:
577
+ #line 264 "parser.rl"
575
578
  {
576
579
  char *np;
577
- json->current_nesting++;
578
- np = JSON_parse_object(json, p, pe, result);
579
- json->current_nesting--;
580
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
580
+ np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
581
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
581
582
  }
582
- goto st21;
583
- tr16:
584
- #line 232 "parser.rl"
583
+ goto st29;
584
+ tr25:
585
+ #line 228 "parser.rl"
585
586
  {
586
587
  if (json->allow_nan) {
587
588
  *result = CInfinity;
588
589
  } else {
589
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
590
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 7);
590
591
  }
591
592
  }
592
- goto st21;
593
- tr18:
594
- #line 225 "parser.rl"
593
+ goto st29;
594
+ tr27:
595
+ #line 221 "parser.rl"
595
596
  {
596
597
  if (json->allow_nan) {
597
598
  *result = CNaN;
598
599
  } else {
599
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
600
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 2);
600
601
  }
601
602
  }
602
- goto st21;
603
- tr22:
604
- #line 219 "parser.rl"
603
+ goto st29;
604
+ tr31:
605
+ #line 215 "parser.rl"
605
606
  {
606
607
  *result = Qfalse;
607
608
  }
608
- goto st21;
609
- tr25:
610
- #line 216 "parser.rl"
609
+ goto st29;
610
+ tr34:
611
+ #line 212 "parser.rl"
611
612
  {
612
613
  *result = Qnil;
613
614
  }
614
- goto st21;
615
- tr28:
616
- #line 222 "parser.rl"
615
+ goto st29;
616
+ tr37:
617
+ #line 218 "parser.rl"
617
618
  {
618
619
  *result = Qtrue;
619
620
  }
620
- goto st21;
621
- st21:
621
+ goto st29;
622
+ st29:
622
623
  if ( ++p == pe )
623
- goto _test_eof21;
624
- case 21:
625
- #line 278 "parser.rl"
626
- { p--; {p++; cs = 21; goto _out;} }
627
- #line 628 "parser.c"
624
+ goto _test_eof29;
625
+ case 29:
626
+ #line 270 "parser.rl"
627
+ { p--; {p++; cs = 29; goto _out;} }
628
+ #line 629 "parser.c"
629
+ switch( (*p) ) {
630
+ case 13: goto st29;
631
+ case 32: goto st29;
632
+ case 47: goto st2;
633
+ }
634
+ if ( 9 <= (*p) && (*p) <= 10 )
635
+ goto st29;
628
636
  goto st0;
629
637
  st2:
630
638
  if ( ++p == pe )
631
639
  goto _test_eof2;
632
640
  case 2:
633
- if ( (*p) == 110 )
634
- goto st3;
641
+ switch( (*p) ) {
642
+ case 42: goto st3;
643
+ case 47: goto st5;
644
+ }
635
645
  goto st0;
636
646
  st3:
637
647
  if ( ++p == pe )
638
648
  goto _test_eof3;
639
649
  case 3:
640
- if ( (*p) == 102 )
650
+ if ( (*p) == 42 )
641
651
  goto st4;
642
- goto st0;
652
+ goto st3;
643
653
  st4:
644
654
  if ( ++p == pe )
645
655
  goto _test_eof4;
646
656
  case 4:
647
- if ( (*p) == 105 )
648
- goto st5;
649
- goto st0;
657
+ switch( (*p) ) {
658
+ case 42: goto st4;
659
+ case 47: goto st29;
660
+ }
661
+ goto st3;
650
662
  st5:
651
663
  if ( ++p == pe )
652
664
  goto _test_eof5;
653
665
  case 5:
654
- if ( (*p) == 110 )
655
- goto st6;
656
- goto st0;
666
+ if ( (*p) == 10 )
667
+ goto st29;
668
+ goto st5;
657
669
  st6:
658
670
  if ( ++p == pe )
659
671
  goto _test_eof6;
660
672
  case 6:
661
- if ( (*p) == 105 )
662
- goto st7;
673
+ switch( (*p) ) {
674
+ case 42: goto st7;
675
+ case 47: goto st9;
676
+ }
663
677
  goto st0;
664
678
  st7:
665
679
  if ( ++p == pe )
666
680
  goto _test_eof7;
667
681
  case 7:
668
- if ( (*p) == 116 )
682
+ if ( (*p) == 42 )
669
683
  goto st8;
670
- goto st0;
684
+ goto st7;
671
685
  st8:
672
686
  if ( ++p == pe )
673
687
  goto _test_eof8;
674
688
  case 8:
675
- if ( (*p) == 121 )
676
- goto tr16;
677
- goto st0;
689
+ switch( (*p) ) {
690
+ case 42: goto st8;
691
+ case 47: goto st1;
692
+ }
693
+ goto st7;
678
694
  st9:
679
695
  if ( ++p == pe )
680
696
  goto _test_eof9;
681
697
  case 9:
682
- if ( (*p) == 97 )
683
- goto st10;
684
- goto st0;
698
+ if ( (*p) == 10 )
699
+ goto st1;
700
+ goto st9;
685
701
  st10:
686
702
  if ( ++p == pe )
687
703
  goto _test_eof10;
688
704
  case 10:
689
- if ( (*p) == 78 )
690
- goto tr18;
705
+ if ( (*p) == 110 )
706
+ goto st11;
691
707
  goto st0;
692
708
  st11:
693
709
  if ( ++p == pe )
694
710
  goto _test_eof11;
695
711
  case 11:
696
- if ( (*p) == 97 )
712
+ if ( (*p) == 102 )
697
713
  goto st12;
698
714
  goto st0;
699
715
  st12:
700
716
  if ( ++p == pe )
701
717
  goto _test_eof12;
702
718
  case 12:
703
- if ( (*p) == 108 )
719
+ if ( (*p) == 105 )
704
720
  goto st13;
705
721
  goto st0;
706
722
  st13:
707
723
  if ( ++p == pe )
708
724
  goto _test_eof13;
709
725
  case 13:
710
- if ( (*p) == 115 )
726
+ if ( (*p) == 110 )
711
727
  goto st14;
712
728
  goto st0;
713
729
  st14:
714
730
  if ( ++p == pe )
715
731
  goto _test_eof14;
716
732
  case 14:
717
- if ( (*p) == 101 )
718
- goto tr22;
733
+ if ( (*p) == 105 )
734
+ goto st15;
719
735
  goto st0;
720
736
  st15:
721
737
  if ( ++p == pe )
722
738
  goto _test_eof15;
723
739
  case 15:
724
- if ( (*p) == 117 )
740
+ if ( (*p) == 116 )
725
741
  goto st16;
726
742
  goto st0;
727
743
  st16:
728
744
  if ( ++p == pe )
729
745
  goto _test_eof16;
730
746
  case 16:
731
- if ( (*p) == 108 )
732
- goto st17;
747
+ if ( (*p) == 121 )
748
+ goto tr25;
733
749
  goto st0;
734
750
  st17:
735
751
  if ( ++p == pe )
736
752
  goto _test_eof17;
737
753
  case 17:
738
- if ( (*p) == 108 )
739
- goto tr25;
754
+ if ( (*p) == 97 )
755
+ goto st18;
740
756
  goto st0;
741
757
  st18:
742
758
  if ( ++p == pe )
743
759
  goto _test_eof18;
744
760
  case 18:
745
- if ( (*p) == 114 )
746
- goto st19;
761
+ if ( (*p) == 78 )
762
+ goto tr27;
747
763
  goto st0;
748
764
  st19:
749
765
  if ( ++p == pe )
750
766
  goto _test_eof19;
751
767
  case 19:
752
- if ( (*p) == 117 )
768
+ if ( (*p) == 97 )
753
769
  goto st20;
754
770
  goto st0;
755
771
  st20:
756
772
  if ( ++p == pe )
757
773
  goto _test_eof20;
758
774
  case 20:
775
+ if ( (*p) == 108 )
776
+ goto st21;
777
+ goto st0;
778
+ st21:
779
+ if ( ++p == pe )
780
+ goto _test_eof21;
781
+ case 21:
782
+ if ( (*p) == 115 )
783
+ goto st22;
784
+ goto st0;
785
+ st22:
786
+ if ( ++p == pe )
787
+ goto _test_eof22;
788
+ case 22:
789
+ if ( (*p) == 101 )
790
+ goto tr31;
791
+ goto st0;
792
+ st23:
793
+ if ( ++p == pe )
794
+ goto _test_eof23;
795
+ case 23:
796
+ if ( (*p) == 117 )
797
+ goto st24;
798
+ goto st0;
799
+ st24:
800
+ if ( ++p == pe )
801
+ goto _test_eof24;
802
+ case 24:
803
+ if ( (*p) == 108 )
804
+ goto st25;
805
+ goto st0;
806
+ st25:
807
+ if ( ++p == pe )
808
+ goto _test_eof25;
809
+ case 25:
810
+ if ( (*p) == 108 )
811
+ goto tr34;
812
+ goto st0;
813
+ st26:
814
+ if ( ++p == pe )
815
+ goto _test_eof26;
816
+ case 26:
817
+ if ( (*p) == 114 )
818
+ goto st27;
819
+ goto st0;
820
+ st27:
821
+ if ( ++p == pe )
822
+ goto _test_eof27;
823
+ case 27:
824
+ if ( (*p) == 117 )
825
+ goto st28;
826
+ goto st0;
827
+ st28:
828
+ if ( ++p == pe )
829
+ goto _test_eof28;
830
+ case 28:
759
831
  if ( (*p) == 101 )
760
- goto tr28;
832
+ goto tr37;
761
833
  goto st0;
762
834
  }
763
- _test_eof21: cs = 21; goto _test_eof;
835
+ _test_eof1: cs = 1; goto _test_eof;
836
+ _test_eof29: cs = 29; goto _test_eof;
764
837
  _test_eof2: cs = 2; goto _test_eof;
765
838
  _test_eof3: cs = 3; goto _test_eof;
766
839
  _test_eof4: cs = 4; goto _test_eof;
@@ -780,12 +853,24 @@ case 20:
780
853
  _test_eof18: cs = 18; goto _test_eof;
781
854
  _test_eof19: cs = 19; goto _test_eof;
782
855
  _test_eof20: cs = 20; goto _test_eof;
856
+ _test_eof21: cs = 21; goto _test_eof;
857
+ _test_eof22: cs = 22; goto _test_eof;
858
+ _test_eof23: cs = 23; goto _test_eof;
859
+ _test_eof24: cs = 24; goto _test_eof;
860
+ _test_eof25: cs = 25; goto _test_eof;
861
+ _test_eof26: cs = 26; goto _test_eof;
862
+ _test_eof27: cs = 27; goto _test_eof;
863
+ _test_eof28: cs = 28; goto _test_eof;
783
864
 
784
865
  _test_eof: {}
785
866
  _out: {}
786
867
  }
787
868
 
788
- #line 299 "parser.rl"
869
+ #line 291 "parser.rl"
870
+
871
+ if (json->freeze) {
872
+ OBJ_FREEZE(*result);
873
+ }
789
874
 
790
875
  if (cs >= JSON_value_first_final) {
791
876
  return p;
@@ -795,15 +880,15 @@ case 20:
795
880
  }
796
881
 
797
882
 
798
- #line 799 "parser.c"
799
- static const int JSON_integer_start = 1;
800
- static const int JSON_integer_first_final = 3;
801
- static const int JSON_integer_error = 0;
883
+ #line 884 "parser.c"
884
+ enum {JSON_integer_start = 1};
885
+ enum {JSON_integer_first_final = 3};
886
+ enum {JSON_integer_error = 0};
802
887
 
803
- static const int JSON_integer_en_main = 1;
888
+ enum {JSON_integer_en_main = 1};
804
889
 
805
890
 
806
- #line 315 "parser.rl"
891
+ #line 311 "parser.rl"
807
892
 
808
893
 
809
894
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -811,15 +896,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
811
896
  int cs = EVIL;
812
897
 
813
898
 
814
- #line 815 "parser.c"
899
+ #line 900 "parser.c"
815
900
  {
816
901
  cs = JSON_integer_start;
817
902
  }
818
903
 
819
- #line 322 "parser.rl"
904
+ #line 318 "parser.rl"
820
905
  json->memo = p;
821
906
 
822
- #line 823 "parser.c"
907
+ #line 908 "parser.c"
823
908
  {
824
909
  if ( p == pe )
825
910
  goto _test_eof;
@@ -853,14 +938,14 @@ case 3:
853
938
  goto st0;
854
939
  goto tr4;
855
940
  tr4:
856
- #line 312 "parser.rl"
941
+ #line 308 "parser.rl"
857
942
  { p--; {p++; cs = 4; goto _out;} }
858
943
  goto st4;
859
944
  st4:
860
945
  if ( ++p == pe )
861
946
  goto _test_eof4;
862
947
  case 4:
863
- #line 864 "parser.c"
948
+ #line 949 "parser.c"
864
949
  goto st0;
865
950
  st5:
866
951
  if ( ++p == pe )
@@ -879,7 +964,7 @@ case 5:
879
964
  _out: {}
880
965
  }
881
966
 
882
- #line 324 "parser.rl"
967
+ #line 320 "parser.rl"
883
968
 
884
969
  if (cs >= JSON_integer_first_final) {
885
970
  long len = p - json->memo;
@@ -894,15 +979,15 @@ case 5:
894
979
  }
895
980
 
896
981
 
897
- #line 898 "parser.c"
898
- static const int JSON_float_start = 1;
899
- static const int JSON_float_first_final = 8;
900
- static const int JSON_float_error = 0;
982
+ #line 983 "parser.c"
983
+ enum {JSON_float_start = 1};
984
+ enum {JSON_float_first_final = 8};
985
+ enum {JSON_float_error = 0};
901
986
 
902
- static const int JSON_float_en_main = 1;
987
+ enum {JSON_float_en_main = 1};
903
988
 
904
989
 
905
- #line 349 "parser.rl"
990
+ #line 345 "parser.rl"
906
991
 
907
992
 
908
993
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -910,15 +995,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
910
995
  int cs = EVIL;
911
996
 
912
997
 
913
- #line 914 "parser.c"
998
+ #line 999 "parser.c"
914
999
  {
915
1000
  cs = JSON_float_start;
916
1001
  }
917
1002
 
918
- #line 356 "parser.rl"
1003
+ #line 352 "parser.rl"
919
1004
  json->memo = p;
920
1005
 
921
- #line 922 "parser.c"
1006
+ #line 1007 "parser.c"
922
1007
  {
923
1008
  if ( p == pe )
924
1009
  goto _test_eof;
@@ -976,14 +1061,14 @@ case 8:
976
1061
  goto st0;
977
1062
  goto tr9;
978
1063
  tr9:
979
- #line 343 "parser.rl"
1064
+ #line 339 "parser.rl"
980
1065
  { p--; {p++; cs = 9; goto _out;} }
981
1066
  goto st9;
982
1067
  st9:
983
1068
  if ( ++p == pe )
984
1069
  goto _test_eof9;
985
1070
  case 9:
986
- #line 987 "parser.c"
1071
+ #line 1072 "parser.c"
987
1072
  goto st0;
988
1073
  st5:
989
1074
  if ( ++p == pe )
@@ -1044,14 +1129,49 @@ case 7:
1044
1129
  _out: {}
1045
1130
  }
1046
1131
 
1047
- #line 358 "parser.rl"
1132
+ #line 354 "parser.rl"
1048
1133
 
1049
1134
  if (cs >= JSON_float_first_final) {
1135
+ VALUE mod = Qnil;
1136
+ ID method_id = 0;
1137
+ if (rb_respond_to(json->decimal_class, i_try_convert)) {
1138
+ mod = json->decimal_class;
1139
+ method_id = i_try_convert;
1140
+ } else if (rb_respond_to(json->decimal_class, i_new)) {
1141
+ mod = json->decimal_class;
1142
+ method_id = i_new;
1143
+ } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
1144
+ VALUE name = rb_class_name(json->decimal_class);
1145
+ const char *name_cstr = RSTRING_PTR(name);
1146
+ const char *last_colon = strrchr(name_cstr, ':');
1147
+ if (last_colon) {
1148
+ const char *mod_path_end = last_colon - 1;
1149
+ VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
1150
+ mod = rb_path_to_class(mod_path);
1151
+
1152
+ const char *method_name_beg = last_colon + 1;
1153
+ long before_len = method_name_beg - name_cstr;
1154
+ long len = RSTRING_LEN(name) - before_len;
1155
+ VALUE method_name = rb_str_substr(name, before_len, len);
1156
+ method_id = SYM2ID(rb_str_intern(method_name));
1157
+ } else {
1158
+ mod = rb_mKernel;
1159
+ method_id = SYM2ID(rb_str_intern(name));
1160
+ }
1161
+ }
1162
+
1050
1163
  long len = p - json->memo;
1051
1164
  fbuffer_clear(json->fbuffer);
1052
1165
  fbuffer_append(json->fbuffer, json->memo, len);
1053
1166
  fbuffer_append_char(json->fbuffer, '\0');
1054
- *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1167
+
1168
+ if (method_id) {
1169
+ VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
1170
+ *result = rb_funcallv(mod, method_id, 1, &text);
1171
+ } else {
1172
+ *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1173
+ }
1174
+
1055
1175
  return p + 1;
1056
1176
  } else {
1057
1177
  return NULL;
@@ -1060,36 +1180,36 @@ case 7:
1060
1180
 
1061
1181
 
1062
1182
 
1063
- #line 1064 "parser.c"
1064
- static const int JSON_array_start = 1;
1065
- static const int JSON_array_first_final = 17;
1066
- static const int JSON_array_error = 0;
1183
+ #line 1184 "parser.c"
1184
+ enum {JSON_array_start = 1};
1185
+ enum {JSON_array_first_final = 17};
1186
+ enum {JSON_array_error = 0};
1067
1187
 
1068
- static const int JSON_array_en_main = 1;
1188
+ enum {JSON_array_en_main = 1};
1069
1189
 
1070
1190
 
1071
- #line 401 "parser.rl"
1191
+ #line 432 "parser.rl"
1072
1192
 
1073
1193
 
1074
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
1194
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
1075
1195
  {
1076
1196
  int cs = EVIL;
1077
1197
  VALUE array_class = json->array_class;
1078
1198
 
1079
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
1080
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
1199
+ if (json->max_nesting && current_nesting > json->max_nesting) {
1200
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
1081
1201
  }
1082
1202
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1083
1203
 
1084
1204
 
1085
- #line 1086 "parser.c"
1205
+ #line 1206 "parser.c"
1086
1206
  {
1087
1207
  cs = JSON_array_start;
1088
1208
  }
1089
1209
 
1090
- #line 414 "parser.rl"
1210
+ #line 445 "parser.rl"
1091
1211
 
1092
- #line 1093 "parser.c"
1212
+ #line 1213 "parser.c"
1093
1213
  {
1094
1214
  if ( p == pe )
1095
1215
  goto _test_eof;
@@ -1128,10 +1248,10 @@ case 2:
1128
1248
  goto st2;
1129
1249
  goto st0;
1130
1250
  tr2:
1131
- #line 378 "parser.rl"
1251
+ #line 409 "parser.rl"
1132
1252
  {
1133
1253
  VALUE v = Qnil;
1134
- char *np = JSON_parse_value(json, p, pe, &v);
1254
+ char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
1135
1255
  if (np == NULL) {
1136
1256
  p--; {p++; cs = 3; goto _out;}
1137
1257
  } else {
@@ -1148,7 +1268,7 @@ st3:
1148
1268
  if ( ++p == pe )
1149
1269
  goto _test_eof3;
1150
1270
  case 3:
1151
- #line 1152 "parser.c"
1271
+ #line 1272 "parser.c"
1152
1272
  switch( (*p) ) {
1153
1273
  case 13: goto st3;
1154
1274
  case 32: goto st3;
@@ -1248,14 +1368,14 @@ case 12:
1248
1368
  goto st3;
1249
1369
  goto st12;
1250
1370
  tr4:
1251
- #line 393 "parser.rl"
1371
+ #line 424 "parser.rl"
1252
1372
  { p--; {p++; cs = 17; goto _out;} }
1253
1373
  goto st17;
1254
1374
  st17:
1255
1375
  if ( ++p == pe )
1256
1376
  goto _test_eof17;
1257
1377
  case 17:
1258
- #line 1259 "parser.c"
1378
+ #line 1379 "parser.c"
1259
1379
  goto st0;
1260
1380
  st13:
1261
1381
  if ( ++p == pe )
@@ -1311,27 +1431,47 @@ case 16:
1311
1431
  _out: {}
1312
1432
  }
1313
1433
 
1314
- #line 415 "parser.rl"
1434
+ #line 446 "parser.rl"
1315
1435
 
1316
1436
  if(cs >= JSON_array_first_final) {
1317
1437
  return p + 1;
1318
1438
  } else {
1319
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1439
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
1320
1440
  return NULL;
1321
1441
  }
1322
1442
  }
1323
1443
 
1324
- static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1444
+ static const size_t MAX_STACK_BUFFER_SIZE = 128;
1445
+ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize)
1325
1446
  {
1326
- char *p = string, *pe = string, *unescape;
1447
+ VALUE result = Qnil;
1448
+ size_t bufferSize = stringEnd - string;
1449
+ char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
1327
1450
  int unescape_len;
1328
1451
  char buf[4];
1329
1452
 
1453
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1454
+ # ifdef HAVE_RB_ENC_INTERNED_STR
1455
+ bufferStart = buffer = ALLOC_N(char, bufferSize ? bufferSize : 1);
1456
+ # else
1457
+ bufferStart = buffer = ALLOC_N(char, bufferSize);
1458
+ # endif
1459
+ } else {
1460
+ # ifdef HAVE_RB_ENC_INTERNED_STR
1461
+ bufferStart = buffer = ALLOCA_N(char, bufferSize ? bufferSize : 1);
1462
+ # else
1463
+ bufferStart = buffer = ALLOCA_N(char, bufferSize);
1464
+ # endif
1465
+ }
1466
+
1330
1467
  while (pe < stringEnd) {
1331
1468
  if (*pe == '\\') {
1332
1469
  unescape = (char *) "?";
1333
1470
  unescape_len = 1;
1334
- if (pe > p) rb_str_buf_cat(result, p, pe - p);
1471
+ if (pe > p) {
1472
+ MEMCPY(buffer, p, char, pe - p);
1473
+ buffer += pe - p;
1474
+ }
1335
1475
  switch (*++pe) {
1336
1476
  case 'n':
1337
1477
  unescape = (char *) "\n";
@@ -1356,13 +1496,27 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1356
1496
  break;
1357
1497
  case 'u':
1358
1498
  if (pe > stringEnd - 4) {
1359
- return Qnil;
1499
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1500
+ ruby_xfree(bufferStart);
1501
+ }
1502
+ rb_enc_raise(
1503
+ EXC_ENCODING eParserError,
1504
+ "incomplete unicode character escape sequence at '%s'", p
1505
+ );
1360
1506
  } else {
1361
1507
  UTF32 ch = unescape_unicode((unsigned char *) ++pe);
1362
1508
  pe += 3;
1363
1509
  if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
1364
1510
  pe++;
1365
- if (pe > stringEnd - 6) return Qnil;
1511
+ if (pe > stringEnd - 6) {
1512
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1513
+ ruby_xfree(bufferStart);
1514
+ }
1515
+ rb_enc_raise(
1516
+ EXC_ENCODING eParserError,
1517
+ "incomplete surrogate pair at '%s'", p
1518
+ );
1519
+ }
1366
1520
  if (pe[0] == '\\' && pe[1] == 'u') {
1367
1521
  UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
1368
1522
  ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
@@ -1381,26 +1535,68 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1381
1535
  p = pe;
1382
1536
  continue;
1383
1537
  }
1384
- rb_str_buf_cat(result, unescape, unescape_len);
1538
+ MEMCPY(buffer, unescape, char, unescape_len);
1539
+ buffer += unescape_len;
1385
1540
  p = ++pe;
1386
1541
  } else {
1387
1542
  pe++;
1388
1543
  }
1389
1544
  }
1390
- rb_str_buf_cat(result, p, pe - p);
1545
+
1546
+ if (pe > p) {
1547
+ MEMCPY(buffer, p, char, pe - p);
1548
+ buffer += pe - p;
1549
+ }
1550
+
1551
+ # ifdef HAVE_RB_ENC_INTERNED_STR
1552
+ if (intern) {
1553
+ result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
1554
+ } else {
1555
+ result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
1556
+ }
1557
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1558
+ ruby_xfree(bufferStart);
1559
+ }
1560
+ # else
1561
+ result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
1562
+
1563
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1564
+ ruby_xfree(bufferStart);
1565
+ }
1566
+
1567
+ if (intern) {
1568
+ # if STR_UMINUS_DEDUPE_FROZEN
1569
+ // Starting from MRI 2.8 it is preferable to freeze the string
1570
+ // before deduplication so that it can be interned directly
1571
+ // otherwise it would be duplicated first which is wasteful.
1572
+ result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
1573
+ # elif STR_UMINUS_DEDUPE
1574
+ // MRI 2.5 and older do not deduplicate strings that are already
1575
+ // frozen.
1576
+ result = rb_funcall(result, i_uminus, 0);
1577
+ # else
1578
+ result = rb_str_freeze(result);
1579
+ # endif
1580
+ }
1581
+ # endif
1582
+
1583
+ if (symbolize) {
1584
+ result = rb_str_intern(result);
1585
+ }
1586
+
1391
1587
  return result;
1392
1588
  }
1393
1589
 
1394
1590
 
1395
- #line 1396 "parser.c"
1396
- static const int JSON_string_start = 1;
1397
- static const int JSON_string_first_final = 8;
1398
- static const int JSON_string_error = 0;
1591
+ #line 1592 "parser.c"
1592
+ enum {JSON_string_start = 1};
1593
+ enum {JSON_string_first_final = 8};
1594
+ enum {JSON_string_error = 0};
1399
1595
 
1400
- static const int JSON_string_en_main = 1;
1596
+ enum {JSON_string_en_main = 1};
1401
1597
 
1402
1598
 
1403
- #line 514 "parser.rl"
1599
+ #line 620 "parser.rl"
1404
1600
 
1405
1601
 
1406
1602
  static int
@@ -1420,17 +1616,16 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
1420
1616
  int cs = EVIL;
1421
1617
  VALUE match_string;
1422
1618
 
1423
- *result = rb_str_buf_new(0);
1424
1619
 
1425
- #line 1426 "parser.c"
1620
+ #line 1621 "parser.c"
1426
1621
  {
1427
1622
  cs = JSON_string_start;
1428
1623
  }
1429
1624
 
1430
- #line 535 "parser.rl"
1625
+ #line 640 "parser.rl"
1431
1626
  json->memo = p;
1432
1627
 
1433
- #line 1434 "parser.c"
1628
+ #line 1629 "parser.c"
1434
1629
  {
1435
1630
  if ( p == pe )
1436
1631
  goto _test_eof;
@@ -1451,29 +1646,28 @@ case 2:
1451
1646
  case 34: goto tr2;
1452
1647
  case 92: goto st3;
1453
1648
  }
1454
- if ( 0 <= (*p) && (*p) <= 31 )
1649
+ if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
1455
1650
  goto st0;
1456
1651
  goto st2;
1457
1652
  tr2:
1458
- #line 500 "parser.rl"
1653
+ #line 607 "parser.rl"
1459
1654
  {
1460
- *result = json_string_unescape(*result, json->memo + 1, p);
1655
+ *result = json_string_unescape(json->memo + 1, p, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
1461
1656
  if (NIL_P(*result)) {
1462
1657
  p--;
1463
1658
  {p++; cs = 8; goto _out;}
1464
1659
  } else {
1465
- FORCE_UTF8(*result);
1466
1660
  {p = (( p + 1))-1;}
1467
1661
  }
1468
1662
  }
1469
- #line 511 "parser.rl"
1663
+ #line 617 "parser.rl"
1470
1664
  { p--; {p++; cs = 8; goto _out;} }
1471
1665
  goto st8;
1472
1666
  st8:
1473
1667
  if ( ++p == pe )
1474
1668
  goto _test_eof8;
1475
1669
  case 8:
1476
- #line 1477 "parser.c"
1670
+ #line 1671 "parser.c"
1477
1671
  goto st0;
1478
1672
  st3:
1479
1673
  if ( ++p == pe )
@@ -1481,7 +1675,7 @@ st3:
1481
1675
  case 3:
1482
1676
  if ( (*p) == 117 )
1483
1677
  goto st4;
1484
- if ( 0 <= (*p) && (*p) <= 31 )
1678
+ if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
1485
1679
  goto st0;
1486
1680
  goto st2;
1487
1681
  st4:
@@ -1549,7 +1743,7 @@ case 7:
1549
1743
  _out: {}
1550
1744
  }
1551
1745
 
1552
- #line 537 "parser.rl"
1746
+ #line 642 "parser.rl"
1553
1747
 
1554
1748
  if (json->create_additions && RTEST(match_string = json->match_string)) {
1555
1749
  VALUE klass;
@@ -1562,9 +1756,6 @@ case 7:
1562
1756
  }
1563
1757
  }
1564
1758
 
1565
- if (json->symbolize_names && json->parsing_name) {
1566
- *result = rb_str_intern(*result);
1567
- }
1568
1759
  if (cs >= JSON_string_first_final) {
1569
1760
  return p + 1;
1570
1761
  } else {
@@ -1586,41 +1777,16 @@ case 7:
1586
1777
 
1587
1778
  static VALUE convert_encoding(VALUE source)
1588
1779
  {
1589
- const char *ptr = RSTRING_PTR(source);
1590
- long len = RSTRING_LEN(source);
1591
- if (len < 2) {
1592
- rb_raise(eParserError, "A JSON text must at least contain two octets!");
1593
- }
1594
1780
  #ifdef HAVE_RUBY_ENCODING_H
1595
- {
1596
- rb_encoding *enc = rb_enc_get(source);
1597
- if (enc == rb_ascii8bit_encoding()) {
1598
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1599
- source = rb_str_conv_enc(source, UTF_32BE, rb_utf8_encoding());
1600
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1601
- source = rb_str_conv_enc(source, UTF_16BE, rb_utf8_encoding());
1602
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1603
- source = rb_str_conv_enc(source, UTF_32LE, rb_utf8_encoding());
1604
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1605
- source = rb_str_conv_enc(source, UTF_16LE, rb_utf8_encoding());
1606
- } else {
1607
- source = rb_str_dup(source);
1608
- FORCE_UTF8(source);
1609
- }
1610
- } else {
1611
- source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
1612
- }
1613
- }
1614
- #else
1615
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1616
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
1617
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1618
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
1619
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1620
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
1621
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1622
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
1781
+ rb_encoding *enc = rb_enc_get(source);
1782
+ if (enc == rb_ascii8bit_encoding()) {
1783
+ if (OBJ_FROZEN(source)) {
1784
+ source = rb_str_dup(source);
1623
1785
  }
1786
+ FORCE_UTF8(source);
1787
+ } else {
1788
+ source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
1789
+ }
1624
1790
  #endif
1625
1791
  return source;
1626
1792
  }
@@ -1630,8 +1796,6 @@ static VALUE convert_encoding(VALUE source)
1630
1796
  *
1631
1797
  * Creates a new JSON::Ext::Parser instance for the string _source_.
1632
1798
  *
1633
- * Creates a new JSON::Ext::Parser instance for the string _source_.
1634
- *
1635
1799
  * It will be configured by the _opts_ hash. _opts_ can have the following
1636
1800
  * keys:
1637
1801
  *
@@ -1643,8 +1807,9 @@ static VALUE convert_encoding(VALUE source)
1643
1807
  * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
1644
1808
  * false.
1645
1809
  * * *symbolize_names*: If set to true, returns symbols for the names
1646
- * (keys) in a JSON object. Otherwise strings are returned, which is also
1647
- * the default.
1810
+ * (keys) in a JSON object. Otherwise strings are returned, which is
1811
+ * also the default. It's not possible to use this option in
1812
+ * conjunction with the *create_additions* option.
1648
1813
  * * *create_additions*: If set to false, the Parser doesn't create
1649
1814
  * additions even if a matching class and create_id was found. This option
1650
1815
  * defaults to false.
@@ -1659,96 +1824,91 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1659
1824
  if (json->Vsource) {
1660
1825
  rb_raise(rb_eTypeError, "already initialized instance");
1661
1826
  }
1662
- #ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1663
1827
  rb_scan_args(argc, argv, "1:", &source, &opts);
1664
- #else
1665
- rb_scan_args(argc, argv, "11", &source, &opts);
1666
- #endif
1667
1828
  if (!NIL_P(opts)) {
1668
- #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1669
- opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
1670
- if (NIL_P(opts)) {
1671
- rb_raise(rb_eArgError, "opts needs to be like a hash");
1672
- } else {
1673
- #endif
1674
- VALUE tmp = ID2SYM(i_max_nesting);
1675
- if (option_given_p(opts, tmp)) {
1676
- VALUE max_nesting = rb_hash_aref(opts, tmp);
1677
- if (RTEST(max_nesting)) {
1678
- Check_Type(max_nesting, T_FIXNUM);
1679
- json->max_nesting = FIX2INT(max_nesting);
1680
- } else {
1681
- json->max_nesting = 0;
1682
- }
1683
- } else {
1684
- json->max_nesting = 100;
1685
- }
1686
- tmp = ID2SYM(i_allow_nan);
1687
- if (option_given_p(opts, tmp)) {
1688
- json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1689
- } else {
1690
- json->allow_nan = 0;
1691
- }
1692
- tmp = ID2SYM(i_symbolize_names);
1693
- if (option_given_p(opts, tmp)) {
1694
- json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1695
- } else {
1696
- json->symbolize_names = 0;
1697
- }
1698
- tmp = ID2SYM(i_quirks_mode);
1699
- if (option_given_p(opts, tmp)) {
1700
- VALUE quirks_mode = rb_hash_aref(opts, tmp);
1701
- json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
1702
- } else {
1703
- json->quirks_mode = 0;
1704
- }
1705
- tmp = ID2SYM(i_create_additions);
1706
- if (option_given_p(opts, tmp)) {
1707
- json->create_additions = RTEST(rb_hash_aref(opts, tmp));
1708
- } else {
1709
- json->create_additions = 0;
1710
- }
1711
- tmp = ID2SYM(i_create_id);
1712
- if (option_given_p(opts, tmp)) {
1713
- json->create_id = rb_hash_aref(opts, tmp);
1714
- } else {
1715
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
1716
- }
1717
- tmp = ID2SYM(i_object_class);
1718
- if (option_given_p(opts, tmp)) {
1719
- json->object_class = rb_hash_aref(opts, tmp);
1720
- } else {
1721
- json->object_class = Qnil;
1722
- }
1723
- tmp = ID2SYM(i_array_class);
1724
- if (option_given_p(opts, tmp)) {
1725
- json->array_class = rb_hash_aref(opts, tmp);
1726
- } else {
1727
- json->array_class = Qnil;
1728
- }
1729
- tmp = ID2SYM(i_match_string);
1730
- if (option_given_p(opts, tmp)) {
1731
- VALUE match_string = rb_hash_aref(opts, tmp);
1732
- json->match_string = RTEST(match_string) ? match_string : Qnil;
1733
- } else {
1734
- json->match_string = Qnil;
1735
- }
1736
- #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1737
- }
1738
- #endif
1829
+ VALUE tmp = ID2SYM(i_max_nesting);
1830
+ if (option_given_p(opts, tmp)) {
1831
+ VALUE max_nesting = rb_hash_aref(opts, tmp);
1832
+ if (RTEST(max_nesting)) {
1833
+ Check_Type(max_nesting, T_FIXNUM);
1834
+ json->max_nesting = FIX2INT(max_nesting);
1835
+ } else {
1836
+ json->max_nesting = 0;
1837
+ }
1838
+ } else {
1839
+ json->max_nesting = 100;
1840
+ }
1841
+ tmp = ID2SYM(i_allow_nan);
1842
+ if (option_given_p(opts, tmp)) {
1843
+ json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1844
+ } else {
1845
+ json->allow_nan = 0;
1846
+ }
1847
+ tmp = ID2SYM(i_symbolize_names);
1848
+ if (option_given_p(opts, tmp)) {
1849
+ json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1850
+ } else {
1851
+ json->symbolize_names = 0;
1852
+ }
1853
+ tmp = ID2SYM(i_freeze);
1854
+ if (option_given_p(opts, tmp)) {
1855
+ json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1856
+ } else {
1857
+ json->freeze = 0;
1858
+ }
1859
+ tmp = ID2SYM(i_create_additions);
1860
+ if (option_given_p(opts, tmp)) {
1861
+ json->create_additions = RTEST(rb_hash_aref(opts, tmp));
1862
+ } else {
1863
+ json->create_additions = 0;
1864
+ }
1865
+ if (json->symbolize_names && json->create_additions) {
1866
+ rb_raise(rb_eArgError,
1867
+ "options :symbolize_names and :create_additions cannot be "
1868
+ " used in conjunction");
1869
+ }
1870
+ tmp = ID2SYM(i_create_id);
1871
+ if (option_given_p(opts, tmp)) {
1872
+ json->create_id = rb_hash_aref(opts, tmp);
1873
+ } else {
1874
+ json->create_id = rb_funcall(mJSON, i_create_id, 0);
1875
+ }
1876
+ tmp = ID2SYM(i_object_class);
1877
+ if (option_given_p(opts, tmp)) {
1878
+ json->object_class = rb_hash_aref(opts, tmp);
1879
+ } else {
1880
+ json->object_class = Qnil;
1881
+ }
1882
+ tmp = ID2SYM(i_array_class);
1883
+ if (option_given_p(opts, tmp)) {
1884
+ json->array_class = rb_hash_aref(opts, tmp);
1885
+ } else {
1886
+ json->array_class = Qnil;
1887
+ }
1888
+ tmp = ID2SYM(i_decimal_class);
1889
+ if (option_given_p(opts, tmp)) {
1890
+ json->decimal_class = rb_hash_aref(opts, tmp);
1891
+ } else {
1892
+ json->decimal_class = Qnil;
1893
+ }
1894
+ tmp = ID2SYM(i_match_string);
1895
+ if (option_given_p(opts, tmp)) {
1896
+ VALUE match_string = rb_hash_aref(opts, tmp);
1897
+ json->match_string = RTEST(match_string) ? match_string : Qnil;
1898
+ } else {
1899
+ json->match_string = Qnil;
1900
+ }
1739
1901
  } else {
1740
1902
  json->max_nesting = 100;
1741
1903
  json->allow_nan = 0;
1742
- json->create_additions = 1;
1743
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
1904
+ json->create_additions = 0;
1905
+ json->create_id = Qnil;
1744
1906
  json->object_class = Qnil;
1745
1907
  json->array_class = Qnil;
1908
+ json->decimal_class = Qnil;
1746
1909
  }
1910
+ source = convert_encoding(StringValue(source));
1747
1911
  StringValue(source);
1748
- if (!json->quirks_mode) {
1749
- source = convert_encoding(source);
1750
- }
1751
- json->current_nesting = 0;
1752
1912
  json->len = RSTRING_LEN(source);
1753
1913
  json->source = RSTRING_PTR(source);;
1754
1914
  json->Vsource = source;
@@ -1756,209 +1916,42 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1756
1916
  }
1757
1917
 
1758
1918
 
1759
- #line 1760 "parser.c"
1760
- static const int JSON_start = 1;
1761
- static const int JSON_first_final = 10;
1762
- static const int JSON_error = 0;
1919
+ #line 1920 "parser.c"
1920
+ enum {JSON_start = 1};
1921
+ enum {JSON_first_final = 10};
1922
+ enum {JSON_error = 0};
1763
1923
 
1764
- static const int JSON_en_main = 1;
1924
+ enum {JSON_en_main = 1};
1765
1925
 
1766
1926
 
1767
- #line 767 "parser.rl"
1927
+ #line 828 "parser.rl"
1768
1928
 
1769
1929
 
1770
- static VALUE cParser_parse_strict(VALUE self)
1930
+ /*
1931
+ * call-seq: parse()
1932
+ *
1933
+ * Parses the current JSON text _source_ and returns the complete data
1934
+ * structure as a result.
1935
+ * It raises JSON::ParserError if fail to parse.
1936
+ */
1937
+ static VALUE cParser_parse(VALUE self)
1771
1938
  {
1772
- char *p, *pe;
1773
- int cs = EVIL;
1774
- VALUE result = Qnil;
1775
- GET_PARSER;
1939
+ char *p, *pe;
1940
+ int cs = EVIL;
1941
+ VALUE result = Qnil;
1942
+ GET_PARSER;
1776
1943
 
1777
1944
 
1778
- #line 1779 "parser.c"
1945
+ #line 1946 "parser.c"
1779
1946
  {
1780
1947
  cs = JSON_start;
1781
1948
  }
1782
1949
 
1783
- #line 777 "parser.rl"
1784
- p = json->source;
1785
- pe = p + json->len;
1950
+ #line 845 "parser.rl"
1951
+ p = json->source;
1952
+ pe = p + json->len;
1786
1953
 
1787
- #line 1788 "parser.c"
1788
- {
1789
- if ( p == pe )
1790
- goto _test_eof;
1791
- switch ( cs )
1792
- {
1793
- st1:
1794
- if ( ++p == pe )
1795
- goto _test_eof1;
1796
- case 1:
1797
- switch( (*p) ) {
1798
- case 13: goto st1;
1799
- case 32: goto st1;
1800
- case 47: goto st2;
1801
- case 91: goto tr3;
1802
- case 123: goto tr4;
1803
- }
1804
- if ( 9 <= (*p) && (*p) <= 10 )
1805
- goto st1;
1806
- goto st0;
1807
- st0:
1808
- cs = 0;
1809
- goto _out;
1810
- st2:
1811
- if ( ++p == pe )
1812
- goto _test_eof2;
1813
- case 2:
1814
- switch( (*p) ) {
1815
- case 42: goto st3;
1816
- case 47: goto st5;
1817
- }
1818
- goto st0;
1819
- st3:
1820
- if ( ++p == pe )
1821
- goto _test_eof3;
1822
- case 3:
1823
- if ( (*p) == 42 )
1824
- goto st4;
1825
- goto st3;
1826
- st4:
1827
- if ( ++p == pe )
1828
- goto _test_eof4;
1829
- case 4:
1830
- switch( (*p) ) {
1831
- case 42: goto st4;
1832
- case 47: goto st1;
1833
- }
1834
- goto st3;
1835
- st5:
1836
- if ( ++p == pe )
1837
- goto _test_eof5;
1838
- case 5:
1839
- if ( (*p) == 10 )
1840
- goto st1;
1841
- goto st5;
1842
- tr3:
1843
- #line 756 "parser.rl"
1844
- {
1845
- char *np;
1846
- json->current_nesting = 1;
1847
- np = JSON_parse_array(json, p, pe, &result);
1848
- if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1849
- }
1850
- goto st10;
1851
- tr4:
1852
- #line 749 "parser.rl"
1853
- {
1854
- char *np;
1855
- json->current_nesting = 1;
1856
- np = JSON_parse_object(json, p, pe, &result);
1857
- if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1858
- }
1859
- goto st10;
1860
- st10:
1861
- if ( ++p == pe )
1862
- goto _test_eof10;
1863
- case 10:
1864
- #line 1865 "parser.c"
1865
- switch( (*p) ) {
1866
- case 13: goto st10;
1867
- case 32: goto st10;
1868
- case 47: goto st6;
1869
- }
1870
- if ( 9 <= (*p) && (*p) <= 10 )
1871
- goto st10;
1872
- goto st0;
1873
- st6:
1874
- if ( ++p == pe )
1875
- goto _test_eof6;
1876
- case 6:
1877
- switch( (*p) ) {
1878
- case 42: goto st7;
1879
- case 47: goto st9;
1880
- }
1881
- goto st0;
1882
- st7:
1883
- if ( ++p == pe )
1884
- goto _test_eof7;
1885
- case 7:
1886
- if ( (*p) == 42 )
1887
- goto st8;
1888
- goto st7;
1889
- st8:
1890
- if ( ++p == pe )
1891
- goto _test_eof8;
1892
- case 8:
1893
- switch( (*p) ) {
1894
- case 42: goto st8;
1895
- case 47: goto st10;
1896
- }
1897
- goto st7;
1898
- st9:
1899
- if ( ++p == pe )
1900
- goto _test_eof9;
1901
- case 9:
1902
- if ( (*p) == 10 )
1903
- goto st10;
1904
- goto st9;
1905
- }
1906
- _test_eof1: cs = 1; goto _test_eof;
1907
- _test_eof2: cs = 2; goto _test_eof;
1908
- _test_eof3: cs = 3; goto _test_eof;
1909
- _test_eof4: cs = 4; goto _test_eof;
1910
- _test_eof5: cs = 5; goto _test_eof;
1911
- _test_eof10: cs = 10; goto _test_eof;
1912
- _test_eof6: cs = 6; goto _test_eof;
1913
- _test_eof7: cs = 7; goto _test_eof;
1914
- _test_eof8: cs = 8; goto _test_eof;
1915
- _test_eof9: cs = 9; goto _test_eof;
1916
-
1917
- _test_eof: {}
1918
- _out: {}
1919
- }
1920
-
1921
- #line 780 "parser.rl"
1922
-
1923
- if (cs >= JSON_first_final && p == pe) {
1924
- return result;
1925
- } else {
1926
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1927
- return Qnil;
1928
- }
1929
- }
1930
-
1931
-
1932
-
1933
- #line 1934 "parser.c"
1934
- static const int JSON_quirks_mode_start = 1;
1935
- static const int JSON_quirks_mode_first_final = 10;
1936
- static const int JSON_quirks_mode_error = 0;
1937
-
1938
- static const int JSON_quirks_mode_en_main = 1;
1939
-
1940
-
1941
- #line 805 "parser.rl"
1942
-
1943
-
1944
- static VALUE cParser_parse_quirks_mode(VALUE self)
1945
- {
1946
- char *p, *pe;
1947
- int cs = EVIL;
1948
- VALUE result = Qnil;
1949
- GET_PARSER;
1950
-
1951
-
1952
- #line 1953 "parser.c"
1953
- {
1954
- cs = JSON_quirks_mode_start;
1955
- }
1956
-
1957
- #line 815 "parser.rl"
1958
- p = json->source;
1959
- pe = p + json->len;
1960
-
1961
- #line 1962 "parser.c"
1954
+ #line 1955 "parser.c"
1962
1955
  {
1963
1956
  if ( p == pe )
1964
1957
  goto _test_eof;
@@ -1992,9 +1985,9 @@ st0:
1992
1985
  cs = 0;
1993
1986
  goto _out;
1994
1987
  tr2:
1995
- #line 797 "parser.rl"
1988
+ #line 820 "parser.rl"
1996
1989
  {
1997
- char *np = JSON_parse_value(json, p, pe, &result);
1990
+ char *np = JSON_parse_value(json, p, pe, &result, 0);
1998
1991
  if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1999
1992
  }
2000
1993
  goto st10;
@@ -2002,7 +1995,7 @@ st10:
2002
1995
  if ( ++p == pe )
2003
1996
  goto _test_eof10;
2004
1997
  case 10:
2005
- #line 2006 "parser.c"
1998
+ #line 1999 "parser.c"
2006
1999
  switch( (*p) ) {
2007
2000
  case 13: goto st10;
2008
2001
  case 32: goto st10;
@@ -2091,30 +2084,13 @@ case 9:
2091
2084
  _out: {}
2092
2085
  }
2093
2086
 
2094
- #line 818 "parser.rl"
2095
-
2096
- if (cs >= JSON_quirks_mode_first_final && p == pe) {
2097
- return result;
2098
- } else {
2099
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
2100
- return Qnil;
2101
- }
2102
- }
2087
+ #line 848 "parser.rl"
2103
2088
 
2104
- /*
2105
- * call-seq: parse()
2106
- *
2107
- * Parses the current JSON text _source_ and returns the complete data
2108
- * structure as a result.
2109
- */
2110
- static VALUE cParser_parse(VALUE self)
2111
- {
2112
- GET_PARSER;
2113
-
2114
- if (json->quirks_mode) {
2115
- return cParser_parse_quirks_mode(self);
2089
+ if (cs >= JSON_first_final && p == pe) {
2090
+ return result;
2116
2091
  } else {
2117
- return cParser_parse_strict(self);
2092
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
2093
+ return Qnil;
2118
2094
  }
2119
2095
  }
2120
2096
 
@@ -2125,6 +2101,7 @@ static void JSON_mark(void *ptr)
2125
2101
  rb_gc_mark_maybe(json->create_id);
2126
2102
  rb_gc_mark_maybe(json->object_class);
2127
2103
  rb_gc_mark_maybe(json->array_class);
2104
+ rb_gc_mark_maybe(json->decimal_class);
2128
2105
  rb_gc_mark_maybe(json->match_string);
2129
2106
  }
2130
2107
 
@@ -2172,35 +2149,34 @@ static VALUE cParser_source(VALUE self)
2172
2149
  return rb_str_dup(json->Vsource);
2173
2150
  }
2174
2151
 
2175
- /*
2176
- * call-seq: quirks_mode?()
2177
- *
2178
- * Returns a true, if this parser is in quirks_mode, false otherwise.
2179
- */
2180
- static VALUE cParser_quirks_mode_p(VALUE self)
2181
- {
2182
- GET_PARSER;
2183
- return json->quirks_mode ? Qtrue : Qfalse;
2184
- }
2185
-
2186
-
2187
2152
  void Init_parser(void)
2188
2153
  {
2154
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
2155
+ rb_ext_ractor_safe(true);
2156
+ #endif
2157
+
2158
+ #undef rb_intern
2189
2159
  rb_require("json/common");
2190
2160
  mJSON = rb_define_module("JSON");
2191
2161
  mExt = rb_define_module_under(mJSON, "Ext");
2192
2162
  cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
2193
2163
  eParserError = rb_path2class("JSON::ParserError");
2194
2164
  eNestingError = rb_path2class("JSON::NestingError");
2165
+ rb_gc_register_mark_object(eParserError);
2166
+ rb_gc_register_mark_object(eNestingError);
2195
2167
  rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
2196
2168
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
2197
2169
  rb_define_method(cParser, "parse", cParser_parse, 0);
2198
2170
  rb_define_method(cParser, "source", cParser_source, 0);
2199
- rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
2200
2171
 
2201
2172
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
2173
+ rb_gc_register_mark_object(CNaN);
2174
+
2202
2175
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
2176
+ rb_gc_register_mark_object(CInfinity);
2177
+
2203
2178
  CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
2179
+ rb_gc_register_mark_object(CMinusInfinity);
2204
2180
 
2205
2181
  i_json_creatable_p = rb_intern("json_creatable?");
2206
2182
  i_json_create = rb_intern("json_create");
@@ -2210,9 +2186,9 @@ void Init_parser(void)
2210
2186
  i_max_nesting = rb_intern("max_nesting");
2211
2187
  i_allow_nan = rb_intern("allow_nan");
2212
2188
  i_symbolize_names = rb_intern("symbolize_names");
2213
- i_quirks_mode = rb_intern("quirks_mode");
2214
2189
  i_object_class = rb_intern("object_class");
2215
2190
  i_array_class = rb_intern("array_class");
2191
+ i_decimal_class = rb_intern("decimal_class");
2216
2192
  i_match = rb_intern("match");
2217
2193
  i_match_string = rb_intern("match_string");
2218
2194
  i_key_p = rb_intern("key?");
@@ -2220,15 +2196,10 @@ void Init_parser(void)
2220
2196
  i_aset = rb_intern("[]=");
2221
2197
  i_aref = rb_intern("[]");
2222
2198
  i_leftshift = rb_intern("<<");
2223
- #ifdef HAVE_RUBY_ENCODING_H
2224
- UTF_8 = rb_utf8_encoding();
2225
- UTF_16BE = rb_enc_find("utf-16be");
2226
- UTF_16LE = rb_enc_find("utf-16le");
2227
- UTF_32BE = rb_enc_find("utf-32be");
2228
- UTF_32LE = rb_enc_find("utf-32le");
2229
- #else
2230
- i_iconv = rb_intern("iconv");
2231
- #endif
2199
+ i_new = rb_intern("new");
2200
+ i_try_convert = rb_intern("try_convert");
2201
+ i_freeze = rb_intern("freeze");
2202
+ i_uminus = rb_intern("-@");
2232
2203
  }
2233
2204
 
2234
2205
  /*