diff options
Diffstat (limited to 'java/src/json/ext/Parser.rl')
-rw-r--r-- | java/src/json/ext/Parser.rl | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index 1ad8f21..4d170e1 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -52,7 +52,8 @@ public class Parser extends RubyObject { 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; @@ -131,6 +132,10 @@ public class Parser extends RubyObject { * <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) @@ -157,7 +162,8 @@ public class Parser extends RubyObject { 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( @@ -489,13 +495,13 @@ public class Parser extends RubyObject { 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) : @@ -525,7 +531,9 @@ public class Parser extends RubyObject { 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; } @@ -540,16 +548,23 @@ public class Parser extends RubyObject { 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; @@ -616,7 +631,7 @@ public class Parser extends RubyObject { } } - 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()); } @@ -734,7 +749,7 @@ 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; |