json 1.8.6 → 2.3.0

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