summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/src/json/ext/Generator.java6
-rw-r--r--java/src/json/ext/GeneratorMethods.java4
-rw-r--r--java/src/json/ext/GeneratorService.java2
-rw-r--r--java/src/json/ext/GeneratorState.java53
-rw-r--r--java/src/json/ext/OptionsReader.java2
-rw-r--r--java/src/json/ext/Parser.java485
-rw-r--r--java/src/json/ext/Parser.rl121
-rw-r--r--java/src/json/ext/ParserService.java2
-rw-r--r--java/src/json/ext/Utils.java2
9 files changed, 520 insertions, 157 deletions
diff --git a/java/src/json/ext/Generator.java b/java/src/json/ext/Generator.java
index fbc394f..78dc078 100644
--- a/java/src/json/ext/Generator.java
+++ b/java/src/json/ext/Generator.java
@@ -1,6 +1,6 @@
/*
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
- *
+ *
* Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
* for details.
*/
@@ -85,11 +85,11 @@ public final class Generator {
/**
* A class that concentrates all the information that is shared by
* generators working on a single session.
- *
+ *
* <p>A session is defined as the process of serializing a single root
* object; any handler directly called by container handlers (arrays and
* hashes/objects) shares this object with its caller.
- *
+ *
* <p>Note that anything called indirectly (via {@link GENERIC_HANDLER})
* won't be part of the session.
*/
diff --git a/java/src/json/ext/GeneratorMethods.java b/java/src/json/ext/GeneratorMethods.java
index 356f2d0..637b579 100644
--- a/java/src/json/ext/GeneratorMethods.java
+++ b/java/src/json/ext/GeneratorMethods.java
@@ -1,6 +1,6 @@
/*
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
- *
+ *
* Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
* for details.
*/
@@ -25,7 +25,7 @@ import org.jruby.util.ByteList;
/**
* A class that populates the
* <code>Json::Ext::Generator::GeneratorMethods</code> module.
- *
+ *
* @author mernen
*/
class GeneratorMethods {
diff --git a/java/src/json/ext/GeneratorService.java b/java/src/json/ext/GeneratorService.java
index 2f3b07e..ed33639 100644
--- a/java/src/json/ext/GeneratorService.java
+++ b/java/src/json/ext/GeneratorService.java
@@ -1,6 +1,6 @@
/*
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
- *
+ *
* Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
* for details.
*/
diff --git a/java/src/json/ext/GeneratorState.java b/java/src/json/ext/GeneratorState.java
index f04eda2..0536ac4 100644
--- a/java/src/json/ext/GeneratorState.java
+++ b/java/src/json/ext/GeneratorState.java
@@ -1,6 +1,6 @@
/*
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
- *
+ *
* Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
* for details.
*/
@@ -24,10 +24,10 @@ import org.jruby.util.ByteList;
/**
* The <code>JSON::Ext::Generator::State</code> class.
- *
+ *
* <p>This class is used to create State instances, that are use to hold data
* while generating a JSON text from a a Ruby data structure.
- *
+ *
* @author mernen
*/
public class GeneratorState extends RubyObject {
@@ -72,10 +72,16 @@ public class GeneratorState extends RubyObject {
private boolean allowNaN = DEFAULT_ALLOW_NAN;
static final boolean DEFAULT_ALLOW_NAN = false;
/**
- * XXX
+ * If set to <code>true</code> all JSON documents generated do not contain
+ * any other characters than ASCII characters.
*/
private boolean asciiOnly = DEFAULT_ASCII_ONLY;
static final boolean DEFAULT_ASCII_ONLY = false;
+ /**
+ * XXX
+ */
+ private boolean quirksMode = DEFAULT_QUIRKS_MODE;
+ static final boolean DEFAULT_QUIRKS_MODE = false;
/**
* The current depth (inside a #to_json call)
@@ -94,7 +100,7 @@ public class GeneratorState extends RubyObject {
/**
* <code>State.from_state(opts)</code>
- *
+ *
* <p>Creates a State object from <code>opts</code>, which ought to be
* {@link RubyHash Hash} to create a new <code>State</code> instance
* configured by <codes>opts</code>, something else to create an
@@ -136,11 +142,11 @@ public class GeneratorState extends RubyObject {
/**
* <code>State#initialize(opts = {})</code>
- *
+ *
* Instantiates a new <code>State</code> object, configured by <code>opts</code>.
- *
+ *
* <code>opts</code> can have the following keys:
- *
+ *
* <dl>
* <dt><code>:indent</code>
* <dd>a {@link RubyString String} used to indent levels (default: <code>""</code>)
@@ -151,7 +157,7 @@ public class GeneratorState extends RubyObject {
* <dd>a String that is put before a <code>":"</code> pair delimiter
* (default: <code>""</code>)
* <dt><code>:object_nl</code>
- * <dd>a String that is put at the end of a JSON object (default: <code>""</code>)
+ * <dd>a String that is put at the end of a JSON object (default: <code>""</code>)
* <dt><code>:array_nl</code>
* <dd>a String that is put at the end of a JSON array (default: <code>""</code>)
* <dt><code>:allow_nan</code>
@@ -181,17 +187,20 @@ public class GeneratorState extends RubyObject {
this.maxNesting = orig.maxNesting;
this.allowNaN = orig.allowNaN;
this.asciiOnly = orig.asciiOnly;
+ this.quirksMode = orig.quirksMode;
this.depth = orig.depth;
return this;
}
/**
- * XXX
+ * Generates a valid JSON document from object <code>obj</code> and returns
+ * the result. If no valid JSON document can be created this method raises
+ * a GeneratorError exception.
*/
@JRubyMethod
public IRubyObject generate(ThreadContext context, IRubyObject obj) {
RubyString result = Generator.generateJson(context, obj, this);
- if (!objectOrArrayLiteral(result)) {
+ if (!quirksMode && !objectOrArrayLiteral(result)) {
throw Utils.newException(context, Utils.M_GENERATOR_ERROR,
"only generation of JSON objects or arrays allowed");
}
@@ -364,6 +373,22 @@ public class GeneratorState extends RubyObject {
return context.getRuntime().newBoolean(asciiOnly);
}
+ @JRubyMethod(name="quirks_mode")
+ public RubyBoolean quirks_mode_get(ThreadContext context) {
+ return context.getRuntime().newBoolean(quirksMode);
+ }
+
+ @JRubyMethod(name="quirks_mode=")
+ public IRubyObject quirks_mode_set(IRubyObject quirks_mode) {
+ quirksMode = quirks_mode.isTrue();
+ return quirks_mode.getRuntime().newBoolean(quirksMode);
+ }
+
+ @JRubyMethod(name="quirks_mode?")
+ public RubyBoolean quirks_mode_p(ThreadContext context) {
+ return context.getRuntime().newBoolean(quirksMode);
+ }
+
public int getDepth() {
return depth;
}
@@ -390,7 +415,7 @@ public class GeneratorState extends RubyObject {
/**
* <code>State#configure(opts)</code>
- *
+ *
* <p>Configures this State instance with the {@link RubyHash Hash}
* <code>opts</code>, and returns itself.
* @param vOpts The options hash
@@ -418,6 +443,7 @@ public class GeneratorState extends RubyObject {
maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
allowNaN = opts.getBool("allow_nan", DEFAULT_ALLOW_NAN);
asciiOnly = opts.getBool("ascii_only", DEFAULT_ASCII_ONLY);
+ quirksMode = opts.getBool("quirks_mode", DEFAULT_QUIRKS_MODE);
depth = opts.getInt("depth", 0);
@@ -426,7 +452,7 @@ public class GeneratorState extends RubyObject {
/**
* <code>State#to_h()</code>
- *
+ *
* <p>Returns the configuration instance variables as a hash, that can be
* passed to the configure method.
* @return
@@ -443,6 +469,7 @@ public class GeneratorState extends RubyObject {
result.op_aset(context, runtime.newSymbol("array_nl"), array_nl_get(context));
result.op_aset(context, runtime.newSymbol("allow_nan"), allow_nan_p(context));
result.op_aset(context, runtime.newSymbol("ascii_only"), ascii_only_p(context));
+ result.op_aset(context, runtime.newSymbol("quirks_mode"), quirks_mode_p(context));
result.op_aset(context, runtime.newSymbol("max_nesting"), max_nesting_get(context));
result.op_aset(context, runtime.newSymbol("depth"), depth_get(context));
return result;
diff --git a/java/src/json/ext/OptionsReader.java b/java/src/json/ext/OptionsReader.java
index c9c9c94..a0b76b1 100644
--- a/java/src/json/ext/OptionsReader.java
+++ b/java/src/json/ext/OptionsReader.java
@@ -1,6 +1,6 @@
/*
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
- *
+ *
* Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
* for details.
*/
diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java
index cea42d4..1240922 100644
--- a/java/src/json/ext/Parser.java
+++ b/java/src/json/ext/Parser.java
@@ -2,7 +2,7 @@
// line 1 "Parser.rl"
/*
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
- *
+ *
* Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
* for details.
*/
@@ -31,16 +31,16 @@ import org.jruby.util.ByteList;
/**
* The <code>JSON::Ext::Parser</code> class.
- *
+ *
* <p>This is the JSON parser implemented as a Java class. To use it as the
* standard parser, set
* <pre>JSON.parser = JSON::Ext::Parser</pre>
* This is performed for you when you <code>include "json/ext"</code>.
- *
+ *
* <p>This class does not perform the actual parsing, just acts as an interface
* to Ruby code. When the {@link #parse()} method is invoked, a
* Parser.ParserSession object is instantiated, which handles the process.
- *
+ *
* @author mernen
*/
public class Parser extends RubyObject {
@@ -51,6 +51,7 @@ public class Parser extends RubyObject {
private int maxNesting;
private boolean allowNaN;
private boolean symbolizeNames;
+ private boolean quirksMode;
private RubyClass objectClass;
private RubyClass arrayClass;
private RubyHash match_string;
@@ -71,7 +72,7 @@ public class Parser extends RubyObject {
/**
* Multiple-value return for internal parser methods.
- *
+ *
* <p>All the <code>parse<var>Stuff</var></code> methods return instances of
* <code>ParserResult</code> when successful, or <code>null</code> when
* there's a problem with the input data.
@@ -100,18 +101,18 @@ public class Parser extends RubyObject {
/**
* <code>Parser.new(source, opts = {})</code>
- *
+ *
* <p>Creates a new <code>JSON::Ext::Parser</code> instance for the string
* <code>source</code>.
* It will be configured by the <code>opts</code> Hash.
* <code>opts</code> can have the following keys:
- *
+ *
* <dl>
* <dt><code>:max_nesting</code>
* <dd>The maximum depth of nesting allowed in the parsed data
* structures. Disable depth checking with <code>:max_nesting => false|nil|0</code>,
* it defaults to 19.
- *
+ *
* <dt><code>:allow_nan</code>
* <dd>If set to <code>true</code>, allow <code>NaN</code>,
* <code>Infinity</code> and <code>-Infinity</code> in defiance of RFC 4627
@@ -120,15 +121,19 @@ public class Parser extends RubyObject {
* <dt><code>:symbolize_names</code>
* <dd>If set to <code>true</code>, returns symbols for the names (keys) in
* a JSON object. Otherwise strings are returned, which is also the default.
+ *
+ * <dt><code>:quirks_mode?</code>
+ * <dd>If set to <code>true</code>, if the parse is in quirks_mode, false
+ * otherwise.
*
* <dt><code>:create_additions</code>
* <dd>If set to <code>false</code>, the Parser doesn't create additions
* even if a matchin class and <code>create_id</code> was found. This option
* defaults to <code>true</code>.
- *
+ *
* <dt><code>:object_class</code>
* <dd>Defaults to Hash.
- *
+ *
* <dt><code>:array_class</code>
* <dd>Defaults to Array.
* </dl>
@@ -148,19 +153,21 @@ public class Parser extends RubyObject {
if (this.vSource != null) {
throw runtime.newTypeError("already initialized instance");
}
- RubyString source = convertEncoding(context, args[0].convertToString());
OptionsReader opts = new OptionsReader(context, args.length > 1 ? args[1] : null);
this.maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
this.allowNaN = opts.getBool("allow_nan", false);
this.symbolizeNames = opts.getBool("symbolize_names", false);
+ this.quirksMode = opts.getBool("quirks_mode", false);
this.createId = opts.getString("create_id", getCreateId(context));
this.createAdditions = opts.getBool("create_additions", true);
this.objectClass = opts.getClass("object_class", runtime.getHash());
this.arrayClass = opts.getClass("array_class", runtime.getArray());
this.match_string = opts.getHash("match_string");
- this.vSource = source;
+ this.vSource = args[0].convertToString();
+ if (!quirksMode) this.vSource = convertEncoding(context, vSource);
+
return this;
}
@@ -229,7 +236,7 @@ public class Parser extends RubyObject {
/**
* <code>Parser#parse()</code>
- *
+ *
* <p>Parses the current JSON text <code>source</code> and returns the
* complete data structure as a result.
*/
@@ -240,7 +247,7 @@ public class Parser extends RubyObject {
/**
* <code>Parser#source()</code>
- *
+ *
* <p>Returns a copy of the current <code>source</code> string, that was
* used to construct this Parser.
*/
@@ -249,6 +256,17 @@ public class Parser extends RubyObject {
return checkAndGetSource().dup();
}
+ /**
+ * <code>Parser#quirks_mode?()</code>
+ *
+ * <p>If set to <code>true</code>, if the parse is in quirks_mode, false
+ * otherwise.
+ */
+ @JRubyMethod(name = "quirks_mode?")
+ public IRubyObject quirks_mode_p(ThreadContext context) {
+ return context.getRuntime().newBoolean(quirksMode);
+ }
+
public RubyString checkAndGetSource() {
if (vSource != null) {
return vSource;
@@ -268,7 +286,7 @@ public class Parser extends RubyObject {
/**
* A string parsing session.
- *
+ *
* <p>Once a ParserSession is instantiated, the source string should not
* change until the parsing is complete. The ParserSession object assumes
* the source {@link RubyString} is still associated to its original
@@ -309,11 +327,11 @@ public class Parser extends RubyObject {
}
-// line 335 "Parser.rl"
+// line 353 "Parser.rl"
-// line 317 "Parser.java"
+// line 335 "Parser.java"
private static byte[] init__JSON_value_actions_0()
{
return new byte [] {
@@ -427,7 +445,7 @@ static final int JSON_value_error = 0;
static final int JSON_value_en_main = 1;
-// line 441 "Parser.rl"
+// line 459 "Parser.rl"
ParserResult parseValue(int p, int pe) {
@@ -435,14 +453,14 @@ static final int JSON_value_en_main = 1;
IRubyObject result = null;
-// line 439 "Parser.java"
+// line 457 "Parser.java"
{
cs = JSON_value_start;
}
-// line 448 "Parser.rl"
+// line 466 "Parser.rl"
-// line 446 "Parser.java"
+// line 464 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -468,13 +486,13 @@ case 1:
while ( _nacts-- > 0 ) {
switch ( _JSON_value_actions[_acts++] ) {
case 9:
-// line 426 "Parser.rl"
+// line 444 "Parser.rl"
{
p--;
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
-// line 478 "Parser.java"
+// line 496 "Parser.java"
}
}
@@ -537,25 +555,25 @@ case 1:
switch ( _JSON_value_actions[_acts++] )
{
case 0:
-// line 343 "Parser.rl"
+// line 361 "Parser.rl"
{
result = getRuntime().getNil();
}
break;
case 1:
-// line 346 "Parser.rl"
+// line 364 "Parser.rl"
{
result = getRuntime().getFalse();
}
break;
case 2:
-// line 349 "Parser.rl"
+// line 367 "Parser.rl"
{
result = getRuntime().getTrue();
}
break;
case 3:
-// line 352 "Parser.rl"
+// line 370 "Parser.rl"
{
if (parser.allowNaN) {
result = getConstant(CONST_NAN);
@@ -565,7 +583,7 @@ case 1:
}
break;
case 4:
-// line 359 "Parser.rl"
+// line 377 "Parser.rl"
{
if (parser.allowNaN) {
result = getConstant(CONST_INFINITY);
@@ -575,9 +593,9 @@ case 1:
}
break;
case 5:
-// line 366 "Parser.rl"
+// line 384 "Parser.rl"
{
- if (pe > p + 9 &&
+ if (pe > p + 9 - (parser.quirksMode ? 1 : 0) &&
absSubSequence(p, p + 9).toString().equals(JSON_MINUS_INFINITY)) {
if (parser.allowNaN) {
@@ -604,7 +622,7 @@ case 1:
}
break;
case 6:
-// line 392 "Parser.rl"
+// line 410 "Parser.rl"
{
ParserResult res = parseString(p, pe);
if (res == null) {
@@ -617,7 +635,7 @@ case 1:
}
break;
case 7:
-// line 402 "Parser.rl"
+// line 420 "Parser.rl"
{
currentNesting++;
ParserResult res = parseArray(p, pe);
@@ -632,7 +650,7 @@ case 1:
}
break;
case 8:
-// line 414 "Parser.rl"
+// line 432 "Parser.rl"
{
currentNesting++;
ParserResult res = parseObject(p, pe);
@@ -646,7 +664,7 @@ case 1:
}
}
break;
-// line 650 "Parser.java"
+// line 668 "Parser.java"
}
}
}
@@ -666,7 +684,7 @@ case 5:
break; }
}
-// line 449 "Parser.rl"
+// line 467 "Parser.rl"
if (cs >= JSON_value_first_final && result != null) {
return new ParserResult(result, p);
@@ -676,7 +694,7 @@ case 5:
}
-// line 680 "Parser.java"
+// line 698 "Parser.java"
private static byte[] init__JSON_integer_actions_0()
{
return new byte [] {
@@ -690,7 +708,7 @@ private static final byte _JSON_integer_actions[] = init__JSON_integer_actions_0
private static byte[] init__JSON_integer_key_offsets_0()
{
return new byte [] {
- 0, 0, 4, 7, 9, 11
+ 0, 0, 4, 7, 9, 9
};
}
@@ -720,7 +738,7 @@ private static final byte _JSON_integer_single_lengths[] = init__JSON_integer_si
private static byte[] init__JSON_integer_range_lengths_0()
{
return new byte [] {
- 0, 1, 1, 1, 1, 0
+ 0, 1, 1, 1, 0, 1
};
}
@@ -730,7 +748,7 @@ private static final byte _JSON_integer_range_lengths[] = init__JSON_integer_ran
private static byte[] init__JSON_integer_index_offsets_0()
{
return new byte [] {
- 0, 0, 4, 7, 9, 11
+ 0, 0, 4, 7, 9, 10
};
}
@@ -740,7 +758,7 @@ private static final byte _JSON_integer_index_offsets[] = init__JSON_integer_ind
private static byte[] init__JSON_integer_indicies_0()
{
return new byte [] {
- 0, 2, 3, 1, 2, 3, 1, 1, 4, 3, 4, 1,
+ 0, 2, 3, 1, 2, 3, 1, 1, 4, 1, 3, 4,
0
};
}
@@ -751,7 +769,7 @@ private static final byte _JSON_integer_indicies[] = init__JSON_integer_indicies
private static byte[] init__JSON_integer_trans_targs_0()
{
return new byte [] {
- 2, 0, 3, 4, 5
+ 2, 0, 3, 5, 4
};
}
@@ -769,28 +787,28 @@ private static final byte _JSON_integer_trans_actions[] = init__JSON_integer_tra
static final int JSON_integer_start = 1;
-static final int JSON_integer_first_final = 5;
+static final int JSON_integer_first_final = 3;
static final int JSON_integer_error = 0;
static final int JSON_integer_en_main = 1;
-// line 468 "Parser.rl"
+// line 486 "Parser.rl"
ParserResult parseInteger(int p, int pe) {
int cs = EVIL;
-// line 786 "Parser.java"
+// line 804 "Parser.java"
{
cs = JSON_integer_start;
}
-// line 474 "Parser.rl"
+// line 492 "Parser.rl"
int memo = p;
-// line 794 "Parser.java"
+// line 812 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -871,13 +889,13 @@ case 1:
switch ( _JSON_integer_actions[_acts++] )
{
case 0:
-// line 462 "Parser.rl"
+// line 480 "Parser.rl"
{
p--;
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
-// line 881 "Parser.java"
+// line 899 "Parser.java"
}
}
}
@@ -897,7 +915,7 @@ case 5:
break; }
}
-// line 476 "Parser.rl"
+// line 494 "Parser.rl"
if (cs < JSON_integer_first_final) {
return null;
@@ -912,7 +930,7 @@ case 5:
}
-// line 916 "Parser.java"
+// line 934 "Parser.java"
private static byte[] init__JSON_float_actions_0()
{
return new byte [] {
@@ -926,7 +944,7 @@ private static final byte _JSON_float_actions[] = init__JSON_float_actions_0();
private static byte[] init__JSON_float_key_offsets_0()
{
return new byte [] {
- 0, 0, 4, 7, 10, 12, 18, 22, 24, 30, 35
+ 0, 0, 4, 7, 10, 12, 16, 18, 23, 29, 29
};
}
@@ -937,8 +955,8 @@ private static char[] init__JSON_float_trans_keys_0()
{
return new char [] {
45, 48, 49, 57, 48, 49, 57, 46, 69, 101, 48, 57,
- 69, 101, 45, 46, 48, 57, 43, 45, 48, 57, 48, 57,
- 69, 101, 45, 46, 48, 57, 46, 69, 101, 48, 57, 0
+ 43, 45, 48, 57, 48, 57, 46, 69, 101, 48, 57, 69,
+ 101, 45, 46, 48, 57, 69, 101, 45, 46, 48, 57, 0
};
}
@@ -948,7 +966,7 @@ private static final char _JSON_float_trans_keys[] = init__JSON_float_trans_keys
private static byte[] init__JSON_float_single_lengths_0()
{
return new byte [] {
- 0, 2, 1, 3, 0, 2, 2, 0, 2, 3, 0
+ 0, 2, 1, 3, 0, 2, 0, 3, 2, 0, 2
};
}
@@ -958,7 +976,7 @@ private static final byte _JSON_float_single_lengths[] = init__JSON_float_single
private static byte[] init__JSON_float_range_lengths_0()
{
return new byte [] {
- 0, 1, 1, 0, 1, 2, 1, 1, 2, 1, 0
+ 0, 1, 1, 0, 1, 1, 1, 1, 2, 0, 2
};
}
@@ -968,7 +986,7 @@ private static final byte _JSON_float_range_lengths[] = init__JSON_float_range_l
private static byte[] init__JSON_float_index_offsets_0()
{
return new byte [] {
- 0, 0, 4, 7, 11, 13, 18, 22, 24, 29, 34
+ 0, 0, 4, 7, 11, 13, 17, 19, 24, 29, 30
};
}
@@ -979,8 +997,8 @@ private static byte[] init__JSON_float_indicies_0()
{
return new byte [] {
0, 2, 3, 1, 2, 3, 1, 4, 5, 5, 1, 6,
- 1, 5, 5, 1, 6, 7, 8, 8, 9, 1, 9, 1,
- 1, 1, 1, 9, 7, 4, 5, 5, 3, 1, 1, 0
+ 1, 7, 7, 8, 1, 8, 1, 4, 5, 5, 3, 1,
+ 5, 5, 1, 6, 9, 1, 1, 1, 1, 8, 9, 0
};
}
@@ -990,7 +1008,7 @@ private static final byte _JSON_float_indicies[] = init__JSON_float_indicies_0()
private static byte[] init__JSON_float_trans_targs_0()
{
return new byte [] {
- 2, 0, 3, 9, 4, 6, 5, 10, 7, 8
+ 2, 0, 3, 7, 4, 5, 8, 6, 10, 9
};
}
@@ -1000,7 +1018,7 @@ private static final byte _JSON_float_trans_targs[] = init__JSON_float_trans_tar
private static byte[] init__JSON_float_trans_actions_0()
{
return new byte [] {
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
};
}
@@ -1008,28 +1026,28 @@ private static final byte _JSON_float_trans_actions[] = init__JSON_float_trans_a
static final int JSON_float_start = 1;
-static final int JSON_float_first_final = 10;
+static final int JSON_float_first_final = 8;
static final int JSON_float_error = 0;
static final int JSON_float_en_main = 1;
-// line 504 "Parser.rl"
+// line 522 "Parser.rl"
ParserResult parseFloat(int p, int pe) {
int cs = EVIL;
-// line 1025 "Parser.java"
+// line 1043 "Parser.java"
{
cs = JSON_float_start;
}
-// line 510 "Parser.rl"
+// line 528 "Parser.rl"
int memo = p;
-// line 1033 "Parser.java"
+// line 1051 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -1110,13 +1128,13 @@ case 1:
switch ( _JSON_float_actions[_acts++] )
{
case 0:
-// line 495 "Parser.rl"
+// line 513 "Parser.rl"
{
p--;
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
-// line 1120 "Parser.java"
+// line 1138 "Parser.java"
}
}
}
@@ -1136,7 +1154,7 @@ case 5:
break; }
}
-// line 512 "Parser.rl"
+// line 530 "Parser.rl"
if (cs < JSON_float_first_final) {
return null;
@@ -1151,7 +1169,7 @@ case 5:
}
-// line 1155 "Parser.java"
+// line 1173 "Parser.java"
private static byte[] init__JSON_string_actions_0()
{
return new byte [] {
@@ -1253,7 +1271,7 @@ static final int JSON_string_error = 0;
static final int JSON_string_en_main = 1;
-// line 556 "Parser.rl"
+// line 574 "Parser.rl"
ParserResult parseString(int p, int pe) {
@@ -1261,15 +1279,15 @@ static final int JSON_string_en_main = 1;
IRubyObject result = null;
-// line 1265 "Parser.java"
+// line 1283 "Parser.java"
{
cs = JSON_string_start;
}
-// line 563 "Parser.rl"
+// line 581 "Parser.rl"
int memo = p;
-// line 1273 "Parser.java"
+// line 1291 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -1350,7 +1368,7 @@ case 1:
switch ( _JSON_string_actions[_acts++] )
{
case 0:
-// line 531 "Parser.rl"
+// line 549 "Parser.rl"
{
int offset = byteList.begin();
ByteList decoded = decoder.decode(byteList, memo + 1 - offset,
@@ -1365,13 +1383,13 @@ case 1:
}
break;
case 1:
-// line 544 "Parser.rl"
+// line 562 "Parser.rl"
{
p--;
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
-// line 1375 "Parser.java"
+// line 1393 "Parser.java"
}
}
}
@@ -1391,7 +1409,7 @@ case 5:
break; }
}
-// line 565 "Parser.rl"
+// line 583 "Parser.rl"
if (parser.createAdditions) {
RubyHash match_string = parser.match_string;
@@ -1408,7 +1426,7 @@ case 5:
}
});
} catch (JumpException e) { }
- if (memoArray[1] != null) {
+ if (memoArray[1] != null) {
RubyClass klass = (RubyClass) memoArray[1];
if (klass.respondsTo("json_creatable?") &&
klass.callMethod(context, "json_creatable?").isTrue()) {
@@ -1426,7 +1444,7 @@ case 5:
}
-// line 1430 "Parser.java"
+// line 1448 "Parser.java"
private static byte[] init__JSON_array_actions_0()
{
return new byte [] {
@@ -1539,7 +1557,7 @@ static final int JSON_array_error = 0;
static final int JSON_array_en_main = 1;
-// line 635 "Parser.rl"
+// line 653 "Parser.rl"
ParserResult parseArray(int p, int pe) {
@@ -1557,14 +1575,14 @@ static final int JSON_array_en_main = 1;
IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
-// line 1561 "Parser.java"
+// line 1579 "Parser.java"
{
cs = JSON_array_start;
}
-// line 652 "Parser.rl"
+// line 670 "Parser.rl"
-// line 1568 "Parser.java"
+// line 1586 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -1645,7 +1663,7 @@ case 1:
switch ( _JSON_array_actions[_acts++] )
{
case 0:
-// line 604 "Parser.rl"
+// line 622 "Parser.rl"
{
ParserResult res = parseValue(p, pe);
if (res == null) {
@@ -1662,13 +1680,13 @@ case 1:
}
break;
case 1:
-// line 619 "Parser.rl"
+// line 637 "Parser.rl"
{
p--;
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
-// line 1672 "Parser.java"
+// line 1690 "Parser.java"
}
}
}
@@ -1688,7 +1706,7 @@ case 5:
break; }
}
-// line 653 "Parser.rl"
+// line 671 "Parser.rl"
if (cs >= JSON_array_first_final) {
return new ParserResult(result, p + 1);
@@ -1698,7 +1716,7 @@ case 5:
}
-// line 1702 "Parser.java"
+// line 1720 "Parser.java"
private static byte[] init__JSON_object_actions_0()
{
return new byte [] {
@@ -1821,7 +1839,7 @@ static final int JSON_object_error = 0;
static final int JSON_object_en_main = 1;
-// line 713 "Parser.rl"
+// line 730 "Parser.rl"
ParserResult parseObject(int p, int pe) {
@@ -1840,14 +1858,14 @@ static final int JSON_object_en_main = 1;
IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
-// line 1844 "Parser.java"
+// line 1862 "Parser.java"
{
cs = JSON_object_start;
}
-// line 731 "Parser.rl"
+// line 748 "Parser.rl"
-// line 1851 "Parser.java"
+// line 1869 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -1928,7 +1946,7 @@ case 1:
switch ( _JSON_object_actions[_acts++] )
{
case 0:
-// line 667 "Parser.rl"
+// line 685 "Parser.rl"
{
ParserResult res = parseValue(p, pe);
if (res == null) {
@@ -1945,7 +1963,7 @@ case 1:
}
break;
case 1:
-// line 682 "Parser.rl"
+// line 700 "Parser.rl"
{
ParserResult res = parseString(p, pe);
if (res == null) {
@@ -1965,13 +1983,13 @@ case 1:
}
break;
case 2:
-// line 700 "Parser.rl"
+// line 718 "Parser.rl"
{
p--;
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
-// line 1975 "Parser.java"
+// line 1993 "Parser.java"
}
}
}
@@ -1991,7 +2009,7 @@ case 5:
break; }
}
-// line 732 "Parser.rl"
+// line 749 "Parser.rl"
if (cs < JSON_object_first_final) {
return null;
@@ -2017,7 +2035,7 @@ case 5:
}
-// line 2021 "Parser.java"
+// line 2039 "Parser.java"
private static byte[] init__JSON_actions_0()
{
return new byte [] {
@@ -2121,25 +2139,25 @@ static final int JSON_error = 0;
static final int JSON_en_main = 1;
-// line 790 "Parser.rl"
+// line 807 "Parser.rl"
- public IRubyObject parse() {
+ public IRubyObject parseStrict() {
int cs = EVIL;
int p, pe;
IRubyObject result = null;
-// line 2134 "Parser.java"
+// line 2152 "Parser.java"
{
cs = JSON_start;
}
-// line 798 "Parser.rl"
+// line 815 "Parser.rl"
p = byteList.begin();
pe = p + byteList.length();
-// line 2143 "Parser.java"
+// line 2161 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -2220,7 +2238,7 @@ case 1:
switch ( _JSON_actions[_acts++] )
{
case 0:
-// line 762 "Parser.rl"
+// line 779 "Parser.rl"
{
currentNesting = 1;
ParserResult res = parseObject(p, pe);
@@ -2234,7 +2252,7 @@ case 1:
}
break;
case 1:
-// line 774 "Parser.rl"
+// line 791 "Parser.rl"
{
currentNesting = 1;
ParserResult res = parseArray(p, pe);
@@ -2247,7 +2265,7 @@ case 1:
}
}
break;
-// line 2251 "Parser.java"
+// line 2269 "Parser.java"
}
}
}
@@ -2267,7 +2285,7 @@ case 5:
break; }
}
-// line 801 "Parser.rl"
+// line 818 "Parser.rl"
if (cs >= JSON_first_final && p == pe) {
return result;
@@ -2276,6 +2294,259 @@ case 5:
}
}
+
+// line 2299 "Parser.java"
+private static byte[] init__JSON_quirks_mode_actions_0()
+{
+ return new byte [] {
+ 0, 1, 0
+ };
+}
+
+private static final byte _JSON_quirks_mode_actions[] = init__JSON_quirks_mode_actions_0();
+
+
+private static byte[] init__JSON_quirks_mode_key_offsets_0()
+{
+ return new byte [] {
+ 0, 0, 16, 18, 19, 21, 22, 24, 25, 27, 28
+ };
+}
+
+private static final byte _JSON_quirks_mode_key_offsets[] = init__JSON_quirks_mode_key_offsets_0();
+
+
+private static char[] init__JSON_quirks_mode_trans_keys_0()
+{
+ return new char [] {
+ 13, 32, 34, 45, 47, 73, 78, 91, 102, 110, 116, 123,
+ 9, 10, 48, 57, 42, 47, 42, 42, 47, 10, 42, 47,
+ 42, 42, 47, 10, 13, 32, 47, 9, 10, 0
+ };
+}
+
+private static final char _JSON_quirks_mode_trans_keys[] = init__JSON_quirks_mode_trans_keys_0();
+
+
+private static byte[] init__JSON_quirks_mode_single_lengths_0()
+{
+ return new byte [] {
+ 0, 12, 2, 1, 2, 1, 2, 1, 2, 1, 3
+ };
+}
+
+private static final byte _JSON_quirks_mode_single_lengths[] = init__JSON_quirks_mode_single_lengths_0();
+
+
+private static byte[] init__JSON_quirks_mode_range_lengths_0()
+{
+ return new byte [] {
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1
+ };
+}
+
+private static final byte _JSON_quirks_mode_range_lengths[] = init__JSON_quirks_mode_range_lengths_0();
+
+
+private static byte[] init__JSON_quirks_mode_index_offsets_0()
+{
+ return new byte [] {
+ 0, 0, 15, 18, 20, 23, 25, 28, 30, 33, 35
+ };
+}
+
+private static final byte _JSON_quirks_mode_index_offsets[] = init__JSON_quirks_mode_index_offsets_0();
+
+
+private static byte[] init__JSON_quirks_mode_indicies_0()
+{
+ return new byte [] {
+ 0, 0, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2,
+ 0, 2, 1, 4, 5, 1, 6, 4, 6, 7, 4, 7,
+ 5, 8, 9, 1, 10, 8, 10, 0, 8, 0, 9, 7,
+ 7, 11, 7, 1, 0
+ };
+}
+
+private static final byte _JSON_quirks_mode_indicies[] = init__JSON_quirks_mode_indicies_0();
+
+
+private static byte[] init__JSON_quirks_mode_trans_targs_0()
+{
+ return new byte [] {
+ 1, 0, 10, 6, 3, 5, 4, 10, 7, 9, 8, 2
+ };
+}
+
+private static final byte _JSON_quirks_mode_trans_targs[] = init__JSON_quirks_mode_trans_targs_0();
+
+
+private static byte[] init__JSON_quirks_mode_trans_actions_0()
+{
+ return new byte [] {
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+}
+
+private static final byte _JSON_quirks_mode_trans_actions[] = init__JSON_quirks_mode_trans_actions_0();
+
+
+static final int JSON_quirks_mode_start = 1;
+static final int JSON_quirks_mode_first_final = 10;
+static final int JSON_quirks_mode_error = 0;
+
+static final int JSON_quirks_mode_en_main = 1;
+
+
+// line 846 "Parser.rl"
+
+
+ public IRubyObject parseQuirksMode() {
+ int cs = EVIL;
+ int p, pe;
+ IRubyObject result = null;
+
+
+// line 2411 "Parser.java"
+ {
+ cs = JSON_quirks_mode_start;
+ }
+
+// line 854 "Parser.rl"
+ p = byteList.begin();
+ pe = p + byteList.length();
+
+// line 2420 "Parser.java"
+ {
+ int _klen;
+ int _trans = 0;
+ int _acts;
+ int _nacts;
+ int _keys;
+ int _goto_targ = 0;
+
+ _goto: while (true) {
+ switch ( _goto_targ ) {
+ case 0:
+ if ( p == pe ) {
+ _goto_targ = 4;
+ continue _goto;
+ }
+ if ( cs == 0 ) {
+ _goto_targ = 5;
+ continue _goto;
+ }
+case 1:
+ _match: do {
+ _keys = _JSON_quirks_mode_key_offsets[cs];
+ _trans = _JSON_quirks_mode_index_offsets[cs];
+ _klen = _JSON_quirks_mode_single_lengths[cs];
+ if ( _klen > 0 ) {
+ int _lower = _keys;
+ int _mid;
+ int _upper = _keys + _klen - 1;
+ while (true) {
+ if ( _upper < _lower )
+ break;
+
+ _mid = _lower + ((_upper-_lower) >> 1);
+ if ( data[p] < _JSON_quirks_mode_trans_keys[_mid] )
+ _upper = _mid - 1;
+ else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid] )
+ _lower = _mid + 1;
+ else {
+ _trans += (_mid - _keys);
+ break _match;
+ }
+ }
+ _keys += _klen;
+ _trans += _klen;
+ }
+
+ _klen = _JSON_quirks_mode_range_lengths[cs];
+ if ( _klen > 0 ) {
+ int _lower = _keys;
+ int _mid;
+ int _upper = _keys + (_klen<<1) - 2;
+ while (true) {
+ if ( _upper < _lower )
+ break;
+
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+ if ( data[p] < _JSON_quirks_mode_trans_keys[_mid] )
+ _upper = _mid - 2;
+ else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid+1] )
+ _lower = _mid + 2;
+ else {
+ _trans += ((_mid - _keys)>>1);
+ break _match;
+ }
+ }
+ _trans += _klen;
+ }
+ } while (false);
+
+ _trans = _JSON_quirks_mode_indicies[_trans];
+ cs = _JSON_quirks_mode_trans_targs[_trans];
+
+ if ( _JSON_quirks_mode_trans_actions[_trans] != 0 ) {
+ _acts = _JSON_quirks_mode_trans_actions[_trans];
+ _nacts = (int) _JSON_quirks_mode_actions[_acts++];
+ while ( _nacts-- > 0 )
+ {
+ switch ( _JSON_quirks_mode_actions[_acts++] )
+ {
+ case 0:
+// line 832 "Parser.rl"
+ {
+ ParserResult res = parseValue(p, pe);
+ if (res == null) {
+ p--;
+ { p += 1; _goto_targ = 5; if (true) continue _goto;}
+ } else {
+ result = res.result;
+ {p = (( res.p))-1;}
+ }
+ }
+ break;
+// line 2513 "Parser.java"
+ }
+ }
+ }
+
+case 2:
+ if ( cs == 0 ) {
+ _goto_targ = 5;
+ continue _goto;
+ }
+ if ( ++p != pe ) {
+ _goto_targ = 1;
+ continue _goto;
+ }
+case 4:
+case 5:
+ }
+ break; }
+ }
+
+// line 857 "Parser.rl"
+
+ if (cs >= JSON_quirks_mode_first_final && p == pe) {
+ return result;
+ } else {
+ throw unexpectedToken(p, pe);
+ }
+ }
+
+ public IRubyObject parse() {
+ if (parser.quirksMode) {
+ return parseQuirksMode();
+ } else {
+ return parseStrict();
+ }
+
+ }
+
/**
* Returns a subsequence of the source ByteList, based on source
* array byte offsets (i.e., the ByteList's own begin offset is not
diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl
index 779d3f3..b037359 100644
--- a/java/src/json/ext/Parser.rl
+++ b/java/src/json/ext/Parser.rl
@@ -1,6 +1,6 @@
/*
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
- *
+ *
* Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
* for details.
*/
@@ -29,16 +29,16 @@ import org.jruby.util.ByteList;
/**
* The <code>JSON::Ext::Parser</code> class.
- *
+ *
* <p>This is the JSON parser implemented as a Java class. To use it as the
* standard parser, set
* <pre>JSON.parser = JSON::Ext::Parser</pre>
* This is performed for you when you <code>include "json/ext"</code>.
- *
+ *
* <p>This class does not perform the actual parsing, just acts as an interface
* to Ruby code. When the {@link #parse()} method is invoked, a
* Parser.ParserSession object is instantiated, which handles the process.
- *
+ *
* @author mernen
*/
public class Parser extends RubyObject {
@@ -49,6 +49,7 @@ public class Parser extends RubyObject {
private int maxNesting;
private boolean allowNaN;
private boolean symbolizeNames;
+ private boolean quirksMode;
private RubyClass objectClass;
private RubyClass arrayClass;
private RubyHash match_string;
@@ -69,7 +70,7 @@ public class Parser extends RubyObject {
/**
* Multiple-value return for internal parser methods.
- *
+ *
* <p>All the <code>parse<var>Stuff</var></code> methods return instances of
* <code>ParserResult</code> when successful, or <code>null</code> when
* there's a problem with the input data.
@@ -98,18 +99,18 @@ public class Parser extends RubyObject {
/**
* <code>Parser.new(source, opts = {})</code>
- *
+ *
* <p>Creates a new <code>JSON::Ext::Parser</code> instance for the string
* <code>source</code>.
* It will be configured by the <code>opts</code> Hash.
* <code>opts</code> can have the following keys:
- *
+ *
* <dl>
* <dt><code>:max_nesting</code>
* <dd>The maximum depth of nesting allowed in the parsed data
* structures. Disable depth checking with <code>:max_nesting => false|nil|0</code>,
* it defaults to 19.
- *
+ *
* <dt><code>:allow_nan</code>
* <dd>If set to <code>true</code>, allow <code>NaN</code>,
* <code>Infinity</code> and <code>-Infinity</code> in defiance of RFC 4627
@@ -118,15 +119,19 @@ public class Parser extends RubyObject {
* <dt><code>:symbolize_names</code>
* <dd>If set to <code>true</code>, returns symbols for the names (keys) in
* a JSON object. Otherwise strings are returned, which is also the default.
+ *
+ * <dt><code>:quirks_mode?</code>
+ * <dd>If set to <code>true</code>, if the parse is in quirks_mode, false
+ * otherwise.
*
* <dt><code>:create_additions</code>
* <dd>If set to <code>false</code>, the Parser doesn't create additions
* even if a matchin class and <code>create_id</code> was found. This option
* defaults to <code>true</code>.
- *
+ *
* <dt><code>:object_class</code>
* <dd>Defaults to Hash.
- *
+ *
* <dt><code>:array_class</code>
* <dd>Defaults to Array.
* </dl>
@@ -146,19 +151,21 @@ public class Parser extends RubyObject {
if (this.vSource != null) {
throw runtime.newTypeError("already initialized instance");
}
- RubyString source = convertEncoding(context, args[0].convertToString());
OptionsReader opts = new OptionsReader(context, args.length > 1 ? args[1] : null);
this.maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
this.allowNaN = opts.getBool("allow_nan", false);
this.symbolizeNames = opts.getBool("symbolize_names", false);
+ this.quirksMode = opts.getBool("quirks_mode", false);
this.createId = opts.getString("create_id", getCreateId(context));
this.createAdditions = opts.getBool("create_additions", true);
this.objectClass = opts.getClass("object_class", runtime.getHash());
this.arrayClass = opts.getClass("array_class", runtime.getArray());
this.match_string = opts.getHash("match_string");
- this.vSource = source;
+ this.vSource = args[0].convertToString();
+ if (!quirksMode) this.vSource = convertEncoding(context, vSource);
+
return this;
}
@@ -227,7 +234,7 @@ public class Parser extends RubyObject {
/**
* <code>Parser#parse()</code>
- *
+ *
* <p>Parses the current JSON text <code>source</code> and returns the
* complete data structure as a result.
*/
@@ -238,7 +245,7 @@ public class Parser extends RubyObject {
/**
* <code>Parser#source()</code>
- *
+ *
* <p>Returns a copy of the current <code>source</code> string, that was
* used to construct this Parser.
*/
@@ -247,6 +254,17 @@ public class Parser extends RubyObject {
return checkAndGetSource().dup();
}
+ /**
+ * <code>Parser#quirks_mode?()</code>
+ *
+ * <p>If set to <code>true</code>, if the parse is in quirks_mode, false
+ * otherwise.
+ */
+ @JRubyMethod(name = "quirks_mode?")
+ public IRubyObject quirks_mode_p(ThreadContext context) {
+ return context.getRuntime().newBoolean(quirksMode);
+ }
+
public RubyString checkAndGetSource() {
if (vSource != null) {
return vSource;
@@ -266,7 +284,7 @@ public class Parser extends RubyObject {
/**
* A string parsing session.
- *
+ *
* <p>Once a ParserSession is instantiated, the source string should not
* change until the parsing is complete. The ParserSession object assumes
* the source {@link RubyString} is still associated to its original
@@ -364,7 +382,7 @@ public class Parser extends RubyObject {
}
}
action parse_number {
- if (pe > fpc + 9 &&
+ if (pe > fpc + 9 - (parser.quirksMode ? 1 : 0) &&
absSubSequence(fpc, fpc + 9).toString().equals(JSON_MINUS_INFINITY)) {
if (parser.allowNaN) {
@@ -464,7 +482,7 @@ public class Parser extends RubyObject {
fbreak;
}
- main := '-'? ( '0' | [1-9][0-9]* ) ( ^[0-9] @exit );
+ main := '-'? ( '0' | [1-9][0-9]* ) ( ^[0-9]? @exit );
}%%
ParserResult parseInteger(int p, int pe) {
@@ -500,7 +518,7 @@ public class Parser extends RubyObject {
main := '-'?
( ( ( '0' | [1-9][0-9]* ) '.' [0-9]+ ( [Ee] [+\-]?[0-9]+ )? )
| ( ( '0' | [1-9][0-9]* ) ( [Ee] [+\-]? [0-9]+ ) ) )
- ( ^[0-9Ee.\-] @exit );
+ ( ^[0-9Ee.\-]? @exit );
}%%
ParserResult parseFloat(int p, int pe) {
@@ -578,7 +596,7 @@ public class Parser extends RubyObject {
}
});
} catch (JumpException e) { }
- if (memoArray[1] != null) {
+ if (memoArray[1] != null) {
RubyClass klass = (RubyClass) memoArray[1];
if (klass.respondsTo("json_creatable?") &&
klass.callMethod(context, "json_creatable?").isTrue()) {
@@ -701,15 +719,14 @@ public class Parser extends RubyObject {
fhold;
fbreak;
}
+
+ pair = ignore* begin_name >parse_name ignore* name_separator
+ ignore* begin_value >parse_value;
+ next_pair = ignore* value_separator pair;
- a_pair = ignore*
- begin_name >parse_name
- ignore* name_separator ignore*
- begin_value >parse_value;
-
- main := begin_object
- (a_pair (ignore* value_separator a_pair)*)?
- ignore* end_object @exit;
+ main := (
+ begin_object (pair (next_pair)*)? ignore* end_object
+ ) @exit;
}%%
ParserResult parseObject(int p, int pe) {
@@ -789,7 +806,7 @@ public class Parser extends RubyObject {
ignore*;
}%%
- public IRubyObject parse() {
+ public IRubyObject parseStrict() {
int cs = EVIL;
int p, pe;
IRubyObject result = null;
@@ -806,6 +823,54 @@ public class Parser extends RubyObject {
}
}
+ %%{
+ machine JSON_quirks_mode;
+ include JSON_common;
+
+ write data;
+
+ action parse_value {
+ ParserResult res = parseValue(fpc, pe);
+ if (res == null) {
+ fhold;
+ fbreak;
+ } else {
+ result = res.result;
+ fexec res.p;
+ }
+ }
+
+ main := ignore*
+ ( begin_value >parse_value)
+ ignore*;
+ }%%
+
+ public IRubyObject parseQuirksMode() {
+ int cs = EVIL;
+ int p, pe;
+ IRubyObject result = null;
+
+ %% write init;
+ p = byteList.begin();
+ pe = p + byteList.length();
+ %% write exec;
+
+ if (cs >= JSON_quirks_mode_first_final && p == pe) {
+ return result;
+ } else {
+ throw unexpectedToken(p, pe);
+ }
+ }
+
+ public IRubyObject parse() {
+ if (parser.quirksMode) {
+ return parseQuirksMode();
+ } else {
+ return parseStrict();
+ }
+
+ }
+
/**
* Returns a subsequence of the source ByteList, based on source
* array byte offsets (i.e., the ByteList's own begin offset is not
diff --git a/java/src/json/ext/ParserService.java b/java/src/json/ext/ParserService.java
index f2ecae1..dde8834 100644
--- a/java/src/json/ext/ParserService.java
+++ b/java/src/json/ext/ParserService.java
@@ -1,6 +1,6 @@
/*
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
- *
+ *
* Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
* for details.
*/
diff --git a/java/src/json/ext/Utils.java b/java/src/json/ext/Utils.java
index f52ac8d..44d6a55 100644
--- a/java/src/json/ext/Utils.java
+++ b/java/src/json/ext/Utils.java
@@ -1,6 +1,6 @@
/*
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
- *
+ *
* Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
* for details.
*/