crsuarezf
crsuarezf

Reputation: 1271

Unpack function requirement in Perl for varying data sizes

I have a function in Perl that reads a packet from a template in this way:

sub read_packet {
  my $contents = shift;
  my @decode = unpack('nnnN', $contents);

  my $version = $decode[0];
  my $identifier = $decode[1];
  my $type = $decode[2];
  my $size = $decode [3];

  @contents = ($version, $identifier, $type, $size);

  return (@contents);
}

A change was required to the template in the unpack function. Now $identifier must support 32 bits, so according to PerlMonks: Pack/Unpack Tutorial (aka How the System Stores Data) (N) -> n,N A 16/32 bit value in "network" (big-endian) order.

So the function was rewritten doing this small change. Now, the program that sends the "packet" could be sending 16/32 bit values. The customer required from me to support both 16/32 bit. What can I do to know when a packet contains an 16 or 32 bit identifier?

Upvotes: 2

Views: 202

Answers (2)

ikegami
ikegami

Reputation: 385917

When the protocol changed in an incompatible manner, the version should have been changed as well. If so, you can use the following:

sub read_packet {
  my $contents = shift;
  (my $version, $contents) = unpack('na*', $contents);

  if ($version < X) {
     return ( $version, unpack('nnN', $rest) );
  } else {
     return ( $version, unpack('NnN', $rest) );
  }
}

Otherwise, you'll have the base it on the size of the packet. However, that requires the size of the packet to be communicated, and not always the case. Fortunately, it does appear to be the case here, so you can use the following:

sub read_packet {
  my $contents = shift;
  return unpack(length($contents) < 12 ? 'nnnN' : 'nNnN', $contents);
}

Upvotes: 2

Borodin
Borodin

Reputation: 126722

If those four fields are all that the packet contains then you can check the length of $contents

  • If the format is nnnN then the length will be 2 + 2 + 2 + 4 = 10 bytes

  • If the format is nNnN then the length will be 2 + 4 + 2 + 4 = 12 bytes

However, if there is data following those four fields then you must try the most commonunpack template and check the result for sanity, using the alternative template if it fails

Upvotes: 5

Related Questions