json 1.7.0 → 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 (88) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.travis.yml +18 -10
  4. data/{CHANGES → CHANGES.md} +217 -69
  5. data/Gemfile +11 -12
  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} +188 -137
  9. data/Rakefile +52 -37
  10. data/VERSION +1 -1
  11. data/ext/json/ext/fbuffer/fbuffer.h +38 -7
  12. data/ext/json/ext/generator/depend +1 -0
  13. data/ext/json/ext/generator/extconf.rb +1 -10
  14. data/ext/json/ext/generator/generator.c +239 -133
  15. data/ext/json/ext/generator/generator.h +35 -26
  16. data/ext/json/ext/parser/depend +1 -0
  17. data/ext/json/ext/parser/extconf.rb +2 -9
  18. data/ext/json/ext/parser/parser.c +446 -514
  19. data/ext/json/ext/parser/parser.h +23 -9
  20. data/ext/json/ext/parser/parser.rl +177 -208
  21. data/ext/json/extconf.rb +2 -0
  22. data/java/src/json/ext/ByteListTranscoder.java +1 -2
  23. data/java/src/json/ext/Generator.java +49 -20
  24. data/java/src/json/ext/GeneratorMethods.java +1 -2
  25. data/java/src/json/ext/GeneratorService.java +1 -2
  26. data/java/src/json/ext/GeneratorState.java +25 -57
  27. data/java/src/json/ext/OptionsReader.java +5 -5
  28. data/java/src/json/ext/Parser.java +141 -419
  29. data/java/src/json/ext/Parser.rl +57 -128
  30. data/java/src/json/ext/ParserService.java +1 -2
  31. data/java/src/json/ext/RuntimeInfo.java +1 -6
  32. data/java/src/json/ext/StringDecoder.java +1 -2
  33. data/java/src/json/ext/StringEncoder.java +5 -0
  34. data/java/src/json/ext/Utils.java +1 -2
  35. data/json-java.gemspec +17 -2
  36. data/json.gemspec +0 -0
  37. data/json_pure.gemspec +25 -26
  38. data/lib/json.rb +3 -2
  39. data/lib/json/add/bigdecimal.rb +10 -2
  40. data/lib/json/add/complex.rb +9 -2
  41. data/lib/json/add/core.rb +1 -0
  42. data/lib/json/add/date.rb +1 -1
  43. data/lib/json/add/date_time.rb +1 -1
  44. data/lib/json/add/exception.rb +1 -1
  45. data/lib/json/add/ostruct.rb +3 -3
  46. data/lib/json/add/range.rb +1 -1
  47. data/lib/json/add/rational.rb +8 -2
  48. data/lib/json/add/regexp.rb +3 -3
  49. data/lib/json/add/set.rb +29 -0
  50. data/lib/json/add/struct.rb +1 -1
  51. data/lib/json/add/symbol.rb +1 -1
  52. data/lib/json/add/time.rb +6 -3
  53. data/lib/json/common.rb +51 -66
  54. data/lib/json/ext.rb +0 -6
  55. data/lib/json/generic_object.rb +36 -4
  56. data/lib/json/pure.rb +2 -8
  57. data/lib/json/pure/generator.rb +106 -119
  58. data/lib/json/pure/parser.rb +48 -88
  59. data/lib/json/version.rb +2 -1
  60. data/references/rfc7159.txt +899 -0
  61. data/tests/fixtures/fail18.json +1 -1
  62. data/tests/fixtures/obsolete_fail1.json +1 -0
  63. data/tests/{test_json_addition.rb → json_addition_test.rb} +53 -38
  64. data/tests/json_common_interface_test.rb +126 -0
  65. data/tests/json_encoding_test.rb +107 -0
  66. data/tests/json_ext_parser_test.rb +15 -0
  67. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
  68. data/tests/json_generator_test.rb +421 -0
  69. data/tests/json_generic_object_test.rb +82 -0
  70. data/tests/json_parser_test.rb +472 -0
  71. data/tests/json_string_matching_test.rb +38 -0
  72. data/tests/{setup_variant.rb → test_helper.rb} +6 -0
  73. data/tools/diff.sh +18 -0
  74. data/tools/fuzz.rb +1 -9
  75. metadata +49 -72
  76. data/COPYING +0 -58
  77. data/GPL +0 -340
  78. data/TODO +0 -1
  79. data/data/example.json +0 -1
  80. data/data/index.html +0 -38
  81. data/data/prototype.js +0 -4184
  82. data/tests/fixtures/fail1.json +0 -1
  83. data/tests/test_json.rb +0 -539
  84. data/tests/test_json_encoding.rb +0 -65
  85. data/tests/test_json_generate.rb +0 -251
  86. data/tests/test_json_generic_object.rb +0 -35
  87. data/tests/test_json_string_matching.rb +0 -40
  88. data/tests/test_json_unicode.rb +0 -72
@@ -0,0 +1,2 @@
1
+ require 'mkmf'
2
+ create_makefile('json')
@@ -1,8 +1,7 @@
1
1
  /*
2
2
  * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
3
  *
4
- * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
5
- * for details.
4
+ * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
6
5
  */
7
6
  package json.ext;
8
7
 
@@ -1,13 +1,13 @@
1
1
  /*
2
2
  * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
3
  *
4
- * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
5
- * for details.
4
+ * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
6
5
  */
7
6
  package json.ext;
8
7
 
9
8
  import org.jruby.Ruby;
10
9
  import org.jruby.RubyArray;
10
+ import org.jruby.RubyBasicObject;
11
11
  import org.jruby.RubyBignum;
12
12
  import org.jruby.RubyBoolean;
13
13
  import org.jruby.RubyClass;
@@ -16,6 +16,7 @@ import org.jruby.RubyFloat;
16
16
  import org.jruby.RubyHash;
17
17
  import org.jruby.RubyNumeric;
18
18
  import org.jruby.RubyString;
19
+ import org.jruby.runtime.ClassIndex;
19
20
  import org.jruby.runtime.ThreadContext;
20
21
  import org.jruby.runtime.builtin.IRubyObject;
21
22
  import org.jruby.util.ByteList;
@@ -58,6 +59,19 @@ public final class Generator {
58
59
  return handler.generateNew(session, object);
59
60
  }
60
61
 
62
+ // NOTE: drop this once Ruby 1.9.3 support is gone!
63
+ private static final int FIXNUM = 1;
64
+ private static final int BIGNUM = 2;
65
+ private static final int ARRAY = 3;
66
+ private static final int STRING = 4;
67
+ private static final int NIL = 5;
68
+ private static final int TRUE = 6;
69
+ private static final int FALSE = 7;
70
+ private static final int HASH = 10;
71
+ private static final int FLOAT = 11;
72
+ // hard-coded due JRuby 1.7 compatibility
73
+ // https://github.com/jruby/jruby/blob/1.7.27/core/src/main/java/org/jruby/runtime/ClassIndex.java
74
+
61
75
  /**
62
76
  * Returns the best serialization handler for the given object.
63
77
  */
@@ -66,16 +80,24 @@ public final class Generator {
66
80
  @SuppressWarnings("unchecked")
67
81
  private static <T extends IRubyObject>
68
82
  Handler<? super T> getHandlerFor(Ruby runtime, T object) {
69
- RubyClass metaClass = object.getMetaClass();
70
- if (metaClass == runtime.getString()) return (Handler)STRING_HANDLER;
71
- if (metaClass == runtime.getFixnum()) return (Handler)FIXNUM_HANDLER;
72
- if (metaClass == runtime.getHash()) return (Handler)HASH_HANDLER;
73
- if (metaClass == runtime.getArray()) return (Handler)ARRAY_HANDLER;
74
- if (object.isNil()) return (Handler)NIL_HANDLER;
75
- if (object == runtime.getTrue()) return (Handler)TRUE_HANDLER;
76
- if (object == runtime.getFalse()) return (Handler)FALSE_HANDLER;
77
- if (metaClass == runtime.getFloat()) return (Handler)FLOAT_HANDLER;
78
- if (metaClass == runtime.getBignum()) return (Handler)BIGNUM_HANDLER;
83
+ switch (((RubyBasicObject) object).getNativeTypeIndex()) {
84
+ // can not use getNativeClassIndex due 1.7 compatibility
85
+ case NIL : return (Handler) NIL_HANDLER;
86
+ case TRUE : return (Handler) TRUE_HANDLER;
87
+ case FALSE : return (Handler) FALSE_HANDLER;
88
+ case FLOAT : return (Handler) FLOAT_HANDLER;
89
+ case FIXNUM : return (Handler) FIXNUM_HANDLER;
90
+ case BIGNUM : return (Handler) BIGNUM_HANDLER;
91
+ case STRING :
92
+ if (((RubyBasicObject) object).getMetaClass() != runtime.getString()) break;
93
+ return (Handler) STRING_HANDLER;
94
+ case ARRAY :
95
+ if (((RubyBasicObject) object).getMetaClass() != runtime.getArray()) break;
96
+ return (Handler) ARRAY_HANDLER;
97
+ case HASH :
98
+ if (((RubyBasicObject) object).getMetaClass() != runtime.getHash()) break;
99
+ return (Handler) HASH_HANDLER;
100
+ }
79
101
  return GENERIC_HANDLER;
80
102
  }
81
103
 
@@ -167,9 +189,14 @@ public final class Generator {
167
189
  }
168
190
 
169
191
  RubyString generateNew(Session session, T object) {
192
+ RubyString result;
170
193
  ByteList buffer = new ByteList(guessSize(session, object));
171
194
  generate(session, object, buffer);
172
- return RubyString.newString(session.getRuntime(), buffer);
195
+ result = RubyString.newString(session.getRuntime(), buffer);
196
+ ThreadContext context = session.getContext();
197
+ RuntimeInfo info = session.getInfo();
198
+ result.force_encoding(context, info.utf8.get());
199
+ return result;
173
200
  }
174
201
 
175
202
  abstract void generate(Session session, T object, ByteList buffer);
@@ -375,8 +402,7 @@ public final class Generator {
375
402
  RuntimeInfo info = session.getInfo();
376
403
  RubyString src;
377
404
 
378
- if (info.encodingsSupported() &&
379
- object.encoding(session.getContext()) != info.utf8.get()) {
405
+ if (object.encoding(session.getContext()) != info.utf8.get()) {
380
406
  src = (RubyString)object.encode(session.getContext(),
381
407
  info.utf8.get());
382
408
  } else {
@@ -421,11 +447,14 @@ public final class Generator {
421
447
  new Handler<IRubyObject>() {
422
448
  @Override
423
449
  RubyString generateNew(Session session, IRubyObject object) {
424
- IRubyObject result =
425
- object.callMethod(session.getContext(), "to_json",
426
- new IRubyObject[] {session.getState()});
427
- if (result instanceof RubyString) return (RubyString)result;
428
- throw session.getRuntime().newTypeError("to_json must return a String");
450
+ if (object.respondsTo("to_json")) {
451
+ IRubyObject result = object.callMethod(session.getContext(), "to_json",
452
+ new IRubyObject[] {session.getState()});
453
+ if (result instanceof RubyString) return (RubyString)result;
454
+ throw session.getRuntime().newTypeError("to_json must return a String");
455
+ } else {
456
+ return OBJECT_HANDLER.generateNew(session, object);
457
+ }
429
458
  }
430
459
 
431
460
  @Override
@@ -1,8 +1,7 @@
1
1
  /*
2
2
  * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
3
  *
4
- * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
5
- * for details.
4
+ * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
6
5
  */
7
6
  package json.ext;
8
7
 
@@ -1,8 +1,7 @@
1
1
  /*
2
2
  * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
3
  *
4
- * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
5
- * for details.
4
+ * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
6
5
  */
7
6
  package json.ext;
8
7
 
@@ -1,8 +1,7 @@
1
1
  /*
2
2
  * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
3
  *
4
- * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
5
- * for details.
4
+ * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
6
5
  */
7
6
  package json.ext;
8
7
 
@@ -62,7 +61,7 @@ public class GeneratorState extends RubyObject {
62
61
  * <code>0</code> means disabled.
63
62
  */
64
63
  private int maxNesting = DEFAULT_MAX_NESTING;
65
- static final int DEFAULT_MAX_NESTING = 19;
64
+ static final int DEFAULT_MAX_NESTING = 100;
66
65
  /**
67
66
  * Whether special float values (<code>NaN</code>, <code>Infinity</code>,
68
67
  * <code>-Infinity</code>) are accepted.
@@ -208,41 +207,11 @@ public class GeneratorState extends RubyObject {
208
207
  @JRubyMethod
209
208
  public IRubyObject generate(ThreadContext context, IRubyObject obj) {
210
209
  RubyString result = Generator.generateJson(context, obj, this);
211
- if (!quirksMode && !objectOrArrayLiteral(result)) {
212
- throw Utils.newException(context, Utils.M_GENERATOR_ERROR,
213
- "only generation of JSON objects or arrays allowed");
214
- }
210
+ RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime());
211
+ result.force_encoding(context, info.utf8.get());
215
212
  return result;
216
213
  }
217
214
 
218
- /**
219
- * Ensures the given string is in the form "[...]" or "{...}", being
220
- * possibly surrounded by white space.
221
- * The string's encoding must be ASCII-compatible.
222
- * @param value
223
- * @return
224
- */
225
- private static boolean objectOrArrayLiteral(RubyString value) {
226
- ByteList bl = value.getByteList();
227
- int len = bl.length();
228
-
229
- for (int pos = 0; pos < len - 1; pos++) {
230
- int b = bl.get(pos);
231
- if (Character.isWhitespace(b)) continue;
232
-
233
- // match the opening brace
234
- switch (b) {
235
- case '[':
236
- return matchClosingBrace(bl, pos, len, ']');
237
- case '{':
238
- return matchClosingBrace(bl, pos, len, '}');
239
- default:
240
- return false;
241
- }
242
- }
243
- return false;
244
- }
245
-
246
215
  private static boolean matchClosingBrace(ByteList bl, int pos, int len,
247
216
  int brace) {
248
217
  for (int endPos = len - 1; endPos > pos; endPos--) {
@@ -258,6 +227,20 @@ public class GeneratorState extends RubyObject {
258
227
  String name = vName.asJavaString();
259
228
  if (getMetaClass().isMethodBound(name, true)) {
260
229
  return send(context, vName, Block.NULL_BLOCK);
230
+ } else {
231
+ IRubyObject value = getInstanceVariables().getInstanceVariable("@" + name);
232
+ return value == null ? context.nil : value;
233
+ }
234
+ }
235
+
236
+ @JRubyMethod(name="[]=", required=2)
237
+ public IRubyObject op_aset(ThreadContext context, IRubyObject vName, IRubyObject value) {
238
+ String name = vName.asJavaString();
239
+ String nameWriter = name + "=";
240
+ if (getMetaClass().isMethodBound(nameWriter, true)) {
241
+ return send(context, context.getRuntime().newString(nameWriter), value, Block.NULL_BLOCK);
242
+ } else {
243
+ getInstanceVariables().setInstanceVariable("@" + name, value);
261
244
  }
262
245
  return context.getRuntime().getNil();
263
246
  }
@@ -381,17 +364,6 @@ public class GeneratorState extends RubyObject {
381
364
  return context.getRuntime().newBoolean(asciiOnly);
382
365
  }
383
366
 
384
- @JRubyMethod(name="quirks_mode")
385
- public RubyBoolean quirks_mode_get(ThreadContext context) {
386
- return context.getRuntime().newBoolean(quirksMode);
387
- }
388
-
389
- @JRubyMethod(name="quirks_mode=")
390
- public IRubyObject quirks_mode_set(IRubyObject quirks_mode) {
391
- quirksMode = quirks_mode.isTrue();
392
- return quirks_mode.getRuntime().newBoolean(quirksMode);
393
- }
394
-
395
367
  @JRubyMethod(name="buffer_initial_length")
396
368
  public RubyInteger buffer_initial_length_get(ThreadContext context) {
397
369
  return context.getRuntime().newFixnum(bufferInitialLength);
@@ -404,11 +376,6 @@ public class GeneratorState extends RubyObject {
404
376
  return buffer_initial_length;
405
377
  }
406
378
 
407
- @JRubyMethod(name="quirks_mode?")
408
- public RubyBoolean quirks_mode_p(ThreadContext context) {
409
- return context.getRuntime().newBoolean(quirksMode);
410
- }
411
-
412
379
  public int getDepth() {
413
380
  return depth;
414
381
  }
@@ -427,7 +394,7 @@ public class GeneratorState extends RubyObject {
427
394
  private ByteList prepareByteList(ThreadContext context, IRubyObject value) {
428
395
  RubyString str = value.convertToString();
429
396
  RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime());
430
- if (info.encodingsSupported() && str.encoding(context) != info.utf8.get()) {
397
+ if (str.encoding(context) != info.utf8.get()) {
431
398
  str = (RubyString)str.encode(context, info.utf8.get());
432
399
  }
433
400
  return str.getByteList().dup();
@@ -441,7 +408,7 @@ public class GeneratorState extends RubyObject {
441
408
  * @param vOpts The options hash
442
409
  * @return The receiver
443
410
  */
444
- @JRubyMethod
411
+ @JRubyMethod(alias = "merge")
445
412
  public IRubyObject configure(ThreadContext context, IRubyObject vOpts) {
446
413
  OptionsReader opts = new OptionsReader(context, vOpts);
447
414
 
@@ -463,7 +430,6 @@ public class GeneratorState extends RubyObject {
463
430
  maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
464
431
  allowNaN = opts.getBool("allow_nan", DEFAULT_ALLOW_NAN);
465
432
  asciiOnly = opts.getBool("ascii_only", DEFAULT_ASCII_ONLY);
466
- quirksMode = opts.getBool("quirks_mode", DEFAULT_QUIRKS_MODE);
467
433
  bufferInitialLength = opts.getInt("buffer_initial_length", DEFAULT_BUFFER_INITIAL_LENGTH);
468
434
 
469
435
  depth = opts.getInt("depth", 0);
@@ -476,9 +442,9 @@ public class GeneratorState extends RubyObject {
476
442
  *
477
443
  * <p>Returns the configuration instance variables as a hash, that can be
478
444
  * passed to the configure method.
479
- * @return
445
+ * @return the hash
480
446
  */
481
- @JRubyMethod
447
+ @JRubyMethod(alias = "to_hash")
482
448
  public RubyHash to_h(ThreadContext context) {
483
449
  Ruby runtime = context.getRuntime();
484
450
  RubyHash result = RubyHash.newHash(runtime);
@@ -490,10 +456,12 @@ public class GeneratorState extends RubyObject {
490
456
  result.op_aset(context, runtime.newSymbol("array_nl"), array_nl_get(context));
491
457
  result.op_aset(context, runtime.newSymbol("allow_nan"), allow_nan_p(context));
492
458
  result.op_aset(context, runtime.newSymbol("ascii_only"), ascii_only_p(context));
493
- result.op_aset(context, runtime.newSymbol("quirks_mode"), quirks_mode_p(context));
494
459
  result.op_aset(context, runtime.newSymbol("max_nesting"), max_nesting_get(context));
495
460
  result.op_aset(context, runtime.newSymbol("depth"), depth_get(context));
496
461
  result.op_aset(context, runtime.newSymbol("buffer_initial_length"), buffer_initial_length_get(context));
462
+ for (String name: getInstanceVariableNameList()) {
463
+ result.op_aset(context, runtime.newSymbol(name.substring(1)), getInstanceVariables().getInstanceVariable(name));
464
+ }
497
465
  return result;
498
466
  }
499
467
 
@@ -1,8 +1,7 @@
1
1
  /*
2
2
  * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
3
  *
4
- * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
5
- * for details.
4
+ * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
6
5
  */
7
6
  package json.ext;
8
7
 
@@ -24,13 +23,14 @@ final class OptionsReader {
24
23
  OptionsReader(ThreadContext context, IRubyObject vOpts) {
25
24
  this.context = context;
26
25
  this.runtime = context.getRuntime();
27
-
28
26
  if (vOpts == null || vOpts.isNil()) {
29
27
  opts = null;
30
28
  } else if (vOpts.respondsTo("to_hash")) {
31
29
  opts = vOpts.convertToHash();
32
- } else {
30
+ } else if (vOpts.respondsTo("to_h")) {
33
31
  opts = vOpts.callMethod(context, "to_h").convertToHash();
32
+ } else {
33
+ opts = vOpts.convertToHash(); /* Should just raise the correct TypeError */
34
34
  }
35
35
  }
36
36
 
@@ -84,7 +84,7 @@ final class OptionsReader {
84
84
 
85
85
  RubyString str = value.convertToString();
86
86
  RuntimeInfo info = getRuntimeInfo();
87
- if (info.encodingsSupported() && str.encoding(context) != info.utf8.get()) {
87
+ if (str.encoding(context) != info.utf8.get()) {
88
88
  str = (RubyString)str.encode(context, info.utf8.get());
89
89
  }
90
90
  return str;
@@ -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,12 +52,12 @@ public class Parser extends RubyObject {
53
52
  private int maxNesting;
54
53
  private boolean allowNaN;
55
54
  private boolean symbolizeNames;
56
- private boolean quirksMode;
57
55
  private RubyClass objectClass;
58
56
  private RubyClass arrayClass;
57
+ private RubyClass decimalClass;
59
58
  private RubyHash match_string;
60
59
 
61
- private static final int DEFAULT_MAX_NESTING = 19;
60
+ private static final int DEFAULT_MAX_NESTING = 100;
62
61
 
63
62
  private static final ByteList JSON_MINUS_INFINITY = new ByteList(ByteList.plain("-Infinity"));
64
63
  // constant names in the JSON module containing those values
@@ -113,7 +112,7 @@ public class Parser extends RubyObject {
113
112
  * <dt><code>:max_nesting</code>
114
113
  * <dd>The maximum depth of nesting allowed in the parsed data
115
114
  * structures. Disable depth checking with <code>:max_nesting => false|nil|0</code>,
116
- * it defaults to 19.
115
+ * it defaults to 100.
117
116
  *
118
117
  * <dt><code>:allow_nan</code>
119
118
  * <dd>If set to <code>true</code>, allow <code>NaN</code>,
@@ -124,13 +123,9 @@ public class Parser extends RubyObject {
124
123
  * <dd>If set to <code>true</code>, returns symbols for the names (keys) in
125
124
  * a JSON object. Otherwise strings are returned, which is also the default.
126
125
  *
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
126
  * <dt><code>:create_additions</code>
132
127
  * <dd>If set to <code>false</code>, the Parser doesn't create additions
133
- * even if a matchin class and <code>create_id</code> was found. This option
128
+ * even if a matching class and <code>create_id</code> was found. This option
134
129
  * defaults to <code>true</code>.
135
130
  *
136
131
  * <dt><code>:object_class</code>
@@ -139,9 +134,10 @@ public class Parser extends RubyObject {
139
134
  * <dt><code>:array_class</code>
140
135
  * <dd>Defaults to Array.
141
136
  *
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.
137
+ * <dt><code>:decimal_class</code>
138
+ * <dd>Specifies which class to use instead of the default (Float) when
139
+ * parsing decimal numbers. This class must accept a single string argument
140
+ * in its constructor.
145
141
  * </dl>
146
142
  */
147
143
  @JRubyMethod(name = "new", required = 1, optional = 1, meta = true)
@@ -164,15 +160,21 @@ public class Parser extends RubyObject {
164
160
  this.maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
165
161
  this.allowNaN = opts.getBool("allow_nan", false);
166
162
  this.symbolizeNames = opts.getBool("symbolize_names", false);
167
- this.quirksMode = opts.getBool("quirks_mode", false);
168
163
  this.createId = opts.getString("create_id", getCreateId(context));
169
- this.createAdditions = opts.getBool("create_additions", true);
164
+ this.createAdditions = opts.getBool("create_additions", false);
170
165
  this.objectClass = opts.getClass("object_class", runtime.getHash());
171
166
  this.arrayClass = opts.getClass("array_class", runtime.getArray());
167
+ this.decimalClass = opts.getClass("decimal_class", null);
172
168
  this.match_string = opts.getHash("match_string");
173
169
 
170
+ if(symbolizeNames && createAdditions) {
171
+ throw runtime.newArgumentError(
172
+ "options :symbolize_names and :create_additions cannot be " +
173
+ " used in conjunction"
174
+ );
175
+ }
174
176
  this.vSource = args[0].convertToString();
175
- if (!quirksMode) this.vSource = convertEncoding(context, vSource);
177
+ this.vSource = convertEncoding(context, vSource);
176
178
 
177
179
  return this;
178
180
  }
@@ -183,33 +185,16 @@ public class Parser extends RubyObject {
183
185
  * Returns the source string if no conversion is needed.
184
186
  */
185
187
  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});
188
+ RubyEncoding encoding = (RubyEncoding)source.encoding(context);
189
+ if (encoding == info.ascii8bit.get()) {
190
+ if (source.isFrozen()) {
191
+ source = (RubyString) source.dup();
192
+ }
193
+ source.force_encoding(context, info.utf8.get());
194
+ } else {
195
+ source = (RubyString) source.encode(context, info.utf8.get());
196
+ }
197
+ return source;
213
198
  }
214
199
 
215
200
  /**
@@ -248,7 +233,7 @@ public class Parser extends RubyObject {
248
233
  */
249
234
  @JRubyMethod
250
235
  public IRubyObject parse(ThreadContext context) {
251
- return new ParserSession(this, context).parse();
236
+ return new ParserSession(this, context, info).parse();
252
237
  }
253
238
 
254
239
  /**
@@ -262,17 +247,6 @@ public class Parser extends RubyObject {
262
247
  return checkAndGetSource().dup();
263
248
  }
264
249
 
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
250
  public RubyString checkAndGetSource() {
277
251
  if (vSource != null) {
278
252
  return vSource;
@@ -304,6 +278,7 @@ public class Parser extends RubyObject {
304
278
  private static class ParserSession {
305
279
  private final Parser parser;
306
280
  private final ThreadContext context;
281
+ private final RuntimeInfo info;
307
282
  private final ByteList byteList;
308
283
  private final ByteList view;
309
284
  private final byte[] data;
@@ -315,9 +290,10 @@ public class Parser extends RubyObject {
315
290
  // no idea about the origins of this value, ask Flori ;)
316
291
  private static final int EVIL = 0x666;
317
292
 
318
- private ParserSession(Parser parser, ThreadContext context) {
293
+ private ParserSession(Parser parser, ThreadContext context, RuntimeInfo info) {
319
294
  this.parser = parser;
320
295
  this.context = context;
296
+ this.info = info;
321
297
  this.byteList = parser.checkAndGetSource().getByteList();
322
298
  this.data = byteList.unsafeBytes();
323
299
  this.view = new ByteList(data, false);
@@ -337,11 +313,11 @@ public class Parser extends RubyObject {
337
313
  }
338
314
 
339
315
 
340
- // line 363 "Parser.rl"
316
+ // line 339 "Parser.rl"
341
317
 
342
318
 
343
319
 
344
- // line 345 "Parser.java"
320
+ // line 321 "Parser.java"
345
321
  private static byte[] init__JSON_value_actions_0()
346
322
  {
347
323
  return new byte [] {
@@ -455,7 +431,7 @@ static final int JSON_value_error = 0;
455
431
  static final int JSON_value_en_main = 1;
456
432
 
457
433
 
458
- // line 469 "Parser.rl"
434
+ // line 445 "Parser.rl"
459
435
 
460
436
 
461
437
  void parseValue(ParserResult res, int p, int pe) {
@@ -463,14 +439,14 @@ static final int JSON_value_en_main = 1;
463
439
  IRubyObject result = null;
464
440
 
465
441
 
466
- // line 467 "Parser.java"
442
+ // line 443 "Parser.java"
467
443
  {
468
444
  cs = JSON_value_start;
469
445
  }
470
446
 
471
- // line 476 "Parser.rl"
447
+ // line 452 "Parser.rl"
472
448
 
473
- // line 474 "Parser.java"
449
+ // line 450 "Parser.java"
474
450
  {
475
451
  int _klen;
476
452
  int _trans = 0;
@@ -496,13 +472,13 @@ case 1:
496
472
  while ( _nacts-- > 0 ) {
497
473
  switch ( _JSON_value_actions[_acts++] ) {
498
474
  case 9:
499
- // line 454 "Parser.rl"
475
+ // line 430 "Parser.rl"
500
476
  {
501
477
  p--;
502
478
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
503
479
  }
504
480
  break;
505
- // line 506 "Parser.java"
481
+ // line 482 "Parser.java"
506
482
  }
507
483
  }
508
484
 
@@ -565,25 +541,25 @@ case 1:
565
541
  switch ( _JSON_value_actions[_acts++] )
566
542
  {
567
543
  case 0:
568
- // line 371 "Parser.rl"
544
+ // line 347 "Parser.rl"
569
545
  {
570
546
  result = getRuntime().getNil();
571
547
  }
572
548
  break;
573
549
  case 1:
574
- // line 374 "Parser.rl"
550
+ // line 350 "Parser.rl"
575
551
  {
576
552
  result = getRuntime().getFalse();
577
553
  }
578
554
  break;
579
555
  case 2:
580
- // line 377 "Parser.rl"
556
+ // line 353 "Parser.rl"
581
557
  {
582
558
  result = getRuntime().getTrue();
583
559
  }
584
560
  break;
585
561
  case 3:
586
- // line 380 "Parser.rl"
562
+ // line 356 "Parser.rl"
587
563
  {
588
564
  if (parser.allowNaN) {
589
565
  result = getConstant(CONST_NAN);
@@ -593,7 +569,7 @@ case 1:
593
569
  }
594
570
  break;
595
571
  case 4:
596
- // line 387 "Parser.rl"
572
+ // line 363 "Parser.rl"
597
573
  {
598
574
  if (parser.allowNaN) {
599
575
  result = getConstant(CONST_INFINITY);
@@ -603,9 +579,9 @@ case 1:
603
579
  }
604
580
  break;
605
581
  case 5:
606
- // line 394 "Parser.rl"
582
+ // line 370 "Parser.rl"
607
583
  {
608
- if (pe > p + 9 - (parser.quirksMode ? 1 : 0) &&
584
+ if (pe > p + 8 &&
609
585
  absSubSequence(p, p + 9).equals(JSON_MINUS_INFINITY)) {
610
586
 
611
587
  if (parser.allowNaN) {
@@ -632,7 +608,7 @@ case 1:
632
608
  }
633
609
  break;
634
610
  case 6:
635
- // line 420 "Parser.rl"
611
+ // line 396 "Parser.rl"
636
612
  {
637
613
  parseString(res, p, pe);
638
614
  if (res.result == null) {
@@ -645,7 +621,7 @@ case 1:
645
621
  }
646
622
  break;
647
623
  case 7:
648
- // line 430 "Parser.rl"
624
+ // line 406 "Parser.rl"
649
625
  {
650
626
  currentNesting++;
651
627
  parseArray(res, p, pe);
@@ -660,7 +636,7 @@ case 1:
660
636
  }
661
637
  break;
662
638
  case 8:
663
- // line 442 "Parser.rl"
639
+ // line 418 "Parser.rl"
664
640
  {
665
641
  currentNesting++;
666
642
  parseObject(res, p, pe);
@@ -674,7 +650,7 @@ case 1:
674
650
  }
675
651
  }
676
652
  break;
677
- // line 678 "Parser.java"
653
+ // line 654 "Parser.java"
678
654
  }
679
655
  }
680
656
  }
@@ -694,7 +670,7 @@ case 5:
694
670
  break; }
695
671
  }
696
672
 
697
- // line 477 "Parser.rl"
673
+ // line 453 "Parser.rl"
698
674
 
699
675
  if (cs >= JSON_value_first_final && result != null) {
700
676
  res.update(result, p);
@@ -704,7 +680,7 @@ case 5:
704
680
  }
705
681
 
706
682
 
707
- // line 708 "Parser.java"
683
+ // line 684 "Parser.java"
708
684
  private static byte[] init__JSON_integer_actions_0()
709
685
  {
710
686
  return new byte [] {
@@ -803,7 +779,7 @@ static final int JSON_integer_error = 0;
803
779
  static final int JSON_integer_en_main = 1;
804
780
 
805
781
 
806
- // line 496 "Parser.rl"
782
+ // line 472 "Parser.rl"
807
783
 
808
784
 
809
785
  void parseInteger(ParserResult res, int p, int pe) {
@@ -821,15 +797,15 @@ static final int JSON_integer_en_main = 1;
821
797
  int cs = EVIL;
822
798
 
823
799
 
824
- // line 825 "Parser.java"
800
+ // line 801 "Parser.java"
825
801
  {
826
802
  cs = JSON_integer_start;
827
803
  }
828
804
 
829
- // line 513 "Parser.rl"
805
+ // line 489 "Parser.rl"
830
806
  int memo = p;
831
807
 
832
- // line 833 "Parser.java"
808
+ // line 809 "Parser.java"
833
809
  {
834
810
  int _klen;
835
811
  int _trans = 0;
@@ -910,13 +886,13 @@ case 1:
910
886
  switch ( _JSON_integer_actions[_acts++] )
911
887
  {
912
888
  case 0:
913
- // line 490 "Parser.rl"
889
+ // line 466 "Parser.rl"
914
890
  {
915
891
  p--;
916
892
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
917
893
  }
918
894
  break;
919
- // line 920 "Parser.java"
895
+ // line 896 "Parser.java"
920
896
  }
921
897
  }
922
898
  }
@@ -936,7 +912,7 @@ case 5:
936
912
  break; }
937
913
  }
938
914
 
939
- // line 515 "Parser.rl"
915
+ // line 491 "Parser.rl"
940
916
 
941
917
  if (cs < JSON_integer_first_final) {
942
918
  return -1;
@@ -944,13 +920,13 @@ case 5:
944
920
 
945
921
  return p;
946
922
  }
947
-
923
+
948
924
  RubyInteger createInteger(int p, int new_p) {
949
925
  Ruby runtime = getRuntime();
950
926
  ByteList num = absSubSequence(p, new_p);
951
927
  return bytesToInum(runtime, num);
952
928
  }
953
-
929
+
954
930
  RubyInteger bytesToInum(Ruby runtime, ByteList num) {
955
931
  return runtime.is1_9() ?
956
932
  ConvertBytes.byteListToInum19(runtime, num, 10, true) :
@@ -958,7 +934,7 @@ case 5:
958
934
  }
959
935
 
960
936
 
961
- // line 962 "Parser.java"
937
+ // line 938 "Parser.java"
962
938
  private static byte[] init__JSON_float_actions_0()
963
939
  {
964
940
  return new byte [] {
@@ -1060,7 +1036,7 @@ static final int JSON_float_error = 0;
1060
1036
  static final int JSON_float_en_main = 1;
1061
1037
 
1062
1038
 
1063
- // line 550 "Parser.rl"
1039
+ // line 526 "Parser.rl"
1064
1040
 
1065
1041
 
1066
1042
  void parseFloat(ParserResult res, int p, int pe) {
@@ -1069,7 +1045,9 @@ static final int JSON_float_en_main = 1;
1069
1045
  res.update(null, p);
1070
1046
  return;
1071
1047
  }
1072
- RubyFloat number = createFloat(p, new_p);
1048
+ IRubyObject number = parser.decimalClass == null ?
1049
+ createFloat(p, new_p) : createCustomDecimal(p, new_p);
1050
+
1073
1051
  res.update(number, new_p + 1);
1074
1052
  return;
1075
1053
  }
@@ -1078,15 +1056,15 @@ static final int JSON_float_en_main = 1;
1078
1056
  int cs = EVIL;
1079
1057
 
1080
1058
 
1081
- // line 1082 "Parser.java"
1059
+ // line 1060 "Parser.java"
1082
1060
  {
1083
1061
  cs = JSON_float_start;
1084
1062
  }
1085
1063
 
1086
- // line 567 "Parser.rl"
1064
+ // line 545 "Parser.rl"
1087
1065
  int memo = p;
1088
1066
 
1089
- // line 1090 "Parser.java"
1067
+ // line 1068 "Parser.java"
1090
1068
  {
1091
1069
  int _klen;
1092
1070
  int _trans = 0;
@@ -1167,13 +1145,13 @@ case 1:
1167
1145
  switch ( _JSON_float_actions[_acts++] )
1168
1146
  {
1169
1147
  case 0:
1170
- // line 541 "Parser.rl"
1148
+ // line 517 "Parser.rl"
1171
1149
  {
1172
1150
  p--;
1173
1151
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1174
1152
  }
1175
1153
  break;
1176
- // line 1177 "Parser.java"
1154
+ // line 1155 "Parser.java"
1177
1155
  }
1178
1156
  }
1179
1157
  }
@@ -1193,23 +1171,30 @@ case 5:
1193
1171
  break; }
1194
1172
  }
1195
1173
 
1196
- // line 569 "Parser.rl"
1174
+ // line 547 "Parser.rl"
1197
1175
 
1198
1176
  if (cs < JSON_float_first_final) {
1199
1177
  return -1;
1200
1178
  }
1201
-
1179
+
1202
1180
  return p;
1203
1181
  }
1204
-
1182
+
1205
1183
  RubyFloat createFloat(int p, int new_p) {
1206
1184
  Ruby runtime = getRuntime();
1207
1185
  ByteList num = absSubSequence(p, new_p);
1208
1186
  return RubyFloat.newFloat(runtime, dc.parse(num, true, runtime.is1_9()));
1209
1187
  }
1210
1188
 
1189
+ IRubyObject createCustomDecimal(int p, int new_p) {
1190
+ Ruby runtime = getRuntime();
1191
+ ByteList num = absSubSequence(p, new_p);
1192
+ IRubyObject numString = runtime.newString(num.toString());
1193
+ return parser.decimalClass.callMethod(context, "new", numString);
1194
+ }
1195
+
1211
1196
 
1212
- // line 1213 "Parser.java"
1197
+ // line 1198 "Parser.java"
1213
1198
  private static byte[] init__JSON_string_actions_0()
1214
1199
  {
1215
1200
  return new byte [] {
@@ -1311,7 +1296,7 @@ static final int JSON_string_error = 0;
1311
1296
  static final int JSON_string_en_main = 1;
1312
1297
 
1313
1298
 
1314
- // line 614 "Parser.rl"
1299
+ // line 599 "Parser.rl"
1315
1300
 
1316
1301
 
1317
1302
  void parseString(ParserResult res, int p, int pe) {
@@ -1319,15 +1304,15 @@ static final int JSON_string_en_main = 1;
1319
1304
  IRubyObject result = null;
1320
1305
 
1321
1306
 
1322
- // line 1323 "Parser.java"
1307
+ // line 1308 "Parser.java"
1323
1308
  {
1324
1309
  cs = JSON_string_start;
1325
1310
  }
1326
1311
 
1327
- // line 621 "Parser.rl"
1312
+ // line 606 "Parser.rl"
1328
1313
  int memo = p;
1329
1314
 
1330
- // line 1331 "Parser.java"
1315
+ // line 1316 "Parser.java"
1331
1316
  {
1332
1317
  int _klen;
1333
1318
  int _trans = 0;
@@ -1408,7 +1393,7 @@ case 1:
1408
1393
  switch ( _JSON_string_actions[_acts++] )
1409
1394
  {
1410
1395
  case 0:
1411
- // line 589 "Parser.rl"
1396
+ // line 574 "Parser.rl"
1412
1397
  {
1413
1398
  int offset = byteList.begin();
1414
1399
  ByteList decoded = decoder.decode(byteList, memo + 1 - offset,
@@ -1423,13 +1408,13 @@ case 1:
1423
1408
  }
1424
1409
  break;
1425
1410
  case 1:
1426
- // line 602 "Parser.rl"
1411
+ // line 587 "Parser.rl"
1427
1412
  {
1428
1413
  p--;
1429
1414
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1430
1415
  }
1431
1416
  break;
1432
- // line 1433 "Parser.java"
1417
+ // line 1418 "Parser.java"
1433
1418
  }
1434
1419
  }
1435
1420
  }
@@ -1449,14 +1434,14 @@ case 5:
1449
1434
  break; }
1450
1435
  }
1451
1436
 
1452
- // line 623 "Parser.rl"
1437
+ // line 608 "Parser.rl"
1453
1438
 
1454
1439
  if (parser.createAdditions) {
1455
- RubyHash match_string = parser.match_string;
1456
- if (match_string != null) {
1440
+ RubyHash matchString = parser.match_string;
1441
+ if (matchString != null) {
1457
1442
  final IRubyObject[] memoArray = { result, null };
1458
1443
  try {
1459
- match_string.visitAll(new RubyHash.Visitor() {
1444
+ matchString.visitAll(new RubyHash.Visitor() {
1460
1445
  @Override
1461
1446
  public void visit(IRubyObject pattern, IRubyObject klass) {
1462
1447
  if (pattern.callMethod(context, "===", memoArray[0]).isTrue()) {
@@ -1477,6 +1462,9 @@ case 5:
1477
1462
  }
1478
1463
 
1479
1464
  if (cs >= JSON_string_first_final && result != null) {
1465
+ if (result instanceof RubyString) {
1466
+ ((RubyString)result).force_encoding(context, info.utf8.get());
1467
+ }
1480
1468
  res.update(result, p + 1);
1481
1469
  } else {
1482
1470
  res.update(null, p + 1);
@@ -1484,7 +1472,7 @@ case 5:
1484
1472
  }
1485
1473
 
1486
1474
 
1487
- // line 1488 "Parser.java"
1475
+ // line 1476 "Parser.java"
1488
1476
  private static byte[] init__JSON_array_actions_0()
1489
1477
  {
1490
1478
  return new byte [] {
@@ -1597,7 +1585,7 @@ static final int JSON_array_error = 0;
1597
1585
  static final int JSON_array_en_main = 1;
1598
1586
 
1599
1587
 
1600
- // line 693 "Parser.rl"
1588
+ // line 681 "Parser.rl"
1601
1589
 
1602
1590
 
1603
1591
  void parseArray(ParserResult res, int p, int pe) {
@@ -1617,14 +1605,14 @@ static final int JSON_array_en_main = 1;
1617
1605
  }
1618
1606
 
1619
1607
 
1620
- // line 1623 "Parser.java"
1608
+ // line 1609 "Parser.java"
1621
1609
  {
1622
1610
  cs = JSON_array_start;
1623
1611
  }
1624
1612
 
1625
- // line 714 "Parser.rl"
1613
+ // line 700 "Parser.rl"
1626
1614
 
1627
- // line 1630 "Parser.java"
1615
+ // line 1616 "Parser.java"
1628
1616
  {
1629
1617
  int _klen;
1630
1618
  int _trans = 0;
@@ -1705,7 +1693,7 @@ case 1:
1705
1693
  switch ( _JSON_array_actions[_acts++] )
1706
1694
  {
1707
1695
  case 0:
1708
- // line 662 "Parser.rl"
1696
+ // line 650 "Parser.rl"
1709
1697
  {
1710
1698
  parseValue(res, p, pe);
1711
1699
  if (res.result == null) {
@@ -1722,13 +1710,13 @@ case 1:
1722
1710
  }
1723
1711
  break;
1724
1712
  case 1:
1725
- // line 677 "Parser.rl"
1713
+ // line 665 "Parser.rl"
1726
1714
  {
1727
1715
  p--;
1728
1716
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1729
1717
  }
1730
1718
  break;
1731
- // line 1734 "Parser.java"
1719
+ // line 1720 "Parser.java"
1732
1720
  }
1733
1721
  }
1734
1722
  }
@@ -1748,7 +1736,7 @@ case 5:
1748
1736
  break; }
1749
1737
  }
1750
1738
 
1751
- // line 715 "Parser.rl"
1739
+ // line 701 "Parser.rl"
1752
1740
 
1753
1741
  if (cs >= JSON_array_first_final) {
1754
1742
  res.update(result, p + 1);
@@ -1758,7 +1746,7 @@ case 5:
1758
1746
  }
1759
1747
 
1760
1748
 
1761
- // line 1764 "Parser.java"
1749
+ // line 1750 "Parser.java"
1762
1750
  private static byte[] init__JSON_object_actions_0()
1763
1751
  {
1764
1752
  return new byte [] {
@@ -1881,7 +1869,7 @@ static final int JSON_object_error = 0;
1881
1869
  static final int JSON_object_en_main = 1;
1882
1870
 
1883
1871
 
1884
- // line 774 "Parser.rl"
1872
+ // line 760 "Parser.rl"
1885
1873
 
1886
1874
 
1887
1875
  void parseObject(ParserResult res, int p, int pe) {
@@ -1906,14 +1894,14 @@ static final int JSON_object_en_main = 1;
1906
1894
  }
1907
1895
 
1908
1896
 
1909
- // line 1912 "Parser.java"
1897
+ // line 1898 "Parser.java"
1910
1898
  {
1911
1899
  cs = JSON_object_start;
1912
1900
  }
1913
1901
 
1914
- // line 798 "Parser.rl"
1902
+ // line 784 "Parser.rl"
1915
1903
 
1916
- // line 1919 "Parser.java"
1904
+ // line 1905 "Parser.java"
1917
1905
  {
1918
1906
  int _klen;
1919
1907
  int _trans = 0;
@@ -1994,7 +1982,7 @@ case 1:
1994
1982
  switch ( _JSON_object_actions[_acts++] )
1995
1983
  {
1996
1984
  case 0:
1997
- // line 729 "Parser.rl"
1985
+ // line 715 "Parser.rl"
1998
1986
  {
1999
1987
  parseValue(res, p, pe);
2000
1988
  if (res.result == null) {
@@ -2011,7 +1999,7 @@ case 1:
2011
1999
  }
2012
2000
  break;
2013
2001
  case 1:
2014
- // line 744 "Parser.rl"
2002
+ // line 730 "Parser.rl"
2015
2003
  {
2016
2004
  parseString(res, p, pe);
2017
2005
  if (res.result == null) {
@@ -2031,13 +2019,13 @@ case 1:
2031
2019
  }
2032
2020
  break;
2033
2021
  case 2:
2034
- // line 762 "Parser.rl"
2022
+ // line 748 "Parser.rl"
2035
2023
  {
2036
2024
  p--;
2037
2025
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
2038
2026
  }
2039
2027
  break;
2040
- // line 2043 "Parser.java"
2028
+ // line 2029 "Parser.java"
2041
2029
  }
2042
2030
  }
2043
2031
  }
@@ -2057,7 +2045,7 @@ case 5:
2057
2045
  break; }
2058
2046
  }
2059
2047
 
2060
- // line 799 "Parser.rl"
2048
+ // line 785 "Parser.rl"
2061
2049
 
2062
2050
  if (cs < JSON_object_first_final) {
2063
2051
  res.update(null, p + 1);
@@ -2090,11 +2078,11 @@ case 5:
2090
2078
  }
2091
2079
 
2092
2080
 
2093
- // line 2096 "Parser.java"
2081
+ // line 2082 "Parser.java"
2094
2082
  private static byte[] init__JSON_actions_0()
2095
2083
  {
2096
2084
  return new byte [] {
2097
- 0, 1, 0, 1, 1
2085
+ 0, 1, 0
2098
2086
  };
2099
2087
  }
2100
2088
 
@@ -2104,7 +2092,7 @@ private static final byte _JSON_actions[] = init__JSON_actions_0();
2104
2092
  private static byte[] init__JSON_key_offsets_0()
2105
2093
  {
2106
2094
  return new byte [] {
2107
- 0, 0, 7, 9, 10, 12, 13, 15, 16, 18, 19
2095
+ 0, 0, 16, 18, 19, 21, 22, 24, 25, 27, 28
2108
2096
  };
2109
2097
  }
2110
2098
 
@@ -2114,9 +2102,9 @@ private static final byte _JSON_key_offsets[] = init__JSON_key_offsets_0();
2114
2102
  private static char[] init__JSON_trans_keys_0()
2115
2103
  {
2116
2104
  return new char [] {
2117
- 13, 32, 47, 91, 123, 9, 10, 42, 47, 42, 42, 47,
2118
- 10, 42, 47, 42, 42, 47, 10, 13, 32, 47, 9, 10,
2119
- 0
2105
+ 13, 32, 34, 45, 47, 73, 78, 91, 102, 110, 116, 123,
2106
+ 9, 10, 48, 57, 42, 47, 42, 42, 47, 10, 42, 47,
2107
+ 42, 42, 47, 10, 13, 32, 47, 9, 10, 0
2120
2108
  };
2121
2109
  }
2122
2110
 
@@ -2126,7 +2114,7 @@ private static final char _JSON_trans_keys[] = init__JSON_trans_keys_0();
2126
2114
  private static byte[] init__JSON_single_lengths_0()
2127
2115
  {
2128
2116
  return new byte [] {
2129
- 0, 5, 2, 1, 2, 1, 2, 1, 2, 1, 3
2117
+ 0, 12, 2, 1, 2, 1, 2, 1, 2, 1, 3
2130
2118
  };
2131
2119
  }
2132
2120
 
@@ -2136,7 +2124,7 @@ private static final byte _JSON_single_lengths[] = init__JSON_single_lengths_0()
2136
2124
  private static byte[] init__JSON_range_lengths_0()
2137
2125
  {
2138
2126
  return new byte [] {
2139
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1
2127
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1
2140
2128
  };
2141
2129
  }
2142
2130
 
@@ -2146,7 +2134,7 @@ private static final byte _JSON_range_lengths[] = init__JSON_range_lengths_0();
2146
2134
  private static byte[] init__JSON_index_offsets_0()
2147
2135
  {
2148
2136
  return new byte [] {
2149
- 0, 0, 7, 10, 12, 15, 17, 20, 22, 25, 27
2137
+ 0, 0, 15, 18, 20, 23, 25, 28, 30, 33, 35
2150
2138
  };
2151
2139
  }
2152
2140
 
@@ -2156,9 +2144,10 @@ private static final byte _JSON_index_offsets[] = init__JSON_index_offsets_0();
2156
2144
  private static byte[] init__JSON_indicies_0()
2157
2145
  {
2158
2146
  return new byte [] {
2159
- 0, 0, 2, 3, 4, 0, 1, 5, 6, 1, 7, 5,
2160
- 7, 0, 5, 0, 6, 8, 9, 1, 10, 8, 10, 11,
2161
- 8, 11, 9, 11, 11, 12, 11, 1, 0
2147
+ 0, 0, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2,
2148
+ 0, 2, 1, 4, 5, 1, 6, 4, 6, 7, 4, 7,
2149
+ 5, 8, 9, 1, 10, 8, 10, 0, 8, 0, 9, 7,
2150
+ 7, 11, 7, 1, 0
2162
2151
  };
2163
2152
  }
2164
2153
 
@@ -2168,8 +2157,7 @@ private static final byte _JSON_indicies[] = init__JSON_indicies_0();
2168
2157
  private static byte[] init__JSON_trans_targs_0()
2169
2158
  {
2170
2159
  return new byte [] {
2171
- 1, 0, 2, 10, 10, 3, 5, 4, 7, 9, 8, 10,
2172
- 6
2160
+ 1, 0, 10, 6, 3, 5, 4, 10, 7, 9, 8, 2
2173
2161
  };
2174
2162
  }
2175
2163
 
@@ -2179,8 +2167,7 @@ private static final byte _JSON_trans_targs[] = init__JSON_trans_targs_0();
2179
2167
  private static byte[] init__JSON_trans_actions_0()
2180
2168
  {
2181
2169
  return new byte [] {
2182
- 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0,
2183
- 0
2170
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
2184
2171
  };
2185
2172
  }
2186
2173
 
@@ -2194,26 +2181,26 @@ static final int JSON_error = 0;
2194
2181
  static final int JSON_en_main = 1;
2195
2182
 
2196
2183
 
2197
- // line 864 "Parser.rl"
2184
+ // line 836 "Parser.rl"
2198
2185
 
2199
2186
 
2200
- public IRubyObject parseStrict() {
2187
+ public IRubyObject parseImplemetation() {
2201
2188
  int cs = EVIL;
2202
2189
  int p, pe;
2203
2190
  IRubyObject result = null;
2204
2191
  ParserResult res = new ParserResult();
2205
2192
 
2206
2193
 
2207
- // line 2210 "Parser.java"
2194
+ // line 2195 "Parser.java"
2208
2195
  {
2209
2196
  cs = JSON_start;
2210
2197
  }
2211
2198
 
2212
- // line 873 "Parser.rl"
2199
+ // line 845 "Parser.rl"
2213
2200
  p = byteList.begin();
2214
2201
  pe = p + byteList.length();
2215
2202
 
2216
- // line 2219 "Parser.java"
2203
+ // line 2204 "Parser.java"
2217
2204
  {
2218
2205
  int _klen;
2219
2206
  int _trans = 0;
@@ -2294,267 +2281,7 @@ case 1:
2294
2281
  switch ( _JSON_actions[_acts++] )
2295
2282
  {
2296
2283
  case 0:
2297
- // line 836 "Parser.rl"
2298
- {
2299
- currentNesting = 1;
2300
- parseObject(res, p, pe);
2301
- if (res.result == null) {
2302
- p--;
2303
- { p += 1; _goto_targ = 5; if (true) continue _goto;}
2304
- } else {
2305
- result = res.result;
2306
- {p = (( res.p))-1;}
2307
- }
2308
- }
2309
- break;
2310
- case 1:
2311
- // line 848 "Parser.rl"
2312
- {
2313
- currentNesting = 1;
2314
- parseArray(res, p, pe);
2315
- if (res.result == null) {
2316
- p--;
2317
- { p += 1; _goto_targ = 5; if (true) continue _goto;}
2318
- } else {
2319
- result = res.result;
2320
- {p = (( res.p))-1;}
2321
- }
2322
- }
2323
- break;
2324
- // line 2327 "Parser.java"
2325
- }
2326
- }
2327
- }
2328
-
2329
- case 2:
2330
- if ( cs == 0 ) {
2331
- _goto_targ = 5;
2332
- continue _goto;
2333
- }
2334
- if ( ++p != pe ) {
2335
- _goto_targ = 1;
2336
- continue _goto;
2337
- }
2338
- case 4:
2339
- case 5:
2340
- }
2341
- break; }
2342
- }
2343
-
2344
- // line 876 "Parser.rl"
2345
-
2346
- if (cs >= JSON_first_final && p == pe) {
2347
- return result;
2348
- } else {
2349
- throw unexpectedToken(p, pe);
2350
- }
2351
- }
2352
-
2353
-
2354
- // line 2357 "Parser.java"
2355
- private static byte[] init__JSON_quirks_mode_actions_0()
2356
- {
2357
- return new byte [] {
2358
- 0, 1, 0
2359
- };
2360
- }
2361
-
2362
- private static final byte _JSON_quirks_mode_actions[] = init__JSON_quirks_mode_actions_0();
2363
-
2364
-
2365
- private static byte[] init__JSON_quirks_mode_key_offsets_0()
2366
- {
2367
- return new byte [] {
2368
- 0, 0, 16, 18, 19, 21, 22, 24, 25, 27, 28
2369
- };
2370
- }
2371
-
2372
- private static final byte _JSON_quirks_mode_key_offsets[] = init__JSON_quirks_mode_key_offsets_0();
2373
-
2374
-
2375
- private static char[] init__JSON_quirks_mode_trans_keys_0()
2376
- {
2377
- return new char [] {
2378
- 13, 32, 34, 45, 47, 73, 78, 91, 102, 110, 116, 123,
2379
- 9, 10, 48, 57, 42, 47, 42, 42, 47, 10, 42, 47,
2380
- 42, 42, 47, 10, 13, 32, 47, 9, 10, 0
2381
- };
2382
- }
2383
-
2384
- private static final char _JSON_quirks_mode_trans_keys[] = init__JSON_quirks_mode_trans_keys_0();
2385
-
2386
-
2387
- private static byte[] init__JSON_quirks_mode_single_lengths_0()
2388
- {
2389
- return new byte [] {
2390
- 0, 12, 2, 1, 2, 1, 2, 1, 2, 1, 3
2391
- };
2392
- }
2393
-
2394
- private static final byte _JSON_quirks_mode_single_lengths[] = init__JSON_quirks_mode_single_lengths_0();
2395
-
2396
-
2397
- private static byte[] init__JSON_quirks_mode_range_lengths_0()
2398
- {
2399
- return new byte [] {
2400
- 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1
2401
- };
2402
- }
2403
-
2404
- private static final byte _JSON_quirks_mode_range_lengths[] = init__JSON_quirks_mode_range_lengths_0();
2405
-
2406
-
2407
- private static byte[] init__JSON_quirks_mode_index_offsets_0()
2408
- {
2409
- return new byte [] {
2410
- 0, 0, 15, 18, 20, 23, 25, 28, 30, 33, 35
2411
- };
2412
- }
2413
-
2414
- private static final byte _JSON_quirks_mode_index_offsets[] = init__JSON_quirks_mode_index_offsets_0();
2415
-
2416
-
2417
- private static byte[] init__JSON_quirks_mode_indicies_0()
2418
- {
2419
- return new byte [] {
2420
- 0, 0, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2,
2421
- 0, 2, 1, 4, 5, 1, 6, 4, 6, 7, 4, 7,
2422
- 5, 8, 9, 1, 10, 8, 10, 0, 8, 0, 9, 7,
2423
- 7, 11, 7, 1, 0
2424
- };
2425
- }
2426
-
2427
- private static final byte _JSON_quirks_mode_indicies[] = init__JSON_quirks_mode_indicies_0();
2428
-
2429
-
2430
- private static byte[] init__JSON_quirks_mode_trans_targs_0()
2431
- {
2432
- return new byte [] {
2433
- 1, 0, 10, 6, 3, 5, 4, 10, 7, 9, 8, 2
2434
- };
2435
- }
2436
-
2437
- private static final byte _JSON_quirks_mode_trans_targs[] = init__JSON_quirks_mode_trans_targs_0();
2438
-
2439
-
2440
- private static byte[] init__JSON_quirks_mode_trans_actions_0()
2441
- {
2442
- return new byte [] {
2443
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
2444
- };
2445
- }
2446
-
2447
- private static final byte _JSON_quirks_mode_trans_actions[] = init__JSON_quirks_mode_trans_actions_0();
2448
-
2449
-
2450
- static final int JSON_quirks_mode_start = 1;
2451
- static final int JSON_quirks_mode_first_final = 10;
2452
- static final int JSON_quirks_mode_error = 0;
2453
-
2454
- static final int JSON_quirks_mode_en_main = 1;
2455
-
2456
-
2457
- // line 904 "Parser.rl"
2458
-
2459
-
2460
- public IRubyObject parseQuirksMode() {
2461
- int cs = EVIL;
2462
- int p, pe;
2463
- IRubyObject result = null;
2464
- ParserResult res = new ParserResult();
2465
-
2466
-
2467
- // line 2470 "Parser.java"
2468
- {
2469
- cs = JSON_quirks_mode_start;
2470
- }
2471
-
2472
- // line 913 "Parser.rl"
2473
- p = byteList.begin();
2474
- pe = p + byteList.length();
2475
-
2476
- // line 2479 "Parser.java"
2477
- {
2478
- int _klen;
2479
- int _trans = 0;
2480
- int _acts;
2481
- int _nacts;
2482
- int _keys;
2483
- int _goto_targ = 0;
2484
-
2485
- _goto: while (true) {
2486
- switch ( _goto_targ ) {
2487
- case 0:
2488
- if ( p == pe ) {
2489
- _goto_targ = 4;
2490
- continue _goto;
2491
- }
2492
- if ( cs == 0 ) {
2493
- _goto_targ = 5;
2494
- continue _goto;
2495
- }
2496
- case 1:
2497
- _match: do {
2498
- _keys = _JSON_quirks_mode_key_offsets[cs];
2499
- _trans = _JSON_quirks_mode_index_offsets[cs];
2500
- _klen = _JSON_quirks_mode_single_lengths[cs];
2501
- if ( _klen > 0 ) {
2502
- int _lower = _keys;
2503
- int _mid;
2504
- int _upper = _keys + _klen - 1;
2505
- while (true) {
2506
- if ( _upper < _lower )
2507
- break;
2508
-
2509
- _mid = _lower + ((_upper-_lower) >> 1);
2510
- if ( data[p] < _JSON_quirks_mode_trans_keys[_mid] )
2511
- _upper = _mid - 1;
2512
- else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid] )
2513
- _lower = _mid + 1;
2514
- else {
2515
- _trans += (_mid - _keys);
2516
- break _match;
2517
- }
2518
- }
2519
- _keys += _klen;
2520
- _trans += _klen;
2521
- }
2522
-
2523
- _klen = _JSON_quirks_mode_range_lengths[cs];
2524
- if ( _klen > 0 ) {
2525
- int _lower = _keys;
2526
- int _mid;
2527
- int _upper = _keys + (_klen<<1) - 2;
2528
- while (true) {
2529
- if ( _upper < _lower )
2530
- break;
2531
-
2532
- _mid = _lower + (((_upper-_lower) >> 1) & ~1);
2533
- if ( data[p] < _JSON_quirks_mode_trans_keys[_mid] )
2534
- _upper = _mid - 2;
2535
- else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid+1] )
2536
- _lower = _mid + 2;
2537
- else {
2538
- _trans += ((_mid - _keys)>>1);
2539
- break _match;
2540
- }
2541
- }
2542
- _trans += _klen;
2543
- }
2544
- } while (false);
2545
-
2546
- _trans = _JSON_quirks_mode_indicies[_trans];
2547
- cs = _JSON_quirks_mode_trans_targs[_trans];
2548
-
2549
- if ( _JSON_quirks_mode_trans_actions[_trans] != 0 ) {
2550
- _acts = _JSON_quirks_mode_trans_actions[_trans];
2551
- _nacts = (int) _JSON_quirks_mode_actions[_acts++];
2552
- while ( _nacts-- > 0 )
2553
- {
2554
- switch ( _JSON_quirks_mode_actions[_acts++] )
2555
- {
2556
- case 0:
2557
- // line 890 "Parser.rl"
2284
+ // line 822 "Parser.rl"
2558
2285
  {
2559
2286
  parseValue(res, p, pe);
2560
2287
  if (res.result == null) {
@@ -2566,7 +2293,7 @@ case 1:
2566
2293
  }
2567
2294
  }
2568
2295
  break;
2569
- // line 2572 "Parser.java"
2296
+ // line 2297 "Parser.java"
2570
2297
  }
2571
2298
  }
2572
2299
  }
@@ -2586,9 +2313,9 @@ case 5:
2586
2313
  break; }
2587
2314
  }
2588
2315
 
2589
- // line 916 "Parser.rl"
2316
+ // line 848 "Parser.rl"
2590
2317
 
2591
- if (cs >= JSON_quirks_mode_first_final && p == pe) {
2318
+ if (cs >= JSON_first_final && p == pe) {
2592
2319
  return result;
2593
2320
  } else {
2594
2321
  throw unexpectedToken(p, pe);
@@ -2596,12 +2323,7 @@ case 5:
2596
2323
  }
2597
2324
 
2598
2325
  public IRubyObject parse() {
2599
- if (parser.quirksMode) {
2600
- return parseQuirksMode();
2601
- } else {
2602
- return parseStrict();
2603
- }
2604
-
2326
+ return parseImplemetation();
2605
2327
  }
2606
2328
 
2607
2329
  /**