summaryrefslogtreecommitdiff
path: root/src/json/ext/GeneratorState.java
diff options
context:
space:
mode:
authorCharles Oliver Nutter <headius@headius.com>2010-08-07 10:58:10 -0500
committerCharles Oliver Nutter <headius@headius.com>2010-08-07 10:58:10 -0500
commit914cca595ccaed53da6d94698c6095fed3648f19 (patch)
tree9a5be6d699d0350d5b2d609fdd5919b8728f0655 /src/json/ext/GeneratorState.java
parent36ba9064c646e32c9490f5cbd26f3f5848687bc8 (diff)
parent56f281e91ea596b46b48b80df57445fee6710590 (diff)
downloadjson-914cca595ccaed53da6d94698c6095fed3648f19.tar.gz
Merge remote branch 'mernen/master'
Diffstat (limited to 'src/json/ext/GeneratorState.java')
-rw-r--r--src/json/ext/GeneratorState.java64
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");
}
}
}