json 1.8.3 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (82) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +7 -10
  4. data/{CHANGES → CHANGES.md} +186 -90
  5. data/Gemfile +10 -6
  6. data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
  7. data/{README.rdoc → README.md} +184 -133
  8. data/Rakefile +33 -37
  9. data/VERSION +1 -1
  10. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  11. data/ext/json/ext/generator/generator.c +47 -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 +374 -459
  15. data/ext/json/ext/parser/parser.h +4 -5
  16. data/ext/json/ext/parser/parser.rl +133 -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 +132 -415
  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 +3 -3
  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/set.rb +29 -0
  45. data/lib/json/add/struct.rb +1 -1
  46. data/lib/json/add/symbol.rb +1 -1
  47. data/lib/json/add/time.rb +1 -1
  48. data/lib/json/common.rb +24 -52
  49. data/lib/json/ext.rb +0 -6
  50. data/lib/json/generic_object.rb +5 -4
  51. data/lib/json/pure/generator.rb +61 -125
  52. data/lib/json/pure/parser.rb +33 -81
  53. data/lib/json/pure.rb +2 -8
  54. data/lib/json/version.rb +2 -1
  55. data/lib/json.rb +1 -0
  56. data/references/rfc7159.txt +899 -0
  57. data/tests/fixtures/obsolete_fail1.json +1 -0
  58. data/tests/{test_json_addition.rb → json_addition_test.rb} +32 -25
  59. data/tests/json_common_interface_test.rb +126 -0
  60. data/tests/json_encoding_test.rb +107 -0
  61. data/tests/json_ext_parser_test.rb +15 -0
  62. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
  63. data/tests/{test_json_generate.rb → json_generator_test.rb} +79 -39
  64. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  65. data/tests/json_parser_test.rb +472 -0
  66. data/tests/json_string_matching_test.rb +38 -0
  67. data/tests/{setup_variant.rb → test_helper.rb} +6 -0
  68. data/tools/diff.sh +18 -0
  69. data/tools/fuzz.rb +1 -9
  70. metadata +29 -47
  71. data/COPYING +0 -58
  72. data/COPYING-json-jruby +0 -57
  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/test_json.rb +0 -553
  80. data/tests/test_json_encoding.rb +0 -65
  81. data/tests/test_json_string_matching.rb +0 -39
  82. 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,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;
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 167 "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 182 "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 149 "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,10 +243,10 @@ 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 {
@@ -247,7 +263,7 @@ st9:
247
263
  if ( ++p == pe )
248
264
  goto _test_eof9;
249
265
  case 9:
250
- #line 251 "parser.c"
266
+ #line 267 "parser.c"
251
267
  switch( (*p) ) {
252
268
  case 13: goto st9;
253
269
  case 32: goto st9;
@@ -336,14 +352,14 @@ case 18:
336
352
  goto st9;
337
353
  goto st18;
338
354
  tr4:
339
- #line 141 "parser.rl"
355
+ #line 157 "parser.rl"
340
356
  { p--; {p++; cs = 27; goto _out;} }
341
357
  goto st27;
342
358
  st27:
343
359
  if ( ++p == pe )
344
360
  goto _test_eof27;
345
361
  case 27:
346
- #line 347 "parser.c"
362
+ #line 363 "parser.c"
347
363
  goto st0;
348
364
  st19:
349
365
  if ( ++p == pe )
@@ -441,7 +457,7 @@ case 26:
441
457
  _out: {}
442
458
  }
443
459
 
444
- #line 167 "parser.rl"
460
+ #line 183 "parser.rl"
445
461
 
446
462
  if (cs >= JSON_object_first_final) {
447
463
  if (json->create_additions) {
@@ -466,281 +482,358 @@ case 26:
466
482
 
467
483
 
468
484
 
469
- #line 470 "parser.c"
485
+ #line 486 "parser.c"
470
486
  enum {JSON_value_start = 1};
471
- enum {JSON_value_first_final = 21};
487
+ enum {JSON_value_first_final = 29};
472
488
  enum {JSON_value_error = 0};
473
489
 
474
490
  enum {JSON_value_en_main = 1};
475
491
 
476
492
 
477
- #line 271 "parser.rl"
493
+ #line 283 "parser.rl"
478
494
 
479
495
 
480
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
496
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
481
497
  {
482
498
  int cs = EVIL;
483
499
 
484
500
 
485
- #line 486 "parser.c"
501
+ #line 502 "parser.c"
486
502
  {
487
503
  cs = JSON_value_start;
488
504
  }
489
505
 
490
- #line 278 "parser.rl"
506
+ #line 290 "parser.rl"
491
507
 
492
- #line 493 "parser.c"
508
+ #line 509 "parser.c"
493
509
  {
494
510
  if ( p == pe )
495
511
  goto _test_eof;
496
512
  switch ( cs )
497
513
  {
514
+ st1:
515
+ if ( ++p == pe )
516
+ goto _test_eof1;
498
517
  case 1:
499
518
  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;
519
+ case 13: goto st1;
520
+ case 32: goto st1;
521
+ case 34: goto tr2;
522
+ case 45: goto tr3;
523
+ case 47: goto st6;
524
+ case 73: goto st10;
525
+ case 78: goto st17;
526
+ case 91: goto tr7;
527
+ case 102: goto st19;
528
+ case 110: goto st23;
529
+ case 116: goto st26;
530
+ case 123: goto tr11;
509
531
  }
510
- if ( 48 <= (*p) && (*p) <= 57 )
511
- goto tr2;
532
+ if ( (*p) > 10 ) {
533
+ if ( 48 <= (*p) && (*p) <= 57 )
534
+ goto tr3;
535
+ } else if ( (*p) >= 9 )
536
+ goto st1;
512
537
  goto st0;
513
538
  st0:
514
539
  cs = 0;
515
540
  goto _out;
516
- tr0:
517
- #line 219 "parser.rl"
541
+ tr2:
542
+ #line 235 "parser.rl"
518
543
  {
519
544
  char *np = JSON_parse_string(json, p, pe, result);
520
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
545
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
521
546
  }
522
- goto st21;
523
- tr2:
524
- #line 224 "parser.rl"
547
+ goto st29;
548
+ tr3:
549
+ #line 240 "parser.rl"
525
550
  {
526
551
  char *np;
527
- if(pe > p + 9 - json->quirks_mode && !strncmp(MinusInfinity, p, 9)) {
552
+ if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
528
553
  if (json->allow_nan) {
529
554
  *result = CMinusInfinity;
530
555
  {p = (( p + 10))-1;}
531
- p--; {p++; cs = 21; goto _out;}
556
+ p--; {p++; cs = 29; goto _out;}
532
557
  } else {
533
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
558
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
534
559
  }
535
560
  }
536
561
  np = JSON_parse_float(json, p, pe, result);
537
562
  if (np != NULL) {p = (( np))-1;}
538
563
  np = JSON_parse_integer(json, p, pe, result);
539
564
  if (np != NULL) {p = (( np))-1;}
540
- p--; {p++; cs = 21; goto _out;}
565
+ p--; {p++; cs = 29; goto _out;}
541
566
  }
542
- goto st21;
543
- tr5:
544
- #line 242 "parser.rl"
567
+ goto st29;
568
+ tr7:
569
+ #line 258 "parser.rl"
545
570
  {
546
571
  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;}
572
+ np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
573
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
551
574
  }
552
- goto st21;
553
- tr9:
554
- #line 250 "parser.rl"
575
+ goto st29;
576
+ tr11:
577
+ #line 264 "parser.rl"
555
578
  {
556
579
  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;}
580
+ np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
581
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
561
582
  }
562
- goto st21;
563
- tr16:
564
- #line 212 "parser.rl"
583
+ goto st29;
584
+ tr25:
585
+ #line 228 "parser.rl"
565
586
  {
566
587
  if (json->allow_nan) {
567
588
  *result = CInfinity;
568
589
  } else {
569
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
590
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
570
591
  }
571
592
  }
572
- goto st21;
573
- tr18:
574
- #line 205 "parser.rl"
593
+ goto st29;
594
+ tr27:
595
+ #line 221 "parser.rl"
575
596
  {
576
597
  if (json->allow_nan) {
577
598
  *result = CNaN;
578
599
  } else {
579
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
600
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
580
601
  }
581
602
  }
582
- goto st21;
583
- tr22:
584
- #line 199 "parser.rl"
603
+ goto st29;
604
+ tr31:
605
+ #line 215 "parser.rl"
585
606
  {
586
607
  *result = Qfalse;
587
608
  }
588
- goto st21;
589
- tr25:
590
- #line 196 "parser.rl"
609
+ goto st29;
610
+ tr34:
611
+ #line 212 "parser.rl"
591
612
  {
592
613
  *result = Qnil;
593
614
  }
594
- goto st21;
595
- tr28:
596
- #line 202 "parser.rl"
615
+ goto st29;
616
+ tr37:
617
+ #line 218 "parser.rl"
597
618
  {
598
619
  *result = Qtrue;
599
620
  }
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"
621
+ goto st29;
622
+ st29:
623
+ if ( ++p == pe )
624
+ goto _test_eof29;
625
+ case 29:
626
+ #line 270 "parser.rl"
627
+ { p--; {p++; cs = 29; goto _out;} }
628
+ #line 629 "parser.c"
629
+ switch( (*p) ) {
630
+ case 13: goto st29;
631
+ case 32: goto st29;
632
+ case 47: goto st2;
633
+ }
634
+ if ( 9 <= (*p) && (*p) <= 10 )
635
+ goto st29;
608
636
  goto st0;
609
637
  st2:
610
638
  if ( ++p == pe )
611
639
  goto _test_eof2;
612
640
  case 2:
613
- if ( (*p) == 110 )
614
- goto st3;
641
+ switch( (*p) ) {
642
+ case 42: goto st3;
643
+ case 47: goto st5;
644
+ }
615
645
  goto st0;
616
646
  st3:
617
647
  if ( ++p == pe )
618
648
  goto _test_eof3;
619
649
  case 3:
620
- if ( (*p) == 102 )
650
+ if ( (*p) == 42 )
621
651
  goto st4;
622
- goto st0;
652
+ goto st3;
623
653
  st4:
624
654
  if ( ++p == pe )
625
655
  goto _test_eof4;
626
656
  case 4:
627
- if ( (*p) == 105 )
628
- goto st5;
629
- goto st0;
657
+ switch( (*p) ) {
658
+ case 42: goto st4;
659
+ case 47: goto st29;
660
+ }
661
+ goto st3;
630
662
  st5:
631
663
  if ( ++p == pe )
632
664
  goto _test_eof5;
633
665
  case 5:
634
- if ( (*p) == 110 )
635
- goto st6;
636
- goto st0;
666
+ if ( (*p) == 10 )
667
+ goto st29;
668
+ goto st5;
637
669
  st6:
638
670
  if ( ++p == pe )
639
671
  goto _test_eof6;
640
672
  case 6:
641
- if ( (*p) == 105 )
642
- goto st7;
673
+ switch( (*p) ) {
674
+ case 42: goto st7;
675
+ case 47: goto st9;
676
+ }
643
677
  goto st0;
644
678
  st7:
645
679
  if ( ++p == pe )
646
680
  goto _test_eof7;
647
681
  case 7:
648
- if ( (*p) == 116 )
682
+ if ( (*p) == 42 )
649
683
  goto st8;
650
- goto st0;
684
+ goto st7;
651
685
  st8:
652
686
  if ( ++p == pe )
653
687
  goto _test_eof8;
654
688
  case 8:
655
- if ( (*p) == 121 )
656
- goto tr16;
657
- goto st0;
689
+ switch( (*p) ) {
690
+ case 42: goto st8;
691
+ case 47: goto st1;
692
+ }
693
+ goto st7;
658
694
  st9:
659
695
  if ( ++p == pe )
660
696
  goto _test_eof9;
661
697
  case 9:
662
- if ( (*p) == 97 )
663
- goto st10;
664
- goto st0;
698
+ if ( (*p) == 10 )
699
+ goto st1;
700
+ goto st9;
665
701
  st10:
666
702
  if ( ++p == pe )
667
703
  goto _test_eof10;
668
704
  case 10:
669
- if ( (*p) == 78 )
670
- goto tr18;
705
+ if ( (*p) == 110 )
706
+ goto st11;
671
707
  goto st0;
672
708
  st11:
673
709
  if ( ++p == pe )
674
710
  goto _test_eof11;
675
711
  case 11:
676
- if ( (*p) == 97 )
712
+ if ( (*p) == 102 )
677
713
  goto st12;
678
714
  goto st0;
679
715
  st12:
680
716
  if ( ++p == pe )
681
717
  goto _test_eof12;
682
718
  case 12:
683
- if ( (*p) == 108 )
719
+ if ( (*p) == 105 )
684
720
  goto st13;
685
721
  goto st0;
686
722
  st13:
687
723
  if ( ++p == pe )
688
724
  goto _test_eof13;
689
725
  case 13:
690
- if ( (*p) == 115 )
726
+ if ( (*p) == 110 )
691
727
  goto st14;
692
728
  goto st0;
693
729
  st14:
694
730
  if ( ++p == pe )
695
731
  goto _test_eof14;
696
732
  case 14:
697
- if ( (*p) == 101 )
698
- goto tr22;
733
+ if ( (*p) == 105 )
734
+ goto st15;
699
735
  goto st0;
700
736
  st15:
701
737
  if ( ++p == pe )
702
738
  goto _test_eof15;
703
739
  case 15:
704
- if ( (*p) == 117 )
740
+ if ( (*p) == 116 )
705
741
  goto st16;
706
742
  goto st0;
707
743
  st16:
708
744
  if ( ++p == pe )
709
745
  goto _test_eof16;
710
746
  case 16:
711
- if ( (*p) == 108 )
712
- goto st17;
747
+ if ( (*p) == 121 )
748
+ goto tr25;
713
749
  goto st0;
714
750
  st17:
715
751
  if ( ++p == pe )
716
752
  goto _test_eof17;
717
753
  case 17:
718
- if ( (*p) == 108 )
719
- goto tr25;
754
+ if ( (*p) == 97 )
755
+ goto st18;
720
756
  goto st0;
721
757
  st18:
722
758
  if ( ++p == pe )
723
759
  goto _test_eof18;
724
760
  case 18:
725
- if ( (*p) == 114 )
726
- goto st19;
761
+ if ( (*p) == 78 )
762
+ goto tr27;
727
763
  goto st0;
728
764
  st19:
729
765
  if ( ++p == pe )
730
766
  goto _test_eof19;
731
767
  case 19:
732
- if ( (*p) == 117 )
768
+ if ( (*p) == 97 )
733
769
  goto st20;
734
770
  goto st0;
735
771
  st20:
736
772
  if ( ++p == pe )
737
773
  goto _test_eof20;
738
774
  case 20:
775
+ if ( (*p) == 108 )
776
+ goto st21;
777
+ goto st0;
778
+ st21:
779
+ if ( ++p == pe )
780
+ goto _test_eof21;
781
+ case 21:
782
+ if ( (*p) == 115 )
783
+ goto st22;
784
+ goto st0;
785
+ st22:
786
+ if ( ++p == pe )
787
+ goto _test_eof22;
788
+ case 22:
739
789
  if ( (*p) == 101 )
740
- goto tr28;
790
+ goto tr31;
791
+ goto st0;
792
+ st23:
793
+ if ( ++p == pe )
794
+ goto _test_eof23;
795
+ case 23:
796
+ if ( (*p) == 117 )
797
+ goto st24;
798
+ goto st0;
799
+ st24:
800
+ if ( ++p == pe )
801
+ goto _test_eof24;
802
+ case 24:
803
+ if ( (*p) == 108 )
804
+ goto st25;
805
+ goto st0;
806
+ st25:
807
+ if ( ++p == pe )
808
+ goto _test_eof25;
809
+ case 25:
810
+ if ( (*p) == 108 )
811
+ goto tr34;
812
+ goto st0;
813
+ st26:
814
+ if ( ++p == pe )
815
+ goto _test_eof26;
816
+ case 26:
817
+ if ( (*p) == 114 )
818
+ goto st27;
819
+ goto st0;
820
+ st27:
821
+ if ( ++p == pe )
822
+ goto _test_eof27;
823
+ case 27:
824
+ if ( (*p) == 117 )
825
+ goto st28;
826
+ goto st0;
827
+ st28:
828
+ if ( ++p == pe )
829
+ goto _test_eof28;
830
+ case 28:
831
+ if ( (*p) == 101 )
832
+ goto tr37;
741
833
  goto st0;
742
834
  }
743
- _test_eof21: cs = 21; goto _test_eof;
835
+ _test_eof1: cs = 1; goto _test_eof;
836
+ _test_eof29: cs = 29; goto _test_eof;
744
837
  _test_eof2: cs = 2; goto _test_eof;
745
838
  _test_eof3: cs = 3; goto _test_eof;
746
839
  _test_eof4: cs = 4; goto _test_eof;
@@ -760,12 +853,20 @@ case 20:
760
853
  _test_eof18: cs = 18; goto _test_eof;
761
854
  _test_eof19: cs = 19; goto _test_eof;
762
855
  _test_eof20: cs = 20; goto _test_eof;
856
+ _test_eof21: cs = 21; goto _test_eof;
857
+ _test_eof22: cs = 22; goto _test_eof;
858
+ _test_eof23: cs = 23; goto _test_eof;
859
+ _test_eof24: cs = 24; goto _test_eof;
860
+ _test_eof25: cs = 25; goto _test_eof;
861
+ _test_eof26: cs = 26; goto _test_eof;
862
+ _test_eof27: cs = 27; goto _test_eof;
863
+ _test_eof28: cs = 28; goto _test_eof;
763
864
 
764
865
  _test_eof: {}
765
866
  _out: {}
766
867
  }
767
868
 
768
- #line 279 "parser.rl"
869
+ #line 291 "parser.rl"
769
870
 
770
871
  if (cs >= JSON_value_first_final) {
771
872
  return p;
@@ -775,7 +876,7 @@ case 20:
775
876
  }
776
877
 
777
878
 
778
- #line 779 "parser.c"
879
+ #line 880 "parser.c"
779
880
  enum {JSON_integer_start = 1};
780
881
  enum {JSON_integer_first_final = 3};
781
882
  enum {JSON_integer_error = 0};
@@ -783,7 +884,7 @@ enum {JSON_integer_error = 0};
783
884
  enum {JSON_integer_en_main = 1};
784
885
 
785
886
 
786
- #line 295 "parser.rl"
887
+ #line 307 "parser.rl"
787
888
 
788
889
 
789
890
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -791,15 +892,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
791
892
  int cs = EVIL;
792
893
 
793
894
 
794
- #line 795 "parser.c"
895
+ #line 896 "parser.c"
795
896
  {
796
897
  cs = JSON_integer_start;
797
898
  }
798
899
 
799
- #line 302 "parser.rl"
900
+ #line 314 "parser.rl"
800
901
  json->memo = p;
801
902
 
802
- #line 803 "parser.c"
903
+ #line 904 "parser.c"
803
904
  {
804
905
  if ( p == pe )
805
906
  goto _test_eof;
@@ -833,14 +934,14 @@ case 3:
833
934
  goto st0;
834
935
  goto tr4;
835
936
  tr4:
836
- #line 292 "parser.rl"
937
+ #line 304 "parser.rl"
837
938
  { p--; {p++; cs = 4; goto _out;} }
838
939
  goto st4;
839
940
  st4:
840
941
  if ( ++p == pe )
841
942
  goto _test_eof4;
842
943
  case 4:
843
- #line 844 "parser.c"
944
+ #line 945 "parser.c"
844
945
  goto st0;
845
946
  st5:
846
947
  if ( ++p == pe )
@@ -859,7 +960,7 @@ case 5:
859
960
  _out: {}
860
961
  }
861
962
 
862
- #line 304 "parser.rl"
963
+ #line 316 "parser.rl"
863
964
 
864
965
  if (cs >= JSON_integer_first_final) {
865
966
  long len = p - json->memo;
@@ -874,7 +975,7 @@ case 5:
874
975
  }
875
976
 
876
977
 
877
- #line 878 "parser.c"
978
+ #line 979 "parser.c"
878
979
  enum {JSON_float_start = 1};
879
980
  enum {JSON_float_first_final = 8};
880
981
  enum {JSON_float_error = 0};
@@ -882,23 +983,36 @@ enum {JSON_float_error = 0};
882
983
  enum {JSON_float_en_main = 1};
883
984
 
884
985
 
885
- #line 329 "parser.rl"
986
+ #line 341 "parser.rl"
987
+
886
988
 
989
+ static int is_bigdecimal_class(VALUE obj)
990
+ {
991
+ if (cBigDecimal == Qundef) {
992
+ if (rb_const_defined(rb_cObject, i_BigDecimal)) {
993
+ cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
994
+ }
995
+ else {
996
+ return 0;
997
+ }
998
+ }
999
+ return obj == cBigDecimal;
1000
+ }
887
1001
 
888
1002
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
889
1003
  {
890
1004
  int cs = EVIL;
891
1005
 
892
1006
 
893
- #line 894 "parser.c"
1007
+ #line 1008 "parser.c"
894
1008
  {
895
1009
  cs = JSON_float_start;
896
1010
  }
897
1011
 
898
- #line 336 "parser.rl"
1012
+ #line 361 "parser.rl"
899
1013
  json->memo = p;
900
1014
 
901
- #line 902 "parser.c"
1015
+ #line 1016 "parser.c"
902
1016
  {
903
1017
  if ( p == pe )
904
1018
  goto _test_eof;
@@ -956,14 +1070,14 @@ case 8:
956
1070
  goto st0;
957
1071
  goto tr9;
958
1072
  tr9:
959
- #line 323 "parser.rl"
1073
+ #line 335 "parser.rl"
960
1074
  { p--; {p++; cs = 9; goto _out;} }
961
1075
  goto st9;
962
1076
  st9:
963
1077
  if ( ++p == pe )
964
1078
  goto _test_eof9;
965
1079
  case 9:
966
- #line 967 "parser.c"
1080
+ #line 1081 "parser.c"
967
1081
  goto st0;
968
1082
  st5:
969
1083
  if ( ++p == pe )
@@ -1024,14 +1138,24 @@ case 7:
1024
1138
  _out: {}
1025
1139
  }
1026
1140
 
1027
- #line 338 "parser.rl"
1141
+ #line 363 "parser.rl"
1028
1142
 
1029
1143
  if (cs >= JSON_float_first_final) {
1030
1144
  long len = p - json->memo;
1031
1145
  fbuffer_clear(json->fbuffer);
1032
1146
  fbuffer_append(json->fbuffer, json->memo, len);
1033
1147
  fbuffer_append_char(json->fbuffer, '\0');
1034
- *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1148
+ if (NIL_P(json->decimal_class)) {
1149
+ *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1150
+ } else {
1151
+ VALUE text;
1152
+ text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
1153
+ if (is_bigdecimal_class(json->decimal_class)) {
1154
+ *result = rb_funcall(Qnil, i_BigDecimal, 1, text);
1155
+ } else {
1156
+ *result = rb_funcall(json->decimal_class, i_new, 1, text);
1157
+ }
1158
+ }
1035
1159
  return p + 1;
1036
1160
  } else {
1037
1161
  return NULL;
@@ -1040,7 +1164,7 @@ case 7:
1040
1164
 
1041
1165
 
1042
1166
 
1043
- #line 1044 "parser.c"
1167
+ #line 1168 "parser.c"
1044
1168
  enum {JSON_array_start = 1};
1045
1169
  enum {JSON_array_first_final = 17};
1046
1170
  enum {JSON_array_error = 0};
@@ -1048,28 +1172,28 @@ enum {JSON_array_error = 0};
1048
1172
  enum {JSON_array_en_main = 1};
1049
1173
 
1050
1174
 
1051
- #line 381 "parser.rl"
1175
+ #line 416 "parser.rl"
1052
1176
 
1053
1177
 
1054
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
1178
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
1055
1179
  {
1056
1180
  int cs = EVIL;
1057
1181
  VALUE array_class = json->array_class;
1058
1182
 
1059
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
1060
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
1183
+ if (json->max_nesting && current_nesting > json->max_nesting) {
1184
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
1061
1185
  }
1062
1186
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1063
1187
 
1064
1188
 
1065
- #line 1066 "parser.c"
1189
+ #line 1190 "parser.c"
1066
1190
  {
1067
1191
  cs = JSON_array_start;
1068
1192
  }
1069
1193
 
1070
- #line 394 "parser.rl"
1194
+ #line 429 "parser.rl"
1071
1195
 
1072
- #line 1073 "parser.c"
1196
+ #line 1197 "parser.c"
1073
1197
  {
1074
1198
  if ( p == pe )
1075
1199
  goto _test_eof;
@@ -1108,10 +1232,10 @@ case 2:
1108
1232
  goto st2;
1109
1233
  goto st0;
1110
1234
  tr2:
1111
- #line 358 "parser.rl"
1235
+ #line 393 "parser.rl"
1112
1236
  {
1113
1237
  VALUE v = Qnil;
1114
- char *np = JSON_parse_value(json, p, pe, &v);
1238
+ char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
1115
1239
  if (np == NULL) {
1116
1240
  p--; {p++; cs = 3; goto _out;}
1117
1241
  } else {
@@ -1128,7 +1252,7 @@ st3:
1128
1252
  if ( ++p == pe )
1129
1253
  goto _test_eof3;
1130
1254
  case 3:
1131
- #line 1132 "parser.c"
1255
+ #line 1256 "parser.c"
1132
1256
  switch( (*p) ) {
1133
1257
  case 13: goto st3;
1134
1258
  case 32: goto st3;
@@ -1228,14 +1352,14 @@ case 12:
1228
1352
  goto st3;
1229
1353
  goto st12;
1230
1354
  tr4:
1231
- #line 373 "parser.rl"
1355
+ #line 408 "parser.rl"
1232
1356
  { p--; {p++; cs = 17; goto _out;} }
1233
1357
  goto st17;
1234
1358
  st17:
1235
1359
  if ( ++p == pe )
1236
1360
  goto _test_eof17;
1237
1361
  case 17:
1238
- #line 1239 "parser.c"
1362
+ #line 1363 "parser.c"
1239
1363
  goto st0;
1240
1364
  st13:
1241
1365
  if ( ++p == pe )
@@ -1291,12 +1415,12 @@ case 16:
1291
1415
  _out: {}
1292
1416
  }
1293
1417
 
1294
- #line 395 "parser.rl"
1418
+ #line 430 "parser.rl"
1295
1419
 
1296
1420
  if(cs >= JSON_array_first_final) {
1297
1421
  return p + 1;
1298
1422
  } else {
1299
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1423
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1300
1424
  return NULL;
1301
1425
  }
1302
1426
  }
@@ -1336,13 +1460,21 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1336
1460
  break;
1337
1461
  case 'u':
1338
1462
  if (pe > stringEnd - 4) {
1339
- return Qnil;
1463
+ rb_enc_raise(
1464
+ EXC_ENCODING eParserError,
1465
+ "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
1466
+ );
1340
1467
  } else {
1341
1468
  UTF32 ch = unescape_unicode((unsigned char *) ++pe);
1342
1469
  pe += 3;
1343
1470
  if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
1344
1471
  pe++;
1345
- if (pe > stringEnd - 6) return Qnil;
1472
+ if (pe > stringEnd - 6) {
1473
+ rb_enc_raise(
1474
+ EXC_ENCODING eParserError,
1475
+ "%u: incomplete surrogate pair at '%s'", __LINE__, p
1476
+ );
1477
+ }
1346
1478
  if (pe[0] == '\\' && pe[1] == 'u') {
1347
1479
  UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
1348
1480
  ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
@@ -1372,7 +1504,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1372
1504
  }
1373
1505
 
1374
1506
 
1375
- #line 1376 "parser.c"
1507
+ #line 1508 "parser.c"
1376
1508
  enum {JSON_string_start = 1};
1377
1509
  enum {JSON_string_first_final = 8};
1378
1510
  enum {JSON_string_error = 0};
@@ -1380,7 +1512,7 @@ enum {JSON_string_error = 0};
1380
1512
  enum {JSON_string_en_main = 1};
1381
1513
 
1382
1514
 
1383
- #line 494 "parser.rl"
1515
+ #line 537 "parser.rl"
1384
1516
 
1385
1517
 
1386
1518
  static int
@@ -1402,15 +1534,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
1402
1534
 
1403
1535
  *result = rb_str_buf_new(0);
1404
1536
 
1405
- #line 1406 "parser.c"
1537
+ #line 1538 "parser.c"
1406
1538
  {
1407
1539
  cs = JSON_string_start;
1408
1540
  }
1409
1541
 
1410
- #line 515 "parser.rl"
1542
+ #line 558 "parser.rl"
1411
1543
  json->memo = p;
1412
1544
 
1413
- #line 1414 "parser.c"
1545
+ #line 1546 "parser.c"
1414
1546
  {
1415
1547
  if ( p == pe )
1416
1548
  goto _test_eof;
@@ -1435,7 +1567,7 @@ case 2:
1435
1567
  goto st0;
1436
1568
  goto st2;
1437
1569
  tr2:
1438
- #line 480 "parser.rl"
1570
+ #line 523 "parser.rl"
1439
1571
  {
1440
1572
  *result = json_string_unescape(*result, json->memo + 1, p);
1441
1573
  if (NIL_P(*result)) {
@@ -1446,14 +1578,14 @@ tr2:
1446
1578
  {p = (( p + 1))-1;}
1447
1579
  }
1448
1580
  }
1449
- #line 491 "parser.rl"
1581
+ #line 534 "parser.rl"
1450
1582
  { p--; {p++; cs = 8; goto _out;} }
1451
1583
  goto st8;
1452
1584
  st8:
1453
1585
  if ( ++p == pe )
1454
1586
  goto _test_eof8;
1455
1587
  case 8:
1456
- #line 1457 "parser.c"
1588
+ #line 1589 "parser.c"
1457
1589
  goto st0;
1458
1590
  st3:
1459
1591
  if ( ++p == pe )
@@ -1529,7 +1661,7 @@ case 7:
1529
1661
  _out: {}
1530
1662
  }
1531
1663
 
1532
- #line 517 "parser.rl"
1664
+ #line 560 "parser.rl"
1533
1665
 
1534
1666
  if (json->create_additions && RTEST(match_string = json->match_string)) {
1535
1667
  VALUE klass;
@@ -1544,6 +1676,10 @@ case 7:
1544
1676
 
1545
1677
  if (json->symbolize_names && json->parsing_name) {
1546
1678
  *result = rb_str_intern(*result);
1679
+ } else {
1680
+ if (RB_TYPE_P(*result, T_STRING)) {
1681
+ rb_str_resize(*result, RSTRING_LEN(*result));
1682
+ }
1547
1683
  }
1548
1684
  if (cs >= JSON_string_first_final) {
1549
1685
  return p + 1;
@@ -1566,41 +1702,16 @@ case 7:
1566
1702
 
1567
1703
  static VALUE convert_encoding(VALUE source)
1568
1704
  {
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
1705
  #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);
1706
+ rb_encoding *enc = rb_enc_get(source);
1707
+ if (enc == rb_ascii8bit_encoding()) {
1708
+ if (OBJ_FROZEN(source)) {
1709
+ source = rb_str_dup(source);
1603
1710
  }
1711
+ FORCE_UTF8(source);
1712
+ } else {
1713
+ source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
1714
+ }
1604
1715
  #endif
1605
1716
  return source;
1606
1717
  }
@@ -1623,8 +1734,9 @@ static VALUE convert_encoding(VALUE source)
1623
1734
  * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
1624
1735
  * false.
1625
1736
  * * *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.
1737
+ * (keys) in a JSON object. Otherwise strings are returned, which is
1738
+ * also the default. It's not possible to use this option in
1739
+ * conjunction with the *create_additions* option.
1628
1740
  * * *create_additions*: If set to false, the Parser doesn't create
1629
1741
  * additions even if a matching class and create_id was found. This option
1630
1742
  * defaults to false.
@@ -1639,12 +1751,18 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1639
1751
  if (json->Vsource) {
1640
1752
  rb_raise(rb_eTypeError, "already initialized instance");
1641
1753
  }
1754
+ #ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1755
+ rb_scan_args(argc, argv, "1:", &source, &opts);
1756
+ #else
1642
1757
  rb_scan_args(argc, argv, "11", &source, &opts);
1758
+ #endif
1643
1759
  if (!NIL_P(opts)) {
1760
+ #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1644
1761
  opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
1645
1762
  if (NIL_P(opts)) {
1646
1763
  rb_raise(rb_eArgError, "opts needs to be like a hash");
1647
1764
  } else {
1765
+ #endif
1648
1766
  VALUE tmp = ID2SYM(i_max_nesting);
1649
1767
  if (option_given_p(opts, tmp)) {
1650
1768
  VALUE max_nesting = rb_hash_aref(opts, tmp);
@@ -1669,19 +1787,17 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1669
1787
  } else {
1670
1788
  json->symbolize_names = 0;
1671
1789
  }
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
1790
  tmp = ID2SYM(i_create_additions);
1680
1791
  if (option_given_p(opts, tmp)) {
1681
1792
  json->create_additions = RTEST(rb_hash_aref(opts, tmp));
1682
1793
  } else {
1683
1794
  json->create_additions = 0;
1684
1795
  }
1796
+ if (json->symbolize_names && json->create_additions) {
1797
+ rb_raise(rb_eArgError,
1798
+ "options :symbolize_names and :create_additions cannot be "
1799
+ " used in conjunction");
1800
+ }
1685
1801
  tmp = ID2SYM(i_create_id);
1686
1802
  if (option_given_p(opts, tmp)) {
1687
1803
  json->create_id = rb_hash_aref(opts, tmp);
@@ -1700,6 +1816,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1700
1816
  } else {
1701
1817
  json->array_class = Qnil;
1702
1818
  }
1819
+ tmp = ID2SYM(i_decimal_class);
1820
+ if (option_given_p(opts, tmp)) {
1821
+ json->decimal_class = rb_hash_aref(opts, tmp);
1822
+ } else {
1823
+ json->decimal_class = Qnil;
1824
+ }
1703
1825
  tmp = ID2SYM(i_match_string);
1704
1826
  if (option_given_p(opts, tmp)) {
1705
1827
  VALUE match_string = rb_hash_aref(opts, tmp);
@@ -1707,7 +1829,9 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1707
1829
  } else {
1708
1830
  json->match_string = Qnil;
1709
1831
  }
1832
+ #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1710
1833
  }
1834
+ #endif
1711
1835
  } else {
1712
1836
  json->max_nesting = 100;
1713
1837
  json->allow_nan = 0;
@@ -1715,12 +1839,9 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1715
1839
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
1716
1840
  json->object_class = Qnil;
1717
1841
  json->array_class = Qnil;
1842
+ json->decimal_class = Qnil;
1718
1843
  }
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;
1844
+ source = convert_encoding(StringValue(source));
1724
1845
  StringValue(source);
1725
1846
  json->len = RSTRING_LEN(source);
1726
1847
  json->source = RSTRING_PTR(source);;
@@ -1729,7 +1850,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1729
1850
  }
1730
1851
 
1731
1852
 
1732
- #line 1733 "parser.c"
1853
+ #line 1854 "parser.c"
1733
1854
  enum {JSON_start = 1};
1734
1855
  enum {JSON_first_final = 10};
1735
1856
  enum {JSON_error = 0};
@@ -1737,201 +1858,33 @@ enum {JSON_error = 0};
1737
1858
  enum {JSON_en_main = 1};
1738
1859
 
1739
1860
 
1740
- #line 740 "parser.rl"
1861
+ #line 762 "parser.rl"
1741
1862
 
1742
1863
 
1743
- static VALUE cParser_parse_strict(VALUE self)
1864
+ /*
1865
+ * call-seq: parse()
1866
+ *
1867
+ * Parses the current JSON text _source_ and returns the complete data
1868
+ * structure as a result.
1869
+ */
1870
+ static VALUE cParser_parse(VALUE self)
1744
1871
  {
1745
- char *p, *pe;
1746
- int cs = EVIL;
1747
- VALUE result = Qnil;
1748
- GET_PARSER;
1872
+ char *p, *pe;
1873
+ int cs = EVIL;
1874
+ VALUE result = Qnil;
1875
+ GET_PARSER;
1749
1876
 
1750
1877
 
1751
- #line 1752 "parser.c"
1878
+ #line 1879 "parser.c"
1752
1879
  {
1753
1880
  cs = JSON_start;
1754
1881
  }
1755
1882
 
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
1883
  #line 778 "parser.rl"
1884
+ p = json->source;
1885
+ pe = p + json->len;
1915
1886
 
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"
1887
+ #line 1888 "parser.c"
1935
1888
  {
1936
1889
  if ( p == pe )
1937
1890
  goto _test_eof;
@@ -1965,9 +1918,9 @@ st0:
1965
1918
  cs = 0;
1966
1919
  goto _out;
1967
1920
  tr2:
1968
- #line 770 "parser.rl"
1921
+ #line 754 "parser.rl"
1969
1922
  {
1970
- char *np = JSON_parse_value(json, p, pe, &result);
1923
+ char *np = JSON_parse_value(json, p, pe, &result, 0);
1971
1924
  if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1972
1925
  }
1973
1926
  goto st10;
@@ -1975,7 +1928,7 @@ st10:
1975
1928
  if ( ++p == pe )
1976
1929
  goto _test_eof10;
1977
1930
  case 10:
1978
- #line 1979 "parser.c"
1931
+ #line 1932 "parser.c"
1979
1932
  switch( (*p) ) {
1980
1933
  case 13: goto st10;
1981
1934
  case 32: goto st10;
@@ -2064,30 +2017,13 @@ case 9:
2064
2017
  _out: {}
2065
2018
  }
2066
2019
 
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;
2020
+ #line 781 "parser.rl"
2086
2021
 
2087
- if (json->quirks_mode) {
2088
- return cParser_parse_quirks_mode(self);
2022
+ if (cs >= JSON_first_final && p == pe) {
2023
+ return result;
2089
2024
  } else {
2090
- return cParser_parse_strict(self);
2025
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
2026
+ return Qnil;
2091
2027
  }
2092
2028
  }
2093
2029
 
@@ -2098,6 +2034,7 @@ static void JSON_mark(void *ptr)
2098
2034
  rb_gc_mark_maybe(json->create_id);
2099
2035
  rb_gc_mark_maybe(json->object_class);
2100
2036
  rb_gc_mark_maybe(json->array_class);
2037
+ rb_gc_mark_maybe(json->decimal_class);
2101
2038
  rb_gc_mark_maybe(json->match_string);
2102
2039
  }
2103
2040
 
@@ -2145,20 +2082,9 @@ static VALUE cParser_source(VALUE self)
2145
2082
  return rb_str_dup(json->Vsource);
2146
2083
  }
2147
2084
 
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
2085
  void Init_parser(void)
2161
2086
  {
2087
+ #undef rb_intern
2162
2088
  rb_require("json/common");
2163
2089
  mJSON = rb_define_module("JSON");
2164
2090
  mExt = rb_define_module_under(mJSON, "Ext");
@@ -2169,7 +2095,6 @@ void Init_parser(void)
2169
2095
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
2170
2096
  rb_define_method(cParser, "parse", cParser_parse, 0);
2171
2097
  rb_define_method(cParser, "source", cParser_source, 0);
2172
- rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
2173
2098
 
2174
2099
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
2175
2100
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
@@ -2183,9 +2108,9 @@ void Init_parser(void)
2183
2108
  i_max_nesting = rb_intern("max_nesting");
2184
2109
  i_allow_nan = rb_intern("allow_nan");
2185
2110
  i_symbolize_names = rb_intern("symbolize_names");
2186
- i_quirks_mode = rb_intern("quirks_mode");
2187
2111
  i_object_class = rb_intern("object_class");
2188
2112
  i_array_class = rb_intern("array_class");
2113
+ i_decimal_class = rb_intern("decimal_class");
2189
2114
  i_match = rb_intern("match");
2190
2115
  i_match_string = rb_intern("match_string");
2191
2116
  i_key_p = rb_intern("key?");
@@ -2193,18 +2118,8 @@ void Init_parser(void)
2193
2118
  i_aset = rb_intern("[]=");
2194
2119
  i_aref = rb_intern("[]");
2195
2120
  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
2121
+ i_new = rb_intern("new");
2122
+ i_BigDecimal = rb_intern("BigDecimal");
2208
2123
  }
2209
2124
 
2210
2125
  /*