As always TIMTOWTDI, but personally I'd implement it as if I was reading a stream, i.e. with read. Either you give each class the ability to parse the binary representation of itself, or you implement the reading as a single function that just constructs objects of the corresponding class (this would make it easier if the sections aren't entirely independent of each other, like if you've got a checksum over multiple sections). I've chosen the latter here:

use warnings; use 5.012; # for "package BLOCK" syntax package MainHeader { use Moo; has foo => ( is => 'ro' ); } package ExtHeader { use Moo; has bar => ( is => 'ro' ); } package Section { use Moo; has type => ( is => 'ro' ); has quz => ( is => 'ro' ); } my $binfile = "\x01\x06Hello\0" ."\x02\x04\0\x12\x34\x56" ."\x13\x02\xBE\xEF"; sub binread { # helper function for read+unpack my ($fh, $bytes, $templ) = @_; read($fh, my $data, $bytes) == $bytes or die "failed to read $bytes bytes"; return unpack($templ, $data); } open my $fh, '<:raw', \$binfile or die $!; my @packets; while (!eof($fh)) { my ($type, $length) = binread($fh, 2, "CC"); if ($type == 0x01) { my ($foo) = binread($fh, $length, 'Z*'); my $hdr = MainHeader->new( foo => $foo ); push @packets, $hdr; } elsif ($type == 0x02) { my ($bar) = binread($fh, $length, 'N'); my $exthdr = ExtHeader->new( bar => $bar ); push @packets, $exthdr; } elsif ($type == 0x13) { my ($quz) = binread($fh, $length, 'n'); my $sect = Section->new( type => $type, quz => $quz ); push @packets, $sect; } else { die "Unknown packet type $type" } } close $fh; use Data::Dump; dd @packets; __END__ ( bless({ foo => "Hello" }, "MainHeader"), bless({ bar => 1193046 }, "ExtHeader"), bless({ quz => 48879, type => 19 }, "Section"), )

In reply to Re: Best way to a parse a big binary file by haukex
in thread Best way to a parse a big binary file by Dirk80

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.