java/src/json/ext/Parser.rl in json_pure-2.0.4 vs java/src/json/ext/Parser.rl in json_pure-2.1.0
- old
+ new
@@ -50,11 +50,12 @@
private int maxNesting;
private boolean allowNaN;
private boolean symbolizeNames;
private RubyClass objectClass;
private RubyClass arrayClass;
- private RubyHash matchString;
+ private RubyClass decimalClass;
+ private RubyHash match_string;
private static final int DEFAULT_MAX_NESTING = 100;
private static final ByteList JSON_MINUS_INFINITY = new ByteList(ByteList.plain("-Infinity"));
// constant names in the JSON module containing those values
@@ -129,10 +130,14 @@
* <dd>Defaults to Hash.
*
* <dt><code>:array_class</code>
* <dd>Defaults to Array.
*
+ * <dt><code>:decimal_class</code>
+ * <dd>Specifies which class to use instead of the default (Float) when
+ * parsing decimal numbers. This class must accept a single string argument
+ * in its constructor.
* </dl>
*/
@JRubyMethod(name = "new", required = 1, optional = 1, meta = true)
public static IRubyObject newInstance(IRubyObject clazz, IRubyObject[] args, Block block) {
Parser parser = (Parser)((RubyClass)clazz).allocate();
@@ -155,11 +160,12 @@
this.symbolizeNames = opts.getBool("symbolize_names", false);
this.createId = opts.getString("create_id", getCreateId(context));
this.createAdditions = opts.getBool("create_additions", false);
this.objectClass = opts.getClass("object_class", runtime.getHash());
this.arrayClass = opts.getClass("array_class", runtime.getArray());
- this.matchString = opts.getHash("match_string");
+ this.decimalClass = opts.getClass("decimal_class", null);
+ this.match_string = opts.getHash("match_string");
if(symbolizeNames && createAdditions) {
throw runtime.newArgumentError(
"options :symbolize_names and :create_additions cannot be " +
" used in conjunction"
@@ -487,17 +493,17 @@
return -1;
}
return p;
}
-
+
RubyInteger createInteger(int p, int new_p) {
Ruby runtime = getRuntime();
ByteList num = absSubSequence(p, new_p);
return bytesToInum(runtime, num);
}
-
+
RubyInteger bytesToInum(Ruby runtime, ByteList num) {
return runtime.is1_9() ?
ConvertBytes.byteListToInum19(runtime, num, 10, true) :
ConvertBytes.byteListToInum(runtime, num, 10, true);
}
@@ -523,11 +529,13 @@
int new_p = parseFloatInternal(p, pe);
if (new_p == -1) {
res.update(null, p);
return;
}
- RubyFloat number = createFloat(p, new_p);
+ IRubyObject number = parser.decimalClass == null ?
+ createFloat(p, new_p) : createCustomDecimal(p, new_p);
+
res.update(number, new_p + 1);
return;
}
int parseFloatInternal(int p, int pe) {
@@ -538,20 +546,27 @@
%% write exec;
if (cs < JSON_float_first_final) {
return -1;
}
-
+
return p;
}
-
+
RubyFloat createFloat(int p, int new_p) {
Ruby runtime = getRuntime();
ByteList num = absSubSequence(p, new_p);
return RubyFloat.newFloat(runtime, dc.parse(num, true, runtime.is1_9()));
}
+ IRubyObject createCustomDecimal(int p, int new_p) {
+ Ruby runtime = getRuntime();
+ ByteList num = absSubSequence(p, new_p);
+ IRubyObject numString = runtime.newString(num.toString());
+ return parser.decimalClass.callMethod(context, "new", numString);
+ }
+
%%{
machine JSON_string;
include JSON_common;
write data;
@@ -614,11 +629,11 @@
}
}
}
}
- if (cs >= JSON_string_first_final && result != null) {
+ if (cs >= JSON_string_first_final && result != null) {
if (result instanceof RubyString) {
((RubyString)result).force_encoding(context, info.utf8.get());
}
res.update(result, p + 1);
} else {
@@ -732,10 +747,10 @@
action exit {
fhold;
fbreak;
}
-
+
pair = ignore* begin_name >parse_name ignore* name_separator
ignore* begin_value >parse_value;
next_pair = ignore* value_separator pair;
main := (