perl: fixed stream deserializer in pp.

This commit is contained in:
tokuhirom 2010-09-18 09:44:32 +09:00
parent 953aa95c64
commit 2c9966a0a3
5 changed files with 57 additions and 25 deletions

View File

@ -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 (@{$self->{stack}} == 0) {
$self->{is_finished}++;
last LOOP;
}
}
$self->{pos} = $p;
if ( $len == $p ) {
$self->{ data } .= substr( $value, 0, $p );
$self->{ remain } = undef;
}
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;

View File

@ -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';
}

View File

@ -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++;

View File

@ -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;
}

View File

@ -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);
}