QUOTE
unpack TEMPLATE,EXPR
unpack does the reverse of pack: it takes a string and expands it out into a list of values. (In scalar context, it returns merely the first value produced.)
The string is broken into chunks described by the TEMPLATE. Each chunk is converted separately to a value. Typically, either the string is a result of pack, or the bytes of the string represent a C structure of some kind.
The TEMPLATE has the same format as in the pack function. Here's a subroutine that does substring:
sub substr {
my($what,$where,$howmuch) = @_;
unpack(\"x$where a$howmuch\", $what);
}
and then there's
sub ordinal { unpack(\"c\",$_[0]); } # same as ord()
In addition to fields allowed in pack(), you may prefix a field with a % to indicate that you want a -bit checksum of the items instead of the items themselves. Default is a 16-bit checksum. Checksum is calculated by summing numeric values of expanded values (for string fields the sum of ord($char) is taken, for bit fields the sum of zeroes and ones).
For example, the following computes the same number as the System V sum program:
$checksum = do {
local $/; # slurp!
unpack(\"%32C*\",<>) % 65535;
};
The following efficiently counts the number of set bits in a bit vector:
$setbits = unpack(\"%32b*\", $selectmask);
The p and P formats should be used with care. Since Perl has no way of checking whether the value passed to unpack() corresponds to a valid memory location, passing a pointer value that's not known to be valid is likely to have disastrous consequences.
If the repeat count of a field is larger than what the remainder of the input string allows, repeat count is decreased. If the input string is longer than one described by the TEMPLATE, the rest is ignored.
See pack for more examples and notes.
QUOTE
pack TEMPLATE,LIST
Takes a LIST of values and converts it into a string using the rules given by the TEMPLATE. The resulting string is the concatenation of the converted values. Typically, each converted value looks like its machine-level representation. For example, on 32-bit machines a converted integer may be represented by a sequence of 4 bytes.
The TEMPLATE is a sequence of characters that give the order and type of values, as follows:
a A string with arbitrary binary data, will be null padded.
A An ASCII string, will be space padded.
Z A null terminated (asciz) string, will be null padded.
b A bit string (ascending bit order inside each byte, like vec()).
B A bit string (descending bit order inside each byte).
h A hex string (low nybble first).
H A hex string (high nybble first).
c A signed char value.
C An unsigned char value. Only does bytes. See U for Unicode.
s A signed short value.
S An unsigned short value.
(This 'short' is _exactly_ 16 bits, which may differ from
what a local C compiler calls 'short'. If you want
native-length shorts, use the '!' suffix.)
i A signed integer value.
I An unsigned integer value.
(This 'integer' is _at_least_ 32 bits wide. Its exact
size depends on what a local C compiler calls 'int',
and may even be larger than the 'long' described in
the next item.)
l A signed long value.
L An unsigned long value.
(This 'long' is _exactly_ 32 bits, which may differ from
what a local C compiler calls 'long'. If you want
native-length longs, use the '!' suffix.)
n An unsigned short in \"network\" (big-endian) order.
N An unsigned long in \"network\" (big-endian) order.
v An unsigned short in \"VAX\" (little-endian) order.
V An unsigned long in \"VAX\" (little-endian) order.
(These 'shorts' and 'longs' are _exactly_ 16 bits and
_exactly_ 32 bits, respectively.)
q A signed quad (64-bit) value.
Q An unsigned quad value.
(Quads are available only if your system supports 64-bit
integer values _and_ if Perl has been compiled to support those.
Causes a fatal error otherwise.)
f A single-precision float in the native format.
d A double-precision float in the native format.
p A pointer to a null-terminated string.
P A pointer to a structure (fixed-length string).
u A uuencoded string.
U A Unicode character number. Encodes to UTF-8 internally.
Works even if C