summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrsyuki <frsyuki@users.sourceforge.jp>2010-04-23 18:13:36 +0900
committerfrsyuki <frsyuki@users.sourceforge.jp>2010-04-23 18:13:36 +0900
commitb10a7367440a33c9675be8fa435c9b202ff0c4f8 (patch)
tree63745f5eae7c9684520839c63f422124749ac33b
parent60fbaf7612a5340de16ba98277ef01ffb80d1da0 (diff)
downloadmsgpack-python-b10a7367440a33c9675be8fa435c9b202ff0c4f8.tar.gz
ruby: fixese backward compatibility of streaming deserializer
-rw-r--r--ruby/msgpack_test.rb22
-rw-r--r--ruby/unpack.c34
2 files changed, 48 insertions, 8 deletions
diff --git a/ruby/msgpack_test.rb b/ruby/msgpack_test.rb
index 455aa40..45adf0b 100644
--- a/ruby/msgpack_test.rb
+++ b/ruby/msgpack_test.rb
@@ -218,6 +218,28 @@ class MessagePackTestFormat < Test::Unit::TestCase
assert_equal(parsed, 1)
end
+ it "streaming backward compatibility" do
+ obj = [{["a","b"]=>["c","d"]}, ["e","f"], "d"]
+ pac = MessagePack::Unpacker.new
+ buffer = ""
+ nread = 0
+ parsed = 0
+ obj.to_msgpack.split(//).each do |b|
+ buffer << b
+ nread = pac.execute(buffer, nread)
+ if pac.finished?
+ o = pac.data
+ assert_equal(obj, o)
+ parsed += 1
+ pac.reset
+ buffer.slice!(0, nread)
+ nread = 0
+ next unless buffer.empty?
+ end
+ end
+ assert_equal(parsed, 1)
+ end
+
private
def check(len, obj)
v = obj.to_msgpack
diff --git a/ruby/unpack.c b/ruby/unpack.c
index 73aeeeb..3a95e5a 100644
--- a/ruby/unpack.c
+++ b/ruby/unpack.c
@@ -389,25 +389,43 @@ static VALUE MessagePack_unpack(VALUE self, VALUE data)
}
+static VALUE MessagePack_Unpacker_execute_impl(VALUE self, VALUE data,
+ size_t from, size_t limit)
+{
+ UNPACKER(self, mp);
+
+ if(from >= limit) {
+ rb_raise(eUnpackError, "offset is bigger than data buffer size.");
+ }
+
+ int ret = template_execute_wrap(mp, data, limit, &from);
+
+ if(ret < 0) {
+ rb_raise(eUnpackError, "parse error.");
+ } else if(ret > 0) {
+ mp->user.finished = 1;
+ return ULONG2NUM(from);
+ } else {
+ mp->user.finished = 0;
+ return ULONG2NUM(from);
+ }
+}
+
/* compat */
static VALUE MessagePack_Unpacker_execute_limit(VALUE self, VALUE data,
VALUE off, VALUE limit)
{
CHECK_STRING_TYPE(data);
- UNPACKER(self, mp);
- size_t from = (size_t)NUM2ULONG(off);
- int ret = template_execute_wrap(mp, data, NUM2ULONG(limit), &from);
- return INT2FIX(ret);
+ return MessagePack_Unpacker_execute_impl(self, data,
+ (size_t)NUM2ULONG(off), (size_t)NUM2ULONG(limit));
}
/* compat */
static VALUE MessagePack_Unpacker_execute(VALUE self, VALUE data, VALUE off)
{
CHECK_STRING_TYPE(data);
- UNPACKER(self, mp);
- size_t from = (size_t)NUM2ULONG(off);
- int ret = template_execute_wrap(mp, data, RSTRING_LEN(data), &from);
- return INT2FIX(ret);
+ return MessagePack_Unpacker_execute_impl(self, data,
+ (size_t)NUM2ULONG(off), (size_t)RSTRING_LEN(data));
}
/* compat */