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
[email protected] | CPAN ID: PEVANS
srand($,=" ");print sort{rand>0.5}grep{0.8>rand}qw(another Just hacker of Perl)
signature.asc
Description: Digital signature
