summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Luz <dev@mernen.com>2010-08-09 04:57:56 -0300
committerDaniel Luz <dev@mernen.com>2010-08-09 05:02:56 -0300
commit9acbc624e599ed8a865c0dedfa4378526c123526 (patch)
tree7ea8b67d1f7666ae27d1987bf3bc89352babd25c
parent914cca595ccaed53da6d94698c6095fed3648f19 (diff)
parente8ef17ece7ddacbe7dde00ec3cb8a96401e1882c (diff)
downloadjson-9acbc624e599ed8a865c0dedfa4378526c123526.tar.gz
Merge branch 'master' (early part) into unified
-rw-r--r--ext/json/ext/generator/generator.c5
-rw-r--r--lib/json/pure/generator.rb132
-rwxr-xr-xtests/test_json_generate.rb17
3 files changed, 77 insertions, 77 deletions
diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c
index b4cb740..0617466 100644
--- a/ext/json/ext/generator/generator.c
+++ b/ext/json/ext/generator/generator.c
@@ -14,7 +14,7 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
i_pack, i_unpack, i_create_id, i_extend, i_key_p, i_aref, i_send,
- i_respond_to_p, i_match, i_keys, i_depth;
+ i_respond_to_p, i_match, i_keys, i_depth, i_dup;
/*
* Copyright 2001-2004 Unicode, Inc.
@@ -1043,7 +1043,7 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts)
if (NIL_P(CJSON_SAFE_STATE_PROTOTYPE)) {
CJSON_SAFE_STATE_PROTOTYPE = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
}
- return CJSON_SAFE_STATE_PROTOTYPE;
+ return rb_funcall(CJSON_SAFE_STATE_PROTOTYPE, i_dup, 0);
}
}
@@ -1406,6 +1406,7 @@ void Init_generator()
i_respond_to_p = rb_intern("respond_to?");
i_match = rb_intern("match");
i_keys = rb_intern("keys");
+ i_dup = rb_intern("dup");
#ifdef HAVE_RUBY_ENCODING_H
CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
i_encoding = rb_intern("encoding");
diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb
index 12959bf..335c6ae 100644
--- a/lib/json/pure/generator.rb
+++ b/lib/json/pure/generator.rb
@@ -112,7 +112,7 @@ module JSON
when Hash
new(opts)
else
- SAFE_STATE_PROTOTYPE
+ SAFE_STATE_PROTOTYPE.dup
end
end
@@ -167,7 +167,7 @@ module JSON
# generated JSON.
attr_accessor :depth
- def check_max_nesting(depth) # :nodoc:
+ def check_max_nesting # :nodoc:
return if @max_nesting.zero?
current_nesting = depth + 1
current_nesting > @max_nesting and
@@ -252,51 +252,41 @@ module JSON
# _state_ is a JSON::State object, that can also be used to configure the
# produced JSON string output further.
# _depth_ is used to find out nesting depth, to indent accordingly.
- def to_json(state = nil, depth = 0, *)
- if state
- state = State.from_state(state)
- state.check_max_nesting(depth)
- end
- json_transform(state, depth)
+ def to_json(state = nil, *)
+ state = State.from_state(state)
+ state.check_max_nesting
+ json_transform(state)
end
private
- def json_shift(state, depth)
- state and not state.object_nl.empty? or return ''
- state.indent * depth
+ def json_shift(state)
+ state.object_nl.empty? or return ''
+ state.indent * state.depth
end
- def json_transform(state, depth)
+ def json_transform(state)
delim = ','
- if state
- delim << state.object_nl
- result = '{'
- result << state.object_nl
- depth += 1
- first = true
- indent = state && !state.object_nl.empty?
- each { |key,value|
- result << delim unless first
- result << state.indent * depth if indent
- result << key.to_s.to_json(state, depth)
- result << state.space_before
- result << ':'
- result << state.space
- result << value.to_json(state, depth)
- first = false
- }
- depth -= 1
- result << state.object_nl
- result << state.indent * depth if indent if indent
- result << '}'
- else
- result = '{'
- result << map { |key,value|
- key.to_s.to_json << ':' << value.to_json
- }.join(delim)
- result << '}'
- end
+ delim << state.object_nl
+ result = '{'
+ result << state.object_nl
+ depth = state.depth += 1
+ first = true
+ indent = !state.object_nl.empty?
+ each { |key,value|
+ result << delim unless first
+ result << state.indent * depth if indent
+ result << key.to_s.to_json(state)
+ result << state.space_before
+ result << ':'
+ result << state.space
+ result << value.to_json(state)
+ first = false
+ }
+ depth = state.depth -= 1
+ result << state.object_nl
+ result << state.indent * depth if indent if indent
+ result << '}'
result
end
end
@@ -306,39 +296,32 @@ module JSON
# this Array instance.
# _state_ is a JSON::State object, that can also be used to configure the
# produced JSON string output further.
- # _depth_ is used to find out nesting depth, to indent accordingly.
- def to_json(state = nil, depth = 0, *)
- if state
- state = State.from_state(state)
- state.check_max_nesting(depth)
- end
- json_transform(state, depth)
+ def to_json(state = nil, *)
+ state = State.from_state(state)
+ state.check_max_nesting
+ json_transform(state)
end
private
- def json_transform(state, depth)
+ def json_transform(state)
delim = ','
- if state
- delim << state.array_nl
- result = '['
- result << state.array_nl
- depth += 1
- first = true
- indent = state && !state.array_nl.empty?
- each { |value|
- result << delim unless first
- result << state.indent * depth if indent
- result << value.to_json(state, depth)
- first = false
- }
- depth -= 1
- result << state.array_nl
+ delim << state.array_nl
+ result = '['
+ result << state.array_nl
+ depth = state.depth += 1
+ first = true
+ indent = !state.array_nl.empty?
+ each { |value|
+ result << delim unless first
result << state.indent * depth if indent
- result << ']'
- else
- '[' << map { |value| value.to_json }.join(delim) << ']'
- end
+ result << value.to_json(state)
+ first = false
+ }
+ depth = state.depth -= 1
+ result << state.array_nl
+ result << state.indent * depth if indent
+ result << ']'
end
end
@@ -350,15 +333,16 @@ module JSON
module Float
# Returns a JSON string representation for this Float number.
def to_json(state = nil, *)
+ state = State.from_state(state)
case
when infinite?
- if state && state.allow_nan?
+ if state.allow_nan?
to_s
else
raise GeneratorError, "#{self} not allowed in JSON"
end
when nan?
- if state && state.allow_nan?
+ if state.allow_nan?
to_s
else
raise GeneratorError, "#{self} not allowed in JSON"
@@ -374,9 +358,8 @@ module JSON
# This string should be encoded with UTF-8 A call to this method
# returns a JSON string encoded with UTF16 big endian characters as
# \u????.
- def to_json(*args)
- state, = *args
- state ||= State.from_state(state)
+ def to_json(state = nil, *args)
+ state = State.from_state(state)
if encoding == ::Encoding::UTF_8
string = self
else
@@ -392,9 +375,8 @@ module JSON
# This string should be encoded with UTF-8 A call to this method
# returns a JSON string encoded with UTF16 big endian characters as
# \u????.
- def to_json(*args)
- state, = *args
- state ||= State.from_state(state)
+ def to_json(state = nil, *args)
+ state = State.from_state(state)
if state.ascii_only?
'"' << JSON.utf8_to_json_ascii(self) << '"'
else
diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb
index 8dc804b..d67a4b2 100755
--- a/tests/test_json_generate.rb
+++ b/tests/test_json_generate.rb
@@ -164,4 +164,21 @@ EOT
assert_raises(GeneratorError) { pretty_generate([JSON::MinusInfinity]) }
assert_equal "[\n -Infinity\n]", pretty_generate([JSON::MinusInfinity], :allow_nan => true)
end
+
+ def test_depth
+ ary = []; ary << ary
+ assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
+ assert_raises(JSON::NestingError) { JSON.generate(ary) }
+ assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
+ assert_equal 0, JSON::FAST_STATE_PROTOTYPE.depth
+ assert_raises(JSON::NestingError) { JSON.fast_generate(ary) }
+ assert_equal 0, JSON::FAST_STATE_PROTOTYPE.depth
+ assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
+ assert_raises(JSON::NestingError) { JSON.pretty_generate(ary) }
+ assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
+ s = JSON.state.new
+ assert_equal 0, s.depth
+ assert_raises(JSON::NestingError) { ary.to_json(s) }
+ assert_equal 19, s.depth
+ end
end