json 1.8.6 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +13 -5
  4. data/{CHANGES → CHANGES.md} +212 -95
  5. data/Gemfile +10 -3
  6. data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
  7. data/README.md +187 -107
  8. data/Rakefile +36 -104
  9. data/VERSION +1 -1
  10. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  11. data/ext/json/ext/generator/generator.c +175 -98
  12. data/ext/json/ext/generator/generator.h +0 -6
  13. data/ext/json/ext/parser/extconf.rb +3 -0
  14. data/ext/json/ext/parser/parser.c +380 -483
  15. data/ext/json/ext/parser/parser.h +4 -5
  16. data/ext/json/ext/parser/parser.rl +109 -175
  17. data/ext/json/extconf.rb +0 -1
  18. data/java/src/json/ext/Generator.java +35 -15
  19. data/java/src/json/ext/GeneratorState.java +2 -54
  20. data/java/src/json/ext/OptionsReader.java +1 -1
  21. data/java/src/json/ext/Parser.java +131 -413
  22. data/java/src/json/ext/Parser.rl +47 -122
  23. data/java/src/json/ext/RuntimeInfo.java +0 -4
  24. data/json-java.gemspec +4 -5
  25. data/json.gemspec +0 -0
  26. data/json_pure.gemspec +11 -15
  27. data/lib/json.rb +379 -29
  28. data/lib/json/add/bigdecimal.rb +3 -2
  29. data/lib/json/add/complex.rb +4 -3
  30. data/lib/json/add/core.rb +1 -0
  31. data/lib/json/add/date.rb +1 -1
  32. data/lib/json/add/date_time.rb +1 -1
  33. data/lib/json/add/exception.rb +1 -1
  34. data/lib/json/add/ostruct.rb +3 -3
  35. data/lib/json/add/range.rb +1 -1
  36. data/lib/json/add/rational.rb +3 -2
  37. data/lib/json/add/regexp.rb +3 -3
  38. data/lib/json/add/set.rb +29 -0
  39. data/lib/json/add/struct.rb +1 -1
  40. data/lib/json/add/symbol.rb +1 -1
  41. data/lib/json/add/time.rb +1 -1
  42. data/lib/json/common.rb +335 -128
  43. data/lib/json/ext.rb +0 -6
  44. data/lib/json/generic_object.rb +5 -4
  45. data/lib/json/pure.rb +2 -8
  46. data/lib/json/pure/generator.rb +54 -125
  47. data/lib/json/pure/parser.rb +42 -82
  48. data/lib/json/version.rb +2 -1
  49. data/references/rfc7159.txt +899 -0
  50. data/tests/fixtures/obsolete_fail1.json +1 -0
  51. data/tests/{test_json_addition.rb → json_addition_test.rb} +32 -25
  52. data/tests/json_common_interface_test.rb +126 -0
  53. data/tests/json_encoding_test.rb +107 -0
  54. data/tests/json_ext_parser_test.rb +15 -0
  55. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +10 -8
  56. data/tests/{test_json_generate.rb → json_generator_test.rb} +112 -39
  57. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  58. data/tests/json_parser_test.rb +472 -0
  59. data/tests/json_string_matching_test.rb +38 -0
  60. data/tests/{setup_variant.rb → test_helper.rb} +6 -0
  61. data/tools/fuzz.rb +1 -9
  62. metadata +38 -43
  63. data/TODO +0 -1
  64. data/data/example.json +0 -1
  65. data/data/index.html +0 -38
  66. data/data/prototype.js +0 -4184
  67. data/tests/fixtures/fail1.json +0 -1
  68. data/tests/test_json.rb +0 -519
  69. data/tests/test_json_encoding.rb +0 -65
  70. data/tests/test_json_string_matching.rb +0 -39
  71. data/tests/test_json_unicode.rb +0 -72
@@ -1,7 +1,6 @@
1
1
  #ifndef _GENERATOR_H_
2
2
  #define _GENERATOR_H_
3
3
 
4
- #include <string.h>
5
4
  #include <math.h>
6
5
  #include <ctype.h>
7
6
 
@@ -21,10 +20,6 @@
21
20
  #define rb_obj_instance_variables(object) rb_funcall(object, rb_intern("instance_variables"), 0)
22
21
  #endif
23
22
 
24
- #ifndef RB_TYPE_P
25
- #define RB_TYPE_P(obj, type) (rb_type(obj) == type)
26
- #endif
27
-
28
23
  #define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key))
29
24
 
30
25
  /* unicode definitions */
@@ -77,7 +72,6 @@ typedef struct JSON_Generator_StateStruct {
77
72
  long max_nesting;
78
73
  char allow_nan;
79
74
  char ascii_only;
80
- char quirks_mode;
81
75
  long depth;
82
76
  long buffer_initial_length;
83
77
  } JSON_Generator_State;
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: false
1
2
  require 'mkmf'
2
3
 
4
+ have_func("rb_enc_raise", "ruby.h")
5
+
3
6
  create_makefile 'json/ext/parser'
@@ -1,10 +1,10 @@
1
-
1
+ /* This file is automatically generated from parser.rl by using ragel */
2
2
  #line 1 "parser.rl"
3
3
  #include "../fbuffer/fbuffer.h"
4
4
  #include "parser.h"
5
5
 
6
6
  #if defined HAVE_RUBY_ENCODING_H
7
- # define EXC_ENCODING UTF_8,
7
+ # define EXC_ENCODING rb_utf8_encoding(),
8
8
  # ifndef HAVE_RB_ENC_RAISE
9
9
  static void
10
10
  enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
@@ -27,7 +27,7 @@ enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
27
27
 
28
28
  /* unicode */
29
29
 
30
- static const char digit_values[256] = {
30
+ static const signed char digit_values[256] = {
31
31
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
32
32
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
33
33
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
@@ -46,7 +46,7 @@ static const char digit_values[256] = {
46
46
 
47
47
  static UTF32 unescape_unicode(const unsigned char *p)
48
48
  {
49
- char b;
49
+ signed char b;
50
50
  UTF32 result = 0;
51
51
  b = digit_values[p[0]];
52
52
  if (b < 0) return UNI_REPLACEMENT_CHAR;
@@ -89,57 +89,53 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
89
89
  return len;
90
90
  }
91
91
 
92
- #ifdef HAVE_RUBY_ENCODING_H
93
- static rb_encoding *UTF_8, *UTF_16BE, *UTF_16LE, *UTF_32BE, *UTF_32LE;
94
- #else
95
- static ID i_iconv;
96
- #endif
97
-
98
92
  static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
99
93
  static VALUE CNaN, CInfinity, CMinusInfinity;
94
+ static VALUE cBigDecimal = Qundef;
100
95
 
101
96
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
102
- i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
103
- i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
104
- i_match_string, i_aset, i_aref, i_leftshift;
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;
105
101
 
106
102
 
107
- #line 130 "parser.rl"
103
+ #line 126 "parser.rl"
108
104
 
109
105
 
110
106
 
111
- #line 112 "parser.c"
112
- static const int JSON_object_start = 1;
113
- static const int JSON_object_first_final = 27;
114
- static const int JSON_object_error = 0;
107
+ #line 108 "parser.c"
108
+ enum {JSON_object_start = 1};
109
+ enum {JSON_object_first_final = 27};
110
+ enum {JSON_object_error = 0};
115
111
 
116
- static const int JSON_object_en_main = 1;
112
+ enum {JSON_object_en_main = 1};
117
113
 
118
114
 
119
- #line 171 "parser.rl"
115
+ #line 168 "parser.rl"
120
116
 
121
117
 
122
- 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)
123
119
  {
124
120
  int cs = EVIL;
125
121
  VALUE last_name = Qnil;
126
122
  VALUE object_class = json->object_class;
127
123
 
128
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
129
- 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);
130
126
  }
131
127
 
132
128
  *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
133
129
 
134
130
 
135
- #line 136 "parser.c"
131
+ #line 132 "parser.c"
136
132
  {
137
133
  cs = JSON_object_start;
138
134
  }
139
135
 
140
- #line 186 "parser.rl"
136
+ #line 183 "parser.rl"
141
137
 
142
- #line 143 "parser.c"
138
+ #line 139 "parser.c"
143
139
  {
144
140
  if ( p == pe )
145
141
  goto _test_eof;
@@ -167,7 +163,7 @@ case 2:
167
163
  goto st2;
168
164
  goto st0;
169
165
  tr2:
170
- #line 153 "parser.rl"
166
+ #line 150 "parser.rl"
171
167
  {
172
168
  char *np;
173
169
  json->parsing_name = 1;
@@ -180,7 +176,7 @@ st3:
180
176
  if ( ++p == pe )
181
177
  goto _test_eof3;
182
178
  case 3:
183
- #line 184 "parser.c"
179
+ #line 180 "parser.c"
184
180
  switch( (*p) ) {
185
181
  case 13: goto st3;
186
182
  case 32: goto st3;
@@ -247,14 +243,15 @@ case 8:
247
243
  goto st8;
248
244
  goto st0;
249
245
  tr11:
250
- #line 138 "parser.rl"
246
+ #line 134 "parser.rl"
251
247
  {
252
248
  VALUE v = Qnil;
253
- char *np = JSON_parse_value(json, p, pe, &v);
249
+ char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
254
250
  if (np == NULL) {
255
251
  p--; {p++; cs = 9; goto _out;}
256
252
  } else {
257
253
  if (NIL_P(json->object_class)) {
254
+ OBJ_FREEZE(last_name);
258
255
  rb_hash_aset(*result, last_name, v);
259
256
  } else {
260
257
  rb_funcall(*result, i_aset, 2, last_name, v);
@@ -267,7 +264,7 @@ st9:
267
264
  if ( ++p == pe )
268
265
  goto _test_eof9;
269
266
  case 9:
270
- #line 271 "parser.c"
267
+ #line 268 "parser.c"
271
268
  switch( (*p) ) {
272
269
  case 13: goto st9;
273
270
  case 32: goto st9;
@@ -356,14 +353,14 @@ case 18:
356
353
  goto st9;
357
354
  goto st18;
358
355
  tr4:
359
- #line 161 "parser.rl"
356
+ #line 158 "parser.rl"
360
357
  { p--; {p++; cs = 27; goto _out;} }
361
358
  goto st27;
362
359
  st27:
363
360
  if ( ++p == pe )
364
361
  goto _test_eof27;
365
362
  case 27:
366
- #line 367 "parser.c"
363
+ #line 364 "parser.c"
367
364
  goto st0;
368
365
  st19:
369
366
  if ( ++p == pe )
@@ -461,7 +458,7 @@ case 26:
461
458
  _out: {}
462
459
  }
463
460
 
464
- #line 187 "parser.rl"
461
+ #line 184 "parser.rl"
465
462
 
466
463
  if (cs >= JSON_object_first_final) {
467
464
  if (json->create_additions) {
@@ -486,69 +483,78 @@ case 26:
486
483
 
487
484
 
488
485
 
489
- #line 490 "parser.c"
490
- static const int JSON_value_start = 1;
491
- static const int JSON_value_first_final = 21;
492
- static const int JSON_value_error = 0;
486
+ #line 487 "parser.c"
487
+ enum {JSON_value_start = 1};
488
+ enum {JSON_value_first_final = 29};
489
+ enum {JSON_value_error = 0};
493
490
 
494
- static const int JSON_value_en_main = 1;
491
+ enum {JSON_value_en_main = 1};
495
492
 
496
493
 
497
- #line 291 "parser.rl"
494
+ #line 284 "parser.rl"
498
495
 
499
496
 
500
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
497
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
501
498
  {
502
499
  int cs = EVIL;
503
500
 
504
501
 
505
- #line 506 "parser.c"
502
+ #line 503 "parser.c"
506
503
  {
507
504
  cs = JSON_value_start;
508
505
  }
509
506
 
510
- #line 298 "parser.rl"
507
+ #line 291 "parser.rl"
511
508
 
512
- #line 513 "parser.c"
509
+ #line 510 "parser.c"
513
510
  {
514
511
  if ( p == pe )
515
512
  goto _test_eof;
516
513
  switch ( cs )
517
514
  {
515
+ st1:
516
+ if ( ++p == pe )
517
+ goto _test_eof1;
518
518
  case 1:
519
519
  switch( (*p) ) {
520
- case 34: goto tr0;
521
- case 45: goto tr2;
522
- case 73: goto st2;
523
- case 78: goto st9;
524
- case 91: goto tr5;
525
- case 102: goto st11;
526
- case 110: goto st15;
527
- case 116: goto st18;
528
- case 123: goto tr9;
520
+ case 13: goto st1;
521
+ case 32: goto st1;
522
+ case 34: goto tr2;
523
+ case 45: goto tr3;
524
+ case 47: goto st6;
525
+ case 73: goto st10;
526
+ case 78: goto st17;
527
+ case 91: goto tr7;
528
+ case 102: goto st19;
529
+ case 110: goto st23;
530
+ case 116: goto st26;
531
+ case 123: goto tr11;
529
532
  }
530
- if ( 48 <= (*p) && (*p) <= 57 )
531
- goto tr2;
533
+ if ( (*p) > 10 ) {
534
+ if ( 48 <= (*p) && (*p) <= 57 )
535
+ goto tr3;
536
+ } else if ( (*p) >= 9 )
537
+ goto st1;
532
538
  goto st0;
533
539
  st0:
534
540
  cs = 0;
535
541
  goto _out;
536
- tr0:
537
- #line 239 "parser.rl"
542
+ tr2:
543
+ #line 236 "parser.rl"
538
544
  {
539
545
  char *np = JSON_parse_string(json, p, pe, result);
540
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
546
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
541
547
  }
542
- goto st21;
543
- tr2:
544
- #line 244 "parser.rl"
548
+ goto st29;
549
+ tr3:
550
+ #line 241 "parser.rl"
545
551
  {
546
552
  char *np;
547
- if(pe > p + 9 - json->quirks_mode && !strncmp(MinusInfinity, p, 9)) {
553
+ if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
548
554
  if (json->allow_nan) {
549
555
  *result = CMinusInfinity;
550
556
  {p = (( p + 10))-1;}
551
- p--; {p++; cs = 21; goto _out;}
557
+ p--; {p++; cs = 29; goto _out;}
552
558
  } else {
553
559
  rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
554
560
  }
@@ -557,31 +563,27 @@ tr2:
557
563
  if (np != NULL) {p = (( np))-1;}
558
564
  np = JSON_parse_integer(json, p, pe, result);
559
565
  if (np != NULL) {p = (( np))-1;}
560
- p--; {p++; cs = 21; goto _out;}
566
+ p--; {p++; cs = 29; goto _out;}
561
567
  }
562
- goto st21;
563
- tr5:
564
- #line 262 "parser.rl"
568
+ goto st29;
569
+ tr7:
570
+ #line 259 "parser.rl"
565
571
  {
566
572
  char *np;
567
- json->current_nesting++;
568
- np = JSON_parse_array(json, p, pe, result);
569
- json->current_nesting--;
570
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
573
+ np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
574
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
571
575
  }
572
- goto st21;
573
- tr9:
574
- #line 270 "parser.rl"
576
+ goto st29;
577
+ tr11:
578
+ #line 265 "parser.rl"
575
579
  {
576
580
  char *np;
577
- json->current_nesting++;
578
- np = JSON_parse_object(json, p, pe, result);
579
- json->current_nesting--;
580
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
581
+ np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
582
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
581
583
  }
582
- goto st21;
583
- tr16:
584
- #line 232 "parser.rl"
584
+ goto st29;
585
+ tr25:
586
+ #line 229 "parser.rl"
585
587
  {
586
588
  if (json->allow_nan) {
587
589
  *result = CInfinity;
@@ -589,9 +591,9 @@ tr16:
589
591
  rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
590
592
  }
591
593
  }
592
- goto st21;
593
- tr18:
594
- #line 225 "parser.rl"
594
+ goto st29;
595
+ tr27:
596
+ #line 222 "parser.rl"
595
597
  {
596
598
  if (json->allow_nan) {
597
599
  *result = CNaN;
@@ -599,168 +601,240 @@ tr18:
599
601
  rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
600
602
  }
601
603
  }
602
- goto st21;
603
- tr22:
604
- #line 219 "parser.rl"
604
+ goto st29;
605
+ tr31:
606
+ #line 216 "parser.rl"
605
607
  {
606
608
  *result = Qfalse;
607
609
  }
608
- goto st21;
609
- tr25:
610
- #line 216 "parser.rl"
610
+ goto st29;
611
+ tr34:
612
+ #line 213 "parser.rl"
611
613
  {
612
614
  *result = Qnil;
613
615
  }
614
- goto st21;
615
- tr28:
616
- #line 222 "parser.rl"
616
+ goto st29;
617
+ tr37:
618
+ #line 219 "parser.rl"
617
619
  {
618
620
  *result = Qtrue;
619
621
  }
620
- goto st21;
621
- st21:
622
- if ( ++p == pe )
623
- goto _test_eof21;
624
- case 21:
625
- #line 278 "parser.rl"
626
- { p--; {p++; cs = 21; goto _out;} }
627
- #line 628 "parser.c"
622
+ goto st29;
623
+ st29:
624
+ if ( ++p == pe )
625
+ goto _test_eof29;
626
+ case 29:
627
+ #line 271 "parser.rl"
628
+ { p--; {p++; cs = 29; goto _out;} }
629
+ #line 630 "parser.c"
630
+ switch( (*p) ) {
631
+ case 13: goto st29;
632
+ case 32: goto st29;
633
+ case 47: goto st2;
634
+ }
635
+ if ( 9 <= (*p) && (*p) <= 10 )
636
+ goto st29;
628
637
  goto st0;
629
638
  st2:
630
639
  if ( ++p == pe )
631
640
  goto _test_eof2;
632
641
  case 2:
633
- if ( (*p) == 110 )
634
- goto st3;
642
+ switch( (*p) ) {
643
+ case 42: goto st3;
644
+ case 47: goto st5;
645
+ }
635
646
  goto st0;
636
647
  st3:
637
648
  if ( ++p == pe )
638
649
  goto _test_eof3;
639
650
  case 3:
640
- if ( (*p) == 102 )
651
+ if ( (*p) == 42 )
641
652
  goto st4;
642
- goto st0;
653
+ goto st3;
643
654
  st4:
644
655
  if ( ++p == pe )
645
656
  goto _test_eof4;
646
657
  case 4:
647
- if ( (*p) == 105 )
648
- goto st5;
649
- goto st0;
658
+ switch( (*p) ) {
659
+ case 42: goto st4;
660
+ case 47: goto st29;
661
+ }
662
+ goto st3;
650
663
  st5:
651
664
  if ( ++p == pe )
652
665
  goto _test_eof5;
653
666
  case 5:
654
- if ( (*p) == 110 )
655
- goto st6;
656
- goto st0;
667
+ if ( (*p) == 10 )
668
+ goto st29;
669
+ goto st5;
657
670
  st6:
658
671
  if ( ++p == pe )
659
672
  goto _test_eof6;
660
673
  case 6:
661
- if ( (*p) == 105 )
662
- goto st7;
674
+ switch( (*p) ) {
675
+ case 42: goto st7;
676
+ case 47: goto st9;
677
+ }
663
678
  goto st0;
664
679
  st7:
665
680
  if ( ++p == pe )
666
681
  goto _test_eof7;
667
682
  case 7:
668
- if ( (*p) == 116 )
683
+ if ( (*p) == 42 )
669
684
  goto st8;
670
- goto st0;
685
+ goto st7;
671
686
  st8:
672
687
  if ( ++p == pe )
673
688
  goto _test_eof8;
674
689
  case 8:
675
- if ( (*p) == 121 )
676
- goto tr16;
677
- goto st0;
690
+ switch( (*p) ) {
691
+ case 42: goto st8;
692
+ case 47: goto st1;
693
+ }
694
+ goto st7;
678
695
  st9:
679
696
  if ( ++p == pe )
680
697
  goto _test_eof9;
681
698
  case 9:
682
- if ( (*p) == 97 )
683
- goto st10;
684
- goto st0;
699
+ if ( (*p) == 10 )
700
+ goto st1;
701
+ goto st9;
685
702
  st10:
686
703
  if ( ++p == pe )
687
704
  goto _test_eof10;
688
705
  case 10:
689
- if ( (*p) == 78 )
690
- goto tr18;
706
+ if ( (*p) == 110 )
707
+ goto st11;
691
708
  goto st0;
692
709
  st11:
693
710
  if ( ++p == pe )
694
711
  goto _test_eof11;
695
712
  case 11:
696
- if ( (*p) == 97 )
713
+ if ( (*p) == 102 )
697
714
  goto st12;
698
715
  goto st0;
699
716
  st12:
700
717
  if ( ++p == pe )
701
718
  goto _test_eof12;
702
719
  case 12:
703
- if ( (*p) == 108 )
720
+ if ( (*p) == 105 )
704
721
  goto st13;
705
722
  goto st0;
706
723
  st13:
707
724
  if ( ++p == pe )
708
725
  goto _test_eof13;
709
726
  case 13:
710
- if ( (*p) == 115 )
727
+ if ( (*p) == 110 )
711
728
  goto st14;
712
729
  goto st0;
713
730
  st14:
714
731
  if ( ++p == pe )
715
732
  goto _test_eof14;
716
733
  case 14:
717
- if ( (*p) == 101 )
718
- goto tr22;
734
+ if ( (*p) == 105 )
735
+ goto st15;
719
736
  goto st0;
720
737
  st15:
721
738
  if ( ++p == pe )
722
739
  goto _test_eof15;
723
740
  case 15:
724
- if ( (*p) == 117 )
741
+ if ( (*p) == 116 )
725
742
  goto st16;
726
743
  goto st0;
727
744
  st16:
728
745
  if ( ++p == pe )
729
746
  goto _test_eof16;
730
747
  case 16:
731
- if ( (*p) == 108 )
732
- goto st17;
748
+ if ( (*p) == 121 )
749
+ goto tr25;
733
750
  goto st0;
734
751
  st17:
735
752
  if ( ++p == pe )
736
753
  goto _test_eof17;
737
754
  case 17:
738
- if ( (*p) == 108 )
739
- goto tr25;
755
+ if ( (*p) == 97 )
756
+ goto st18;
740
757
  goto st0;
741
758
  st18:
742
759
  if ( ++p == pe )
743
760
  goto _test_eof18;
744
761
  case 18:
745
- if ( (*p) == 114 )
746
- goto st19;
762
+ if ( (*p) == 78 )
763
+ goto tr27;
747
764
  goto st0;
748
765
  st19:
749
766
  if ( ++p == pe )
750
767
  goto _test_eof19;
751
768
  case 19:
752
- if ( (*p) == 117 )
769
+ if ( (*p) == 97 )
753
770
  goto st20;
754
771
  goto st0;
755
772
  st20:
756
773
  if ( ++p == pe )
757
774
  goto _test_eof20;
758
775
  case 20:
776
+ if ( (*p) == 108 )
777
+ goto st21;
778
+ goto st0;
779
+ st21:
780
+ if ( ++p == pe )
781
+ goto _test_eof21;
782
+ case 21:
783
+ if ( (*p) == 115 )
784
+ goto st22;
785
+ goto st0;
786
+ st22:
787
+ if ( ++p == pe )
788
+ goto _test_eof22;
789
+ case 22:
790
+ if ( (*p) == 101 )
791
+ goto tr31;
792
+ goto st0;
793
+ st23:
794
+ if ( ++p == pe )
795
+ goto _test_eof23;
796
+ case 23:
797
+ if ( (*p) == 117 )
798
+ goto st24;
799
+ goto st0;
800
+ st24:
801
+ if ( ++p == pe )
802
+ goto _test_eof24;
803
+ case 24:
804
+ if ( (*p) == 108 )
805
+ goto st25;
806
+ goto st0;
807
+ st25:
808
+ if ( ++p == pe )
809
+ goto _test_eof25;
810
+ case 25:
811
+ if ( (*p) == 108 )
812
+ goto tr34;
813
+ goto st0;
814
+ st26:
815
+ if ( ++p == pe )
816
+ goto _test_eof26;
817
+ case 26:
818
+ if ( (*p) == 114 )
819
+ goto st27;
820
+ goto st0;
821
+ st27:
822
+ if ( ++p == pe )
823
+ goto _test_eof27;
824
+ case 27:
825
+ if ( (*p) == 117 )
826
+ goto st28;
827
+ goto st0;
828
+ st28:
829
+ if ( ++p == pe )
830
+ goto _test_eof28;
831
+ case 28:
759
832
  if ( (*p) == 101 )
760
- goto tr28;
833
+ goto tr37;
761
834
  goto st0;
762
835
  }
763
- _test_eof21: cs = 21; goto _test_eof;
836
+ _test_eof1: cs = 1; goto _test_eof;
837
+ _test_eof29: cs = 29; goto _test_eof;
764
838
  _test_eof2: cs = 2; goto _test_eof;
765
839
  _test_eof3: cs = 3; goto _test_eof;
766
840
  _test_eof4: cs = 4; goto _test_eof;
@@ -780,12 +854,20 @@ case 20:
780
854
  _test_eof18: cs = 18; goto _test_eof;
781
855
  _test_eof19: cs = 19; goto _test_eof;
782
856
  _test_eof20: cs = 20; goto _test_eof;
857
+ _test_eof21: cs = 21; goto _test_eof;
858
+ _test_eof22: cs = 22; goto _test_eof;
859
+ _test_eof23: cs = 23; goto _test_eof;
860
+ _test_eof24: cs = 24; goto _test_eof;
861
+ _test_eof25: cs = 25; goto _test_eof;
862
+ _test_eof26: cs = 26; goto _test_eof;
863
+ _test_eof27: cs = 27; goto _test_eof;
864
+ _test_eof28: cs = 28; goto _test_eof;
783
865
 
784
866
  _test_eof: {}
785
867
  _out: {}
786
868
  }
787
869
 
788
- #line 299 "parser.rl"
870
+ #line 292 "parser.rl"
789
871
 
790
872
  if (cs >= JSON_value_first_final) {
791
873
  return p;
@@ -795,15 +877,15 @@ case 20:
795
877
  }
796
878
 
797
879
 
798
- #line 799 "parser.c"
799
- static const int JSON_integer_start = 1;
800
- static const int JSON_integer_first_final = 3;
801
- static const int JSON_integer_error = 0;
880
+ #line 881 "parser.c"
881
+ enum {JSON_integer_start = 1};
882
+ enum {JSON_integer_first_final = 3};
883
+ enum {JSON_integer_error = 0};
802
884
 
803
- static const int JSON_integer_en_main = 1;
885
+ enum {JSON_integer_en_main = 1};
804
886
 
805
887
 
806
- #line 315 "parser.rl"
888
+ #line 308 "parser.rl"
807
889
 
808
890
 
809
891
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -811,15 +893,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
811
893
  int cs = EVIL;
812
894
 
813
895
 
814
- #line 815 "parser.c"
896
+ #line 897 "parser.c"
815
897
  {
816
898
  cs = JSON_integer_start;
817
899
  }
818
900
 
819
- #line 322 "parser.rl"
901
+ #line 315 "parser.rl"
820
902
  json->memo = p;
821
903
 
822
- #line 823 "parser.c"
904
+ #line 905 "parser.c"
823
905
  {
824
906
  if ( p == pe )
825
907
  goto _test_eof;
@@ -853,14 +935,14 @@ case 3:
853
935
  goto st0;
854
936
  goto tr4;
855
937
  tr4:
856
- #line 312 "parser.rl"
938
+ #line 305 "parser.rl"
857
939
  { p--; {p++; cs = 4; goto _out;} }
858
940
  goto st4;
859
941
  st4:
860
942
  if ( ++p == pe )
861
943
  goto _test_eof4;
862
944
  case 4:
863
- #line 864 "parser.c"
945
+ #line 946 "parser.c"
864
946
  goto st0;
865
947
  st5:
866
948
  if ( ++p == pe )
@@ -879,7 +961,7 @@ case 5:
879
961
  _out: {}
880
962
  }
881
963
 
882
- #line 324 "parser.rl"
964
+ #line 317 "parser.rl"
883
965
 
884
966
  if (cs >= JSON_integer_first_final) {
885
967
  long len = p - json->memo;
@@ -894,31 +976,44 @@ case 5:
894
976
  }
895
977
 
896
978
 
897
- #line 898 "parser.c"
898
- static const int JSON_float_start = 1;
899
- static const int JSON_float_first_final = 8;
900
- static const int JSON_float_error = 0;
979
+ #line 980 "parser.c"
980
+ enum {JSON_float_start = 1};
981
+ enum {JSON_float_first_final = 8};
982
+ enum {JSON_float_error = 0};
983
+
984
+ enum {JSON_float_en_main = 1};
901
985
 
902
- static const int JSON_float_en_main = 1;
903
986
 
987
+ #line 342 "parser.rl"
904
988
 
905
- #line 349 "parser.rl"
906
989
 
990
+ static int is_bigdecimal_class(VALUE obj)
991
+ {
992
+ if (cBigDecimal == Qundef) {
993
+ if (rb_const_defined(rb_cObject, i_BigDecimal)) {
994
+ cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
995
+ }
996
+ else {
997
+ return 0;
998
+ }
999
+ }
1000
+ return obj == cBigDecimal;
1001
+ }
907
1002
 
908
1003
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
909
1004
  {
910
1005
  int cs = EVIL;
911
1006
 
912
1007
 
913
- #line 914 "parser.c"
1008
+ #line 1009 "parser.c"
914
1009
  {
915
1010
  cs = JSON_float_start;
916
1011
  }
917
1012
 
918
- #line 356 "parser.rl"
1013
+ #line 362 "parser.rl"
919
1014
  json->memo = p;
920
1015
 
921
- #line 922 "parser.c"
1016
+ #line 1017 "parser.c"
922
1017
  {
923
1018
  if ( p == pe )
924
1019
  goto _test_eof;
@@ -976,14 +1071,14 @@ case 8:
976
1071
  goto st0;
977
1072
  goto tr9;
978
1073
  tr9:
979
- #line 343 "parser.rl"
1074
+ #line 336 "parser.rl"
980
1075
  { p--; {p++; cs = 9; goto _out;} }
981
1076
  goto st9;
982
1077
  st9:
983
1078
  if ( ++p == pe )
984
1079
  goto _test_eof9;
985
1080
  case 9:
986
- #line 987 "parser.c"
1081
+ #line 1082 "parser.c"
987
1082
  goto st0;
988
1083
  st5:
989
1084
  if ( ++p == pe )
@@ -1044,14 +1139,24 @@ case 7:
1044
1139
  _out: {}
1045
1140
  }
1046
1141
 
1047
- #line 358 "parser.rl"
1142
+ #line 364 "parser.rl"
1048
1143
 
1049
1144
  if (cs >= JSON_float_first_final) {
1050
1145
  long len = p - json->memo;
1051
1146
  fbuffer_clear(json->fbuffer);
1052
1147
  fbuffer_append(json->fbuffer, json->memo, len);
1053
1148
  fbuffer_append_char(json->fbuffer, '\0');
1054
- *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1149
+ if (NIL_P(json->decimal_class)) {
1150
+ *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1151
+ } else {
1152
+ VALUE text;
1153
+ text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
1154
+ if (is_bigdecimal_class(json->decimal_class)) {
1155
+ *result = rb_funcall(Qnil, i_BigDecimal, 1, text);
1156
+ } else {
1157
+ *result = rb_funcall(json->decimal_class, i_new, 1, text);
1158
+ }
1159
+ }
1055
1160
  return p + 1;
1056
1161
  } else {
1057
1162
  return NULL;
@@ -1060,36 +1165,36 @@ case 7:
1060
1165
 
1061
1166
 
1062
1167
 
1063
- #line 1064 "parser.c"
1064
- static const int JSON_array_start = 1;
1065
- static const int JSON_array_first_final = 17;
1066
- static const int JSON_array_error = 0;
1168
+ #line 1169 "parser.c"
1169
+ enum {JSON_array_start = 1};
1170
+ enum {JSON_array_first_final = 17};
1171
+ enum {JSON_array_error = 0};
1067
1172
 
1068
- static const int JSON_array_en_main = 1;
1173
+ enum {JSON_array_en_main = 1};
1069
1174
 
1070
1175
 
1071
- #line 401 "parser.rl"
1176
+ #line 417 "parser.rl"
1072
1177
 
1073
1178
 
1074
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
1179
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
1075
1180
  {
1076
1181
  int cs = EVIL;
1077
1182
  VALUE array_class = json->array_class;
1078
1183
 
1079
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
1080
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
1184
+ if (json->max_nesting && current_nesting > json->max_nesting) {
1185
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
1081
1186
  }
1082
1187
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1083
1188
 
1084
1189
 
1085
- #line 1086 "parser.c"
1190
+ #line 1191 "parser.c"
1086
1191
  {
1087
1192
  cs = JSON_array_start;
1088
1193
  }
1089
1194
 
1090
- #line 414 "parser.rl"
1195
+ #line 430 "parser.rl"
1091
1196
 
1092
- #line 1093 "parser.c"
1197
+ #line 1198 "parser.c"
1093
1198
  {
1094
1199
  if ( p == pe )
1095
1200
  goto _test_eof;
@@ -1128,10 +1233,10 @@ case 2:
1128
1233
  goto st2;
1129
1234
  goto st0;
1130
1235
  tr2:
1131
- #line 378 "parser.rl"
1236
+ #line 394 "parser.rl"
1132
1237
  {
1133
1238
  VALUE v = Qnil;
1134
- char *np = JSON_parse_value(json, p, pe, &v);
1239
+ char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
1135
1240
  if (np == NULL) {
1136
1241
  p--; {p++; cs = 3; goto _out;}
1137
1242
  } else {
@@ -1148,7 +1253,7 @@ st3:
1148
1253
  if ( ++p == pe )
1149
1254
  goto _test_eof3;
1150
1255
  case 3:
1151
- #line 1152 "parser.c"
1256
+ #line 1257 "parser.c"
1152
1257
  switch( (*p) ) {
1153
1258
  case 13: goto st3;
1154
1259
  case 32: goto st3;
@@ -1248,14 +1353,14 @@ case 12:
1248
1353
  goto st3;
1249
1354
  goto st12;
1250
1355
  tr4:
1251
- #line 393 "parser.rl"
1356
+ #line 409 "parser.rl"
1252
1357
  { p--; {p++; cs = 17; goto _out;} }
1253
1358
  goto st17;
1254
1359
  st17:
1255
1360
  if ( ++p == pe )
1256
1361
  goto _test_eof17;
1257
1362
  case 17:
1258
- #line 1259 "parser.c"
1363
+ #line 1364 "parser.c"
1259
1364
  goto st0;
1260
1365
  st13:
1261
1366
  if ( ++p == pe )
@@ -1311,7 +1416,7 @@ case 16:
1311
1416
  _out: {}
1312
1417
  }
1313
1418
 
1314
- #line 415 "parser.rl"
1419
+ #line 431 "parser.rl"
1315
1420
 
1316
1421
  if(cs >= JSON_array_first_final) {
1317
1422
  return p + 1;
@@ -1356,13 +1461,21 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1356
1461
  break;
1357
1462
  case 'u':
1358
1463
  if (pe > stringEnd - 4) {
1359
- return Qnil;
1464
+ rb_enc_raise(
1465
+ EXC_ENCODING eParserError,
1466
+ "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
1467
+ );
1360
1468
  } else {
1361
1469
  UTF32 ch = unescape_unicode((unsigned char *) ++pe);
1362
1470
  pe += 3;
1363
1471
  if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
1364
1472
  pe++;
1365
- if (pe > stringEnd - 6) return Qnil;
1473
+ if (pe > stringEnd - 6) {
1474
+ rb_enc_raise(
1475
+ EXC_ENCODING eParserError,
1476
+ "%u: incomplete surrogate pair at '%s'", __LINE__, p
1477
+ );
1478
+ }
1366
1479
  if (pe[0] == '\\' && pe[1] == 'u') {
1367
1480
  UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
1368
1481
  ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
@@ -1392,15 +1505,15 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1392
1505
  }
1393
1506
 
1394
1507
 
1395
- #line 1396 "parser.c"
1396
- static const int JSON_string_start = 1;
1397
- static const int JSON_string_first_final = 8;
1398
- static const int JSON_string_error = 0;
1508
+ #line 1509 "parser.c"
1509
+ enum {JSON_string_start = 1};
1510
+ enum {JSON_string_first_final = 8};
1511
+ enum {JSON_string_error = 0};
1399
1512
 
1400
- static const int JSON_string_en_main = 1;
1513
+ enum {JSON_string_en_main = 1};
1401
1514
 
1402
1515
 
1403
- #line 514 "parser.rl"
1516
+ #line 538 "parser.rl"
1404
1517
 
1405
1518
 
1406
1519
  static int
@@ -1422,15 +1535,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
1422
1535
 
1423
1536
  *result = rb_str_buf_new(0);
1424
1537
 
1425
- #line 1426 "parser.c"
1538
+ #line 1539 "parser.c"
1426
1539
  {
1427
1540
  cs = JSON_string_start;
1428
1541
  }
1429
1542
 
1430
- #line 535 "parser.rl"
1543
+ #line 559 "parser.rl"
1431
1544
  json->memo = p;
1432
1545
 
1433
- #line 1434 "parser.c"
1546
+ #line 1547 "parser.c"
1434
1547
  {
1435
1548
  if ( p == pe )
1436
1549
  goto _test_eof;
@@ -1451,11 +1564,11 @@ case 2:
1451
1564
  case 34: goto tr2;
1452
1565
  case 92: goto st3;
1453
1566
  }
1454
- if ( 0 <= (*p) && (*p) <= 31 )
1567
+ if ( 0 <= (signed char)(*p) && (*p) <= 31 )
1455
1568
  goto st0;
1456
1569
  goto st2;
1457
1570
  tr2:
1458
- #line 500 "parser.rl"
1571
+ #line 524 "parser.rl"
1459
1572
  {
1460
1573
  *result = json_string_unescape(*result, json->memo + 1, p);
1461
1574
  if (NIL_P(*result)) {
@@ -1466,14 +1579,14 @@ tr2:
1466
1579
  {p = (( p + 1))-1;}
1467
1580
  }
1468
1581
  }
1469
- #line 511 "parser.rl"
1582
+ #line 535 "parser.rl"
1470
1583
  { p--; {p++; cs = 8; goto _out;} }
1471
1584
  goto st8;
1472
1585
  st8:
1473
1586
  if ( ++p == pe )
1474
1587
  goto _test_eof8;
1475
1588
  case 8:
1476
- #line 1477 "parser.c"
1589
+ #line 1590 "parser.c"
1477
1590
  goto st0;
1478
1591
  st3:
1479
1592
  if ( ++p == pe )
@@ -1481,7 +1594,7 @@ st3:
1481
1594
  case 3:
1482
1595
  if ( (*p) == 117 )
1483
1596
  goto st4;
1484
- if ( 0 <= (*p) && (*p) <= 31 )
1597
+ if ( 0 <= (signed char)(*p) && (*p) <= 31 )
1485
1598
  goto st0;
1486
1599
  goto st2;
1487
1600
  st4:
@@ -1549,7 +1662,7 @@ case 7:
1549
1662
  _out: {}
1550
1663
  }
1551
1664
 
1552
- #line 537 "parser.rl"
1665
+ #line 561 "parser.rl"
1553
1666
 
1554
1667
  if (json->create_additions && RTEST(match_string = json->match_string)) {
1555
1668
  VALUE klass;
@@ -1564,6 +1677,8 @@ case 7:
1564
1677
 
1565
1678
  if (json->symbolize_names && json->parsing_name) {
1566
1679
  *result = rb_str_intern(*result);
1680
+ } else if (RB_TYPE_P(*result, T_STRING)) {
1681
+ rb_str_resize(*result, RSTRING_LEN(*result));
1567
1682
  }
1568
1683
  if (cs >= JSON_string_first_final) {
1569
1684
  return p + 1;
@@ -1586,41 +1701,16 @@ case 7:
1586
1701
 
1587
1702
  static VALUE convert_encoding(VALUE source)
1588
1703
  {
1589
- const char *ptr = RSTRING_PTR(source);
1590
- long len = RSTRING_LEN(source);
1591
- if (len < 2) {
1592
- rb_raise(eParserError, "A JSON text must at least contain two octets!");
1593
- }
1594
1704
  #ifdef HAVE_RUBY_ENCODING_H
1595
- {
1596
- rb_encoding *enc = rb_enc_get(source);
1597
- if (enc == rb_ascii8bit_encoding()) {
1598
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1599
- source = rb_str_conv_enc(source, UTF_32BE, rb_utf8_encoding());
1600
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1601
- source = rb_str_conv_enc(source, UTF_16BE, rb_utf8_encoding());
1602
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1603
- source = rb_str_conv_enc(source, UTF_32LE, rb_utf8_encoding());
1604
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1605
- source = rb_str_conv_enc(source, UTF_16LE, rb_utf8_encoding());
1606
- } else {
1607
- source = rb_str_dup(source);
1608
- FORCE_UTF8(source);
1609
- }
1610
- } else {
1611
- source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
1612
- }
1613
- }
1614
- #else
1615
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1616
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
1617
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1618
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
1619
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1620
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
1621
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1622
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
1705
+ rb_encoding *enc = rb_enc_get(source);
1706
+ if (enc == rb_ascii8bit_encoding()) {
1707
+ if (OBJ_FROZEN(source)) {
1708
+ source = rb_str_dup(source);
1623
1709
  }
1710
+ FORCE_UTF8(source);
1711
+ } else {
1712
+ source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
1713
+ }
1624
1714
  #endif
1625
1715
  return source;
1626
1716
  }
@@ -1643,8 +1733,9 @@ static VALUE convert_encoding(VALUE source)
1643
1733
  * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
1644
1734
  * false.
1645
1735
  * * *symbolize_names*: If set to true, returns symbols for the names
1646
- * (keys) in a JSON object. Otherwise strings are returned, which is also
1647
- * the default.
1736
+ * (keys) in a JSON object. Otherwise strings are returned, which is
1737
+ * also the default. It's not possible to use this option in
1738
+ * conjunction with the *create_additions* option.
1648
1739
  * * *create_additions*: If set to false, the Parser doesn't create
1649
1740
  * additions even if a matching class and create_id was found. This option
1650
1741
  * defaults to false.
@@ -1695,19 +1786,17 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1695
1786
  } else {
1696
1787
  json->symbolize_names = 0;
1697
1788
  }
1698
- tmp = ID2SYM(i_quirks_mode);
1699
- if (option_given_p(opts, tmp)) {
1700
- VALUE quirks_mode = rb_hash_aref(opts, tmp);
1701
- json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
1702
- } else {
1703
- json->quirks_mode = 0;
1704
- }
1705
1789
  tmp = ID2SYM(i_create_additions);
1706
1790
  if (option_given_p(opts, tmp)) {
1707
1791
  json->create_additions = RTEST(rb_hash_aref(opts, tmp));
1708
1792
  } else {
1709
1793
  json->create_additions = 0;
1710
1794
  }
1795
+ if (json->symbolize_names && json->create_additions) {
1796
+ rb_raise(rb_eArgError,
1797
+ "options :symbolize_names and :create_additions cannot be "
1798
+ " used in conjunction");
1799
+ }
1711
1800
  tmp = ID2SYM(i_create_id);
1712
1801
  if (option_given_p(opts, tmp)) {
1713
1802
  json->create_id = rb_hash_aref(opts, tmp);
@@ -1726,6 +1815,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1726
1815
  } else {
1727
1816
  json->array_class = Qnil;
1728
1817
  }
1818
+ tmp = ID2SYM(i_decimal_class);
1819
+ if (option_given_p(opts, tmp)) {
1820
+ json->decimal_class = rb_hash_aref(opts, tmp);
1821
+ } else {
1822
+ json->decimal_class = Qnil;
1823
+ }
1729
1824
  tmp = ID2SYM(i_match_string);
1730
1825
  if (option_given_p(opts, tmp)) {
1731
1826
  VALUE match_string = rb_hash_aref(opts, tmp);
@@ -1739,16 +1834,14 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1739
1834
  } else {
1740
1835
  json->max_nesting = 100;
1741
1836
  json->allow_nan = 0;
1742
- json->create_additions = 1;
1837
+ json->create_additions = 0;
1743
1838
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
1744
1839
  json->object_class = Qnil;
1745
1840
  json->array_class = Qnil;
1841
+ json->decimal_class = Qnil;
1746
1842
  }
1843
+ source = convert_encoding(StringValue(source));
1747
1844
  StringValue(source);
1748
- if (!json->quirks_mode) {
1749
- source = convert_encoding(source);
1750
- }
1751
- json->current_nesting = 0;
1752
1845
  json->len = RSTRING_LEN(source);
1753
1846
  json->source = RSTRING_PTR(source);;
1754
1847
  json->Vsource = source;
@@ -1756,209 +1849,41 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1756
1849
  }
1757
1850
 
1758
1851
 
1759
- #line 1760 "parser.c"
1760
- static const int JSON_start = 1;
1761
- static const int JSON_first_final = 10;
1762
- static const int JSON_error = 0;
1852
+ #line 1853 "parser.c"
1853
+ enum {JSON_start = 1};
1854
+ enum {JSON_first_final = 10};
1855
+ enum {JSON_error = 0};
1763
1856
 
1764
- static const int JSON_en_main = 1;
1857
+ enum {JSON_en_main = 1};
1765
1858
 
1766
1859
 
1767
- #line 767 "parser.rl"
1860
+ #line 761 "parser.rl"
1768
1861
 
1769
1862
 
1770
- static VALUE cParser_parse_strict(VALUE self)
1863
+ /*
1864
+ * call-seq: parse()
1865
+ *
1866
+ * Parses the current JSON text _source_ and returns the complete data
1867
+ * structure as a result.
1868
+ */
1869
+ static VALUE cParser_parse(VALUE self)
1771
1870
  {
1772
- char *p, *pe;
1773
- int cs = EVIL;
1774
- VALUE result = Qnil;
1775
- GET_PARSER;
1871
+ char *p, *pe;
1872
+ int cs = EVIL;
1873
+ VALUE result = Qnil;
1874
+ GET_PARSER;
1776
1875
 
1777
1876
 
1778
- #line 1779 "parser.c"
1877
+ #line 1878 "parser.c"
1779
1878
  {
1780
1879
  cs = JSON_start;
1781
1880
  }
1782
1881
 
1783
1882
  #line 777 "parser.rl"
1784
- p = json->source;
1785
- pe = p + json->len;
1883
+ p = json->source;
1884
+ pe = p + json->len;
1786
1885
 
1787
- #line 1788 "parser.c"
1788
- {
1789
- if ( p == pe )
1790
- goto _test_eof;
1791
- switch ( cs )
1792
- {
1793
- st1:
1794
- if ( ++p == pe )
1795
- goto _test_eof1;
1796
- case 1:
1797
- switch( (*p) ) {
1798
- case 13: goto st1;
1799
- case 32: goto st1;
1800
- case 47: goto st2;
1801
- case 91: goto tr3;
1802
- case 123: goto tr4;
1803
- }
1804
- if ( 9 <= (*p) && (*p) <= 10 )
1805
- goto st1;
1806
- goto st0;
1807
- st0:
1808
- cs = 0;
1809
- goto _out;
1810
- st2:
1811
- if ( ++p == pe )
1812
- goto _test_eof2;
1813
- case 2:
1814
- switch( (*p) ) {
1815
- case 42: goto st3;
1816
- case 47: goto st5;
1817
- }
1818
- goto st0;
1819
- st3:
1820
- if ( ++p == pe )
1821
- goto _test_eof3;
1822
- case 3:
1823
- if ( (*p) == 42 )
1824
- goto st4;
1825
- goto st3;
1826
- st4:
1827
- if ( ++p == pe )
1828
- goto _test_eof4;
1829
- case 4:
1830
- switch( (*p) ) {
1831
- case 42: goto st4;
1832
- case 47: goto st1;
1833
- }
1834
- goto st3;
1835
- st5:
1836
- if ( ++p == pe )
1837
- goto _test_eof5;
1838
- case 5:
1839
- if ( (*p) == 10 )
1840
- goto st1;
1841
- goto st5;
1842
- tr3:
1843
- #line 756 "parser.rl"
1844
- {
1845
- char *np;
1846
- json->current_nesting = 1;
1847
- np = JSON_parse_array(json, p, pe, &result);
1848
- if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1849
- }
1850
- goto st10;
1851
- tr4:
1852
- #line 749 "parser.rl"
1853
- {
1854
- char *np;
1855
- json->current_nesting = 1;
1856
- np = JSON_parse_object(json, p, pe, &result);
1857
- if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1858
- }
1859
- goto st10;
1860
- st10:
1861
- if ( ++p == pe )
1862
- goto _test_eof10;
1863
- case 10:
1864
- #line 1865 "parser.c"
1865
- switch( (*p) ) {
1866
- case 13: goto st10;
1867
- case 32: goto st10;
1868
- case 47: goto st6;
1869
- }
1870
- if ( 9 <= (*p) && (*p) <= 10 )
1871
- goto st10;
1872
- goto st0;
1873
- st6:
1874
- if ( ++p == pe )
1875
- goto _test_eof6;
1876
- case 6:
1877
- switch( (*p) ) {
1878
- case 42: goto st7;
1879
- case 47: goto st9;
1880
- }
1881
- goto st0;
1882
- st7:
1883
- if ( ++p == pe )
1884
- goto _test_eof7;
1885
- case 7:
1886
- if ( (*p) == 42 )
1887
- goto st8;
1888
- goto st7;
1889
- st8:
1890
- if ( ++p == pe )
1891
- goto _test_eof8;
1892
- case 8:
1893
- switch( (*p) ) {
1894
- case 42: goto st8;
1895
- case 47: goto st10;
1896
- }
1897
- goto st7;
1898
- st9:
1899
- if ( ++p == pe )
1900
- goto _test_eof9;
1901
- case 9:
1902
- if ( (*p) == 10 )
1903
- goto st10;
1904
- goto st9;
1905
- }
1906
- _test_eof1: cs = 1; goto _test_eof;
1907
- _test_eof2: cs = 2; goto _test_eof;
1908
- _test_eof3: cs = 3; goto _test_eof;
1909
- _test_eof4: cs = 4; goto _test_eof;
1910
- _test_eof5: cs = 5; goto _test_eof;
1911
- _test_eof10: cs = 10; goto _test_eof;
1912
- _test_eof6: cs = 6; goto _test_eof;
1913
- _test_eof7: cs = 7; goto _test_eof;
1914
- _test_eof8: cs = 8; goto _test_eof;
1915
- _test_eof9: cs = 9; goto _test_eof;
1916
-
1917
- _test_eof: {}
1918
- _out: {}
1919
- }
1920
-
1921
- #line 780 "parser.rl"
1922
-
1923
- if (cs >= JSON_first_final && p == pe) {
1924
- return result;
1925
- } else {
1926
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1927
- return Qnil;
1928
- }
1929
- }
1930
-
1931
-
1932
-
1933
- #line 1934 "parser.c"
1934
- static const int JSON_quirks_mode_start = 1;
1935
- static const int JSON_quirks_mode_first_final = 10;
1936
- static const int JSON_quirks_mode_error = 0;
1937
-
1938
- static const int JSON_quirks_mode_en_main = 1;
1939
-
1940
-
1941
- #line 805 "parser.rl"
1942
-
1943
-
1944
- static VALUE cParser_parse_quirks_mode(VALUE self)
1945
- {
1946
- char *p, *pe;
1947
- int cs = EVIL;
1948
- VALUE result = Qnil;
1949
- GET_PARSER;
1950
-
1951
-
1952
- #line 1953 "parser.c"
1953
- {
1954
- cs = JSON_quirks_mode_start;
1955
- }
1956
-
1957
- #line 815 "parser.rl"
1958
- p = json->source;
1959
- pe = p + json->len;
1960
-
1961
- #line 1962 "parser.c"
1886
+ #line 1887 "parser.c"
1962
1887
  {
1963
1888
  if ( p == pe )
1964
1889
  goto _test_eof;
@@ -1992,9 +1917,9 @@ st0:
1992
1917
  cs = 0;
1993
1918
  goto _out;
1994
1919
  tr2:
1995
- #line 797 "parser.rl"
1920
+ #line 753 "parser.rl"
1996
1921
  {
1997
- char *np = JSON_parse_value(json, p, pe, &result);
1922
+ char *np = JSON_parse_value(json, p, pe, &result, 0);
1998
1923
  if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1999
1924
  }
2000
1925
  goto st10;
@@ -2002,7 +1927,7 @@ st10:
2002
1927
  if ( ++p == pe )
2003
1928
  goto _test_eof10;
2004
1929
  case 10:
2005
- #line 2006 "parser.c"
1930
+ #line 1931 "parser.c"
2006
1931
  switch( (*p) ) {
2007
1932
  case 13: goto st10;
2008
1933
  case 32: goto st10;
@@ -2091,30 +2016,13 @@ case 9:
2091
2016
  _out: {}
2092
2017
  }
2093
2018
 
2094
- #line 818 "parser.rl"
2095
-
2096
- if (cs >= JSON_quirks_mode_first_final && p == pe) {
2097
- return result;
2098
- } else {
2099
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
2100
- return Qnil;
2101
- }
2102
- }
2103
-
2104
- /*
2105
- * call-seq: parse()
2106
- *
2107
- * Parses the current JSON text _source_ and returns the complete data
2108
- * structure as a result.
2109
- */
2110
- static VALUE cParser_parse(VALUE self)
2111
- {
2112
- GET_PARSER;
2019
+ #line 780 "parser.rl"
2113
2020
 
2114
- if (json->quirks_mode) {
2115
- return cParser_parse_quirks_mode(self);
2021
+ if (cs >= JSON_first_final && p == pe) {
2022
+ return result;
2116
2023
  } else {
2117
- return cParser_parse_strict(self);
2024
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
2025
+ return Qnil;
2118
2026
  }
2119
2027
  }
2120
2028
 
@@ -2125,6 +2033,7 @@ static void JSON_mark(void *ptr)
2125
2033
  rb_gc_mark_maybe(json->create_id);
2126
2034
  rb_gc_mark_maybe(json->object_class);
2127
2035
  rb_gc_mark_maybe(json->array_class);
2036
+ rb_gc_mark_maybe(json->decimal_class);
2128
2037
  rb_gc_mark_maybe(json->match_string);
2129
2038
  }
2130
2039
 
@@ -2172,35 +2081,30 @@ static VALUE cParser_source(VALUE self)
2172
2081
  return rb_str_dup(json->Vsource);
2173
2082
  }
2174
2083
 
2175
- /*
2176
- * call-seq: quirks_mode?()
2177
- *
2178
- * Returns a true, if this parser is in quirks_mode, false otherwise.
2179
- */
2180
- static VALUE cParser_quirks_mode_p(VALUE self)
2181
- {
2182
- GET_PARSER;
2183
- return json->quirks_mode ? Qtrue : Qfalse;
2184
- }
2185
-
2186
-
2187
2084
  void Init_parser(void)
2188
2085
  {
2086
+ #undef rb_intern
2189
2087
  rb_require("json/common");
2190
2088
  mJSON = rb_define_module("JSON");
2191
2089
  mExt = rb_define_module_under(mJSON, "Ext");
2192
2090
  cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
2193
2091
  eParserError = rb_path2class("JSON::ParserError");
2194
2092
  eNestingError = rb_path2class("JSON::NestingError");
2093
+ rb_gc_register_mark_object(eParserError);
2094
+ rb_gc_register_mark_object(eNestingError);
2195
2095
  rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
2196
2096
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
2197
2097
  rb_define_method(cParser, "parse", cParser_parse, 0);
2198
2098
  rb_define_method(cParser, "source", cParser_source, 0);
2199
- rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
2200
2099
 
2201
2100
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
2101
+ rb_gc_register_mark_object(CNaN);
2102
+
2202
2103
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
2104
+ rb_gc_register_mark_object(CInfinity);
2105
+
2203
2106
  CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
2107
+ rb_gc_register_mark_object(CMinusInfinity);
2204
2108
 
2205
2109
  i_json_creatable_p = rb_intern("json_creatable?");
2206
2110
  i_json_create = rb_intern("json_create");
@@ -2210,9 +2114,9 @@ void Init_parser(void)
2210
2114
  i_max_nesting = rb_intern("max_nesting");
2211
2115
  i_allow_nan = rb_intern("allow_nan");
2212
2116
  i_symbolize_names = rb_intern("symbolize_names");
2213
- i_quirks_mode = rb_intern("quirks_mode");
2214
2117
  i_object_class = rb_intern("object_class");
2215
2118
  i_array_class = rb_intern("array_class");
2119
+ i_decimal_class = rb_intern("decimal_class");
2216
2120
  i_match = rb_intern("match");
2217
2121
  i_match_string = rb_intern("match_string");
2218
2122
  i_key_p = rb_intern("key?");
@@ -2220,15 +2124,8 @@ void Init_parser(void)
2220
2124
  i_aset = rb_intern("[]=");
2221
2125
  i_aref = rb_intern("[]");
2222
2126
  i_leftshift = rb_intern("<<");
2223
- #ifdef HAVE_RUBY_ENCODING_H
2224
- UTF_8 = rb_utf8_encoding();
2225
- UTF_16BE = rb_enc_find("utf-16be");
2226
- UTF_16LE = rb_enc_find("utf-16le");
2227
- UTF_32BE = rb_enc_find("utf-32be");
2228
- UTF_32LE = rb_enc_find("utf-32le");
2229
- #else
2230
- i_iconv = rb_intern("iconv");
2231
- #endif
2127
+ i_new = rb_intern("new");
2128
+ i_BigDecimal = rb_intern("BigDecimal");
2232
2129
  }
2233
2130
 
2234
2131
  /*