summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Frank <flori@ping.de>2011-12-20 23:05:15 +0100
committerFlorian Frank <flori@ping.de>2011-12-20 23:05:15 +0100
commitaa7feb07b68e13ce2e024669873a8a6a89f304dc (patch)
tree6c11497c2c6e417cbb56705fb96c7366e6fc58fb
parentdec1286737e8d9c3d61ec9f6726a88d65592f48e (diff)
downloadjson-aa7feb07b68e13ce2e024669873a8a6a89f304dc.tar.gz
Support duck typed ruby array in JRuby as well
-rw-r--r--ext/json/ext/parser/parser.c10
-rw-r--r--java/src/json/ext/Parser.java16
-rw-r--r--java/src/json/ext/Parser.rl16
-rwxr-xr-xtests/test_json.rb30
4 files changed, 50 insertions, 22 deletions
diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c
index e262f09..c572a95 100644
--- a/ext/json/ext/parser/parser.c
+++ b/ext/json/ext/parser/parser.c
@@ -445,12 +445,12 @@ case 26:
if (cs >= JSON_object_first_final) {
if (json->create_additions) {
- VALUE klassname;
+ VALUE klassname;
if (NIL_P(json->object_class)) {
- klassname = rb_hash_aref(*result, json->create_id);
- } else {
- klassname = rb_funcall(*result, i_aref, 1, json->create_id);
- }
+ klassname = rb_hash_aref(*result, json->create_id);
+ } else {
+ klassname = rb_funcall(*result, i_aref, 1, json->create_id);
+ }
if (!NIL_P(klassname)) {
VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java
index 1ff25a6..579b047 100644
--- a/java/src/json/ext/Parser.java
+++ b/java/src/json/ext/Parser.java
@@ -1608,12 +1608,12 @@ static final int JSON_array_en_main = 1;
// this is guaranteed to be a RubyArray due to the earlier
// allocator test at OptionsReader#getClass
- RubyArray result;
- if (parser.arrayClass != getRuntime().getArray()) {
- result = (RubyArray)parser.arrayClass.newInstance(context,
- IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
- } else {
+ IRubyObject result;
+ if (parser.arrayClass == getRuntime().getArray()) {
result = RubyArray.newArray(getRuntime());
+ } else {
+ result = parser.arrayClass.newInstance(context,
+ IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
}
@@ -1712,10 +1712,10 @@ case 1:
p--;
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
} else {
- if (parser.arrayClass != getRuntime().getArray()) {
- result.callMethod(context, "<<", res.result);
+ if (parser.arrayClass == getRuntime().getArray()) {
+ ((RubyArray)result).append(res.result);
} else {
- result.append(res.result);
+ result.callMethod(context, "<<", res.result);
}
{p = (( res.p))-1;}
}
diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl
index bb6a38f..fd759f5 100644
--- a/java/src/json/ext/Parser.rl
+++ b/java/src/json/ext/Parser.rl
@@ -663,10 +663,10 @@ public class Parser extends RubyObject {
fhold;
fbreak;
} else {
- if (parser.arrayClass != getRuntime().getArray()) {
- result.callMethod(context, "<<", res.result);
+ if (parser.arrayClass == getRuntime().getArray()) {
+ ((RubyArray)result).append(res.result);
} else {
- result.append(res.result);
+ result.callMethod(context, "<<", res.result);
}
fexec res.p;
}
@@ -700,12 +700,12 @@ public class Parser extends RubyObject {
// this is guaranteed to be a RubyArray due to the earlier
// allocator test at OptionsReader#getClass
- RubyArray result;
- if (parser.arrayClass != getRuntime().getArray()) {
- result = (RubyArray)parser.arrayClass.newInstance(context,
- IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
- } else {
+ IRubyObject result;
+ if (parser.arrayClass == getRuntime().getArray()) {
result = RubyArray.newArray(getRuntime());
+ } else {
+ result = parser.arrayClass.newInstance(context,
+ IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
}
%% write init;
diff --git a/tests/test_json.rb b/tests/test_json.rb
index fe21475..c06fd19 100755
--- a/tests/test_json.rb
+++ b/tests/test_json.rb
@@ -219,13 +219,41 @@ class TC_JSON < Test::Unit::TestCase
end
end
- def test_parse_array_custom_class
+ class SubArrayWrapper
+ def initialize
+ @data = []
+ end
+
+ attr_reader :data
+
+ def [](index)
+ @data[index]
+ end
+
+ def <<(value)
+ @data << value
+ @shifted = true
+ end
+
+ def shifted?
+ @shifted
+ end
+ end
+
+ def test_parse_array_custom_array_derived_class
res = parse('[1,2]', :array_class => SubArray)
assert_equal([1,2], res)
assert_equal(SubArray, res.class)
assert res.shifted?
end
+ def test_parse_array_custom_non_array_derived_class
+ res = parse('[1,2]', :array_class => SubArrayWrapper)
+ assert_equal([1,2], res.data)
+ assert_equal(SubArrayWrapper, res.class)
+ assert res.shifted?
+ end
+
def test_parse_object
assert_equal({}, parse('{}'))
assert_equal({}, parse(' { } '))