json 1.8.3 → 2.4.0

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 (83) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.travis.yml +9 -12
  4. data/{CHANGES → CHANGES.md} +219 -90
  5. data/Gemfile +10 -6
  6. data/{COPYING-json-jruby → LICENSE} +5 -6
  7. data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
  8. data/{README.rdoc → README.md} +201 -134
  9. data/Rakefile +35 -113
  10. data/VERSION +1 -1
  11. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  12. data/ext/json/ext/generator/generator.c +255 -101
  13. data/ext/json/ext/generator/generator.h +12 -4
  14. data/ext/json/ext/parser/extconf.rb +28 -0
  15. data/ext/json/ext/parser/parser.c +410 -462
  16. data/ext/json/ext/parser/parser.h +5 -5
  17. data/ext/json/ext/parser/parser.rl +166 -181
  18. data/ext/json/extconf.rb +1 -1
  19. data/java/src/json/ext/ByteListTranscoder.java +1 -2
  20. data/java/src/json/ext/Generator.java +39 -36
  21. data/java/src/json/ext/GeneratorMethods.java +1 -2
  22. data/java/src/json/ext/GeneratorService.java +1 -2
  23. data/java/src/json/ext/GeneratorState.java +33 -56
  24. data/java/src/json/ext/OptionsReader.java +2 -3
  25. data/java/src/json/ext/Parser.java +146 -417
  26. data/java/src/json/ext/Parser.rl +62 -126
  27. data/java/src/json/ext/ParserService.java +1 -2
  28. data/java/src/json/ext/RuntimeInfo.java +1 -6
  29. data/java/src/json/ext/StringDecoder.java +1 -2
  30. data/java/src/json/ext/StringEncoder.java +13 -2
  31. data/java/src/json/ext/Utils.java +1 -2
  32. data/json-java.gemspec +22 -7
  33. data/json.gemspec +0 -0
  34. data/json_pure.gemspec +22 -29
  35. data/lib/json/add/bigdecimal.rb +3 -2
  36. data/lib/json/add/complex.rb +4 -4
  37. data/lib/json/add/core.rb +1 -0
  38. data/lib/json/add/date.rb +1 -1
  39. data/lib/json/add/date_time.rb +1 -1
  40. data/lib/json/add/exception.rb +1 -1
  41. data/lib/json/add/ostruct.rb +3 -3
  42. data/lib/json/add/range.rb +1 -1
  43. data/lib/json/add/rational.rb +3 -3
  44. data/lib/json/add/regexp.rb +3 -3
  45. data/lib/json/add/set.rb +29 -0
  46. data/lib/json/add/struct.rb +1 -1
  47. data/lib/json/add/symbol.rb +1 -1
  48. data/lib/json/add/time.rb +1 -1
  49. data/lib/json/common.rb +350 -152
  50. data/lib/json/ext.rb +0 -6
  51. data/lib/json/generic_object.rb +5 -4
  52. data/lib/json/pure/generator.rb +83 -126
  53. data/lib/json/pure/parser.rb +62 -84
  54. data/lib/json/pure.rb +2 -8
  55. data/lib/json/version.rb +2 -1
  56. data/lib/json.rb +550 -29
  57. data/references/rfc7159.txt +899 -0
  58. data/tests/fixtures/obsolete_fail1.json +1 -0
  59. data/tests/{test_json_addition.rb → json_addition_test.rb} +28 -25
  60. data/tests/json_common_interface_test.rb +169 -0
  61. data/tests/json_encoding_test.rb +107 -0
  62. data/tests/json_ext_parser_test.rb +15 -0
  63. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +13 -8
  64. data/tests/{test_json_generate.rb → json_generator_test.rb} +134 -39
  65. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  66. data/tests/json_parser_test.rb +497 -0
  67. data/tests/json_string_matching_test.rb +38 -0
  68. data/tests/test_helper.rb +17 -0
  69. data/tools/diff.sh +18 -0
  70. data/tools/fuzz.rb +1 -9
  71. metadata +47 -53
  72. data/COPYING +0 -58
  73. data/GPL +0 -340
  74. data/TODO +0 -1
  75. data/data/example.json +0 -1
  76. data/data/index.html +0 -38
  77. data/data/prototype.js +0 -4184
  78. data/tests/fixtures/fail1.json +0 -1
  79. data/tests/setup_variant.rb +0 -11
  80. data/tests/test_json.rb +0 -553
  81. data/tests/test_json_encoding.rb +0 -65
  82. data/tests/test_json_string_matching.rb +0 -39
  83. data/tests/test_json_unicode.rb +0 -72
@@ -1,11 +1,33 @@
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
+ #if defined HAVE_RUBY_ENCODING_H
7
+ # define EXC_ENCODING rb_utf8_encoding(),
8
+ # ifndef HAVE_RB_ENC_RAISE
9
+ static void
10
+ enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
11
+ {
12
+ va_list args;
13
+ VALUE mesg;
14
+
15
+ va_start(args, fmt);
16
+ mesg = rb_enc_vsprintf(enc, fmt, args);
17
+ va_end(args);
18
+
19
+ rb_exc_raise(rb_exc_new3(exc, mesg));
20
+ }
21
+ # define rb_enc_raise enc_raise
22
+ # endif
23
+ #else
24
+ # define EXC_ENCODING /* nothing */
25
+ # define rb_enc_raise rb_raise
26
+ #endif
27
+
6
28
  /* unicode */
7
29
 
8
- static const char digit_values[256] = {
30
+ static const signed char digit_values[256] = {
9
31
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
10
32
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
11
33
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
@@ -24,7 +46,7 @@ static const char digit_values[256] = {
24
46
 
25
47
  static UTF32 unescape_unicode(const unsigned char *p)
26
48
  {
27
- char b;
49
+ signed char b;
28
50
  UTF32 result = 0;
29
51
  b = digit_values[p[0]];
30
52
  if (b < 0) return UNI_REPLACEMENT_CHAR;
@@ -67,28 +89,22 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
67
89
  return len;
68
90
  }
69
91
 
70
- #ifdef HAVE_RUBY_ENCODING_H
71
- static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
72
- CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
73
- static ID i_encoding, i_encode;
74
- #else
75
- static ID i_iconv;
76
- #endif
77
-
78
92
  static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
79
93
  static VALUE CNaN, CInfinity, CMinusInfinity;
94
+ static VALUE cBigDecimal = Qundef;
80
95
 
81
96
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
82
- i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
83
- i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
84
- i_match_string, i_aset, i_aref, i_leftshift;
97
+ i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
98
+ i_object_class, i_array_class, i_decimal_class, i_key_p,
99
+ i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
100
+ i_leftshift, i_new, i_BigDecimal, i_freeze, i_uminus;
85
101
 
86
102
 
87
- #line 110 "parser.rl"
103
+ #line 126 "parser.rl"
88
104
 
89
105
 
90
106
 
91
- #line 92 "parser.c"
107
+ #line 108 "parser.c"
92
108
  enum {JSON_object_start = 1};
93
109
  enum {JSON_object_first_final = 27};
94
110
  enum {JSON_object_error = 0};
@@ -96,30 +112,30 @@ enum {JSON_object_error = 0};
96
112
  enum {JSON_object_en_main = 1};
97
113
 
98
114
 
99
- #line 151 "parser.rl"
115
+ #line 168 "parser.rl"
100
116
 
101
117
 
102
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
118
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
103
119
  {
104
120
  int cs = EVIL;
105
121
  VALUE last_name = Qnil;
106
122
  VALUE object_class = json->object_class;
107
123
 
108
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
109
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
124
+ if (json->max_nesting && current_nesting > json->max_nesting) {
125
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
110
126
  }
111
127
 
112
128
  *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
113
129
 
114
130
 
115
- #line 116 "parser.c"
131
+ #line 132 "parser.c"
116
132
  {
117
133
  cs = JSON_object_start;
118
134
  }
119
135
 
120
- #line 166 "parser.rl"
136
+ #line 183 "parser.rl"
121
137
 
122
- #line 123 "parser.c"
138
+ #line 139 "parser.c"
123
139
  {
124
140
  if ( p == pe )
125
141
  goto _test_eof;
@@ -147,7 +163,7 @@ case 2:
147
163
  goto st2;
148
164
  goto st0;
149
165
  tr2:
150
- #line 133 "parser.rl"
166
+ #line 150 "parser.rl"
151
167
  {
152
168
  char *np;
153
169
  json->parsing_name = 1;
@@ -160,7 +176,7 @@ st3:
160
176
  if ( ++p == pe )
161
177
  goto _test_eof3;
162
178
  case 3:
163
- #line 164 "parser.c"
179
+ #line 180 "parser.c"
164
180
  switch( (*p) ) {
165
181
  case 13: goto st3;
166
182
  case 32: goto st3;
@@ -227,14 +243,15 @@ case 8:
227
243
  goto st8;
228
244
  goto st0;
229
245
  tr11:
230
- #line 118 "parser.rl"
246
+ #line 134 "parser.rl"
231
247
  {
232
248
  VALUE v = Qnil;
233
- char *np = JSON_parse_value(json, p, pe, &v);
249
+ char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
234
250
  if (np == NULL) {
235
251
  p--; {p++; cs = 9; goto _out;}
236
252
  } else {
237
253
  if (NIL_P(json->object_class)) {
254
+ OBJ_FREEZE(last_name);
238
255
  rb_hash_aset(*result, last_name, v);
239
256
  } else {
240
257
  rb_funcall(*result, i_aset, 2, last_name, v);
@@ -247,7 +264,7 @@ st9:
247
264
  if ( ++p == pe )
248
265
  goto _test_eof9;
249
266
  case 9:
250
- #line 251 "parser.c"
267
+ #line 268 "parser.c"
251
268
  switch( (*p) ) {
252
269
  case 13: goto st9;
253
270
  case 32: goto st9;
@@ -336,14 +353,14 @@ case 18:
336
353
  goto st9;
337
354
  goto st18;
338
355
  tr4:
339
- #line 141 "parser.rl"
356
+ #line 158 "parser.rl"
340
357
  { p--; {p++; cs = 27; goto _out;} }
341
358
  goto st27;
342
359
  st27:
343
360
  if ( ++p == pe )
344
361
  goto _test_eof27;
345
362
  case 27:
346
- #line 347 "parser.c"
363
+ #line 364 "parser.c"
347
364
  goto st0;
348
365
  st19:
349
366
  if ( ++p == pe )
@@ -441,7 +458,7 @@ case 26:
441
458
  _out: {}
442
459
  }
443
460
 
444
- #line 167 "parser.rl"
461
+ #line 184 "parser.rl"
445
462
 
446
463
  if (cs >= JSON_object_first_final) {
447
464
  if (json->create_additions) {
@@ -466,281 +483,358 @@ case 26:
466
483
 
467
484
 
468
485
 
469
- #line 470 "parser.c"
486
+ #line 487 "parser.c"
470
487
  enum {JSON_value_start = 1};
471
- enum {JSON_value_first_final = 21};
488
+ enum {JSON_value_first_final = 29};
472
489
  enum {JSON_value_error = 0};
473
490
 
474
491
  enum {JSON_value_en_main = 1};
475
492
 
476
493
 
477
- #line 271 "parser.rl"
494
+ #line 284 "parser.rl"
478
495
 
479
496
 
480
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
497
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
481
498
  {
482
499
  int cs = EVIL;
483
500
 
484
501
 
485
- #line 486 "parser.c"
502
+ #line 503 "parser.c"
486
503
  {
487
504
  cs = JSON_value_start;
488
505
  }
489
506
 
490
- #line 278 "parser.rl"
507
+ #line 291 "parser.rl"
491
508
 
492
- #line 493 "parser.c"
509
+ #line 510 "parser.c"
493
510
  {
494
511
  if ( p == pe )
495
512
  goto _test_eof;
496
513
  switch ( cs )
497
514
  {
515
+ st1:
516
+ if ( ++p == pe )
517
+ goto _test_eof1;
498
518
  case 1:
499
519
  switch( (*p) ) {
500
- case 34: goto tr0;
501
- case 45: goto tr2;
502
- case 73: goto st2;
503
- case 78: goto st9;
504
- case 91: goto tr5;
505
- case 102: goto st11;
506
- case 110: goto st15;
507
- case 116: goto st18;
508
- case 123: goto tr9;
520
+ case 13: goto st1;
521
+ case 32: goto st1;
522
+ case 34: goto tr2;
523
+ case 45: goto tr3;
524
+ case 47: goto st6;
525
+ case 73: goto st10;
526
+ case 78: goto st17;
527
+ case 91: goto tr7;
528
+ case 102: goto st19;
529
+ case 110: goto st23;
530
+ case 116: goto st26;
531
+ case 123: goto tr11;
509
532
  }
510
- if ( 48 <= (*p) && (*p) <= 57 )
511
- goto tr2;
533
+ if ( (*p) > 10 ) {
534
+ if ( 48 <= (*p) && (*p) <= 57 )
535
+ goto tr3;
536
+ } else if ( (*p) >= 9 )
537
+ goto st1;
512
538
  goto st0;
513
539
  st0:
514
540
  cs = 0;
515
541
  goto _out;
516
- tr0:
517
- #line 219 "parser.rl"
542
+ tr2:
543
+ #line 236 "parser.rl"
518
544
  {
519
545
  char *np = JSON_parse_string(json, p, pe, result);
520
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
546
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
521
547
  }
522
- goto st21;
523
- tr2:
524
- #line 224 "parser.rl"
548
+ goto st29;
549
+ tr3:
550
+ #line 241 "parser.rl"
525
551
  {
526
552
  char *np;
527
- if(pe > p + 9 - json->quirks_mode && !strncmp(MinusInfinity, p, 9)) {
553
+ if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
528
554
  if (json->allow_nan) {
529
555
  *result = CMinusInfinity;
530
556
  {p = (( p + 10))-1;}
531
- p--; {p++; cs = 21; goto _out;}
557
+ p--; {p++; cs = 29; goto _out;}
532
558
  } else {
533
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
559
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
534
560
  }
535
561
  }
536
562
  np = JSON_parse_float(json, p, pe, result);
537
563
  if (np != NULL) {p = (( np))-1;}
538
564
  np = JSON_parse_integer(json, p, pe, result);
539
565
  if (np != NULL) {p = (( np))-1;}
540
- p--; {p++; cs = 21; goto _out;}
566
+ p--; {p++; cs = 29; goto _out;}
541
567
  }
542
- goto st21;
543
- tr5:
544
- #line 242 "parser.rl"
568
+ goto st29;
569
+ tr7:
570
+ #line 259 "parser.rl"
545
571
  {
546
572
  char *np;
547
- json->current_nesting++;
548
- np = JSON_parse_array(json, p, pe, result);
549
- json->current_nesting--;
550
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
573
+ np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
574
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
551
575
  }
552
- goto st21;
553
- tr9:
554
- #line 250 "parser.rl"
576
+ goto st29;
577
+ tr11:
578
+ #line 265 "parser.rl"
555
579
  {
556
580
  char *np;
557
- json->current_nesting++;
558
- np = JSON_parse_object(json, p, pe, result);
559
- json->current_nesting--;
560
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
581
+ np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
582
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
561
583
  }
562
- goto st21;
563
- tr16:
564
- #line 212 "parser.rl"
584
+ goto st29;
585
+ tr25:
586
+ #line 229 "parser.rl"
565
587
  {
566
588
  if (json->allow_nan) {
567
589
  *result = CInfinity;
568
590
  } else {
569
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
591
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
570
592
  }
571
593
  }
572
- goto st21;
573
- tr18:
574
- #line 205 "parser.rl"
594
+ goto st29;
595
+ tr27:
596
+ #line 222 "parser.rl"
575
597
  {
576
598
  if (json->allow_nan) {
577
599
  *result = CNaN;
578
600
  } else {
579
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
601
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
580
602
  }
581
603
  }
582
- goto st21;
583
- tr22:
584
- #line 199 "parser.rl"
604
+ goto st29;
605
+ tr31:
606
+ #line 216 "parser.rl"
585
607
  {
586
608
  *result = Qfalse;
587
609
  }
588
- goto st21;
589
- tr25:
590
- #line 196 "parser.rl"
610
+ goto st29;
611
+ tr34:
612
+ #line 213 "parser.rl"
591
613
  {
592
614
  *result = Qnil;
593
615
  }
594
- goto st21;
595
- tr28:
596
- #line 202 "parser.rl"
616
+ goto st29;
617
+ tr37:
618
+ #line 219 "parser.rl"
597
619
  {
598
620
  *result = Qtrue;
599
621
  }
600
- goto st21;
601
- st21:
622
+ goto st29;
623
+ st29:
602
624
  if ( ++p == pe )
603
- goto _test_eof21;
604
- case 21:
605
- #line 258 "parser.rl"
606
- { p--; {p++; cs = 21; goto _out;} }
607
- #line 608 "parser.c"
625
+ goto _test_eof29;
626
+ case 29:
627
+ #line 271 "parser.rl"
628
+ { p--; {p++; cs = 29; goto _out;} }
629
+ #line 630 "parser.c"
630
+ switch( (*p) ) {
631
+ case 13: goto st29;
632
+ case 32: goto st29;
633
+ case 47: goto st2;
634
+ }
635
+ if ( 9 <= (*p) && (*p) <= 10 )
636
+ goto st29;
608
637
  goto st0;
609
638
  st2:
610
639
  if ( ++p == pe )
611
640
  goto _test_eof2;
612
641
  case 2:
613
- if ( (*p) == 110 )
614
- goto st3;
642
+ switch( (*p) ) {
643
+ case 42: goto st3;
644
+ case 47: goto st5;
645
+ }
615
646
  goto st0;
616
647
  st3:
617
648
  if ( ++p == pe )
618
649
  goto _test_eof3;
619
650
  case 3:
620
- if ( (*p) == 102 )
651
+ if ( (*p) == 42 )
621
652
  goto st4;
622
- goto st0;
653
+ goto st3;
623
654
  st4:
624
655
  if ( ++p == pe )
625
656
  goto _test_eof4;
626
657
  case 4:
627
- if ( (*p) == 105 )
628
- goto st5;
629
- goto st0;
658
+ switch( (*p) ) {
659
+ case 42: goto st4;
660
+ case 47: goto st29;
661
+ }
662
+ goto st3;
630
663
  st5:
631
664
  if ( ++p == pe )
632
665
  goto _test_eof5;
633
666
  case 5:
634
- if ( (*p) == 110 )
635
- goto st6;
636
- goto st0;
667
+ if ( (*p) == 10 )
668
+ goto st29;
669
+ goto st5;
637
670
  st6:
638
671
  if ( ++p == pe )
639
672
  goto _test_eof6;
640
673
  case 6:
641
- if ( (*p) == 105 )
642
- goto st7;
674
+ switch( (*p) ) {
675
+ case 42: goto st7;
676
+ case 47: goto st9;
677
+ }
643
678
  goto st0;
644
679
  st7:
645
680
  if ( ++p == pe )
646
681
  goto _test_eof7;
647
682
  case 7:
648
- if ( (*p) == 116 )
683
+ if ( (*p) == 42 )
649
684
  goto st8;
650
- goto st0;
685
+ goto st7;
651
686
  st8:
652
687
  if ( ++p == pe )
653
688
  goto _test_eof8;
654
689
  case 8:
655
- if ( (*p) == 121 )
656
- goto tr16;
657
- goto st0;
690
+ switch( (*p) ) {
691
+ case 42: goto st8;
692
+ case 47: goto st1;
693
+ }
694
+ goto st7;
658
695
  st9:
659
696
  if ( ++p == pe )
660
697
  goto _test_eof9;
661
698
  case 9:
662
- if ( (*p) == 97 )
663
- goto st10;
664
- goto st0;
699
+ if ( (*p) == 10 )
700
+ goto st1;
701
+ goto st9;
665
702
  st10:
666
703
  if ( ++p == pe )
667
704
  goto _test_eof10;
668
705
  case 10:
669
- if ( (*p) == 78 )
670
- goto tr18;
706
+ if ( (*p) == 110 )
707
+ goto st11;
671
708
  goto st0;
672
709
  st11:
673
710
  if ( ++p == pe )
674
711
  goto _test_eof11;
675
712
  case 11:
676
- if ( (*p) == 97 )
713
+ if ( (*p) == 102 )
677
714
  goto st12;
678
715
  goto st0;
679
716
  st12:
680
717
  if ( ++p == pe )
681
718
  goto _test_eof12;
682
719
  case 12:
683
- if ( (*p) == 108 )
720
+ if ( (*p) == 105 )
684
721
  goto st13;
685
722
  goto st0;
686
723
  st13:
687
724
  if ( ++p == pe )
688
725
  goto _test_eof13;
689
726
  case 13:
690
- if ( (*p) == 115 )
727
+ if ( (*p) == 110 )
691
728
  goto st14;
692
729
  goto st0;
693
730
  st14:
694
731
  if ( ++p == pe )
695
732
  goto _test_eof14;
696
733
  case 14:
697
- if ( (*p) == 101 )
698
- goto tr22;
734
+ if ( (*p) == 105 )
735
+ goto st15;
699
736
  goto st0;
700
737
  st15:
701
738
  if ( ++p == pe )
702
739
  goto _test_eof15;
703
740
  case 15:
704
- if ( (*p) == 117 )
741
+ if ( (*p) == 116 )
705
742
  goto st16;
706
743
  goto st0;
707
744
  st16:
708
745
  if ( ++p == pe )
709
746
  goto _test_eof16;
710
747
  case 16:
711
- if ( (*p) == 108 )
712
- goto st17;
748
+ if ( (*p) == 121 )
749
+ goto tr25;
713
750
  goto st0;
714
751
  st17:
715
752
  if ( ++p == pe )
716
753
  goto _test_eof17;
717
754
  case 17:
718
- if ( (*p) == 108 )
719
- goto tr25;
755
+ if ( (*p) == 97 )
756
+ goto st18;
720
757
  goto st0;
721
758
  st18:
722
759
  if ( ++p == pe )
723
760
  goto _test_eof18;
724
761
  case 18:
725
- if ( (*p) == 114 )
726
- goto st19;
762
+ if ( (*p) == 78 )
763
+ goto tr27;
727
764
  goto st0;
728
765
  st19:
729
766
  if ( ++p == pe )
730
767
  goto _test_eof19;
731
768
  case 19:
732
- if ( (*p) == 117 )
769
+ if ( (*p) == 97 )
733
770
  goto st20;
734
771
  goto st0;
735
772
  st20:
736
773
  if ( ++p == pe )
737
774
  goto _test_eof20;
738
775
  case 20:
776
+ if ( (*p) == 108 )
777
+ goto st21;
778
+ goto st0;
779
+ st21:
780
+ if ( ++p == pe )
781
+ goto _test_eof21;
782
+ case 21:
783
+ if ( (*p) == 115 )
784
+ goto st22;
785
+ goto st0;
786
+ st22:
787
+ if ( ++p == pe )
788
+ goto _test_eof22;
789
+ case 22:
739
790
  if ( (*p) == 101 )
740
- goto tr28;
791
+ goto tr31;
792
+ goto st0;
793
+ st23:
794
+ if ( ++p == pe )
795
+ goto _test_eof23;
796
+ case 23:
797
+ if ( (*p) == 117 )
798
+ goto st24;
799
+ goto st0;
800
+ st24:
801
+ if ( ++p == pe )
802
+ goto _test_eof24;
803
+ case 24:
804
+ if ( (*p) == 108 )
805
+ goto st25;
806
+ goto st0;
807
+ st25:
808
+ if ( ++p == pe )
809
+ goto _test_eof25;
810
+ case 25:
811
+ if ( (*p) == 108 )
812
+ goto tr34;
813
+ goto st0;
814
+ st26:
815
+ if ( ++p == pe )
816
+ goto _test_eof26;
817
+ case 26:
818
+ if ( (*p) == 114 )
819
+ goto st27;
820
+ goto st0;
821
+ st27:
822
+ if ( ++p == pe )
823
+ goto _test_eof27;
824
+ case 27:
825
+ if ( (*p) == 117 )
826
+ goto st28;
827
+ goto st0;
828
+ st28:
829
+ if ( ++p == pe )
830
+ goto _test_eof28;
831
+ case 28:
832
+ if ( (*p) == 101 )
833
+ goto tr37;
741
834
  goto st0;
742
835
  }
743
- _test_eof21: cs = 21; goto _test_eof;
836
+ _test_eof1: cs = 1; goto _test_eof;
837
+ _test_eof29: cs = 29; goto _test_eof;
744
838
  _test_eof2: cs = 2; goto _test_eof;
745
839
  _test_eof3: cs = 3; goto _test_eof;
746
840
  _test_eof4: cs = 4; goto _test_eof;
@@ -760,12 +854,24 @@ case 20:
760
854
  _test_eof18: cs = 18; goto _test_eof;
761
855
  _test_eof19: cs = 19; goto _test_eof;
762
856
  _test_eof20: cs = 20; goto _test_eof;
857
+ _test_eof21: cs = 21; goto _test_eof;
858
+ _test_eof22: cs = 22; goto _test_eof;
859
+ _test_eof23: cs = 23; goto _test_eof;
860
+ _test_eof24: cs = 24; goto _test_eof;
861
+ _test_eof25: cs = 25; goto _test_eof;
862
+ _test_eof26: cs = 26; goto _test_eof;
863
+ _test_eof27: cs = 27; goto _test_eof;
864
+ _test_eof28: cs = 28; goto _test_eof;
763
865
 
764
866
  _test_eof: {}
765
867
  _out: {}
766
868
  }
767
869
 
768
- #line 279 "parser.rl"
870
+ #line 292 "parser.rl"
871
+
872
+ if (json->freeze) {
873
+ OBJ_FREEZE(*result);
874
+ }
769
875
 
770
876
  if (cs >= JSON_value_first_final) {
771
877
  return p;
@@ -775,7 +881,7 @@ case 20:
775
881
  }
776
882
 
777
883
 
778
- #line 779 "parser.c"
884
+ #line 885 "parser.c"
779
885
  enum {JSON_integer_start = 1};
780
886
  enum {JSON_integer_first_final = 3};
781
887
  enum {JSON_integer_error = 0};
@@ -783,7 +889,7 @@ enum {JSON_integer_error = 0};
783
889
  enum {JSON_integer_en_main = 1};
784
890
 
785
891
 
786
- #line 295 "parser.rl"
892
+ #line 312 "parser.rl"
787
893
 
788
894
 
789
895
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -791,15 +897,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
791
897
  int cs = EVIL;
792
898
 
793
899
 
794
- #line 795 "parser.c"
900
+ #line 901 "parser.c"
795
901
  {
796
902
  cs = JSON_integer_start;
797
903
  }
798
904
 
799
- #line 302 "parser.rl"
905
+ #line 319 "parser.rl"
800
906
  json->memo = p;
801
907
 
802
- #line 803 "parser.c"
908
+ #line 909 "parser.c"
803
909
  {
804
910
  if ( p == pe )
805
911
  goto _test_eof;
@@ -833,14 +939,14 @@ case 3:
833
939
  goto st0;
834
940
  goto tr4;
835
941
  tr4:
836
- #line 292 "parser.rl"
942
+ #line 309 "parser.rl"
837
943
  { p--; {p++; cs = 4; goto _out;} }
838
944
  goto st4;
839
945
  st4:
840
946
  if ( ++p == pe )
841
947
  goto _test_eof4;
842
948
  case 4:
843
- #line 844 "parser.c"
949
+ #line 950 "parser.c"
844
950
  goto st0;
845
951
  st5:
846
952
  if ( ++p == pe )
@@ -859,7 +965,7 @@ case 5:
859
965
  _out: {}
860
966
  }
861
967
 
862
- #line 304 "parser.rl"
968
+ #line 321 "parser.rl"
863
969
 
864
970
  if (cs >= JSON_integer_first_final) {
865
971
  long len = p - json->memo;
@@ -874,7 +980,7 @@ case 5:
874
980
  }
875
981
 
876
982
 
877
- #line 878 "parser.c"
983
+ #line 984 "parser.c"
878
984
  enum {JSON_float_start = 1};
879
985
  enum {JSON_float_first_final = 8};
880
986
  enum {JSON_float_error = 0};
@@ -882,23 +988,36 @@ enum {JSON_float_error = 0};
882
988
  enum {JSON_float_en_main = 1};
883
989
 
884
990
 
885
- #line 329 "parser.rl"
991
+ #line 346 "parser.rl"
992
+
886
993
 
994
+ static int is_bigdecimal_class(VALUE obj)
995
+ {
996
+ if (cBigDecimal == Qundef) {
997
+ if (rb_const_defined(rb_cObject, i_BigDecimal)) {
998
+ cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
999
+ }
1000
+ else {
1001
+ return 0;
1002
+ }
1003
+ }
1004
+ return obj == cBigDecimal;
1005
+ }
887
1006
 
888
1007
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
889
1008
  {
890
1009
  int cs = EVIL;
891
1010
 
892
1011
 
893
- #line 894 "parser.c"
1012
+ #line 1013 "parser.c"
894
1013
  {
895
1014
  cs = JSON_float_start;
896
1015
  }
897
1016
 
898
- #line 336 "parser.rl"
1017
+ #line 366 "parser.rl"
899
1018
  json->memo = p;
900
1019
 
901
- #line 902 "parser.c"
1020
+ #line 1021 "parser.c"
902
1021
  {
903
1022
  if ( p == pe )
904
1023
  goto _test_eof;
@@ -956,14 +1075,14 @@ case 8:
956
1075
  goto st0;
957
1076
  goto tr9;
958
1077
  tr9:
959
- #line 323 "parser.rl"
1078
+ #line 340 "parser.rl"
960
1079
  { p--; {p++; cs = 9; goto _out;} }
961
1080
  goto st9;
962
1081
  st9:
963
1082
  if ( ++p == pe )
964
1083
  goto _test_eof9;
965
1084
  case 9:
966
- #line 967 "parser.c"
1085
+ #line 1086 "parser.c"
967
1086
  goto st0;
968
1087
  st5:
969
1088
  if ( ++p == pe )
@@ -1024,14 +1143,24 @@ case 7:
1024
1143
  _out: {}
1025
1144
  }
1026
1145
 
1027
- #line 338 "parser.rl"
1146
+ #line 368 "parser.rl"
1028
1147
 
1029
1148
  if (cs >= JSON_float_first_final) {
1030
1149
  long len = p - json->memo;
1031
1150
  fbuffer_clear(json->fbuffer);
1032
1151
  fbuffer_append(json->fbuffer, json->memo, len);
1033
1152
  fbuffer_append_char(json->fbuffer, '\0');
1034
- *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1153
+ if (NIL_P(json->decimal_class)) {
1154
+ *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1155
+ } else {
1156
+ VALUE text;
1157
+ text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
1158
+ if (is_bigdecimal_class(json->decimal_class)) {
1159
+ *result = rb_funcall(Qnil, i_BigDecimal, 1, text);
1160
+ } else {
1161
+ *result = rb_funcall(json->decimal_class, i_new, 1, text);
1162
+ }
1163
+ }
1035
1164
  return p + 1;
1036
1165
  } else {
1037
1166
  return NULL;
@@ -1040,7 +1169,7 @@ case 7:
1040
1169
 
1041
1170
 
1042
1171
 
1043
- #line 1044 "parser.c"
1172
+ #line 1173 "parser.c"
1044
1173
  enum {JSON_array_start = 1};
1045
1174
  enum {JSON_array_first_final = 17};
1046
1175
  enum {JSON_array_error = 0};
@@ -1048,28 +1177,28 @@ enum {JSON_array_error = 0};
1048
1177
  enum {JSON_array_en_main = 1};
1049
1178
 
1050
1179
 
1051
- #line 381 "parser.rl"
1180
+ #line 421 "parser.rl"
1052
1181
 
1053
1182
 
1054
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
1183
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
1055
1184
  {
1056
1185
  int cs = EVIL;
1057
1186
  VALUE array_class = json->array_class;
1058
1187
 
1059
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
1060
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
1188
+ if (json->max_nesting && current_nesting > json->max_nesting) {
1189
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
1061
1190
  }
1062
1191
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1063
1192
 
1064
1193
 
1065
- #line 1066 "parser.c"
1194
+ #line 1195 "parser.c"
1066
1195
  {
1067
1196
  cs = JSON_array_start;
1068
1197
  }
1069
1198
 
1070
- #line 394 "parser.rl"
1199
+ #line 434 "parser.rl"
1071
1200
 
1072
- #line 1073 "parser.c"
1201
+ #line 1202 "parser.c"
1073
1202
  {
1074
1203
  if ( p == pe )
1075
1204
  goto _test_eof;
@@ -1108,10 +1237,10 @@ case 2:
1108
1237
  goto st2;
1109
1238
  goto st0;
1110
1239
  tr2:
1111
- #line 358 "parser.rl"
1240
+ #line 398 "parser.rl"
1112
1241
  {
1113
1242
  VALUE v = Qnil;
1114
- char *np = JSON_parse_value(json, p, pe, &v);
1243
+ char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
1115
1244
  if (np == NULL) {
1116
1245
  p--; {p++; cs = 3; goto _out;}
1117
1246
  } else {
@@ -1128,7 +1257,7 @@ st3:
1128
1257
  if ( ++p == pe )
1129
1258
  goto _test_eof3;
1130
1259
  case 3:
1131
- #line 1132 "parser.c"
1260
+ #line 1261 "parser.c"
1132
1261
  switch( (*p) ) {
1133
1262
  case 13: goto st3;
1134
1263
  case 32: goto st3;
@@ -1228,14 +1357,14 @@ case 12:
1228
1357
  goto st3;
1229
1358
  goto st12;
1230
1359
  tr4:
1231
- #line 373 "parser.rl"
1360
+ #line 413 "parser.rl"
1232
1361
  { p--; {p++; cs = 17; goto _out;} }
1233
1362
  goto st17;
1234
1363
  st17:
1235
1364
  if ( ++p == pe )
1236
1365
  goto _test_eof17;
1237
1366
  case 17:
1238
- #line 1239 "parser.c"
1367
+ #line 1368 "parser.c"
1239
1368
  goto st0;
1240
1369
  st13:
1241
1370
  if ( ++p == pe )
@@ -1291,12 +1420,12 @@ case 16:
1291
1420
  _out: {}
1292
1421
  }
1293
1422
 
1294
- #line 395 "parser.rl"
1423
+ #line 435 "parser.rl"
1295
1424
 
1296
1425
  if(cs >= JSON_array_first_final) {
1297
1426
  return p + 1;
1298
1427
  } else {
1299
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1428
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1300
1429
  return NULL;
1301
1430
  }
1302
1431
  }
@@ -1336,13 +1465,21 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1336
1465
  break;
1337
1466
  case 'u':
1338
1467
  if (pe > stringEnd - 4) {
1339
- return Qnil;
1468
+ rb_enc_raise(
1469
+ EXC_ENCODING eParserError,
1470
+ "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
1471
+ );
1340
1472
  } else {
1341
1473
  UTF32 ch = unescape_unicode((unsigned char *) ++pe);
1342
1474
  pe += 3;
1343
1475
  if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
1344
1476
  pe++;
1345
- if (pe > stringEnd - 6) return Qnil;
1477
+ if (pe > stringEnd - 6) {
1478
+ rb_enc_raise(
1479
+ EXC_ENCODING eParserError,
1480
+ "%u: incomplete surrogate pair at '%s'", __LINE__, p
1481
+ );
1482
+ }
1346
1483
  if (pe[0] == '\\' && pe[1] == 'u') {
1347
1484
  UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
1348
1485
  ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
@@ -1372,7 +1509,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1372
1509
  }
1373
1510
 
1374
1511
 
1375
- #line 1376 "parser.c"
1512
+ #line 1513 "parser.c"
1376
1513
  enum {JSON_string_start = 1};
1377
1514
  enum {JSON_string_first_final = 8};
1378
1515
  enum {JSON_string_error = 0};
@@ -1380,7 +1517,7 @@ enum {JSON_string_error = 0};
1380
1517
  enum {JSON_string_en_main = 1};
1381
1518
 
1382
1519
 
1383
- #line 494 "parser.rl"
1520
+ #line 542 "parser.rl"
1384
1521
 
1385
1522
 
1386
1523
  static int
@@ -1402,15 +1539,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
1402
1539
 
1403
1540
  *result = rb_str_buf_new(0);
1404
1541
 
1405
- #line 1406 "parser.c"
1542
+ #line 1543 "parser.c"
1406
1543
  {
1407
1544
  cs = JSON_string_start;
1408
1545
  }
1409
1546
 
1410
- #line 515 "parser.rl"
1547
+ #line 563 "parser.rl"
1411
1548
  json->memo = p;
1412
1549
 
1413
- #line 1414 "parser.c"
1550
+ #line 1551 "parser.c"
1414
1551
  {
1415
1552
  if ( p == pe )
1416
1553
  goto _test_eof;
@@ -1431,11 +1568,11 @@ case 2:
1431
1568
  case 34: goto tr2;
1432
1569
  case 92: goto st3;
1433
1570
  }
1434
- if ( 0 <= (*p) && (*p) <= 31 )
1571
+ if ( 0 <= (signed char)(*p) && (*p) <= 31 )
1435
1572
  goto st0;
1436
1573
  goto st2;
1437
1574
  tr2:
1438
- #line 480 "parser.rl"
1575
+ #line 528 "parser.rl"
1439
1576
  {
1440
1577
  *result = json_string_unescape(*result, json->memo + 1, p);
1441
1578
  if (NIL_P(*result)) {
@@ -1446,14 +1583,14 @@ tr2:
1446
1583
  {p = (( p + 1))-1;}
1447
1584
  }
1448
1585
  }
1449
- #line 491 "parser.rl"
1586
+ #line 539 "parser.rl"
1450
1587
  { p--; {p++; cs = 8; goto _out;} }
1451
1588
  goto st8;
1452
1589
  st8:
1453
1590
  if ( ++p == pe )
1454
1591
  goto _test_eof8;
1455
1592
  case 8:
1456
- #line 1457 "parser.c"
1593
+ #line 1594 "parser.c"
1457
1594
  goto st0;
1458
1595
  st3:
1459
1596
  if ( ++p == pe )
@@ -1461,7 +1598,7 @@ st3:
1461
1598
  case 3:
1462
1599
  if ( (*p) == 117 )
1463
1600
  goto st4;
1464
- if ( 0 <= (*p) && (*p) <= 31 )
1601
+ if ( 0 <= (signed char)(*p) && (*p) <= 31 )
1465
1602
  goto st0;
1466
1603
  goto st2;
1467
1604
  st4:
@@ -1529,7 +1666,7 @@ case 7:
1529
1666
  _out: {}
1530
1667
  }
1531
1668
 
1532
- #line 517 "parser.rl"
1669
+ #line 565 "parser.rl"
1533
1670
 
1534
1671
  if (json->create_additions && RTEST(match_string = json->match_string)) {
1535
1672
  VALUE klass;
@@ -1544,6 +1681,23 @@ case 7:
1544
1681
 
1545
1682
  if (json->symbolize_names && json->parsing_name) {
1546
1683
  *result = rb_str_intern(*result);
1684
+ } else if (RB_TYPE_P(*result, T_STRING)) {
1685
+ # if STR_UMINUS_DEDUPE_FROZEN
1686
+ if (json->freeze) {
1687
+ // Starting from MRI 2.8 it is preferable to freeze the string
1688
+ // before deduplication so that it can be interned directly
1689
+ // otherwise it would be duplicated first which is wasteful.
1690
+ *result = rb_funcall(rb_str_freeze(*result), i_uminus, 0);
1691
+ }
1692
+ # elif STR_UMINUS_DEDUPE
1693
+ if (json->freeze) {
1694
+ // MRI 2.5 and older do not deduplicate strings that are already
1695
+ // frozen.
1696
+ *result = rb_funcall(*result, i_uminus, 0);
1697
+ }
1698
+ # else
1699
+ rb_str_resize(*result, RSTRING_LEN(*result));
1700
+ # endif
1547
1701
  }
1548
1702
  if (cs >= JSON_string_first_final) {
1549
1703
  return p + 1;
@@ -1566,41 +1720,16 @@ case 7:
1566
1720
 
1567
1721
  static VALUE convert_encoding(VALUE source)
1568
1722
  {
1569
- char *ptr = RSTRING_PTR(source);
1570
- long len = RSTRING_LEN(source);
1571
- if (len < 2) {
1572
- rb_raise(eParserError, "A JSON text must at least contain two octets!");
1573
- }
1574
1723
  #ifdef HAVE_RUBY_ENCODING_H
1575
- {
1576
- VALUE encoding = rb_funcall(source, i_encoding, 0);
1577
- if (encoding == CEncoding_ASCII_8BIT) {
1578
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1579
- source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32BE);
1580
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1581
- source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16BE);
1582
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1583
- source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32LE);
1584
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1585
- source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16LE);
1586
- } else {
1587
- source = rb_str_dup(source);
1588
- FORCE_UTF8(source);
1589
- }
1590
- } else {
1591
- source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8);
1592
- }
1593
- }
1594
- #else
1595
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1596
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
1597
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1598
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
1599
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1600
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
1601
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1602
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
1724
+ rb_encoding *enc = rb_enc_get(source);
1725
+ if (enc == rb_ascii8bit_encoding()) {
1726
+ if (OBJ_FROZEN(source)) {
1727
+ source = rb_str_dup(source);
1603
1728
  }
1729
+ FORCE_UTF8(source);
1730
+ } else {
1731
+ source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
1732
+ }
1604
1733
  #endif
1605
1734
  return source;
1606
1735
  }
@@ -1623,8 +1752,9 @@ static VALUE convert_encoding(VALUE source)
1623
1752
  * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
1624
1753
  * false.
1625
1754
  * * *symbolize_names*: If set to true, returns symbols for the names
1626
- * (keys) in a JSON object. Otherwise strings are returned, which is also
1627
- * the default.
1755
+ * (keys) in a JSON object. Otherwise strings are returned, which is
1756
+ * also the default. It's not possible to use this option in
1757
+ * conjunction with the *create_additions* option.
1628
1758
  * * *create_additions*: If set to false, the Parser doesn't create
1629
1759
  * additions even if a matching class and create_id was found. This option
1630
1760
  * defaults to false.
@@ -1639,12 +1769,18 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1639
1769
  if (json->Vsource) {
1640
1770
  rb_raise(rb_eTypeError, "already initialized instance");
1641
1771
  }
1772
+ #ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1773
+ rb_scan_args(argc, argv, "1:", &source, &opts);
1774
+ #else
1642
1775
  rb_scan_args(argc, argv, "11", &source, &opts);
1776
+ #endif
1643
1777
  if (!NIL_P(opts)) {
1778
+ #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1644
1779
  opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
1645
1780
  if (NIL_P(opts)) {
1646
1781
  rb_raise(rb_eArgError, "opts needs to be like a hash");
1647
1782
  } else {
1783
+ #endif
1648
1784
  VALUE tmp = ID2SYM(i_max_nesting);
1649
1785
  if (option_given_p(opts, tmp)) {
1650
1786
  VALUE max_nesting = rb_hash_aref(opts, tmp);
@@ -1669,12 +1805,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1669
1805
  } else {
1670
1806
  json->symbolize_names = 0;
1671
1807
  }
1672
- tmp = ID2SYM(i_quirks_mode);
1808
+ tmp = ID2SYM(i_freeze);
1673
1809
  if (option_given_p(opts, tmp)) {
1674
- VALUE quirks_mode = rb_hash_aref(opts, tmp);
1675
- json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
1810
+ json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1676
1811
  } else {
1677
- json->quirks_mode = 0;
1812
+ json->freeze = 0;
1678
1813
  }
1679
1814
  tmp = ID2SYM(i_create_additions);
1680
1815
  if (option_given_p(opts, tmp)) {
@@ -1682,6 +1817,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1682
1817
  } else {
1683
1818
  json->create_additions = 0;
1684
1819
  }
1820
+ if (json->symbolize_names && json->create_additions) {
1821
+ rb_raise(rb_eArgError,
1822
+ "options :symbolize_names and :create_additions cannot be "
1823
+ " used in conjunction");
1824
+ }
1685
1825
  tmp = ID2SYM(i_create_id);
1686
1826
  if (option_given_p(opts, tmp)) {
1687
1827
  json->create_id = rb_hash_aref(opts, tmp);
@@ -1700,6 +1840,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1700
1840
  } else {
1701
1841
  json->array_class = Qnil;
1702
1842
  }
1843
+ tmp = ID2SYM(i_decimal_class);
1844
+ if (option_given_p(opts, tmp)) {
1845
+ json->decimal_class = rb_hash_aref(opts, tmp);
1846
+ } else {
1847
+ json->decimal_class = Qnil;
1848
+ }
1703
1849
  tmp = ID2SYM(i_match_string);
1704
1850
  if (option_given_p(opts, tmp)) {
1705
1851
  VALUE match_string = rb_hash_aref(opts, tmp);
@@ -1707,20 +1853,19 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1707
1853
  } else {
1708
1854
  json->match_string = Qnil;
1709
1855
  }
1856
+ #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1710
1857
  }
1858
+ #endif
1711
1859
  } else {
1712
1860
  json->max_nesting = 100;
1713
1861
  json->allow_nan = 0;
1714
- json->create_additions = 1;
1862
+ json->create_additions = 0;
1715
1863
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
1716
1864
  json->object_class = Qnil;
1717
1865
  json->array_class = Qnil;
1866
+ json->decimal_class = Qnil;
1718
1867
  }
1719
- source = rb_convert_type(source, T_STRING, "String", "to_str");
1720
- if (!json->quirks_mode) {
1721
- source = convert_encoding(StringValue(source));
1722
- }
1723
- json->current_nesting = 0;
1868
+ source = convert_encoding(StringValue(source));
1724
1869
  StringValue(source);
1725
1870
  json->len = RSTRING_LEN(source);
1726
1871
  json->source = RSTRING_PTR(source);;
@@ -1729,7 +1874,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1729
1874
  }
1730
1875
 
1731
1876
 
1732
- #line 1733 "parser.c"
1877
+ #line 1878 "parser.c"
1733
1878
  enum {JSON_start = 1};
1734
1879
  enum {JSON_first_final = 10};
1735
1880
  enum {JSON_error = 0};
@@ -1737,201 +1882,33 @@ enum {JSON_error = 0};
1737
1882
  enum {JSON_en_main = 1};
1738
1883
 
1739
1884
 
1740
- #line 740 "parser.rl"
1885
+ #line 786 "parser.rl"
1741
1886
 
1742
1887
 
1743
- static VALUE cParser_parse_strict(VALUE self)
1888
+ /*
1889
+ * call-seq: parse()
1890
+ *
1891
+ * Parses the current JSON text _source_ and returns the complete data
1892
+ * structure as a result.
1893
+ */
1894
+ static VALUE cParser_parse(VALUE self)
1744
1895
  {
1745
- char *p, *pe;
1746
- int cs = EVIL;
1747
- VALUE result = Qnil;
1748
- GET_PARSER;
1896
+ char *p, *pe;
1897
+ int cs = EVIL;
1898
+ VALUE result = Qnil;
1899
+ GET_PARSER;
1749
1900
 
1750
1901
 
1751
- #line 1752 "parser.c"
1902
+ #line 1903 "parser.c"
1752
1903
  {
1753
1904
  cs = JSON_start;
1754
1905
  }
1755
1906
 
1756
- #line 750 "parser.rl"
1757
- p = json->source;
1758
- pe = p + json->len;
1907
+ #line 802 "parser.rl"
1908
+ p = json->source;
1909
+ pe = p + json->len;
1759
1910
 
1760
- #line 1761 "parser.c"
1761
- {
1762
- if ( p == pe )
1763
- goto _test_eof;
1764
- switch ( cs )
1765
- {
1766
- st1:
1767
- if ( ++p == pe )
1768
- goto _test_eof1;
1769
- case 1:
1770
- switch( (*p) ) {
1771
- case 13: goto st1;
1772
- case 32: goto st1;
1773
- case 47: goto st2;
1774
- case 91: goto tr3;
1775
- case 123: goto tr4;
1776
- }
1777
- if ( 9 <= (*p) && (*p) <= 10 )
1778
- goto st1;
1779
- goto st0;
1780
- st0:
1781
- cs = 0;
1782
- goto _out;
1783
- st2:
1784
- if ( ++p == pe )
1785
- goto _test_eof2;
1786
- case 2:
1787
- switch( (*p) ) {
1788
- case 42: goto st3;
1789
- case 47: goto st5;
1790
- }
1791
- goto st0;
1792
- st3:
1793
- if ( ++p == pe )
1794
- goto _test_eof3;
1795
- case 3:
1796
- if ( (*p) == 42 )
1797
- goto st4;
1798
- goto st3;
1799
- st4:
1800
- if ( ++p == pe )
1801
- goto _test_eof4;
1802
- case 4:
1803
- switch( (*p) ) {
1804
- case 42: goto st4;
1805
- case 47: goto st1;
1806
- }
1807
- goto st3;
1808
- st5:
1809
- if ( ++p == pe )
1810
- goto _test_eof5;
1811
- case 5:
1812
- if ( (*p) == 10 )
1813
- goto st1;
1814
- goto st5;
1815
- tr3:
1816
- #line 729 "parser.rl"
1817
- {
1818
- char *np;
1819
- json->current_nesting = 1;
1820
- np = JSON_parse_array(json, p, pe, &result);
1821
- if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1822
- }
1823
- goto st10;
1824
- tr4:
1825
- #line 722 "parser.rl"
1826
- {
1827
- char *np;
1828
- json->current_nesting = 1;
1829
- np = JSON_parse_object(json, p, pe, &result);
1830
- if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1831
- }
1832
- goto st10;
1833
- st10:
1834
- if ( ++p == pe )
1835
- goto _test_eof10;
1836
- case 10:
1837
- #line 1838 "parser.c"
1838
- switch( (*p) ) {
1839
- case 13: goto st10;
1840
- case 32: goto st10;
1841
- case 47: goto st6;
1842
- }
1843
- if ( 9 <= (*p) && (*p) <= 10 )
1844
- goto st10;
1845
- goto st0;
1846
- st6:
1847
- if ( ++p == pe )
1848
- goto _test_eof6;
1849
- case 6:
1850
- switch( (*p) ) {
1851
- case 42: goto st7;
1852
- case 47: goto st9;
1853
- }
1854
- goto st0;
1855
- st7:
1856
- if ( ++p == pe )
1857
- goto _test_eof7;
1858
- case 7:
1859
- if ( (*p) == 42 )
1860
- goto st8;
1861
- goto st7;
1862
- st8:
1863
- if ( ++p == pe )
1864
- goto _test_eof8;
1865
- case 8:
1866
- switch( (*p) ) {
1867
- case 42: goto st8;
1868
- case 47: goto st10;
1869
- }
1870
- goto st7;
1871
- st9:
1872
- if ( ++p == pe )
1873
- goto _test_eof9;
1874
- case 9:
1875
- if ( (*p) == 10 )
1876
- goto st10;
1877
- goto st9;
1878
- }
1879
- _test_eof1: cs = 1; goto _test_eof;
1880
- _test_eof2: cs = 2; goto _test_eof;
1881
- _test_eof3: cs = 3; goto _test_eof;
1882
- _test_eof4: cs = 4; goto _test_eof;
1883
- _test_eof5: cs = 5; goto _test_eof;
1884
- _test_eof10: cs = 10; goto _test_eof;
1885
- _test_eof6: cs = 6; goto _test_eof;
1886
- _test_eof7: cs = 7; goto _test_eof;
1887
- _test_eof8: cs = 8; goto _test_eof;
1888
- _test_eof9: cs = 9; goto _test_eof;
1889
-
1890
- _test_eof: {}
1891
- _out: {}
1892
- }
1893
-
1894
- #line 753 "parser.rl"
1895
-
1896
- if (cs >= JSON_first_final && p == pe) {
1897
- return result;
1898
- } else {
1899
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1900
- return Qnil;
1901
- }
1902
- }
1903
-
1904
-
1905
-
1906
- #line 1907 "parser.c"
1907
- enum {JSON_quirks_mode_start = 1};
1908
- enum {JSON_quirks_mode_first_final = 10};
1909
- enum {JSON_quirks_mode_error = 0};
1910
-
1911
- enum {JSON_quirks_mode_en_main = 1};
1912
-
1913
-
1914
- #line 778 "parser.rl"
1915
-
1916
-
1917
- static VALUE cParser_parse_quirks_mode(VALUE self)
1918
- {
1919
- char *p, *pe;
1920
- int cs = EVIL;
1921
- VALUE result = Qnil;
1922
- GET_PARSER;
1923
-
1924
-
1925
- #line 1926 "parser.c"
1926
- {
1927
- cs = JSON_quirks_mode_start;
1928
- }
1929
-
1930
- #line 788 "parser.rl"
1931
- p = json->source;
1932
- pe = p + json->len;
1933
-
1934
- #line 1935 "parser.c"
1911
+ #line 1912 "parser.c"
1935
1912
  {
1936
1913
  if ( p == pe )
1937
1914
  goto _test_eof;
@@ -1965,9 +1942,9 @@ st0:
1965
1942
  cs = 0;
1966
1943
  goto _out;
1967
1944
  tr2:
1968
- #line 770 "parser.rl"
1945
+ #line 778 "parser.rl"
1969
1946
  {
1970
- char *np = JSON_parse_value(json, p, pe, &result);
1947
+ char *np = JSON_parse_value(json, p, pe, &result, 0);
1971
1948
  if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1972
1949
  }
1973
1950
  goto st10;
@@ -1975,7 +1952,7 @@ st10:
1975
1952
  if ( ++p == pe )
1976
1953
  goto _test_eof10;
1977
1954
  case 10:
1978
- #line 1979 "parser.c"
1955
+ #line 1956 "parser.c"
1979
1956
  switch( (*p) ) {
1980
1957
  case 13: goto st10;
1981
1958
  case 32: goto st10;
@@ -2064,30 +2041,13 @@ case 9:
2064
2041
  _out: {}
2065
2042
  }
2066
2043
 
2067
- #line 791 "parser.rl"
2068
-
2069
- if (cs >= JSON_quirks_mode_first_final && p == pe) {
2070
- return result;
2071
- } else {
2072
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
2073
- return Qnil;
2074
- }
2075
- }
2076
-
2077
- /*
2078
- * call-seq: parse()
2079
- *
2080
- * Parses the current JSON text _source_ and returns the complete data
2081
- * structure as a result.
2082
- */
2083
- static VALUE cParser_parse(VALUE self)
2084
- {
2085
- GET_PARSER;
2044
+ #line 805 "parser.rl"
2086
2045
 
2087
- if (json->quirks_mode) {
2088
- return cParser_parse_quirks_mode(self);
2046
+ if (cs >= JSON_first_final && p == pe) {
2047
+ return result;
2089
2048
  } else {
2090
- return cParser_parse_strict(self);
2049
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
2050
+ return Qnil;
2091
2051
  }
2092
2052
  }
2093
2053
 
@@ -2098,6 +2058,7 @@ static void JSON_mark(void *ptr)
2098
2058
  rb_gc_mark_maybe(json->create_id);
2099
2059
  rb_gc_mark_maybe(json->object_class);
2100
2060
  rb_gc_mark_maybe(json->array_class);
2061
+ rb_gc_mark_maybe(json->decimal_class);
2101
2062
  rb_gc_mark_maybe(json->match_string);
2102
2063
  }
2103
2064
 
@@ -2145,35 +2106,30 @@ static VALUE cParser_source(VALUE self)
2145
2106
  return rb_str_dup(json->Vsource);
2146
2107
  }
2147
2108
 
2148
- /*
2149
- * call-seq: quirks_mode?()
2150
- *
2151
- * Returns a true, if this parser is in quirks_mode, false otherwise.
2152
- */
2153
- static VALUE cParser_quirks_mode_p(VALUE self)
2154
- {
2155
- GET_PARSER;
2156
- return json->quirks_mode ? Qtrue : Qfalse;
2157
- }
2158
-
2159
-
2160
2109
  void Init_parser(void)
2161
2110
  {
2111
+ #undef rb_intern
2162
2112
  rb_require("json/common");
2163
2113
  mJSON = rb_define_module("JSON");
2164
2114
  mExt = rb_define_module_under(mJSON, "Ext");
2165
2115
  cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
2166
2116
  eParserError = rb_path2class("JSON::ParserError");
2167
2117
  eNestingError = rb_path2class("JSON::NestingError");
2118
+ rb_gc_register_mark_object(eParserError);
2119
+ rb_gc_register_mark_object(eNestingError);
2168
2120
  rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
2169
2121
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
2170
2122
  rb_define_method(cParser, "parse", cParser_parse, 0);
2171
2123
  rb_define_method(cParser, "source", cParser_source, 0);
2172
- rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
2173
2124
 
2174
2125
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
2126
+ rb_gc_register_mark_object(CNaN);
2127
+
2175
2128
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
2129
+ rb_gc_register_mark_object(CInfinity);
2130
+
2176
2131
  CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
2132
+ rb_gc_register_mark_object(CMinusInfinity);
2177
2133
 
2178
2134
  i_json_creatable_p = rb_intern("json_creatable?");
2179
2135
  i_json_create = rb_intern("json_create");
@@ -2183,9 +2139,9 @@ void Init_parser(void)
2183
2139
  i_max_nesting = rb_intern("max_nesting");
2184
2140
  i_allow_nan = rb_intern("allow_nan");
2185
2141
  i_symbolize_names = rb_intern("symbolize_names");
2186
- i_quirks_mode = rb_intern("quirks_mode");
2187
2142
  i_object_class = rb_intern("object_class");
2188
2143
  i_array_class = rb_intern("array_class");
2144
+ i_decimal_class = rb_intern("decimal_class");
2189
2145
  i_match = rb_intern("match");
2190
2146
  i_match_string = rb_intern("match_string");
2191
2147
  i_key_p = rb_intern("key?");
@@ -2193,18 +2149,10 @@ void Init_parser(void)
2193
2149
  i_aset = rb_intern("[]=");
2194
2150
  i_aref = rb_intern("[]");
2195
2151
  i_leftshift = rb_intern("<<");
2196
- #ifdef HAVE_RUBY_ENCODING_H
2197
- CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
2198
- CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
2199
- CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
2200
- CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
2201
- CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
2202
- CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
2203
- i_encoding = rb_intern("encoding");
2204
- i_encode = rb_intern("encode");
2205
- #else
2206
- i_iconv = rb_intern("iconv");
2207
- #endif
2152
+ i_new = rb_intern("new");
2153
+ i_BigDecimal = rb_intern("BigDecimal");
2154
+ i_freeze = rb_intern("freeze");
2155
+ i_uminus = rb_intern("-@");
2208
2156
  }
2209
2157
 
2210
2158
  /*