mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-03-23 09:14:00 +01:00
perl: fixed stream deserializer in pp.
This commit is contained in:
parent
953aa95c64
commit
2c9966a0a3
@ -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;
|
||||
|
@ -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';
|
||||
}
|
||||
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
}
|
||||
|
23
perl/t/12_stream_unpack3.t
Normal file
23
perl/t/12_stream_unpack3.t
Normal 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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user