json 1.8.6 → 2.7.2

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.
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
  /*