json 1.8.3 → 2.1.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.

Potentially problematic release.


This version of json might be problematic. Click here for more details.

Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -10
  4. data/{CHANGES → CHANGES.md} +183 -90
  5. data/Gemfile +11 -5
  6. data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
  7. data/{README.rdoc → README.md} +147 -113
  8. data/Rakefile +32 -36
  9. data/VERSION +1 -1
  10. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  11. data/ext/json/ext/generator/generator.c +46 -61
  12. data/ext/json/ext/generator/generator.h +7 -2
  13. data/ext/json/ext/parser/extconf.rb +3 -0
  14. data/ext/json/ext/parser/parser.c +353 -460
  15. data/ext/json/ext/parser/parser.h +4 -5
  16. data/ext/json/ext/parser/parser.rl +111 -181
  17. data/ext/json/extconf.rb +0 -1
  18. data/java/src/json/ext/ByteListTranscoder.java +1 -2
  19. data/java/src/json/ext/Generator.java +11 -12
  20. data/java/src/json/ext/GeneratorMethods.java +1 -2
  21. data/java/src/json/ext/GeneratorService.java +1 -2
  22. data/java/src/json/ext/GeneratorState.java +3 -56
  23. data/java/src/json/ext/OptionsReader.java +2 -3
  24. data/java/src/json/ext/Parser.java +135 -418
  25. data/java/src/json/ext/Parser.rl +48 -124
  26. data/java/src/json/ext/ParserService.java +1 -2
  27. data/java/src/json/ext/RuntimeInfo.java +1 -6
  28. data/java/src/json/ext/StringDecoder.java +1 -2
  29. data/java/src/json/ext/StringEncoder.java +5 -0
  30. data/java/src/json/ext/Utils.java +1 -2
  31. data/json-java.gemspec +15 -0
  32. data/json.gemspec +0 -0
  33. data/json_pure.gemspec +24 -26
  34. data/lib/json/add/bigdecimal.rb +1 -0
  35. data/lib/json/add/complex.rb +2 -1
  36. data/lib/json/add/core.rb +1 -0
  37. data/lib/json/add/date.rb +1 -1
  38. data/lib/json/add/date_time.rb +1 -1
  39. data/lib/json/add/exception.rb +1 -1
  40. data/lib/json/add/ostruct.rb +2 -2
  41. data/lib/json/add/range.rb +1 -1
  42. data/lib/json/add/rational.rb +1 -0
  43. data/lib/json/add/regexp.rb +1 -1
  44. data/lib/json/add/struct.rb +1 -1
  45. data/lib/json/add/symbol.rb +1 -1
  46. data/lib/json/add/time.rb +1 -1
  47. data/lib/json/common.rb +24 -52
  48. data/lib/json/ext.rb +0 -6
  49. data/lib/json/generic_object.rb +5 -4
  50. data/lib/json/pure/generator.rb +61 -125
  51. data/lib/json/pure/parser.rb +33 -81
  52. data/lib/json/pure.rb +2 -8
  53. data/lib/json/version.rb +2 -1
  54. data/lib/json.rb +1 -0
  55. data/references/rfc7159.txt +899 -0
  56. data/tests/fixtures/obsolete_fail1.json +1 -0
  57. data/tests/{test_json_addition.rb → json_addition_test.rb} +22 -25
  58. data/tests/json_common_interface_test.rb +126 -0
  59. data/tests/json_encoding_test.rb +107 -0
  60. data/tests/json_ext_parser_test.rb +15 -0
  61. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
  62. data/tests/{test_json_generate.rb → json_generator_test.rb} +79 -39
  63. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  64. data/tests/json_parser_test.rb +471 -0
  65. data/tests/json_string_matching_test.rb +38 -0
  66. data/tests/{setup_variant.rb → test_helper.rb} +10 -0
  67. data/tools/diff.sh +18 -0
  68. data/tools/fuzz.rb +1 -9
  69. metadata +28 -43
  70. data/COPYING +0 -58
  71. data/COPYING-json-jruby +0 -57
  72. data/GPL +0 -340
  73. data/TODO +0 -1
  74. data/tests/fixtures/fail1.json +0 -1
  75. data/tests/test_json.rb +0 -553
  76. data/tests/test_json_encoding.rb +0 -65
  77. data/tests/test_json_string_matching.rb +0 -39
  78. data/tests/test_json_unicode.rb +0 -72
@@ -3,6 +3,28 @@
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
30
  static const char digit_values[256] = {
@@ -67,28 +89,21 @@ 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;
80
94
 
81
95
  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;
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;
85
100
 
86
101
 
87
- #line 110 "parser.rl"
102
+ #line 125 "parser.rl"
88
103
 
89
104
 
90
105
 
91
- #line 92 "parser.c"
106
+ #line 107 "parser.c"
92
107
  enum {JSON_object_start = 1};
93
108
  enum {JSON_object_first_final = 27};
94
109
  enum {JSON_object_error = 0};
@@ -96,30 +111,30 @@ enum {JSON_object_error = 0};
96
111
  enum {JSON_object_en_main = 1};
97
112
 
98
113
 
99
- #line 151 "parser.rl"
114
+ #line 166 "parser.rl"
100
115
 
101
116
 
102
- 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)
103
118
  {
104
119
  int cs = EVIL;
105
120
  VALUE last_name = Qnil;
106
121
  VALUE object_class = json->object_class;
107
122
 
108
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
109
- 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);
110
125
  }
111
126
 
112
127
  *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
113
128
 
114
129
 
115
- #line 116 "parser.c"
130
+ #line 131 "parser.c"
116
131
  {
117
132
  cs = JSON_object_start;
118
133
  }
119
134
 
120
- #line 166 "parser.rl"
135
+ #line 181 "parser.rl"
121
136
 
122
- #line 123 "parser.c"
137
+ #line 138 "parser.c"
123
138
  {
124
139
  if ( p == pe )
125
140
  goto _test_eof;
@@ -147,7 +162,7 @@ case 2:
147
162
  goto st2;
148
163
  goto st0;
149
164
  tr2:
150
- #line 133 "parser.rl"
165
+ #line 148 "parser.rl"
151
166
  {
152
167
  char *np;
153
168
  json->parsing_name = 1;
@@ -160,7 +175,7 @@ st3:
160
175
  if ( ++p == pe )
161
176
  goto _test_eof3;
162
177
  case 3:
163
- #line 164 "parser.c"
178
+ #line 179 "parser.c"
164
179
  switch( (*p) ) {
165
180
  case 13: goto st3;
166
181
  case 32: goto st3;
@@ -227,10 +242,10 @@ case 8:
227
242
  goto st8;
228
243
  goto st0;
229
244
  tr11:
230
- #line 118 "parser.rl"
245
+ #line 133 "parser.rl"
231
246
  {
232
247
  VALUE v = Qnil;
233
- char *np = JSON_parse_value(json, p, pe, &v);
248
+ char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
234
249
  if (np == NULL) {
235
250
  p--; {p++; cs = 9; goto _out;}
236
251
  } else {
@@ -247,7 +262,7 @@ st9:
247
262
  if ( ++p == pe )
248
263
  goto _test_eof9;
249
264
  case 9:
250
- #line 251 "parser.c"
265
+ #line 266 "parser.c"
251
266
  switch( (*p) ) {
252
267
  case 13: goto st9;
253
268
  case 32: goto st9;
@@ -336,14 +351,14 @@ case 18:
336
351
  goto st9;
337
352
  goto st18;
338
353
  tr4:
339
- #line 141 "parser.rl"
354
+ #line 156 "parser.rl"
340
355
  { p--; {p++; cs = 27; goto _out;} }
341
356
  goto st27;
342
357
  st27:
343
358
  if ( ++p == pe )
344
359
  goto _test_eof27;
345
360
  case 27:
346
- #line 347 "parser.c"
361
+ #line 362 "parser.c"
347
362
  goto st0;
348
363
  st19:
349
364
  if ( ++p == pe )
@@ -441,7 +456,7 @@ case 26:
441
456
  _out: {}
442
457
  }
443
458
 
444
- #line 167 "parser.rl"
459
+ #line 182 "parser.rl"
445
460
 
446
461
  if (cs >= JSON_object_first_final) {
447
462
  if (json->create_additions) {
@@ -466,281 +481,358 @@ case 26:
466
481
 
467
482
 
468
483
 
469
- #line 470 "parser.c"
484
+ #line 485 "parser.c"
470
485
  enum {JSON_value_start = 1};
471
- enum {JSON_value_first_final = 21};
486
+ enum {JSON_value_first_final = 29};
472
487
  enum {JSON_value_error = 0};
473
488
 
474
489
  enum {JSON_value_en_main = 1};
475
490
 
476
491
 
477
- #line 271 "parser.rl"
492
+ #line 282 "parser.rl"
478
493
 
479
494
 
480
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
495
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
481
496
  {
482
497
  int cs = EVIL;
483
498
 
484
499
 
485
- #line 486 "parser.c"
500
+ #line 501 "parser.c"
486
501
  {
487
502
  cs = JSON_value_start;
488
503
  }
489
504
 
490
- #line 278 "parser.rl"
505
+ #line 289 "parser.rl"
491
506
 
492
- #line 493 "parser.c"
507
+ #line 508 "parser.c"
493
508
  {
494
509
  if ( p == pe )
495
510
  goto _test_eof;
496
511
  switch ( cs )
497
512
  {
513
+ st1:
514
+ if ( ++p == pe )
515
+ goto _test_eof1;
498
516
  case 1:
499
517
  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;
518
+ case 13: goto st1;
519
+ case 32: goto st1;
520
+ case 34: goto tr2;
521
+ case 45: goto tr3;
522
+ case 47: goto st6;
523
+ case 73: goto st10;
524
+ case 78: goto st17;
525
+ case 91: goto tr7;
526
+ case 102: goto st19;
527
+ case 110: goto st23;
528
+ case 116: goto st26;
529
+ case 123: goto tr11;
509
530
  }
510
- if ( 48 <= (*p) && (*p) <= 57 )
511
- goto tr2;
531
+ if ( (*p) > 10 ) {
532
+ if ( 48 <= (*p) && (*p) <= 57 )
533
+ goto tr3;
534
+ } else if ( (*p) >= 9 )
535
+ goto st1;
512
536
  goto st0;
513
537
  st0:
514
538
  cs = 0;
515
539
  goto _out;
516
- tr0:
517
- #line 219 "parser.rl"
540
+ tr2:
541
+ #line 234 "parser.rl"
518
542
  {
519
543
  char *np = JSON_parse_string(json, p, pe, result);
520
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
544
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
521
545
  }
522
- goto st21;
523
- tr2:
524
- #line 224 "parser.rl"
546
+ goto st29;
547
+ tr3:
548
+ #line 239 "parser.rl"
525
549
  {
526
550
  char *np;
527
- if(pe > p + 9 - json->quirks_mode && !strncmp(MinusInfinity, p, 9)) {
551
+ if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
528
552
  if (json->allow_nan) {
529
553
  *result = CMinusInfinity;
530
554
  {p = (( p + 10))-1;}
531
- p--; {p++; cs = 21; goto _out;}
555
+ p--; {p++; cs = 29; goto _out;}
532
556
  } else {
533
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
557
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
534
558
  }
535
559
  }
536
560
  np = JSON_parse_float(json, p, pe, result);
537
561
  if (np != NULL) {p = (( np))-1;}
538
562
  np = JSON_parse_integer(json, p, pe, result);
539
563
  if (np != NULL) {p = (( np))-1;}
540
- p--; {p++; cs = 21; goto _out;}
564
+ p--; {p++; cs = 29; goto _out;}
541
565
  }
542
- goto st21;
543
- tr5:
544
- #line 242 "parser.rl"
566
+ goto st29;
567
+ tr7:
568
+ #line 257 "parser.rl"
545
569
  {
546
570
  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;}
571
+ np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
572
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
551
573
  }
552
- goto st21;
553
- tr9:
554
- #line 250 "parser.rl"
574
+ goto st29;
575
+ tr11:
576
+ #line 263 "parser.rl"
555
577
  {
556
578
  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;}
579
+ np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
580
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
561
581
  }
562
- goto st21;
563
- tr16:
564
- #line 212 "parser.rl"
582
+ goto st29;
583
+ tr25:
584
+ #line 227 "parser.rl"
565
585
  {
566
586
  if (json->allow_nan) {
567
587
  *result = CInfinity;
568
588
  } else {
569
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
589
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
570
590
  }
571
591
  }
572
- goto st21;
573
- tr18:
574
- #line 205 "parser.rl"
592
+ goto st29;
593
+ tr27:
594
+ #line 220 "parser.rl"
575
595
  {
576
596
  if (json->allow_nan) {
577
597
  *result = CNaN;
578
598
  } else {
579
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
599
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
580
600
  }
581
601
  }
582
- goto st21;
583
- tr22:
584
- #line 199 "parser.rl"
602
+ goto st29;
603
+ tr31:
604
+ #line 214 "parser.rl"
585
605
  {
586
606
  *result = Qfalse;
587
607
  }
588
- goto st21;
589
- tr25:
590
- #line 196 "parser.rl"
608
+ goto st29;
609
+ tr34:
610
+ #line 211 "parser.rl"
591
611
  {
592
612
  *result = Qnil;
593
613
  }
594
- goto st21;
595
- tr28:
596
- #line 202 "parser.rl"
614
+ goto st29;
615
+ tr37:
616
+ #line 217 "parser.rl"
597
617
  {
598
618
  *result = Qtrue;
599
619
  }
600
- goto st21;
601
- st21:
602
- 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"
620
+ goto st29;
621
+ st29:
622
+ if ( ++p == pe )
623
+ goto _test_eof29;
624
+ case 29:
625
+ #line 269 "parser.rl"
626
+ { p--; {p++; cs = 29; goto _out;} }
627
+ #line 628 "parser.c"
628
+ switch( (*p) ) {
629
+ case 13: goto st29;
630
+ case 32: goto st29;
631
+ case 47: goto st2;
632
+ }
633
+ if ( 9 <= (*p) && (*p) <= 10 )
634
+ goto st29;
608
635
  goto st0;
609
636
  st2:
610
637
  if ( ++p == pe )
611
638
  goto _test_eof2;
612
639
  case 2:
613
- if ( (*p) == 110 )
614
- goto st3;
640
+ switch( (*p) ) {
641
+ case 42: goto st3;
642
+ case 47: goto st5;
643
+ }
615
644
  goto st0;
616
645
  st3:
617
646
  if ( ++p == pe )
618
647
  goto _test_eof3;
619
648
  case 3:
620
- if ( (*p) == 102 )
649
+ if ( (*p) == 42 )
621
650
  goto st4;
622
- goto st0;
651
+ goto st3;
623
652
  st4:
624
653
  if ( ++p == pe )
625
654
  goto _test_eof4;
626
655
  case 4:
627
- if ( (*p) == 105 )
628
- goto st5;
629
- goto st0;
656
+ switch( (*p) ) {
657
+ case 42: goto st4;
658
+ case 47: goto st29;
659
+ }
660
+ goto st3;
630
661
  st5:
631
662
  if ( ++p == pe )
632
663
  goto _test_eof5;
633
664
  case 5:
634
- if ( (*p) == 110 )
635
- goto st6;
636
- goto st0;
665
+ if ( (*p) == 10 )
666
+ goto st29;
667
+ goto st5;
637
668
  st6:
638
669
  if ( ++p == pe )
639
670
  goto _test_eof6;
640
671
  case 6:
641
- if ( (*p) == 105 )
642
- goto st7;
672
+ switch( (*p) ) {
673
+ case 42: goto st7;
674
+ case 47: goto st9;
675
+ }
643
676
  goto st0;
644
677
  st7:
645
678
  if ( ++p == pe )
646
679
  goto _test_eof7;
647
680
  case 7:
648
- if ( (*p) == 116 )
681
+ if ( (*p) == 42 )
649
682
  goto st8;
650
- goto st0;
683
+ goto st7;
651
684
  st8:
652
685
  if ( ++p == pe )
653
686
  goto _test_eof8;
654
687
  case 8:
655
- if ( (*p) == 121 )
656
- goto tr16;
657
- goto st0;
688
+ switch( (*p) ) {
689
+ case 42: goto st8;
690
+ case 47: goto st1;
691
+ }
692
+ goto st7;
658
693
  st9:
659
694
  if ( ++p == pe )
660
695
  goto _test_eof9;
661
696
  case 9:
662
- if ( (*p) == 97 )
663
- goto st10;
664
- goto st0;
697
+ if ( (*p) == 10 )
698
+ goto st1;
699
+ goto st9;
665
700
  st10:
666
701
  if ( ++p == pe )
667
702
  goto _test_eof10;
668
703
  case 10:
669
- if ( (*p) == 78 )
670
- goto tr18;
704
+ if ( (*p) == 110 )
705
+ goto st11;
671
706
  goto st0;
672
707
  st11:
673
708
  if ( ++p == pe )
674
709
  goto _test_eof11;
675
710
  case 11:
676
- if ( (*p) == 97 )
711
+ if ( (*p) == 102 )
677
712
  goto st12;
678
713
  goto st0;
679
714
  st12:
680
715
  if ( ++p == pe )
681
716
  goto _test_eof12;
682
717
  case 12:
683
- if ( (*p) == 108 )
718
+ if ( (*p) == 105 )
684
719
  goto st13;
685
720
  goto st0;
686
721
  st13:
687
722
  if ( ++p == pe )
688
723
  goto _test_eof13;
689
724
  case 13:
690
- if ( (*p) == 115 )
725
+ if ( (*p) == 110 )
691
726
  goto st14;
692
727
  goto st0;
693
728
  st14:
694
729
  if ( ++p == pe )
695
730
  goto _test_eof14;
696
731
  case 14:
697
- if ( (*p) == 101 )
698
- goto tr22;
732
+ if ( (*p) == 105 )
733
+ goto st15;
699
734
  goto st0;
700
735
  st15:
701
736
  if ( ++p == pe )
702
737
  goto _test_eof15;
703
738
  case 15:
704
- if ( (*p) == 117 )
739
+ if ( (*p) == 116 )
705
740
  goto st16;
706
741
  goto st0;
707
742
  st16:
708
743
  if ( ++p == pe )
709
744
  goto _test_eof16;
710
745
  case 16:
711
- if ( (*p) == 108 )
712
- goto st17;
746
+ if ( (*p) == 121 )
747
+ goto tr25;
713
748
  goto st0;
714
749
  st17:
715
750
  if ( ++p == pe )
716
751
  goto _test_eof17;
717
752
  case 17:
718
- if ( (*p) == 108 )
719
- goto tr25;
753
+ if ( (*p) == 97 )
754
+ goto st18;
720
755
  goto st0;
721
756
  st18:
722
757
  if ( ++p == pe )
723
758
  goto _test_eof18;
724
759
  case 18:
725
- if ( (*p) == 114 )
726
- goto st19;
760
+ if ( (*p) == 78 )
761
+ goto tr27;
727
762
  goto st0;
728
763
  st19:
729
764
  if ( ++p == pe )
730
765
  goto _test_eof19;
731
766
  case 19:
732
- if ( (*p) == 117 )
767
+ if ( (*p) == 97 )
733
768
  goto st20;
734
769
  goto st0;
735
770
  st20:
736
771
  if ( ++p == pe )
737
772
  goto _test_eof20;
738
773
  case 20:
774
+ if ( (*p) == 108 )
775
+ goto st21;
776
+ goto st0;
777
+ st21:
778
+ if ( ++p == pe )
779
+ goto _test_eof21;
780
+ case 21:
781
+ if ( (*p) == 115 )
782
+ goto st22;
783
+ goto st0;
784
+ st22:
785
+ if ( ++p == pe )
786
+ goto _test_eof22;
787
+ case 22:
788
+ if ( (*p) == 101 )
789
+ goto tr31;
790
+ goto st0;
791
+ st23:
792
+ if ( ++p == pe )
793
+ goto _test_eof23;
794
+ case 23:
795
+ if ( (*p) == 117 )
796
+ goto st24;
797
+ goto st0;
798
+ st24:
799
+ if ( ++p == pe )
800
+ goto _test_eof24;
801
+ case 24:
802
+ if ( (*p) == 108 )
803
+ goto st25;
804
+ goto st0;
805
+ st25:
806
+ if ( ++p == pe )
807
+ goto _test_eof25;
808
+ case 25:
809
+ if ( (*p) == 108 )
810
+ goto tr34;
811
+ goto st0;
812
+ st26:
813
+ if ( ++p == pe )
814
+ goto _test_eof26;
815
+ case 26:
816
+ if ( (*p) == 114 )
817
+ goto st27;
818
+ goto st0;
819
+ st27:
820
+ if ( ++p == pe )
821
+ goto _test_eof27;
822
+ case 27:
823
+ if ( (*p) == 117 )
824
+ goto st28;
825
+ goto st0;
826
+ st28:
827
+ if ( ++p == pe )
828
+ goto _test_eof28;
829
+ case 28:
739
830
  if ( (*p) == 101 )
740
- goto tr28;
831
+ goto tr37;
741
832
  goto st0;
742
833
  }
743
- _test_eof21: cs = 21; goto _test_eof;
834
+ _test_eof1: cs = 1; goto _test_eof;
835
+ _test_eof29: cs = 29; goto _test_eof;
744
836
  _test_eof2: cs = 2; goto _test_eof;
745
837
  _test_eof3: cs = 3; goto _test_eof;
746
838
  _test_eof4: cs = 4; goto _test_eof;
@@ -760,12 +852,20 @@ case 20:
760
852
  _test_eof18: cs = 18; goto _test_eof;
761
853
  _test_eof19: cs = 19; goto _test_eof;
762
854
  _test_eof20: cs = 20; goto _test_eof;
855
+ _test_eof21: cs = 21; goto _test_eof;
856
+ _test_eof22: cs = 22; goto _test_eof;
857
+ _test_eof23: cs = 23; goto _test_eof;
858
+ _test_eof24: cs = 24; goto _test_eof;
859
+ _test_eof25: cs = 25; goto _test_eof;
860
+ _test_eof26: cs = 26; goto _test_eof;
861
+ _test_eof27: cs = 27; goto _test_eof;
862
+ _test_eof28: cs = 28; goto _test_eof;
763
863
 
764
864
  _test_eof: {}
765
865
  _out: {}
766
866
  }
767
867
 
768
- #line 279 "parser.rl"
868
+ #line 290 "parser.rl"
769
869
 
770
870
  if (cs >= JSON_value_first_final) {
771
871
  return p;
@@ -775,7 +875,7 @@ case 20:
775
875
  }
776
876
 
777
877
 
778
- #line 779 "parser.c"
878
+ #line 879 "parser.c"
779
879
  enum {JSON_integer_start = 1};
780
880
  enum {JSON_integer_first_final = 3};
781
881
  enum {JSON_integer_error = 0};
@@ -783,7 +883,7 @@ enum {JSON_integer_error = 0};
783
883
  enum {JSON_integer_en_main = 1};
784
884
 
785
885
 
786
- #line 295 "parser.rl"
886
+ #line 306 "parser.rl"
787
887
 
788
888
 
789
889
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -791,15 +891,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
791
891
  int cs = EVIL;
792
892
 
793
893
 
794
- #line 795 "parser.c"
894
+ #line 895 "parser.c"
795
895
  {
796
896
  cs = JSON_integer_start;
797
897
  }
798
898
 
799
- #line 302 "parser.rl"
899
+ #line 313 "parser.rl"
800
900
  json->memo = p;
801
901
 
802
- #line 803 "parser.c"
902
+ #line 903 "parser.c"
803
903
  {
804
904
  if ( p == pe )
805
905
  goto _test_eof;
@@ -833,14 +933,14 @@ case 3:
833
933
  goto st0;
834
934
  goto tr4;
835
935
  tr4:
836
- #line 292 "parser.rl"
936
+ #line 303 "parser.rl"
837
937
  { p--; {p++; cs = 4; goto _out;} }
838
938
  goto st4;
839
939
  st4:
840
940
  if ( ++p == pe )
841
941
  goto _test_eof4;
842
942
  case 4:
843
- #line 844 "parser.c"
943
+ #line 944 "parser.c"
844
944
  goto st0;
845
945
  st5:
846
946
  if ( ++p == pe )
@@ -859,7 +959,7 @@ case 5:
859
959
  _out: {}
860
960
  }
861
961
 
862
- #line 304 "parser.rl"
962
+ #line 315 "parser.rl"
863
963
 
864
964
  if (cs >= JSON_integer_first_final) {
865
965
  long len = p - json->memo;
@@ -874,7 +974,7 @@ case 5:
874
974
  }
875
975
 
876
976
 
877
- #line 878 "parser.c"
977
+ #line 978 "parser.c"
878
978
  enum {JSON_float_start = 1};
879
979
  enum {JSON_float_first_final = 8};
880
980
  enum {JSON_float_error = 0};
@@ -882,7 +982,7 @@ enum {JSON_float_error = 0};
882
982
  enum {JSON_float_en_main = 1};
883
983
 
884
984
 
885
- #line 329 "parser.rl"
985
+ #line 340 "parser.rl"
886
986
 
887
987
 
888
988
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -890,15 +990,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
890
990
  int cs = EVIL;
891
991
 
892
992
 
893
- #line 894 "parser.c"
993
+ #line 994 "parser.c"
894
994
  {
895
995
  cs = JSON_float_start;
896
996
  }
897
997
 
898
- #line 336 "parser.rl"
998
+ #line 347 "parser.rl"
899
999
  json->memo = p;
900
1000
 
901
- #line 902 "parser.c"
1001
+ #line 1002 "parser.c"
902
1002
  {
903
1003
  if ( p == pe )
904
1004
  goto _test_eof;
@@ -956,14 +1056,14 @@ case 8:
956
1056
  goto st0;
957
1057
  goto tr9;
958
1058
  tr9:
959
- #line 323 "parser.rl"
1059
+ #line 334 "parser.rl"
960
1060
  { p--; {p++; cs = 9; goto _out;} }
961
1061
  goto st9;
962
1062
  st9:
963
1063
  if ( ++p == pe )
964
1064
  goto _test_eof9;
965
1065
  case 9:
966
- #line 967 "parser.c"
1066
+ #line 1067 "parser.c"
967
1067
  goto st0;
968
1068
  st5:
969
1069
  if ( ++p == pe )
@@ -1024,14 +1124,20 @@ case 7:
1024
1124
  _out: {}
1025
1125
  }
1026
1126
 
1027
- #line 338 "parser.rl"
1127
+ #line 349 "parser.rl"
1028
1128
 
1029
1129
  if (cs >= JSON_float_first_final) {
1030
1130
  long len = p - json->memo;
1031
1131
  fbuffer_clear(json->fbuffer);
1032
1132
  fbuffer_append(json->fbuffer, json->memo, len);
1033
1133
  fbuffer_append_char(json->fbuffer, '\0');
1034
- *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1134
+ if (NIL_P(json->decimal_class)) {
1135
+ *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1136
+ } else {
1137
+ VALUE text;
1138
+ text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
1139
+ *result = rb_funcall(json->decimal_class, i_new, 1, text);
1140
+ }
1035
1141
  return p + 1;
1036
1142
  } else {
1037
1143
  return NULL;
@@ -1040,7 +1146,7 @@ case 7:
1040
1146
 
1041
1147
 
1042
1148
 
1043
- #line 1044 "parser.c"
1149
+ #line 1150 "parser.c"
1044
1150
  enum {JSON_array_start = 1};
1045
1151
  enum {JSON_array_first_final = 17};
1046
1152
  enum {JSON_array_error = 0};
@@ -1048,28 +1154,28 @@ enum {JSON_array_error = 0};
1048
1154
  enum {JSON_array_en_main = 1};
1049
1155
 
1050
1156
 
1051
- #line 381 "parser.rl"
1157
+ #line 398 "parser.rl"
1052
1158
 
1053
1159
 
1054
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
1160
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
1055
1161
  {
1056
1162
  int cs = EVIL;
1057
1163
  VALUE array_class = json->array_class;
1058
1164
 
1059
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
1060
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
1165
+ if (json->max_nesting && current_nesting > json->max_nesting) {
1166
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
1061
1167
  }
1062
1168
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1063
1169
 
1064
1170
 
1065
- #line 1066 "parser.c"
1171
+ #line 1172 "parser.c"
1066
1172
  {
1067
1173
  cs = JSON_array_start;
1068
1174
  }
1069
1175
 
1070
- #line 394 "parser.rl"
1176
+ #line 411 "parser.rl"
1071
1177
 
1072
- #line 1073 "parser.c"
1178
+ #line 1179 "parser.c"
1073
1179
  {
1074
1180
  if ( p == pe )
1075
1181
  goto _test_eof;
@@ -1108,10 +1214,10 @@ case 2:
1108
1214
  goto st2;
1109
1215
  goto st0;
1110
1216
  tr2:
1111
- #line 358 "parser.rl"
1217
+ #line 375 "parser.rl"
1112
1218
  {
1113
1219
  VALUE v = Qnil;
1114
- char *np = JSON_parse_value(json, p, pe, &v);
1220
+ char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
1115
1221
  if (np == NULL) {
1116
1222
  p--; {p++; cs = 3; goto _out;}
1117
1223
  } else {
@@ -1128,7 +1234,7 @@ st3:
1128
1234
  if ( ++p == pe )
1129
1235
  goto _test_eof3;
1130
1236
  case 3:
1131
- #line 1132 "parser.c"
1237
+ #line 1238 "parser.c"
1132
1238
  switch( (*p) ) {
1133
1239
  case 13: goto st3;
1134
1240
  case 32: goto st3;
@@ -1228,14 +1334,14 @@ case 12:
1228
1334
  goto st3;
1229
1335
  goto st12;
1230
1336
  tr4:
1231
- #line 373 "parser.rl"
1337
+ #line 390 "parser.rl"
1232
1338
  { p--; {p++; cs = 17; goto _out;} }
1233
1339
  goto st17;
1234
1340
  st17:
1235
1341
  if ( ++p == pe )
1236
1342
  goto _test_eof17;
1237
1343
  case 17:
1238
- #line 1239 "parser.c"
1344
+ #line 1345 "parser.c"
1239
1345
  goto st0;
1240
1346
  st13:
1241
1347
  if ( ++p == pe )
@@ -1291,12 +1397,12 @@ case 16:
1291
1397
  _out: {}
1292
1398
  }
1293
1399
 
1294
- #line 395 "parser.rl"
1400
+ #line 412 "parser.rl"
1295
1401
 
1296
1402
  if(cs >= JSON_array_first_final) {
1297
1403
  return p + 1;
1298
1404
  } else {
1299
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1405
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1300
1406
  return NULL;
1301
1407
  }
1302
1408
  }
@@ -1336,13 +1442,21 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1336
1442
  break;
1337
1443
  case 'u':
1338
1444
  if (pe > stringEnd - 4) {
1339
- return Qnil;
1445
+ rb_enc_raise(
1446
+ EXC_ENCODING eParserError,
1447
+ "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
1448
+ );
1340
1449
  } else {
1341
1450
  UTF32 ch = unescape_unicode((unsigned char *) ++pe);
1342
1451
  pe += 3;
1343
1452
  if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
1344
1453
  pe++;
1345
- if (pe > stringEnd - 6) return Qnil;
1454
+ if (pe > stringEnd - 6) {
1455
+ rb_enc_raise(
1456
+ EXC_ENCODING eParserError,
1457
+ "%u: incomplete surrogate pair at '%s'", __LINE__, p
1458
+ );
1459
+ }
1346
1460
  if (pe[0] == '\\' && pe[1] == 'u') {
1347
1461
  UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
1348
1462
  ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
@@ -1372,7 +1486,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1372
1486
  }
1373
1487
 
1374
1488
 
1375
- #line 1376 "parser.c"
1489
+ #line 1490 "parser.c"
1376
1490
  enum {JSON_string_start = 1};
1377
1491
  enum {JSON_string_first_final = 8};
1378
1492
  enum {JSON_string_error = 0};
@@ -1380,7 +1494,7 @@ enum {JSON_string_error = 0};
1380
1494
  enum {JSON_string_en_main = 1};
1381
1495
 
1382
1496
 
1383
- #line 494 "parser.rl"
1497
+ #line 519 "parser.rl"
1384
1498
 
1385
1499
 
1386
1500
  static int
@@ -1402,15 +1516,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
1402
1516
 
1403
1517
  *result = rb_str_buf_new(0);
1404
1518
 
1405
- #line 1406 "parser.c"
1519
+ #line 1520 "parser.c"
1406
1520
  {
1407
1521
  cs = JSON_string_start;
1408
1522
  }
1409
1523
 
1410
- #line 515 "parser.rl"
1524
+ #line 540 "parser.rl"
1411
1525
  json->memo = p;
1412
1526
 
1413
- #line 1414 "parser.c"
1527
+ #line 1528 "parser.c"
1414
1528
  {
1415
1529
  if ( p == pe )
1416
1530
  goto _test_eof;
@@ -1435,7 +1549,7 @@ case 2:
1435
1549
  goto st0;
1436
1550
  goto st2;
1437
1551
  tr2:
1438
- #line 480 "parser.rl"
1552
+ #line 505 "parser.rl"
1439
1553
  {
1440
1554
  *result = json_string_unescape(*result, json->memo + 1, p);
1441
1555
  if (NIL_P(*result)) {
@@ -1446,14 +1560,14 @@ tr2:
1446
1560
  {p = (( p + 1))-1;}
1447
1561
  }
1448
1562
  }
1449
- #line 491 "parser.rl"
1563
+ #line 516 "parser.rl"
1450
1564
  { p--; {p++; cs = 8; goto _out;} }
1451
1565
  goto st8;
1452
1566
  st8:
1453
1567
  if ( ++p == pe )
1454
1568
  goto _test_eof8;
1455
1569
  case 8:
1456
- #line 1457 "parser.c"
1570
+ #line 1571 "parser.c"
1457
1571
  goto st0;
1458
1572
  st3:
1459
1573
  if ( ++p == pe )
@@ -1529,7 +1643,7 @@ case 7:
1529
1643
  _out: {}
1530
1644
  }
1531
1645
 
1532
- #line 517 "parser.rl"
1646
+ #line 542 "parser.rl"
1533
1647
 
1534
1648
  if (json->create_additions && RTEST(match_string = json->match_string)) {
1535
1649
  VALUE klass;
@@ -1544,6 +1658,8 @@ case 7:
1544
1658
 
1545
1659
  if (json->symbolize_names && json->parsing_name) {
1546
1660
  *result = rb_str_intern(*result);
1661
+ } else {
1662
+ rb_str_resize(*result, RSTRING_LEN(*result));
1547
1663
  }
1548
1664
  if (cs >= JSON_string_first_final) {
1549
1665
  return p + 1;
@@ -1566,41 +1682,16 @@ case 7:
1566
1682
 
1567
1683
  static VALUE convert_encoding(VALUE source)
1568
1684
  {
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
1685
  #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);
1686
+ rb_encoding *enc = rb_enc_get(source);
1687
+ if (enc == rb_ascii8bit_encoding()) {
1688
+ if (OBJ_FROZEN(source)) {
1689
+ source = rb_str_dup(source);
1603
1690
  }
1691
+ FORCE_UTF8(source);
1692
+ } else {
1693
+ source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
1694
+ }
1604
1695
  #endif
1605
1696
  return source;
1606
1697
  }
@@ -1623,8 +1714,9 @@ static VALUE convert_encoding(VALUE source)
1623
1714
  * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
1624
1715
  * false.
1625
1716
  * * *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.
1717
+ * (keys) in a JSON object. Otherwise strings are returned, which is
1718
+ * also the default. It's not possible to use this option in
1719
+ * conjunction with the *create_additions* option.
1628
1720
  * * *create_additions*: If set to false, the Parser doesn't create
1629
1721
  * additions even if a matching class and create_id was found. This option
1630
1722
  * defaults to false.
@@ -1639,12 +1731,18 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1639
1731
  if (json->Vsource) {
1640
1732
  rb_raise(rb_eTypeError, "already initialized instance");
1641
1733
  }
1734
+ #ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1735
+ rb_scan_args(argc, argv, "1:", &source, &opts);
1736
+ #else
1642
1737
  rb_scan_args(argc, argv, "11", &source, &opts);
1738
+ #endif
1643
1739
  if (!NIL_P(opts)) {
1740
+ #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1644
1741
  opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
1645
1742
  if (NIL_P(opts)) {
1646
1743
  rb_raise(rb_eArgError, "opts needs to be like a hash");
1647
1744
  } else {
1745
+ #endif
1648
1746
  VALUE tmp = ID2SYM(i_max_nesting);
1649
1747
  if (option_given_p(opts, tmp)) {
1650
1748
  VALUE max_nesting = rb_hash_aref(opts, tmp);
@@ -1669,19 +1767,17 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1669
1767
  } else {
1670
1768
  json->symbolize_names = 0;
1671
1769
  }
1672
- tmp = ID2SYM(i_quirks_mode);
1673
- if (option_given_p(opts, tmp)) {
1674
- VALUE quirks_mode = rb_hash_aref(opts, tmp);
1675
- json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
1676
- } else {
1677
- json->quirks_mode = 0;
1678
- }
1679
1770
  tmp = ID2SYM(i_create_additions);
1680
1771
  if (option_given_p(opts, tmp)) {
1681
1772
  json->create_additions = RTEST(rb_hash_aref(opts, tmp));
1682
1773
  } else {
1683
1774
  json->create_additions = 0;
1684
1775
  }
1776
+ if (json->symbolize_names && json->create_additions) {
1777
+ rb_raise(rb_eArgError,
1778
+ "options :symbolize_names and :create_additions cannot be "
1779
+ " used in conjunction");
1780
+ }
1685
1781
  tmp = ID2SYM(i_create_id);
1686
1782
  if (option_given_p(opts, tmp)) {
1687
1783
  json->create_id = rb_hash_aref(opts, tmp);
@@ -1700,6 +1796,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1700
1796
  } else {
1701
1797
  json->array_class = Qnil;
1702
1798
  }
1799
+ tmp = ID2SYM(i_decimal_class);
1800
+ if (option_given_p(opts, tmp)) {
1801
+ json->decimal_class = rb_hash_aref(opts, tmp);
1802
+ } else {
1803
+ json->decimal_class = Qnil;
1804
+ }
1703
1805
  tmp = ID2SYM(i_match_string);
1704
1806
  if (option_given_p(opts, tmp)) {
1705
1807
  VALUE match_string = rb_hash_aref(opts, tmp);
@@ -1707,7 +1809,9 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1707
1809
  } else {
1708
1810
  json->match_string = Qnil;
1709
1811
  }
1812
+ #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1710
1813
  }
1814
+ #endif
1711
1815
  } else {
1712
1816
  json->max_nesting = 100;
1713
1817
  json->allow_nan = 0;
@@ -1715,12 +1819,9 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1715
1819
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
1716
1820
  json->object_class = Qnil;
1717
1821
  json->array_class = Qnil;
1822
+ json->decimal_class = Qnil;
1718
1823
  }
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;
1824
+ source = convert_encoding(StringValue(source));
1724
1825
  StringValue(source);
1725
1826
  json->len = RSTRING_LEN(source);
1726
1827
  json->source = RSTRING_PTR(source);;
@@ -1729,7 +1830,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1729
1830
  }
1730
1831
 
1731
1832
 
1732
- #line 1733 "parser.c"
1833
+ #line 1834 "parser.c"
1733
1834
  enum {JSON_start = 1};
1734
1835
  enum {JSON_first_final = 10};
1735
1836
  enum {JSON_error = 0};
@@ -1737,201 +1838,33 @@ enum {JSON_error = 0};
1737
1838
  enum {JSON_en_main = 1};
1738
1839
 
1739
1840
 
1740
- #line 740 "parser.rl"
1841
+ #line 742 "parser.rl"
1741
1842
 
1742
1843
 
1743
- static VALUE cParser_parse_strict(VALUE self)
1844
+ /*
1845
+ * call-seq: parse()
1846
+ *
1847
+ * Parses the current JSON text _source_ and returns the complete data
1848
+ * structure as a result.
1849
+ */
1850
+ static VALUE cParser_parse(VALUE self)
1744
1851
  {
1745
- char *p, *pe;
1746
- int cs = EVIL;
1747
- VALUE result = Qnil;
1748
- GET_PARSER;
1852
+ char *p, *pe;
1853
+ int cs = EVIL;
1854
+ VALUE result = Qnil;
1855
+ GET_PARSER;
1749
1856
 
1750
1857
 
1751
- #line 1752 "parser.c"
1858
+ #line 1859 "parser.c"
1752
1859
  {
1753
1860
  cs = JSON_start;
1754
1861
  }
1755
1862
 
1756
- #line 750 "parser.rl"
1757
- p = json->source;
1758
- pe = p + json->len;
1759
-
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;
1863
+ #line 758 "parser.rl"
1864
+ p = json->source;
1865
+ pe = p + json->len;
1933
1866
 
1934
- #line 1935 "parser.c"
1867
+ #line 1868 "parser.c"
1935
1868
  {
1936
1869
  if ( p == pe )
1937
1870
  goto _test_eof;
@@ -1965,9 +1898,9 @@ st0:
1965
1898
  cs = 0;
1966
1899
  goto _out;
1967
1900
  tr2:
1968
- #line 770 "parser.rl"
1901
+ #line 734 "parser.rl"
1969
1902
  {
1970
- char *np = JSON_parse_value(json, p, pe, &result);
1903
+ char *np = JSON_parse_value(json, p, pe, &result, 0);
1971
1904
  if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1972
1905
  }
1973
1906
  goto st10;
@@ -1975,7 +1908,7 @@ st10:
1975
1908
  if ( ++p == pe )
1976
1909
  goto _test_eof10;
1977
1910
  case 10:
1978
- #line 1979 "parser.c"
1911
+ #line 1912 "parser.c"
1979
1912
  switch( (*p) ) {
1980
1913
  case 13: goto st10;
1981
1914
  case 32: goto st10;
@@ -2064,30 +1997,13 @@ case 9:
2064
1997
  _out: {}
2065
1998
  }
2066
1999
 
2067
- #line 791 "parser.rl"
2000
+ #line 761 "parser.rl"
2068
2001
 
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;
2086
-
2087
- if (json->quirks_mode) {
2088
- return cParser_parse_quirks_mode(self);
2002
+ if (cs >= JSON_first_final && p == pe) {
2003
+ return result;
2089
2004
  } else {
2090
- return cParser_parse_strict(self);
2005
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
2006
+ return Qnil;
2091
2007
  }
2092
2008
  }
2093
2009
 
@@ -2098,6 +2014,7 @@ static void JSON_mark(void *ptr)
2098
2014
  rb_gc_mark_maybe(json->create_id);
2099
2015
  rb_gc_mark_maybe(json->object_class);
2100
2016
  rb_gc_mark_maybe(json->array_class);
2017
+ rb_gc_mark_maybe(json->decimal_class);
2101
2018
  rb_gc_mark_maybe(json->match_string);
2102
2019
  }
2103
2020
 
@@ -2145,18 +2062,6 @@ static VALUE cParser_source(VALUE self)
2145
2062
  return rb_str_dup(json->Vsource);
2146
2063
  }
2147
2064
 
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
2065
  void Init_parser(void)
2161
2066
  {
2162
2067
  rb_require("json/common");
@@ -2169,7 +2074,6 @@ void Init_parser(void)
2169
2074
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
2170
2075
  rb_define_method(cParser, "parse", cParser_parse, 0);
2171
2076
  rb_define_method(cParser, "source", cParser_source, 0);
2172
- rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
2173
2077
 
2174
2078
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
2175
2079
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
@@ -2183,9 +2087,9 @@ void Init_parser(void)
2183
2087
  i_max_nesting = rb_intern("max_nesting");
2184
2088
  i_allow_nan = rb_intern("allow_nan");
2185
2089
  i_symbolize_names = rb_intern("symbolize_names");
2186
- i_quirks_mode = rb_intern("quirks_mode");
2187
2090
  i_object_class = rb_intern("object_class");
2188
2091
  i_array_class = rb_intern("array_class");
2092
+ i_decimal_class = rb_intern("decimal_class");
2189
2093
  i_match = rb_intern("match");
2190
2094
  i_match_string = rb_intern("match_string");
2191
2095
  i_key_p = rb_intern("key?");
@@ -2193,18 +2097,7 @@ void Init_parser(void)
2193
2097
  i_aset = rb_intern("[]=");
2194
2098
  i_aref = rb_intern("[]");
2195
2099
  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
2100
+ i_new = rb_intern("new");
2208
2101
  }
2209
2102
 
2210
2103
  /*