# main # my $t0 = Benchmark->new(); my $FEED; ($go{file}) ? open $FEED, "<:perlio", $go{file} : open $FEED, "<&", *STDIN; binmode $FEED; my %vtmf_type = ( 0 => \&read_int, 1 => \&read_byte, 2 => \&var_length, 3 => \&read_long, 4 => sub { return 0 }, 5 => \&escape, 6 => \&var_length, 7 => \&read_price, __DEFAULT__ => sub { $log->warn("skipping message"); return ('', 255) } ); my $message_length_bin; while (read $FEED, $message_length_bin, 2) { my $message_length = unpack 'n', $message_length_bin; my $tag_bin; while (read $FEED, $tag_bin, 2) { my $tag_field = unpack 'B16', $tag_bin; my $type = oct('0b' . substr $tag_field, 0, 3); my $tag = substr $tag_field, 3, 16; my ($value, $tag_length) = ($vtmf_type{$type} || $vtmf_type{__DEFAULT__})->($FEED); print oct('0b' . $tag) . '=' . $value . ','; $message_length -= 2 + $tag_length; last unless $message_length; } print "\n"; } my $t1 = Benchmark->new(); if ($go{time}) { my $td = timediff($t1, $t0); $log->info("The code took: ", timestr($td)); } exit 0; # subroutines # sub read_int { my $handle = shift; read $FEED, my($num_bin), 4; my $value = hex unpack "H*", $num_bin; return ($value, 4); } sub read_long { my $handle = shift; read $handle, my($num_bin), 8; my ($hi, $lo) = map { hex $_ } (unpack 'A8A8', unpack 'H16', $num_bin); my $num = $hi * 2**32 + $lo; return ($num, 8); } sub read_price { my $handle = shift; read $handle, my ($num_bin), 8; my ($hi, $lo) = map { hex $_ } (unpack 'A8A8', unpack 'H16', $num_bin); my $num = $hi * 2**32 + $lo; $num /= 10**7; return ($num, 8); } sub read_byte { my $handle = shift; read $handle, my($num_bin), 1; my $val = unpack 'A', $num_bin; return ($val, 1); } sub escape { return ('', 0); } sub var_length { my $handle = shift; read $handle, my($length_bin), 1; my $length = hex unpack 'H2', $length_bin; read $handle, my($value_bin), $length; my $value = unpack "A${length}", $value_bin; return ($value, $length + 1); }