diff options
author | Charles Oliver Nutter <headius@headius.com> | 2010-08-07 10:58:10 -0500 |
---|---|---|
committer | Charles Oliver Nutter <headius@headius.com> | 2010-08-07 10:58:10 -0500 |
commit | 914cca595ccaed53da6d94698c6095fed3648f19 (patch) | |
tree | 9a5be6d699d0350d5b2d609fdd5919b8728f0655 /src/json/ext/GeneratorState.java | |
parent | 36ba9064c646e32c9490f5cbd26f3f5848687bc8 (diff) | |
parent | 56f281e91ea596b46b48b80df57445fee6710590 (diff) | |
download | json-914cca595ccaed53da6d94698c6095fed3648f19.tar.gz |
Merge remote branch 'mernen/master'
Diffstat (limited to 'src/json/ext/GeneratorState.java')
-rw-r--r-- | src/json/ext/GeneratorState.java | 64 |
1 files changed, 47 insertions, 17 deletions
diff --git a/src/json/ext/GeneratorState.java b/src/json/ext/GeneratorState.java index 107a204..63263e8 100644 --- a/src/json/ext/GeneratorState.java +++ b/src/json/ext/GeneratorState.java @@ -77,6 +77,11 @@ public class GeneratorState extends RubyObject { private boolean asciiOnly = DEFAULT_ASCII_ONLY; static final boolean DEFAULT_ASCII_ONLY = false; + /** + * The current depth (inside a #to_json call) + */ + private int depth = 0; + static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klazz) { return new GeneratorState(runtime, klazz); @@ -176,6 +181,7 @@ public class GeneratorState extends RubyObject { this.maxNesting = orig.maxNesting; this.allowNaN = orig.allowNaN; this.asciiOnly = orig.asciiOnly; + this.depth = orig.depth; return this; } @@ -184,7 +190,7 @@ public class GeneratorState extends RubyObject { */ @JRubyMethod public IRubyObject generate(ThreadContext context, IRubyObject obj) { - RubyString result = Generator.generateJson(context, obj, this, 0); + RubyString result = Generator.generateJson(context, obj, this); if (!objectOrArrayLiteral(result)) { throw Utils.newException(context, Utils.M_GENERATOR_ERROR, "only generation of JSON objects or arrays allowed"); @@ -323,6 +329,13 @@ public class GeneratorState extends RubyObject { return context.getRuntime().newBoolean(maxNesting != 0); } + /** + * Returns the maximum level of nesting configured for this state. + */ + public int getMaxNesting() { + return maxNesting; + } + @JRubyMethod(name="max_nesting") public RubyInteger max_nesting_get(ThreadContext context) { return context.getRuntime().newFixnum(maxNesting); @@ -352,14 +365,26 @@ public class GeneratorState extends RubyObject { return context.getRuntime().newBoolean(asciiOnly); } + public int getDepth() { + return depth; + } + + @JRubyMethod(name="depth") + public RubyInteger depth_get(ThreadContext context) { + return context.getRuntime().newFixnum(depth); + } + + @JRubyMethod(name="depth=") + public IRubyObject depth_set(IRubyObject vDepth) { + depth = RubyNumeric.fix2int(vDepth); + return vDepth; + } + private ByteList prepareByteList(ThreadContext context, IRubyObject value) { RubyString str = value.convertToString(); - IRubyObject encoding = str.encoding(context); - if (encoding != null) { - RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); - if (encoding != info.utf8) { - str = (RubyString)str.encode(context, info.utf8); - } + RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); + if (info.encodingsSupported() && str.encoding(context) != info.utf8) { + str = (RubyString)str.encode(context, info.utf8); } return str.getByteList().dup(); } @@ -374,7 +399,7 @@ public class GeneratorState extends RubyObject { */ @JRubyMethod public IRubyObject configure(ThreadContext context, IRubyObject vOpts) { - OptionsReader opts = OptionsReader.withStrings(context, vOpts); + OptionsReader opts = new OptionsReader(context, vOpts); ByteList indent = opts.getString("indent"); if (indent != null) this.indent = indent; @@ -395,6 +420,8 @@ public class GeneratorState extends RubyObject { allowNaN = opts.getBool("allow_nan", DEFAULT_ALLOW_NAN); asciiOnly = opts.getBool("ascii_only", DEFAULT_ASCII_ONLY); + depth = opts.getInt("depth", 0); + return this; } @@ -418,15 +445,18 @@ public class GeneratorState extends RubyObject { 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("max_nesting"), max_nesting_get(context)); + result.op_aset(context, runtime.newSymbol("depth"), depth_get(context)); return result; } - /** - * Returns the maximum level of nesting configured for this state. - * @return - */ - public int getMaxNesting() { - return maxNesting; + public int increaseDepth() { + depth++; + checkMaxNesting(); + return depth; + } + + public int decreaseDepth() { + return --depth; } /** @@ -434,10 +464,10 @@ public class GeneratorState extends RubyObject { * @param context * @param depth The corrent depth */ - void checkMaxNesting(ThreadContext context, int depth) { + private void checkMaxNesting() { if (maxNesting != 0 && depth > maxNesting) { - throw Utils.newException(context, Utils.M_NESTING_ERROR, - "nesting of " + depth + " is too deep"); + throw Utils.newException(getRuntime().getCurrentContext(), + Utils.M_NESTING_ERROR, "nesting of " + depth + " is too deep"); } } } |