Parse::Binary::Nested: simple non-OO unpackf
[wormy.git] / Parse / Binary / Nested.pm
index 371a65b47dbf76ff9d9893a560c5e8a1e8f1fdf9..75c22fa897eacaa3335cccec230722f6db603d02 100644 (file)
@@ -5,14 +5,18 @@ use strict;
 use warnings;
 
 use Carp;
 use warnings;
 
 use Carp;
+use Exporter qw(import);
 
 
-our $VERSION = '1.02';
+our $VERSION = '1.10';
+our @EXPORT_OK = qw(unpackf);
 
 sub new {
        my ($class, $format) = @_;
 
 sub new {
        my ($class, $format) = @_;
+       ref $format
+               or $format = [0 => $format];
        ref $format eq 'ARRAY'
                or croak "Invalid Parse::Binary::Nested format: should be an array ref";
        ref $format eq 'ARRAY'
                or croak "Invalid Parse::Binary::Nested format: should be an array ref";
-       bless $format, $class;
+       bless [$format, $class->template($format)], $class;
 }
 
 sub template {
 }
 
 sub template {
@@ -39,14 +43,15 @@ sub convert {
        # map flat results into a named and nested hash
        my %res;
        $pos ||= \(my $_pos);
        # map flat results into a named and nested hash
        my %res;
        $pos ||= \(my $_pos);
-       while (my ($field, $template) = splice @$format, 0, 2) {
+       for (my $i = 0; $i < $#$format; $i += 2) {
+               my ($field, $template) = @$format[$i, $i+1];
                if (ref $template eq 'ARRAY') {
                        my ($count, @subformat) = @$template;
                        $$pos++ if $count eq 'C';
                        my $max = $count =~ s/^(\d+)// ? $1 : 0;
                        $count = !$count ? $max
                                : $count eq '*' ? $res{levelcount}->{total} : shift @$data;
                if (ref $template eq 'ARRAY') {
                        my ($count, @subformat) = @$template;
                        $$pos++ if $count eq 'C';
                        my $max = $count =~ s/^(\d+)// ? $1 : 0;
                        $count = !$count ? $max
                                : $count eq '*' ? $res{levelcount}->{total} : shift @$data;
-                       $res{$field}->[$_] = $self->convert([@subformat], $data, $pos)
+                       $res{$field}->[$_] = $self->convert(\@subformat, $data, $pos)
                                for 0 .. ($max || $count)-1;
                        splice @{ $res{$field} }, $count if $max > $count;
                        $res{$field} = $res{$field}->[0] if $max == 1;
                                for 0 .. ($max || $count)-1;
                        splice @{ $res{$field} }, $count if $max > $count;
                        $res{$field} = $res{$field}->[0] if $max == 1;
@@ -108,9 +113,11 @@ sub convert {
 }
 
 sub unpackf {
 }
 
 sub unpackf {
-       my ($self, $input) = @_;
-       my @data = unpack $self->template($self), $input;
-       return $self->convert([@$self], \@data);
+       my ($format, $input) = @_;
+       my $self = UNIVERSAL::isa($format, __PACKAGE__) ? $format
+               : __PACKAGE__->new($format);
+       my @data = unpack $self->[1], $input;
+       return $self->convert($self->[0], \@data);
 }
 
 1;
 }
 
 1;
@@ -121,7 +128,9 @@ Parse::Binary::Nested - Structured unpack
 
 =head1 SYNOPSIS
 
 
 =head1 SYNOPSIS
 
-       use Parse::Binary::Nested;
+       use Parse::Binary::Nested qw(unpackf);
+       my $data = unpackf([message => 'Z*'], "hi\0");
+
        my $parser = Parser::Binary::Nested->new([
                foos => [
                        'C', # count
        my $parser = Parser::Binary::Nested->new([
                foos => [
                        'C', # count
@@ -130,8 +139,7 @@ Parse::Binary::Nested - Structured unpack
                ],
                trail => 'a*',
        ]);
                ],
                trail => 'a*',
        ]);
-       
-       my $data = $parser->unpackf("\1foo\0.rest");
+       $data = $parser->unpackf("\1foo\0.rest");
        print $data->{foos}->[0]->{message};
 
 =head1 DESCRIPTION
        print $data->{foos}->[0]->{message};
 
 =head1 DESCRIPTION