json 1.8.3 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.travis.yml +9 -12
  4. data/{CHANGES → CHANGES.md} +219 -90
  5. data/Gemfile +10 -6
  6. data/{COPYING-json-jruby → LICENSE} +5 -6
  7. data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
  8. data/{README.rdoc → README.md} +201 -134
  9. data/Rakefile +35 -113
  10. data/VERSION +1 -1
  11. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  12. data/ext/json/ext/generator/generator.c +255 -101
  13. data/ext/json/ext/generator/generator.h +12 -4
  14. data/ext/json/ext/parser/extconf.rb +28 -0
  15. data/ext/json/ext/parser/parser.c +410 -462
  16. data/ext/json/ext/parser/parser.h +5 -5
  17. data/ext/json/ext/parser/parser.rl +166 -181
  18. data/ext/json/extconf.rb +1 -1
  19. data/java/src/json/ext/ByteListTranscoder.java +1 -2
  20. data/java/src/json/ext/Generator.java +39 -36
  21. data/java/src/json/ext/GeneratorMethods.java +1 -2
  22. data/java/src/json/ext/GeneratorService.java +1 -2
  23. data/java/src/json/ext/GeneratorState.java +33 -56
  24. data/java/src/json/ext/OptionsReader.java +2 -3
  25. data/java/src/json/ext/Parser.java +146 -417
  26. data/java/src/json/ext/Parser.rl +62 -126
  27. data/java/src/json/ext/ParserService.java +1 -2
  28. data/java/src/json/ext/RuntimeInfo.java +1 -6
  29. data/java/src/json/ext/StringDecoder.java +1 -2
  30. data/java/src/json/ext/StringEncoder.java +13 -2
  31. data/java/src/json/ext/Utils.java +1 -2
  32. data/json-java.gemspec +22 -7
  33. data/json.gemspec +0 -0
  34. data/json_pure.gemspec +22 -29
  35. data/lib/json/add/bigdecimal.rb +3 -2
  36. data/lib/json/add/complex.rb +4 -4
  37. data/lib/json/add/core.rb +1 -0
  38. data/lib/json/add/date.rb +1 -1
  39. data/lib/json/add/date_time.rb +1 -1
  40. data/lib/json/add/exception.rb +1 -1
  41. data/lib/json/add/ostruct.rb +3 -3
  42. data/lib/json/add/range.rb +1 -1
  43. data/lib/json/add/rational.rb +3 -3
  44. data/lib/json/add/regexp.rb +3 -3
  45. data/lib/json/add/set.rb +29 -0
  46. data/lib/json/add/struct.rb +1 -1
  47. data/lib/json/add/symbol.rb +1 -1
  48. data/lib/json/add/time.rb +1 -1
  49. data/lib/json/common.rb +350 -152
  50. data/lib/json/ext.rb +0 -6
  51. data/lib/json/generic_object.rb +5 -4
  52. data/lib/json/pure/generator.rb +83 -126
  53. data/lib/json/pure/parser.rb +62 -84
  54. data/lib/json/pure.rb +2 -8
  55. data/lib/json/version.rb +2 -1
  56. data/lib/json.rb +550 -29
  57. data/references/rfc7159.txt +899 -0
  58. data/tests/fixtures/obsolete_fail1.json +1 -0
  59. data/tests/{test_json_addition.rb → json_addition_test.rb} +28 -25
  60. data/tests/json_common_interface_test.rb +169 -0
  61. data/tests/json_encoding_test.rb +107 -0
  62. data/tests/json_ext_parser_test.rb +15 -0
  63. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +13 -8
  64. data/tests/{test_json_generate.rb → json_generator_test.rb} +134 -39
  65. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  66. data/tests/json_parser_test.rb +497 -0
  67. data/tests/json_string_matching_test.rb +38 -0
  68. data/tests/test_helper.rb +17 -0
  69. data/tools/diff.sh +18 -0
  70. data/tools/fuzz.rb +1 -9
  71. metadata +47 -53
  72. data/COPYING +0 -58
  73. data/GPL +0 -340
  74. data/TODO +0 -1
  75. data/data/example.json +0 -1
  76. data/data/index.html +0 -38
  77. data/data/prototype.js +0 -4184
  78. data/tests/fixtures/fail1.json +0 -1
  79. data/tests/setup_variant.rb +0 -11
  80. data/tests/test_json.rb +0 -553
  81. data/tests/test_json_encoding.rb +0 -65
  82. data/tests/test_json_string_matching.rb +0 -39
  83. data/tests/test_json_unicode.rb +0 -72
@@ -3,8 +3,7 @@
3
3
  /*
4
4
  * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
5
5
  *
6
- * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
7
- * for details.
6
+ * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
8
7
  */
9
8
  package json.ext;
10
9
 
@@ -53,9 +52,10 @@ public class Parser extends RubyObject {
53
52
  private int maxNesting;
54
53
  private boolean allowNaN;
55
54
  private boolean symbolizeNames;
56
- private boolean quirksMode;
55
+ private boolean freeze;
57
56
  private RubyClass objectClass;
58
57
  private RubyClass arrayClass;
58
+ private RubyClass decimalClass;
59
59
  private RubyHash match_string;
60
60
 
61
61
  private static final int DEFAULT_MAX_NESTING = 100;
@@ -124,10 +124,6 @@ public class Parser extends RubyObject {
124
124
  * <dd>If set to <code>true</code>, returns symbols for the names (keys) in
125
125
  * a JSON object. Otherwise strings are returned, which is also the default.
126
126
  *
127
- * <dt><code>:quirks_mode?</code>
128
- * <dd>If set to <code>true</code>, if the parse is in quirks_mode, false
129
- * otherwise.
130
- *
131
127
  * <dt><code>:create_additions</code>
132
128
  * <dd>If set to <code>false</code>, the Parser doesn't create additions
133
129
  * even if a matching class and <code>create_id</code> was found. This option
@@ -139,9 +135,10 @@ public class Parser extends RubyObject {
139
135
  * <dt><code>:array_class</code>
140
136
  * <dd>Defaults to Array.
141
137
  *
142
- * <dt><code>:quirks_mode</code>
143
- * <dd>Enables quirks_mode for parser, that is for example parsing single
144
- * JSON values instead of documents is possible.
138
+ * <dt><code>:decimal_class</code>
139
+ * <dd>Specifies which class to use instead of the default (Float) when
140
+ * parsing decimal numbers. This class must accept a single string argument
141
+ * in its constructor.
145
142
  * </dl>
146
143
  */
147
144
  @JRubyMethod(name = "new", required = 1, optional = 1, meta = true)
@@ -164,15 +161,22 @@ public class Parser extends RubyObject {
164
161
  this.maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
165
162
  this.allowNaN = opts.getBool("allow_nan", false);
166
163
  this.symbolizeNames = opts.getBool("symbolize_names", false);
167
- this.quirksMode = opts.getBool("quirks_mode", false);
164
+ this.freeze = opts.getBool("freeze", false);
168
165
  this.createId = opts.getString("create_id", getCreateId(context));
169
166
  this.createAdditions = opts.getBool("create_additions", false);
170
167
  this.objectClass = opts.getClass("object_class", runtime.getHash());
171
168
  this.arrayClass = opts.getClass("array_class", runtime.getArray());
169
+ this.decimalClass = opts.getClass("decimal_class", null);
172
170
  this.match_string = opts.getHash("match_string");
173
171
 
172
+ if(symbolizeNames && createAdditions) {
173
+ throw runtime.newArgumentError(
174
+ "options :symbolize_names and :create_additions cannot be " +
175
+ " used in conjunction"
176
+ );
177
+ }
174
178
  this.vSource = args[0].convertToString();
175
- if (!quirksMode) this.vSource = convertEncoding(context, vSource);
179
+ this.vSource = convertEncoding(context, vSource);
176
180
 
177
181
  return this;
178
182
  }
@@ -183,33 +187,16 @@ public class Parser extends RubyObject {
183
187
  * Returns the source string if no conversion is needed.
184
188
  */
185
189
  private RubyString convertEncoding(ThreadContext context, RubyString source) {
186
- ByteList bl = source.getByteList();
187
- int len = bl.length();
188
- if (len < 2) {
189
- throw Utils.newException(context, Utils.M_PARSER_ERROR,
190
- "A JSON text must at least contain two octets!");
191
- }
192
-
193
- if (info.encodingsSupported()) {
194
- RubyEncoding encoding = (RubyEncoding)source.encoding(context);
195
- if (encoding != info.ascii8bit.get()) {
196
- return (RubyString)source.encode(context, info.utf8.get());
197
- }
198
-
199
- String sniffedEncoding = sniffByteList(bl);
200
- if (sniffedEncoding == null) return source; // assume UTF-8
201
- return reinterpretEncoding(context, source, sniffedEncoding);
202
- }
203
-
204
- String sniffedEncoding = sniffByteList(bl);
205
- if (sniffedEncoding == null) return source; // assume UTF-8
206
- Ruby runtime = context.getRuntime();
207
- return (RubyString)info.jsonModule.get().
208
- callMethod(context, "iconv",
209
- new IRubyObject[] {
210
- runtime.newString("utf-8"),
211
- runtime.newString(sniffedEncoding),
212
- source});
190
+ RubyEncoding encoding = (RubyEncoding)source.encoding(context);
191
+ if (encoding == info.ascii8bit.get()) {
192
+ if (source.isFrozen()) {
193
+ source = (RubyString) source.dup();
194
+ }
195
+ source.force_encoding(context, info.utf8.get());
196
+ } else {
197
+ source = (RubyString) source.encode(context, info.utf8.get());
198
+ }
199
+ return source;
213
200
  }
214
201
 
215
202
  /**
@@ -262,17 +249,6 @@ public class Parser extends RubyObject {
262
249
  return checkAndGetSource().dup();
263
250
  }
264
251
 
265
- /**
266
- * <code>Parser#quirks_mode?()</code>
267
- *
268
- * <p>If set to <code>true</code>, if the parse is in quirks_mode, false
269
- * otherwise.
270
- */
271
- @JRubyMethod(name = "quirks_mode?")
272
- public IRubyObject quirks_mode_p(ThreadContext context) {
273
- return context.getRuntime().newBoolean(quirksMode);
274
- }
275
-
276
252
  public RubyString checkAndGetSource() {
277
253
  if (vSource != null) {
278
254
  return vSource;
@@ -339,11 +315,11 @@ public class Parser extends RubyObject {
339
315
  }
340
316
 
341
317
 
342
- // line 365 "Parser.rl"
318
+ // line 341 "Parser.rl"
343
319
 
344
320
 
345
321
 
346
- // line 347 "Parser.java"
322
+ // line 323 "Parser.java"
347
323
  private static byte[] init__JSON_value_actions_0()
348
324
  {
349
325
  return new byte [] {
@@ -457,7 +433,7 @@ static final int JSON_value_error = 0;
457
433
  static final int JSON_value_en_main = 1;
458
434
 
459
435
 
460
- // line 471 "Parser.rl"
436
+ // line 447 "Parser.rl"
461
437
 
462
438
 
463
439
  void parseValue(ParserResult res, int p, int pe) {
@@ -465,14 +441,14 @@ static final int JSON_value_en_main = 1;
465
441
  IRubyObject result = null;
466
442
 
467
443
 
468
- // line 469 "Parser.java"
444
+ // line 445 "Parser.java"
469
445
  {
470
446
  cs = JSON_value_start;
471
447
  }
472
448
 
473
- // line 478 "Parser.rl"
449
+ // line 454 "Parser.rl"
474
450
 
475
- // line 476 "Parser.java"
451
+ // line 452 "Parser.java"
476
452
  {
477
453
  int _klen;
478
454
  int _trans = 0;
@@ -498,13 +474,13 @@ case 1:
498
474
  while ( _nacts-- > 0 ) {
499
475
  switch ( _JSON_value_actions[_acts++] ) {
500
476
  case 9:
501
- // line 456 "Parser.rl"
477
+ // line 432 "Parser.rl"
502
478
  {
503
479
  p--;
504
480
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
505
481
  }
506
482
  break;
507
- // line 508 "Parser.java"
483
+ // line 484 "Parser.java"
508
484
  }
509
485
  }
510
486
 
@@ -567,25 +543,25 @@ case 1:
567
543
  switch ( _JSON_value_actions[_acts++] )
568
544
  {
569
545
  case 0:
570
- // line 373 "Parser.rl"
546
+ // line 349 "Parser.rl"
571
547
  {
572
548
  result = getRuntime().getNil();
573
549
  }
574
550
  break;
575
551
  case 1:
576
- // line 376 "Parser.rl"
552
+ // line 352 "Parser.rl"
577
553
  {
578
554
  result = getRuntime().getFalse();
579
555
  }
580
556
  break;
581
557
  case 2:
582
- // line 379 "Parser.rl"
558
+ // line 355 "Parser.rl"
583
559
  {
584
560
  result = getRuntime().getTrue();
585
561
  }
586
562
  break;
587
563
  case 3:
588
- // line 382 "Parser.rl"
564
+ // line 358 "Parser.rl"
589
565
  {
590
566
  if (parser.allowNaN) {
591
567
  result = getConstant(CONST_NAN);
@@ -595,7 +571,7 @@ case 1:
595
571
  }
596
572
  break;
597
573
  case 4:
598
- // line 389 "Parser.rl"
574
+ // line 365 "Parser.rl"
599
575
  {
600
576
  if (parser.allowNaN) {
601
577
  result = getConstant(CONST_INFINITY);
@@ -605,9 +581,9 @@ case 1:
605
581
  }
606
582
  break;
607
583
  case 5:
608
- // line 396 "Parser.rl"
584
+ // line 372 "Parser.rl"
609
585
  {
610
- if (pe > p + 9 - (parser.quirksMode ? 1 : 0) &&
586
+ if (pe > p + 8 &&
611
587
  absSubSequence(p, p + 9).equals(JSON_MINUS_INFINITY)) {
612
588
 
613
589
  if (parser.allowNaN) {
@@ -634,7 +610,7 @@ case 1:
634
610
  }
635
611
  break;
636
612
  case 6:
637
- // line 422 "Parser.rl"
613
+ // line 398 "Parser.rl"
638
614
  {
639
615
  parseString(res, p, pe);
640
616
  if (res.result == null) {
@@ -647,7 +623,7 @@ case 1:
647
623
  }
648
624
  break;
649
625
  case 7:
650
- // line 432 "Parser.rl"
626
+ // line 408 "Parser.rl"
651
627
  {
652
628
  currentNesting++;
653
629
  parseArray(res, p, pe);
@@ -662,7 +638,7 @@ case 1:
662
638
  }
663
639
  break;
664
640
  case 8:
665
- // line 444 "Parser.rl"
641
+ // line 420 "Parser.rl"
666
642
  {
667
643
  currentNesting++;
668
644
  parseObject(res, p, pe);
@@ -676,7 +652,7 @@ case 1:
676
652
  }
677
653
  }
678
654
  break;
679
- // line 680 "Parser.java"
655
+ // line 656 "Parser.java"
680
656
  }
681
657
  }
682
658
  }
@@ -696,9 +672,12 @@ case 5:
696
672
  break; }
697
673
  }
698
674
 
699
- // line 479 "Parser.rl"
675
+ // line 455 "Parser.rl"
700
676
 
701
677
  if (cs >= JSON_value_first_final && result != null) {
678
+ if (parser.freeze) {
679
+ result.setFrozen(true);
680
+ }
702
681
  res.update(result, p);
703
682
  } else {
704
683
  res.update(null, p);
@@ -706,7 +685,7 @@ case 5:
706
685
  }
707
686
 
708
687
 
709
- // line 710 "Parser.java"
688
+ // line 689 "Parser.java"
710
689
  private static byte[] init__JSON_integer_actions_0()
711
690
  {
712
691
  return new byte [] {
@@ -805,7 +784,7 @@ static final int JSON_integer_error = 0;
805
784
  static final int JSON_integer_en_main = 1;
806
785
 
807
786
 
808
- // line 498 "Parser.rl"
787
+ // line 477 "Parser.rl"
809
788
 
810
789
 
811
790
  void parseInteger(ParserResult res, int p, int pe) {
@@ -823,15 +802,15 @@ static final int JSON_integer_en_main = 1;
823
802
  int cs = EVIL;
824
803
 
825
804
 
826
- // line 827 "Parser.java"
805
+ // line 806 "Parser.java"
827
806
  {
828
807
  cs = JSON_integer_start;
829
808
  }
830
809
 
831
- // line 515 "Parser.rl"
810
+ // line 494 "Parser.rl"
832
811
  int memo = p;
833
812
 
834
- // line 835 "Parser.java"
813
+ // line 814 "Parser.java"
835
814
  {
836
815
  int _klen;
837
816
  int _trans = 0;
@@ -912,13 +891,13 @@ case 1:
912
891
  switch ( _JSON_integer_actions[_acts++] )
913
892
  {
914
893
  case 0:
915
- // line 492 "Parser.rl"
894
+ // line 471 "Parser.rl"
916
895
  {
917
896
  p--;
918
897
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
919
898
  }
920
899
  break;
921
- // line 922 "Parser.java"
900
+ // line 901 "Parser.java"
922
901
  }
923
902
  }
924
903
  }
@@ -938,7 +917,7 @@ case 5:
938
917
  break; }
939
918
  }
940
919
 
941
- // line 517 "Parser.rl"
920
+ // line 496 "Parser.rl"
942
921
 
943
922
  if (cs < JSON_integer_first_final) {
944
923
  return -1;
@@ -946,13 +925,13 @@ case 5:
946
925
 
947
926
  return p;
948
927
  }
949
-
928
+
950
929
  RubyInteger createInteger(int p, int new_p) {
951
930
  Ruby runtime = getRuntime();
952
931
  ByteList num = absSubSequence(p, new_p);
953
932
  return bytesToInum(runtime, num);
954
933
  }
955
-
934
+
956
935
  RubyInteger bytesToInum(Ruby runtime, ByteList num) {
957
936
  return runtime.is1_9() ?
958
937
  ConvertBytes.byteListToInum19(runtime, num, 10, true) :
@@ -960,7 +939,7 @@ case 5:
960
939
  }
961
940
 
962
941
 
963
- // line 964 "Parser.java"
942
+ // line 943 "Parser.java"
964
943
  private static byte[] init__JSON_float_actions_0()
965
944
  {
966
945
  return new byte [] {
@@ -1062,7 +1041,7 @@ static final int JSON_float_error = 0;
1062
1041
  static final int JSON_float_en_main = 1;
1063
1042
 
1064
1043
 
1065
- // line 552 "Parser.rl"
1044
+ // line 531 "Parser.rl"
1066
1045
 
1067
1046
 
1068
1047
  void parseFloat(ParserResult res, int p, int pe) {
@@ -1071,7 +1050,9 @@ static final int JSON_float_en_main = 1;
1071
1050
  res.update(null, p);
1072
1051
  return;
1073
1052
  }
1074
- RubyFloat number = createFloat(p, new_p);
1053
+ IRubyObject number = parser.decimalClass == null ?
1054
+ createFloat(p, new_p) : createCustomDecimal(p, new_p);
1055
+
1075
1056
  res.update(number, new_p + 1);
1076
1057
  return;
1077
1058
  }
@@ -1080,15 +1061,15 @@ static final int JSON_float_en_main = 1;
1080
1061
  int cs = EVIL;
1081
1062
 
1082
1063
 
1083
- // line 1084 "Parser.java"
1064
+ // line 1065 "Parser.java"
1084
1065
  {
1085
1066
  cs = JSON_float_start;
1086
1067
  }
1087
1068
 
1088
- // line 569 "Parser.rl"
1069
+ // line 550 "Parser.rl"
1089
1070
  int memo = p;
1090
1071
 
1091
- // line 1092 "Parser.java"
1072
+ // line 1073 "Parser.java"
1092
1073
  {
1093
1074
  int _klen;
1094
1075
  int _trans = 0;
@@ -1169,13 +1150,13 @@ case 1:
1169
1150
  switch ( _JSON_float_actions[_acts++] )
1170
1151
  {
1171
1152
  case 0:
1172
- // line 543 "Parser.rl"
1153
+ // line 522 "Parser.rl"
1173
1154
  {
1174
1155
  p--;
1175
1156
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1176
1157
  }
1177
1158
  break;
1178
- // line 1179 "Parser.java"
1159
+ // line 1160 "Parser.java"
1179
1160
  }
1180
1161
  }
1181
1162
  }
@@ -1195,23 +1176,30 @@ case 5:
1195
1176
  break; }
1196
1177
  }
1197
1178
 
1198
- // line 571 "Parser.rl"
1179
+ // line 552 "Parser.rl"
1199
1180
 
1200
1181
  if (cs < JSON_float_first_final) {
1201
1182
  return -1;
1202
1183
  }
1203
-
1184
+
1204
1185
  return p;
1205
1186
  }
1206
-
1187
+
1207
1188
  RubyFloat createFloat(int p, int new_p) {
1208
1189
  Ruby runtime = getRuntime();
1209
1190
  ByteList num = absSubSequence(p, new_p);
1210
1191
  return RubyFloat.newFloat(runtime, dc.parse(num, true, runtime.is1_9()));
1211
1192
  }
1212
1193
 
1194
+ IRubyObject createCustomDecimal(int p, int new_p) {
1195
+ Ruby runtime = getRuntime();
1196
+ ByteList num = absSubSequence(p, new_p);
1197
+ IRubyObject numString = runtime.newString(num.toString());
1198
+ return parser.decimalClass.callMethod(context, "new", numString);
1199
+ }
1200
+
1213
1201
 
1214
- // line 1215 "Parser.java"
1202
+ // line 1203 "Parser.java"
1215
1203
  private static byte[] init__JSON_string_actions_0()
1216
1204
  {
1217
1205
  return new byte [] {
@@ -1313,7 +1301,7 @@ static final int JSON_string_error = 0;
1313
1301
  static final int JSON_string_en_main = 1;
1314
1302
 
1315
1303
 
1316
- // line 616 "Parser.rl"
1304
+ // line 604 "Parser.rl"
1317
1305
 
1318
1306
 
1319
1307
  void parseString(ParserResult res, int p, int pe) {
@@ -1321,15 +1309,15 @@ static final int JSON_string_en_main = 1;
1321
1309
  IRubyObject result = null;
1322
1310
 
1323
1311
 
1324
- // line 1325 "Parser.java"
1312
+ // line 1313 "Parser.java"
1325
1313
  {
1326
1314
  cs = JSON_string_start;
1327
1315
  }
1328
1316
 
1329
- // line 623 "Parser.rl"
1317
+ // line 611 "Parser.rl"
1330
1318
  int memo = p;
1331
1319
 
1332
- // line 1333 "Parser.java"
1320
+ // line 1321 "Parser.java"
1333
1321
  {
1334
1322
  int _klen;
1335
1323
  int _trans = 0;
@@ -1410,7 +1398,7 @@ case 1:
1410
1398
  switch ( _JSON_string_actions[_acts++] )
1411
1399
  {
1412
1400
  case 0:
1413
- // line 591 "Parser.rl"
1401
+ // line 579 "Parser.rl"
1414
1402
  {
1415
1403
  int offset = byteList.begin();
1416
1404
  ByteList decoded = decoder.decode(byteList, memo + 1 - offset,
@@ -1425,13 +1413,13 @@ case 1:
1425
1413
  }
1426
1414
  break;
1427
1415
  case 1:
1428
- // line 604 "Parser.rl"
1416
+ // line 592 "Parser.rl"
1429
1417
  {
1430
1418
  p--;
1431
1419
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1432
1420
  }
1433
1421
  break;
1434
- // line 1435 "Parser.java"
1422
+ // line 1423 "Parser.java"
1435
1423
  }
1436
1424
  }
1437
1425
  }
@@ -1451,14 +1439,14 @@ case 5:
1451
1439
  break; }
1452
1440
  }
1453
1441
 
1454
- // line 625 "Parser.rl"
1442
+ // line 613 "Parser.rl"
1455
1443
 
1456
1444
  if (parser.createAdditions) {
1457
- RubyHash match_string = parser.match_string;
1458
- if (match_string != null) {
1445
+ RubyHash matchString = parser.match_string;
1446
+ if (matchString != null) {
1459
1447
  final IRubyObject[] memoArray = { result, null };
1460
1448
  try {
1461
- match_string.visitAll(new RubyHash.Visitor() {
1449
+ matchString.visitAll(new RubyHash.Visitor() {
1462
1450
  @Override
1463
1451
  public void visit(IRubyObject pattern, IRubyObject klass) {
1464
1452
  if (pattern.callMethod(context, "===", memoArray[0]).isTrue()) {
@@ -1478,18 +1466,25 @@ case 5:
1478
1466
  }
1479
1467
  }
1480
1468
 
1481
- if (cs >= JSON_string_first_final && result != null) {
1482
- if (info.encodingsSupported() && result instanceof RubyString) {
1483
- ((RubyString)result).force_encoding(context, info.utf8.get());
1469
+ if (cs >= JSON_string_first_final && result != null) {
1470
+ if (result instanceof RubyString) {
1471
+ RubyString string = (RubyString)result;
1472
+ string.force_encoding(context, info.utf8.get());
1473
+ if (parser.freeze) {
1474
+ string.setFrozen(true);
1475
+ string = getRuntime().freezeAndDedupString(string);
1476
+ }
1477
+ res.update(string, p + 1);
1478
+ } else {
1479
+ res.update(result, p + 1);
1484
1480
  }
1485
- res.update(result, p + 1);
1486
1481
  } else {
1487
1482
  res.update(null, p + 1);
1488
1483
  }
1489
1484
  }
1490
1485
 
1491
1486
 
1492
- // line 1493 "Parser.java"
1487
+ // line 1488 "Parser.java"
1493
1488
  private static byte[] init__JSON_array_actions_0()
1494
1489
  {
1495
1490
  return new byte [] {
@@ -1602,7 +1597,7 @@ static final int JSON_array_error = 0;
1602
1597
  static final int JSON_array_en_main = 1;
1603
1598
 
1604
1599
 
1605
- // line 698 "Parser.rl"
1600
+ // line 693 "Parser.rl"
1606
1601
 
1607
1602
 
1608
1603
  void parseArray(ParserResult res, int p, int pe) {
@@ -1622,14 +1617,14 @@ static final int JSON_array_en_main = 1;
1622
1617
  }
1623
1618
 
1624
1619
 
1625
- // line 1626 "Parser.java"
1620
+ // line 1621 "Parser.java"
1626
1621
  {
1627
1622
  cs = JSON_array_start;
1628
1623
  }
1629
1624
 
1630
- // line 717 "Parser.rl"
1625
+ // line 712 "Parser.rl"
1631
1626
 
1632
- // line 1633 "Parser.java"
1627
+ // line 1628 "Parser.java"
1633
1628
  {
1634
1629
  int _klen;
1635
1630
  int _trans = 0;
@@ -1710,7 +1705,7 @@ case 1:
1710
1705
  switch ( _JSON_array_actions[_acts++] )
1711
1706
  {
1712
1707
  case 0:
1713
- // line 667 "Parser.rl"
1708
+ // line 662 "Parser.rl"
1714
1709
  {
1715
1710
  parseValue(res, p, pe);
1716
1711
  if (res.result == null) {
@@ -1727,13 +1722,13 @@ case 1:
1727
1722
  }
1728
1723
  break;
1729
1724
  case 1:
1730
- // line 682 "Parser.rl"
1725
+ // line 677 "Parser.rl"
1731
1726
  {
1732
1727
  p--;
1733
1728
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1734
1729
  }
1735
1730
  break;
1736
- // line 1737 "Parser.java"
1731
+ // line 1732 "Parser.java"
1737
1732
  }
1738
1733
  }
1739
1734
  }
@@ -1753,7 +1748,7 @@ case 5:
1753
1748
  break; }
1754
1749
  }
1755
1750
 
1756
- // line 718 "Parser.rl"
1751
+ // line 713 "Parser.rl"
1757
1752
 
1758
1753
  if (cs >= JSON_array_first_final) {
1759
1754
  res.update(result, p + 1);
@@ -1763,7 +1758,7 @@ case 5:
1763
1758
  }
1764
1759
 
1765
1760
 
1766
- // line 1767 "Parser.java"
1761
+ // line 1762 "Parser.java"
1767
1762
  private static byte[] init__JSON_object_actions_0()
1768
1763
  {
1769
1764
  return new byte [] {
@@ -1886,7 +1881,7 @@ static final int JSON_object_error = 0;
1886
1881
  static final int JSON_object_en_main = 1;
1887
1882
 
1888
1883
 
1889
- // line 777 "Parser.rl"
1884
+ // line 772 "Parser.rl"
1890
1885
 
1891
1886
 
1892
1887
  void parseObject(ParserResult res, int p, int pe) {
@@ -1911,14 +1906,14 @@ static final int JSON_object_en_main = 1;
1911
1906
  }
1912
1907
 
1913
1908
 
1914
- // line 1915 "Parser.java"
1909
+ // line 1910 "Parser.java"
1915
1910
  {
1916
1911
  cs = JSON_object_start;
1917
1912
  }
1918
1913
 
1919
- // line 801 "Parser.rl"
1914
+ // line 796 "Parser.rl"
1920
1915
 
1921
- // line 1922 "Parser.java"
1916
+ // line 1917 "Parser.java"
1922
1917
  {
1923
1918
  int _klen;
1924
1919
  int _trans = 0;
@@ -1999,7 +1994,7 @@ case 1:
1999
1994
  switch ( _JSON_object_actions[_acts++] )
2000
1995
  {
2001
1996
  case 0:
2002
- // line 732 "Parser.rl"
1997
+ // line 727 "Parser.rl"
2003
1998
  {
2004
1999
  parseValue(res, p, pe);
2005
2000
  if (res.result == null) {
@@ -2016,7 +2011,7 @@ case 1:
2016
2011
  }
2017
2012
  break;
2018
2013
  case 1:
2019
- // line 747 "Parser.rl"
2014
+ // line 742 "Parser.rl"
2020
2015
  {
2021
2016
  parseString(res, p, pe);
2022
2017
  if (res.result == null) {
@@ -2036,13 +2031,13 @@ case 1:
2036
2031
  }
2037
2032
  break;
2038
2033
  case 2:
2039
- // line 765 "Parser.rl"
2034
+ // line 760 "Parser.rl"
2040
2035
  {
2041
2036
  p--;
2042
2037
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
2043
2038
  }
2044
2039
  break;
2045
- // line 2046 "Parser.java"
2040
+ // line 2041 "Parser.java"
2046
2041
  }
2047
2042
  }
2048
2043
  }
@@ -2062,7 +2057,7 @@ case 5:
2062
2057
  break; }
2063
2058
  }
2064
2059
 
2065
- // line 802 "Parser.rl"
2060
+ // line 797 "Parser.rl"
2066
2061
 
2067
2062
  if (cs < JSON_object_first_final) {
2068
2063
  res.update(null, p + 1);
@@ -2095,11 +2090,11 @@ case 5:
2095
2090
  }
2096
2091
 
2097
2092
 
2098
- // line 2099 "Parser.java"
2093
+ // line 2094 "Parser.java"
2099
2094
  private static byte[] init__JSON_actions_0()
2100
2095
  {
2101
2096
  return new byte [] {
2102
- 0, 1, 0, 1, 1
2097
+ 0, 1, 0
2103
2098
  };
2104
2099
  }
2105
2100
 
@@ -2109,7 +2104,7 @@ private static final byte _JSON_actions[] = init__JSON_actions_0();
2109
2104
  private static byte[] init__JSON_key_offsets_0()
2110
2105
  {
2111
2106
  return new byte [] {
2112
- 0, 0, 7, 9, 10, 12, 13, 15, 16, 18, 19
2107
+ 0, 0, 16, 18, 19, 21, 22, 24, 25, 27, 28
2113
2108
  };
2114
2109
  }
2115
2110
 
@@ -2119,9 +2114,9 @@ private static final byte _JSON_key_offsets[] = init__JSON_key_offsets_0();
2119
2114
  private static char[] init__JSON_trans_keys_0()
2120
2115
  {
2121
2116
  return new char [] {
2122
- 13, 32, 47, 91, 123, 9, 10, 42, 47, 42, 42, 47,
2123
- 10, 42, 47, 42, 42, 47, 10, 13, 32, 47, 9, 10,
2124
- 0
2117
+ 13, 32, 34, 45, 47, 73, 78, 91, 102, 110, 116, 123,
2118
+ 9, 10, 48, 57, 42, 47, 42, 42, 47, 10, 42, 47,
2119
+ 42, 42, 47, 10, 13, 32, 47, 9, 10, 0
2125
2120
  };
2126
2121
  }
2127
2122
 
@@ -2131,7 +2126,7 @@ private static final char _JSON_trans_keys[] = init__JSON_trans_keys_0();
2131
2126
  private static byte[] init__JSON_single_lengths_0()
2132
2127
  {
2133
2128
  return new byte [] {
2134
- 0, 5, 2, 1, 2, 1, 2, 1, 2, 1, 3
2129
+ 0, 12, 2, 1, 2, 1, 2, 1, 2, 1, 3
2135
2130
  };
2136
2131
  }
2137
2132
 
@@ -2141,7 +2136,7 @@ private static final byte _JSON_single_lengths[] = init__JSON_single_lengths_0()
2141
2136
  private static byte[] init__JSON_range_lengths_0()
2142
2137
  {
2143
2138
  return new byte [] {
2144
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1
2139
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1
2145
2140
  };
2146
2141
  }
2147
2142
 
@@ -2151,7 +2146,7 @@ private static final byte _JSON_range_lengths[] = init__JSON_range_lengths_0();
2151
2146
  private static byte[] init__JSON_index_offsets_0()
2152
2147
  {
2153
2148
  return new byte [] {
2154
- 0, 0, 7, 10, 12, 15, 17, 20, 22, 25, 27
2149
+ 0, 0, 15, 18, 20, 23, 25, 28, 30, 33, 35
2155
2150
  };
2156
2151
  }
2157
2152
 
@@ -2161,9 +2156,10 @@ private static final byte _JSON_index_offsets[] = init__JSON_index_offsets_0();
2161
2156
  private static byte[] init__JSON_indicies_0()
2162
2157
  {
2163
2158
  return new byte [] {
2164
- 0, 0, 2, 3, 4, 0, 1, 5, 6, 1, 7, 5,
2165
- 7, 0, 5, 0, 6, 8, 9, 1, 10, 8, 10, 11,
2166
- 8, 11, 9, 11, 11, 12, 11, 1, 0
2159
+ 0, 0, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2,
2160
+ 0, 2, 1, 4, 5, 1, 6, 4, 6, 7, 4, 7,
2161
+ 5, 8, 9, 1, 10, 8, 10, 0, 8, 0, 9, 7,
2162
+ 7, 11, 7, 1, 0
2167
2163
  };
2168
2164
  }
2169
2165
 
@@ -2173,8 +2169,7 @@ private static final byte _JSON_indicies[] = init__JSON_indicies_0();
2173
2169
  private static byte[] init__JSON_trans_targs_0()
2174
2170
  {
2175
2171
  return new byte [] {
2176
- 1, 0, 2, 10, 10, 3, 5, 4, 7, 9, 8, 10,
2177
- 6
2172
+ 1, 0, 10, 6, 3, 5, 4, 10, 7, 9, 8, 2
2178
2173
  };
2179
2174
  }
2180
2175
 
@@ -2184,8 +2179,7 @@ private static final byte _JSON_trans_targs[] = init__JSON_trans_targs_0();
2184
2179
  private static byte[] init__JSON_trans_actions_0()
2185
2180
  {
2186
2181
  return new byte [] {
2187
- 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0,
2188
- 0
2182
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
2189
2183
  };
2190
2184
  }
2191
2185
 
@@ -2199,26 +2193,26 @@ static final int JSON_error = 0;
2199
2193
  static final int JSON_en_main = 1;
2200
2194
 
2201
2195
 
2202
- // line 867 "Parser.rl"
2196
+ // line 848 "Parser.rl"
2203
2197
 
2204
2198
 
2205
- public IRubyObject parseStrict() {
2199
+ public IRubyObject parseImplemetation() {
2206
2200
  int cs = EVIL;
2207
2201
  int p, pe;
2208
2202
  IRubyObject result = null;
2209
2203
  ParserResult res = new ParserResult();
2210
2204
 
2211
2205
 
2212
- // line 2213 "Parser.java"
2206
+ // line 2207 "Parser.java"
2213
2207
  {
2214
2208
  cs = JSON_start;
2215
2209
  }
2216
2210
 
2217
- // line 876 "Parser.rl"
2211
+ // line 857 "Parser.rl"
2218
2212
  p = byteList.begin();
2219
2213
  pe = p + byteList.length();
2220
2214
 
2221
- // line 2222 "Parser.java"
2215
+ // line 2216 "Parser.java"
2222
2216
  {
2223
2217
  int _klen;
2224
2218
  int _trans = 0;
@@ -2299,267 +2293,7 @@ case 1:
2299
2293
  switch ( _JSON_actions[_acts++] )
2300
2294
  {
2301
2295
  case 0:
2302
- // line 839 "Parser.rl"
2303
- {
2304
- currentNesting = 1;
2305
- parseObject(res, p, pe);
2306
- if (res.result == null) {
2307
- p--;
2308
- { p += 1; _goto_targ = 5; if (true) continue _goto;}
2309
- } else {
2310
- result = res.result;
2311
- {p = (( res.p))-1;}
2312
- }
2313
- }
2314
- break;
2315
- case 1:
2316
- // line 851 "Parser.rl"
2317
- {
2318
- currentNesting = 1;
2319
- parseArray(res, p, pe);
2320
- if (res.result == null) {
2321
- p--;
2322
- { p += 1; _goto_targ = 5; if (true) continue _goto;}
2323
- } else {
2324
- result = res.result;
2325
- {p = (( res.p))-1;}
2326
- }
2327
- }
2328
- break;
2329
- // line 2330 "Parser.java"
2330
- }
2331
- }
2332
- }
2333
-
2334
- case 2:
2335
- if ( cs == 0 ) {
2336
- _goto_targ = 5;
2337
- continue _goto;
2338
- }
2339
- if ( ++p != pe ) {
2340
- _goto_targ = 1;
2341
- continue _goto;
2342
- }
2343
- case 4:
2344
- case 5:
2345
- }
2346
- break; }
2347
- }
2348
-
2349
- // line 879 "Parser.rl"
2350
-
2351
- if (cs >= JSON_first_final && p == pe) {
2352
- return result;
2353
- } else {
2354
- throw unexpectedToken(p, pe);
2355
- }
2356
- }
2357
-
2358
-
2359
- // line 2360 "Parser.java"
2360
- private static byte[] init__JSON_quirks_mode_actions_0()
2361
- {
2362
- return new byte [] {
2363
- 0, 1, 0
2364
- };
2365
- }
2366
-
2367
- private static final byte _JSON_quirks_mode_actions[] = init__JSON_quirks_mode_actions_0();
2368
-
2369
-
2370
- private static byte[] init__JSON_quirks_mode_key_offsets_0()
2371
- {
2372
- return new byte [] {
2373
- 0, 0, 16, 18, 19, 21, 22, 24, 25, 27, 28
2374
- };
2375
- }
2376
-
2377
- private static final byte _JSON_quirks_mode_key_offsets[] = init__JSON_quirks_mode_key_offsets_0();
2378
-
2379
-
2380
- private static char[] init__JSON_quirks_mode_trans_keys_0()
2381
- {
2382
- return new char [] {
2383
- 13, 32, 34, 45, 47, 73, 78, 91, 102, 110, 116, 123,
2384
- 9, 10, 48, 57, 42, 47, 42, 42, 47, 10, 42, 47,
2385
- 42, 42, 47, 10, 13, 32, 47, 9, 10, 0
2386
- };
2387
- }
2388
-
2389
- private static final char _JSON_quirks_mode_trans_keys[] = init__JSON_quirks_mode_trans_keys_0();
2390
-
2391
-
2392
- private static byte[] init__JSON_quirks_mode_single_lengths_0()
2393
- {
2394
- return new byte [] {
2395
- 0, 12, 2, 1, 2, 1, 2, 1, 2, 1, 3
2396
- };
2397
- }
2398
-
2399
- private static final byte _JSON_quirks_mode_single_lengths[] = init__JSON_quirks_mode_single_lengths_0();
2400
-
2401
-
2402
- private static byte[] init__JSON_quirks_mode_range_lengths_0()
2403
- {
2404
- return new byte [] {
2405
- 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1
2406
- };
2407
- }
2408
-
2409
- private static final byte _JSON_quirks_mode_range_lengths[] = init__JSON_quirks_mode_range_lengths_0();
2410
-
2411
-
2412
- private static byte[] init__JSON_quirks_mode_index_offsets_0()
2413
- {
2414
- return new byte [] {
2415
- 0, 0, 15, 18, 20, 23, 25, 28, 30, 33, 35
2416
- };
2417
- }
2418
-
2419
- private static final byte _JSON_quirks_mode_index_offsets[] = init__JSON_quirks_mode_index_offsets_0();
2420
-
2421
-
2422
- private static byte[] init__JSON_quirks_mode_indicies_0()
2423
- {
2424
- return new byte [] {
2425
- 0, 0, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2,
2426
- 0, 2, 1, 4, 5, 1, 6, 4, 6, 7, 4, 7,
2427
- 5, 8, 9, 1, 10, 8, 10, 0, 8, 0, 9, 7,
2428
- 7, 11, 7, 1, 0
2429
- };
2430
- }
2431
-
2432
- private static final byte _JSON_quirks_mode_indicies[] = init__JSON_quirks_mode_indicies_0();
2433
-
2434
-
2435
- private static byte[] init__JSON_quirks_mode_trans_targs_0()
2436
- {
2437
- return new byte [] {
2438
- 1, 0, 10, 6, 3, 5, 4, 10, 7, 9, 8, 2
2439
- };
2440
- }
2441
-
2442
- private static final byte _JSON_quirks_mode_trans_targs[] = init__JSON_quirks_mode_trans_targs_0();
2443
-
2444
-
2445
- private static byte[] init__JSON_quirks_mode_trans_actions_0()
2446
- {
2447
- return new byte [] {
2448
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
2449
- };
2450
- }
2451
-
2452
- private static final byte _JSON_quirks_mode_trans_actions[] = init__JSON_quirks_mode_trans_actions_0();
2453
-
2454
-
2455
- static final int JSON_quirks_mode_start = 1;
2456
- static final int JSON_quirks_mode_first_final = 10;
2457
- static final int JSON_quirks_mode_error = 0;
2458
-
2459
- static final int JSON_quirks_mode_en_main = 1;
2460
-
2461
-
2462
- // line 907 "Parser.rl"
2463
-
2464
-
2465
- public IRubyObject parseQuirksMode() {
2466
- int cs = EVIL;
2467
- int p, pe;
2468
- IRubyObject result = null;
2469
- ParserResult res = new ParserResult();
2470
-
2471
-
2472
- // line 2473 "Parser.java"
2473
- {
2474
- cs = JSON_quirks_mode_start;
2475
- }
2476
-
2477
- // line 916 "Parser.rl"
2478
- p = byteList.begin();
2479
- pe = p + byteList.length();
2480
-
2481
- // line 2482 "Parser.java"
2482
- {
2483
- int _klen;
2484
- int _trans = 0;
2485
- int _acts;
2486
- int _nacts;
2487
- int _keys;
2488
- int _goto_targ = 0;
2489
-
2490
- _goto: while (true) {
2491
- switch ( _goto_targ ) {
2492
- case 0:
2493
- if ( p == pe ) {
2494
- _goto_targ = 4;
2495
- continue _goto;
2496
- }
2497
- if ( cs == 0 ) {
2498
- _goto_targ = 5;
2499
- continue _goto;
2500
- }
2501
- case 1:
2502
- _match: do {
2503
- _keys = _JSON_quirks_mode_key_offsets[cs];
2504
- _trans = _JSON_quirks_mode_index_offsets[cs];
2505
- _klen = _JSON_quirks_mode_single_lengths[cs];
2506
- if ( _klen > 0 ) {
2507
- int _lower = _keys;
2508
- int _mid;
2509
- int _upper = _keys + _klen - 1;
2510
- while (true) {
2511
- if ( _upper < _lower )
2512
- break;
2513
-
2514
- _mid = _lower + ((_upper-_lower) >> 1);
2515
- if ( data[p] < _JSON_quirks_mode_trans_keys[_mid] )
2516
- _upper = _mid - 1;
2517
- else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid] )
2518
- _lower = _mid + 1;
2519
- else {
2520
- _trans += (_mid - _keys);
2521
- break _match;
2522
- }
2523
- }
2524
- _keys += _klen;
2525
- _trans += _klen;
2526
- }
2527
-
2528
- _klen = _JSON_quirks_mode_range_lengths[cs];
2529
- if ( _klen > 0 ) {
2530
- int _lower = _keys;
2531
- int _mid;
2532
- int _upper = _keys + (_klen<<1) - 2;
2533
- while (true) {
2534
- if ( _upper < _lower )
2535
- break;
2536
-
2537
- _mid = _lower + (((_upper-_lower) >> 1) & ~1);
2538
- if ( data[p] < _JSON_quirks_mode_trans_keys[_mid] )
2539
- _upper = _mid - 2;
2540
- else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid+1] )
2541
- _lower = _mid + 2;
2542
- else {
2543
- _trans += ((_mid - _keys)>>1);
2544
- break _match;
2545
- }
2546
- }
2547
- _trans += _klen;
2548
- }
2549
- } while (false);
2550
-
2551
- _trans = _JSON_quirks_mode_indicies[_trans];
2552
- cs = _JSON_quirks_mode_trans_targs[_trans];
2553
-
2554
- if ( _JSON_quirks_mode_trans_actions[_trans] != 0 ) {
2555
- _acts = _JSON_quirks_mode_trans_actions[_trans];
2556
- _nacts = (int) _JSON_quirks_mode_actions[_acts++];
2557
- while ( _nacts-- > 0 )
2558
- {
2559
- switch ( _JSON_quirks_mode_actions[_acts++] )
2560
- {
2561
- case 0:
2562
- // line 893 "Parser.rl"
2296
+ // line 834 "Parser.rl"
2563
2297
  {
2564
2298
  parseValue(res, p, pe);
2565
2299
  if (res.result == null) {
@@ -2571,7 +2305,7 @@ case 1:
2571
2305
  }
2572
2306
  }
2573
2307
  break;
2574
- // line 2575 "Parser.java"
2308
+ // line 2309 "Parser.java"
2575
2309
  }
2576
2310
  }
2577
2311
  }
@@ -2591,9 +2325,9 @@ case 5:
2591
2325
  break; }
2592
2326
  }
2593
2327
 
2594
- // line 919 "Parser.rl"
2328
+ // line 860 "Parser.rl"
2595
2329
 
2596
- if (cs >= JSON_quirks_mode_first_final && p == pe) {
2330
+ if (cs >= JSON_first_final && p == pe) {
2597
2331
  return result;
2598
2332
  } else {
2599
2333
  throw unexpectedToken(p, pe);
@@ -2601,12 +2335,7 @@ case 5:
2601
2335
  }
2602
2336
 
2603
2337
  public IRubyObject parse() {
2604
- if (parser.quirksMode) {
2605
- return parseQuirksMode();
2606
- } else {
2607
- return parseStrict();
2608
- }
2609
-
2338
+ return parseImplemetation();
2610
2339
  }
2611
2340
 
2612
2341
  /**