exodist has asked for the wisdom of the Perl Monks concerning the following question:

I have been reading the pack and unpack syntax a while now. I can figure out some simple things like basic strings, integers, etc. but I am having trouble formulating a template for the following: I have a scalar with 512 bytes just read in from a hard drive. the bytes are as follows:
16 - Binary data (a UUID) - No idea how to put this in template 16 - Binary data (another UUID) - same 16 - string - A16? 1 byte - a number between 0 and 255 - C1 8 bytes - a 64 bit number - Q1 8 bytes - a 64 bit number - Q1 8 bytes - a 64 bit number - Q1 2 bytes - a 16 bit number - S1
so my template so far looks like this: '??A16CQQQS'
and my overall line would be: @Values = unpack('??A16CQQQS', $Buffer); but my suspicion is that the A16 will give me 16 separate array elements, unfortunately without any idea how to do the first 2 16 byte values (which need to remain binary, completely unchanged)I cannot test it easily. as well I wonder if I can replace 'QQQ' with Q3 and get 3 separate values, one for each 64 bit number.

---below is signature, still a Work In Progress---
I would rather take 30 minutes to re-invent the wheel then take 30 days to learn how to use someone else's. Before pestering me about my re-invention prepare to defend yourself with a way of learning how to use the wheel in less time than it takes for me to make one, one that I might add is specialized to my specific task!

Replies are listed 'Best First'.
Re: Trouble understanding pack/unpack syntax.
by grep (Monsignor) on Jul 02, 2007 at 03:36 UTC
    but my suspicion is that the A16 will give me 16 separate array elements

    Why would you think that? Test it out.

    #/usr/bin/perl use strict; use warnings; use Data::Dumper; my $line = "FooBarBaz"; my @array = unpack('A3A3A3',$line); print Dumper \@array;
    Produces:
    $VAR1 = [ 'Foo', 'Bar', 'Baz' ];
    So A16 will produce 1 element.

    As to your signature: I would suggest reading something I wrote earlier.

Re: Trouble understanding pack/unpack syntax.
by TOD (Friar) on Jul 02, 2007 at 03:33 UTC
Re: Trouble understanding pack/unpack syntax.
by bart (Canon) on Jul 02, 2007 at 20:51 UTC
    but my suspicion is that the A16 will give me 16 separate array elements
    Your intuition is very understandable, but wrong. Loose characters wouldn't be very useful, in general, so the perl implementers chose some other behavior that is more practically useful, as here.
    so my template so far looks like this: '??A16CQQQS'
    Be very careful: 'Q' doesn't work on all platforms — not even on most platforms. Not all perls can even handle 64 bit integers, 53 bits is the most you can reliably use natively. You may want to look into Math::BigInt (with XS driver).

    Also: 'S' is machine dependent. You may want to explicitly choose for 'n' (Big Endian) or 'v' (Little Endian AKA Intel) — which treats it as an unsigned number, BTW. You didn't specify your requirements here, but unsigned numbers can easily be converted to signed, if 2's complement (the usual case), by subtracting 2**16 if the number is 2**15 or higher.

    unfortunately without any idea how to do the first 2 16 byte values (which need to remain binary, completely unchanged)
    Try 'a16' twice.