Data-ParseBinary

 view release on metacpan or  search on metacpan

lib/Data/ParseBinary.pm  view on Meta::CPAN

        Byte("relative_offset"),
        Anchor("absolute_position"),
        Pointer(sub { $_->ctx->{absolute_position} + $_->ctx->{relative_offset} }, Byte("data")),
    );
    $data = $s->parse("\x05\x00\x00\x00\x00\x00\x03\x00\x00\x00\xff");
    # $data is { absolute_position=> 7, relative_offset => 3, data => 255, padding_length => 5 }

Anchor saves the current location in the stream, enable the Pointer to jump to location
relative to it.

Also, $_->stream->tell will point you to the current location, giving the ability for
relative location without using Anchor. The above construct is quevalent to:

    $s = Struct("foo",
        Byte("padding_length"),
        Padding(sub { $_->ctx->{padding_length} } ),
        Byte("relative_offset"),
        Pointer(sub { $_->stream->tell + $_->ctx->{relative_offset} }, Byte("data")),
    );

=head3 Peek
    
    $s = Struct("foo",
        Byte("a"),
        Peek(Byte("b")),
        Byte("c"),
    );

Peek is like Pointer with two differences: one that it is no-op on build.
second the location is calculated relative to the current location,
while with Pointer it's absolute position.

If no distance is supplied, zero is assumed. it is posible to supply
constant distance, (i.e. 5) or code ref. Examples:

    Peek(UBInt16("b"), 5) # Peek 5 bytes ahead
    Peek(UBInt16("b"), sub { $_->ctx->{this_far} }) # calculated number of bytes ahead    

=head2 Strings

=head3 Char

The Char construct represent a single character. This can mean one byte, or
if it have encoding attached, a multi-byte character.

    $s = Char("c", "utf8");
    $s->build("\x{1abcd}");
    # returns "\xf0\x9a\xaf\x8d"

The allowded encodings are:

    UTF-32LE
    UTF-32BE
    UTF-16LE
    UTF-16BE
    UTF-8
    utf8
    or any single-byte encoding supported by the Encode module
    for example: iso-8859-8

If you don't know if your unicode string is BE or LE, then it's probably BE.

=head3 String (constant length / meta)

A string with constant length:

    String("foo", 5)->parse("hello")
    # returns "hello"

A string with variable length, and encoding:

    String("description", sub { $_->ctx->{description_size} }, encoding => 'UTF-16LE' )

The string length is specified in *characters*, not bytes.

=head3 PaddedString

A Padded string with constant length:

    $s = PaddedString("foo", 10, padchar => "X", paddir => "right");
    $s->parse("helloXXXXX") # return "hello"
    $s->build("hello") # return 'helloXXXXX'

I think that it speaks for itself. only that paddir can be one of qw{right left center},
and there can be also trimdir that can be "right" or "left".

When encoding is supplied, for example:

    $s = PaddedString("foo", 10, encoding => "utf8");

The String length is still specified in *bytes*, not characters. If anyone ever
encouter a padded constant length string with multi byte encoding that it's length is
specified in characters, please send me an email.

=head3 PascalString

PascalString - String with a length marker in the beginning:

    $s = PascalString("foo");
    $s->build("hello world") # returns "\x0bhello world"

The marker can be of any kind:

    $s = PascalString("foo", \&UBInt16);
    $s->build("hello") # returns "\x00\x05hello"

(the marker can be pointer to any function that get a name and return construct.
And on parse that construct should return a value. like the built-in primitives for example)

With encoding:

    $s = PascalString("foo", undef, "utf8");

The string length is specified in *characters*, not bytes.

=head3 CString

And finally, CString:

    $s = CString("foo");
    $s->parse("hello\x00") # returns 'hello'



( run in 0.669 second using v1.01-cache-2.11-cpan-39bf76dae61 )