App-MHFS
view release on metacpan or search on metacpan
lib/MHFS/BitTorrent/Bencoding.pm view on Meta::CPAN
my $type = $node->[0];
if(($type eq 'd') || ($type eq 'l')) {
$output .= $type;
my @nextitems = @{$node};
shift @nextitems;
push @nextitems, ['e'];
unshift @toenc, @nextitems;
}
elsif($type eq 'bstr') {
$output .= sprintf("%u:%s", length($node->[1]), $node->[1]);
}
elsif($type eq 'int') {
$output .= 'i'.$node->[1].'e';
}
elsif($type eq 'e') {
$output .= 'e';
}
else {
return undef;
}
}
return $output;
}
sub bdecode {
my ($contents, $foffset) = @_;
my @headnode = ('null');
my @nodestack = (\@headnode);
my $startoffset = $foffset;
while(1) {
# a bstr is always valid as it can be a dict key
if(substr($$contents, $foffset) =~ /^(0|[1-9][0-9]*):/) {
my $count = $1;
$foffset += length($count)+1;
my $bstr = substr($$contents, $foffset, $count);
my $node = ['bstr', $bstr];
$foffset += $count;
push @{$nodestack[-1]}, $node;
}
elsif((substr($$contents, $foffset, 1) eq 'e') &&
(($nodestack[-1][0] eq 'l') ||
(($nodestack[-1][0] eq 'd') &&((scalar(@{$nodestack[-1]}) % 2) == 1)))) {
pop @nodestack;
$foffset++;
}
elsif(($nodestack[-1][0] ne 'd') || ((scalar(@{$nodestack[-1]}) % 2) == 0)) {
my $firstchar = substr($$contents, $foffset++, 1);
if(($firstchar eq 'd') || ($firstchar eq 'l')) {
my $node = [$firstchar];
push @{$nodestack[-1]}, $node;
push @nodestack, $node;
}
elsif(substr($$contents, $foffset-1) =~ /^i(0|\-?[1-9][0-9]*)e/) {
my $node = ['int', $1];
$foffset += length($1)+1;
push @{$nodestack[-1]}, $node;
}
else {
say "bad elm $firstchar $foffset";
return undef;
}
}
else {
say "bad elm $foffset";
return undef;
}
if(scalar(@nodestack) == 1) {
return [$headnode[1], $foffset-$startoffset];
}
}
}
1;
( run in 0.328 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )