1 package Parse::Binary::Nested;
11 my ($class, $format) = @_;
12 ref $format eq 'ARRAY'
13 or croak "Invalid Parse::Binary::Nested format: should be an array ref";
14 bless $format, $class;
18 my ($self, $format) = @_;
19 # total (flattened) unpack template from nested format definitions
21 my $value = $format->[-($_ << 1) - 1];
22 if (ref $value eq 'ARRAY') {
23 my $count = $value->[0];
24 $value = $self->template($value);
25 $value = $count =~ s/^([*\d]+)// ? "$count($value)$1"
26 : $count."X[$count]$count/($value)";
29 $value =~ s/=\d*//g; # hardcoded values
30 $value =~ s/^C(a)(\d+)/$1 . ($2 + 1)/e; # length prefix
33 } reverse 0 .. ($#$format - 1) >> 1;
37 my ($self, $format, $data) = @_;
38 # map flat results into a named and nested hash
40 while (my ($field, $template) = splice @$format, 0, 2) {
41 if (ref $template eq 'ARRAY') {
42 my ($count, @subformat) = @$template;
43 my $max = $count =~ s/^(\d+)// ? $1 : 0;
44 $count = !$count ? $max
45 : $count eq '*' ? $res{levelcount}->{total} : shift @$data;
46 $res{$field}->[$_] = $self->convert([@subformat], $data) for 0 .. ($max || $count)-1;
47 splice @{ $res{$field} }, $count if $max > $count;
48 $res{$field} = $res{$field}->[0] if $max == 1;
51 elsif ($template =~ /^Ca/) {
52 $data->[0] = unpack 'C/a', $data->[0];
54 elsif ($template =~ /^(?:[xX]\d*)*$/) {
57 elsif ($template =~ /=(\d+)?/) {
61 $res{$field} = shift @$data;
67 my ($self, $input) = @_;
68 my @data = unpack $self->template($self), $input;
69 return $self->convert([@$self], \@data);
76 Parse::Binary::Nested - Structured unpack
80 use Parse::Binary::Nested;
81 my $parser = Parser::Binary::Nested->new([
90 my $data = $parser->unpackf("\1foo\0.rest");
91 print $data->{foos}->[0]->{message};
95 Converts a string into a hash of values, just like C<unpack>
96 except that it allows you to name and nest the resulting elements.
98 Format declarations are simalar to C<pack> templates,
99 with the following additions:
105 An array ref groups additional declarations,
106 with the first value specifying a repetition. If this count is variable,
107 the resulting value will be an array ref of hashes.
109 repeat => ['C', name => 'a*', value => 'S']
111 With a count of 1, it will return only a hash ref,
112 thereby simply grouping declarations:
115 test => [1, foo => 'C']
119 A template value of C<Ca$length> is recognised as a length-preceded string
120 with a constant (maximal) size, and will return only the string adjusted
122 This behaviour is very similar to C<(C/a@x$length)>, except that it never reads
123 more than the given number of bytes.
127 Hardcoded values can be inserted using C<=$number> values.
128 This can for example be useful to retain forwards-compatibility:
131 type => '=1', # nothing read
144 Mischa POSLAWSKY <perl@shiar.org>