[% setvar title enhanced groups in pack/unpack %]
Note: these documents may be out of date. Do not use as reference! |
To see what is currently happening visit http://www.perl6.org/
enhanced groups in pack/unpack
Maintainer: Ilya Zakharevich <ilya@math.ohio-state.edu> Date: 16 September 2000 Mailing List: perl6-language-data@perl.org Number: 248 Version: 1 Status: Developing
This RFC makes pack/unpack builtins able to handle non-flat lists. Four additional action-types in TEMPLATES cover most paradigms in binary storage of data: data groups, required group headers, position-specific "named" data, arbitrary-order fields.
Currently pack() encodes data supplied in a flat list, and unpack() extracts data into a flat list. This proposal introduces marked groups in TEMPLATES which allow to handle more complicated structured data.
A group is introduced by a type 'g'
followed by matched parentheses.
g(TEMPLATE)
behaves the same as the (TEMPLATE)
-group. (Syntactic sugar, optional);
g.(TEMPLATE) REST
"lookahead". On unpack(): stores a position in the string, extracts some
substring using TEMPLATE
, then restores the position and extract using
REST. On pack(): the inverse operation.
For example, in struct { short count, flags; char data[1];}
the count
is not immediately preceeding data
, thus one cannot use n/a*
to extract
the variable-length data
. But this works:
($flags, $data) = unpack <<EOP, $string g.( x[n] n ) # Skip count, extract flags, return back n x[n] # extract count, skip flags /a* # extract the data using 'count' EOP
g[TEMPLATE]
pack() expects the corresponding argument to be an array reference.
TEMPLATE
is applied to the data inside this array. unpack() extracts
data described by TEMPLATE
and puts it into an array reference;
g{TEMPLATE}
similar to g[TEMPLATE]
, but for hash references.
g\(TEMPLATE)
similar to g[TEMPLATE]
, but for scalar references.
K
"Packed string contains less data than the Perl data."
Should be used with a multiplier $LEN, as in K[3]int
. The following
$LEN characters of the template form the "key" (as in Hollerit (sp?) code).
For unpack() the "key" is put into the output list. For pack(), if
inside g{TEMPLATE}
: use the value of the given key as the next data to
pack:
pack 'g{ K[3]int N K[4]char C }', $hashref
acts the same as
pack 'g{ N C }', $hashref->{int}, $hashref->{char}
For pack() when not in g{TEMPLATE}
: skip the following argument (and
ignore the key!). Optional: a K!
variant: it is an error if
the skipped argument does not coincide with the key.
Check that the actions on pack() and unpack() are indeed inverse to each other!
k
"Packed string contains more data than the Perl data."
Opposite to K
: the syntax is the same, but on pack() the key is used as
if it were the next-argument-to-process. On unpack() the next extracted
value is not put in the output list. This creates "list46789"
:
pack 'k[4]list A* g[ A/(A)* ]', [6..9]
Optional: a k!
variant: it is an error if the skipped extracted data
does not coincide with the key.
(This is useful less often than K
, but needed time to time.)
None.
Straightforward.
RFC 142: Enhanced Pack/Unpack
RFC 246: pack/unpack uncontrovercial enhancements
RFC 247: pack/unpack C-like enhancements