I find lately I've been doing a lot of binary protocol work, taking
messages that live in TCP streams or files or similar, and doing lots of
pack()/unpack() on them.

I find what works best is to wrap up a message into an object, so I can
do things like:

  my $field = $message->pull_int();

where

 sub pull_int
 {
    my $self = shift;
    my $i = unpack( "N", $self->{buffer} );
    substr( $i, 0, 4 ) = "";
    return $i;
 }

this strikes me as more than a little inelegant. That 4 floating about
there is a "magic" constant. Things like this get worse

 sub pull_strz
 {
    my $self = shift;
    my $s = unpack( "Z*", $self->{buffer} );
    substr( $i, 0, len($s) + 1 ) = "";
    return $s;
 }

Is there some neater way to do this? Can I either:

 a: Get unpack() to consume bytes from the LVALUE

 b: Ask unpack() how much it ate in a generic fashion?

One suggestion I've seen would be to

 sub unpack_and_eat
 {
    my ( $format, $str ) = @_;
    my @values = unpack( $format . " A*", $str );
    $_[1] = pop @values;
    return @values;
 }

but that seems a bit messy, all that O(n^2) copying about the place if
we're going to, say, pull lots of small ints out of a really big buffer.

There surely has to be a better way...

-- 
Paul "LeoNerd" Evans

leon...@leonerd.org.uk     |    CPAN ID: PEVANS
srand($,=" ");print sort{rand>0.5}grep{0.8>rand}qw(another Just hacker of Perl)

Attachment: signature.asc
Description: Digital signature

Reply via email to