summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortokuhirom <tokuhirom@gmail.com>2010-09-18 09:44:32 +0900
committertokuhirom <tokuhirom@gmail.com>2010-09-18 09:44:32 +0900
commit2c9966a0a304dc4bdb5fc003100ec37b2ec3d70a (patch)
tree4625a0fe97551f3440d85316e6fd200150d0c002
parent953aa95c648fef85f9c11c5ed251f3ddab988a83 (diff)
downloadmsgpack-python-2c9966a0a304dc4bdb5fc003100ec37b2ec3d70a.tar.gz
perl: fixed stream deserializer in pp.
-rw-r--r--perl/lib/Data/MessagePack/PP.pm46
-rw-r--r--perl/t/03_stream_unpack.t4
-rw-r--r--perl/t/09_stddata.t1
-rw-r--r--perl/t/10_splitted_bytes.t6
-rw-r--r--perl/t/12_stream_unpack3.t23
5 files changed, 56 insertions, 24 deletions
diff --git a/perl/lib/Data/MessagePack/PP.pm b/perl/lib/Data/MessagePack/PP.pm
index 6a06c3c..0dd6427 100644
--- a/perl/lib/Data/MessagePack/PP.pm
+++ b/perl/lib/Data/MessagePack/PP.pm
@@ -370,7 +370,7 @@ package
use strict;
sub new {
- bless { stack => [] }, shift;
+ bless { pos => 0 }, shift;
}
@@ -384,25 +384,30 @@ sub execute_limit {
sub execute {
my ( $self, $data, $offset, $limit ) = @_;
- my $value = substr( $data, $offset || 0, $limit ? $limit : length $data );
+ $offset ||= 0;
+ my $value = substr( $data, $offset, $limit ? $limit : length $data );
my $len = length $value;
+ $self->{data} .= $value;
+ local $self->{stack} = [];
+
$p = 0;
- while ( $len > $p ) {
- _count( $self, $value ) or last;
+ LOOP: while ( length($self->{data}) > $p ) {
+ _count( $self, $self->{data} ) or last;
- if ( @{ $self->{stack} } > 0 ) {
- pop @{ $self->{stack} } if --$self->{stack}->[-1] == 0;
+ while ( @{ $self->{stack} } > 0 && --$self->{stack}->[-1] == 0) {
+ pop @{ $self->{stack} };
}
- }
- if ( $len == $p ) {
- $self->{ data } .= substr( $value, 0, $p );
- $self->{ remain } = undef;
+ if (@{$self->{stack}} == 0) {
+ $self->{is_finished}++;
+ last LOOP;
+ }
}
+ $self->{pos} = $p;
- return $p;
+ return $p + $offset;
}
@@ -424,7 +429,9 @@ sub _count {
$num = $byte & ~0x90;
}
- push @{ $self->{stack} }, $num + 1;
+ if (defined($num) && $num > 0) {
+ push @{ $self->{stack} }, $num + 1;
+ }
return 1;
}
@@ -443,7 +450,9 @@ sub _count {
$num = $byte & ~0x80;
}
- push @{ $self->{stack} }, $num * 2 + 1; # a pair
+ if ($num > 0) {
+ push @{ $self->{stack} }, $num * 2 + 1; # a pair
+ }
return 1;
}
@@ -511,22 +520,19 @@ sub _count {
sub data {
- my $data = Data::MessagePack->unpack( $_[0]->{ data } );
- $_[0]->reset;
- return $data;
+ return Data::MessagePack->unpack( substr($_[0]->{ data }, 0, $_[0]->{pos}) );
}
sub is_finished {
my ( $self ) = @_;
- ( scalar( @{ $self->{stack} } ) or defined $self->{ remain } ) ? 0 : 1;
+ return $self->{is_finished};
}
-
sub reset :method {
- $_[0]->{ stack } = [];
$_[0]->{ data } = undef;
- $_[0]->{ remain } = undef;
+ $_[0]->{ pos } = 0;
+ $_[0]->{ is_finished } = 0;
}
1;
diff --git a/perl/t/03_stream_unpack.t b/perl/t/03_stream_unpack.t
index a4ab4eb..646fc24 100644
--- a/perl/t/03_stream_unpack.t
+++ b/perl/t/03_stream_unpack.t
@@ -37,7 +37,7 @@ for (my $i=0; $i<scalar(@dat); ) {
for (1..5) {
$up->execute("\xc0", 0); # nil
}
- ok $up->is_finished;
- is_deeply $up->data, [undef, undef, undef, undef, undef];
+ ok $up->is_finished, 'finished';
+ is_deeply $up->data, [undef, undef, undef, undef, undef], 'array, is_deeply';
}
diff --git a/perl/t/09_stddata.t b/perl/t/09_stddata.t
index a618787..f98d696 100644
--- a/perl/t/09_stddata.t
+++ b/perl/t/09_stddata.t
@@ -32,6 +32,7 @@ for my $mpac($mpac1, $mpac2) {
my $i = 0;
while($offset < length($mpac)) {
$offset = $mps->execute($mpac, $offset);
+ ok $mps->is_finished, "data[$i] : is_finished";
is_deeply $mps->data, $data[$i], "data[$i]";
$mps->reset;
$i++;
diff --git a/perl/t/10_splitted_bytes.t b/perl/t/10_splitted_bytes.t
index 232d870..15598f4 100644
--- a/perl/t/10_splitted_bytes.t
+++ b/perl/t/10_splitted_bytes.t
@@ -27,12 +27,14 @@ foreach my $size(1 .. 16) {
open my $stream, '<:bytes :scalar', \$packed;
binmode $stream;
my $buff;
+ my $done = 0;
while( read($stream, $buff, $size) ) {
#note "buff: ", join " ", map { unpack 'H2', $_ } split //, $buff;
- $up->execute($buff);
+ $done = $up->execute($buff);
}
- ok $up->is_finished, 'is_finished';
+ is $done, length($packed);
+ ok $up->is_finished, "is_finished: $size";
my $data = $up->data;
is_deeply $data, $input;
}
diff --git a/perl/t/12_stream_unpack3.t b/perl/t/12_stream_unpack3.t
new file mode 100644
index 0000000..118acc3
--- /dev/null
+++ b/perl/t/12_stream_unpack3.t
@@ -0,0 +1,23 @@
+use strict;
+use warnings;
+use Data::MessagePack;
+use Test::More;
+use t::Util;
+
+my @input = (
+ +[[]],
+ [[],[]],
+ [{"a" => 97},{"a" => 97}],
+ [{"a" => 97},{"a" => 97},{"a" => 97}],
+);
+
+plan tests => @input * 2;
+
+for my $input (@input) {
+ my $packed = Data::MessagePack->pack($input);
+ my $up = Data::MessagePack::Unpacker->new();
+ $up->execute($packed, 0);
+ ok $up->is_finished, 'finished';
+ is_deeply($up->data, $input);
+}
+