rem45acp
rem45acp

Reputation: 469

Perl - Pack Complex 16-bit Word

I have to pack a complicated message into a 16-bit word that is defined like so:

I can't seem to get the pack() command right. I want to pack: Error type E, Mode 7, Status Type B, Additional Status ON

my $msg = pack("n",
    pack("C", 0, 0, 0, 0, 1, 0, 0, 0), #error state
    pack("C", 7, 0, 1, 0, 1)
);

Perl doc, http://perldoc.perl.org/functions/pack.html, does not say about little/big endian when it comes to packing chars.

Upvotes: 1

Views: 267

Answers (2)

ikegami
ikegami

Reputation: 386706

pack produces 1 or more byte for each input, so it can't accept bits. Build your word first, then pass it to pack.

my $word = 0;

$word |= 1 << 0 if $error_type_A;
$word |= 1 << 1 if $error_type_B;
$word |= 1 << 2 if $error_type_C;
$word |= 1 << 3 if $error_type_D;
$word |= 1 << 4 if $error_type_E;
$word |= 1 << 5 if $error_type_F;
$word |= 1 << 6 if $error_type_G;
$word |= 1 << 7 if $error_type_H;

$word |= $mode << 8;

$word |= 1 << 12 if $status_type_A;
$word |= 1 << 13 if $status_type_B;
$word |= 1 << 14 if $status_type_C;

$word |= 1 << 15 if $reset;

pack 'n', $word

Upvotes: 1

John C
John C

Reputation: 4396

You could try using vec instead of pack. Eg:

vec($i, 0,1) = 1;               # set bit zero
print unpack('b*', $i), "\n";   # 10000000
vec($i, 1,1) = 1;               # set bit 1 
print unpack('b*', $i), "\n";   # 11000000
vec($i, 4,1) = 1;               # set bit 4
print unpack('b*', $i), "\n";   # 11001000
vec($i, 15,1) = 1;              # set bit 15
print unpack('b*', $i), "\n";   # 1100100000000001

Upvotes: 1

Related Questions