Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

pack() v unpack() padding: bug or ???

by BrowserUk (Patriarch)
on Feb 16, 2015 at 13:44 UTC ( [id://1116868]=perlquestion: print w/replies, xml ) Need Help??

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

The description of the 'a', 'A' & 'Z' templates for pack reads:

a A string with arbitrary binary data, will be null padded. A A text (ASCII) string, will be space padded. Z A null-terminated (ASCIZ) string, will be null padded.

And sure enough:

print length pack '(A2)*', 'fr','ed','x';; 6 print unpack 'C*', pack '(A2)*', 'fr','ed','x';; 102 114 101 100 120 32 print length pack '(a2)*', 'fr','ed','x';; 6 print unpack 'C*', pack '(a2)*', 'fr','ed','x';; 102 114 101 100 120 0 print length pack '(Z2)*', 'fr','ed','x';; 6 print unpack 'C*', pack '(Z2)*', 'fr','ed','x';; 102 0 101 0 120 0 ## Note! the 'r' & 'd' characters have been thrown +away? Another bug?

And the docs for unpack say:

unpack does the reverse of pack: it takes a string and expands it out into a list of values.

But:

printf "'%s'\n", join"'", unpack '(A2)*', 'fredx';; 'fr'ed'x' printf "'%s'\n", join"'", unpack '(a2)*', 'fredx';; 'fr'ed'x' printf "'%s'\n", join"'", unpack '(Z2)*', 'fredx';; 'fr'ed'x'

Shouldn't that last element from unpack ('x') be padded with either space or null?

Has it always been 'wrong'? Is it too late to change it?


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

Replies are listed 'Best First'.
Re: pack() v unpack() padding: bug or ???
by Athanasius (Archbishop) on Feb 16, 2015 at 16:11 UTC

    Hello BrowserUk,

    As I understand it, pack (A2)*, LIST says: for each element in LIST, convert it to a 2-byte ASCII string, padded with a trailing space character if necessary; then return the concatenation of these converted elements as a single string.

    Logically, then, since unpack “does the reverse of pack”, unpack (A2)*, STRING should break STRING into 2-character chunks, and for each chunk, first remove any trailing spaces, then convert it to an appropriate value. Which is what I see:

    2:03 >perl -MData::Dump -wE "my @c = unpack '(A2)*', 'f 12dx z'; dd \ +@c;" ["f", 12, "dx", " z"] 2:04 >

    Note that "f " has been converted to "f" by removal of the trailing space (padding).

    print unpack 'C*', pack '(Z2)*', 'fr','ed','x';; 102 0 101 0 120 0 ## Note! the 'r' & 'd' characters have been thrown +away? Another bug?

    I don’t see a problem here, either. The template Z2 specifies a 2-byte null-terminated string. Packing 'fr' of course requires 3 bytes, so the second character is thrown away and the packed result is f\0. Isn’t that what it’s supposed to do?

    Hope that helps (and I apologise if I’ve missed the point!),

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      I don’t see a problem here, either. The template Z2 specifies a 2-byte null-terminated string. Packing 'fr' of course requires 3 bytes, so the second character is thrown away and the packed result is f\0. Isn’t that what it’s supposed to do?

      Can you think of a good use for that? Or even a not good use?

      Mentioned in the docs is "Z A null-terminated (ASCIZ) string, will be null padded.". Wouldn't you expect it to grab the 2 characters and then add the null byte (if required)?

      As is, it makes: pack 'Z1', $anything; a very complicated why of generating a null.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
      In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

        BrowserUk:

        Since it specifies ASCIZ, I'd expect it to work like it does. Isn't 'a2' the behaviour you're asking for?

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

Re: pack() v unpack() padding: bug or ???
by Anonymous Monk on Feb 16, 2015 at 13:57 UTC
    This pack thing is just a pain. unpack is not the exact opposite, no.
    The "a", "A", and "Z" types gobble just one value, but pack it as a string of length count, padding with nulls or spaces as needed. When unpacking, "A" strips trailing whitespace and nulls, "Z" strips everything after the first null, and "a" returns data with no stripping at all.
    pack

      Another way to look at it is: unpack() does the opposite of pack() and the opposite of padding is stripping. (No, I'm not claiming that unpack() always does the exact opposite of pack().)

      - tye        

Re: pack() v unpack() padding: bug or ???
by GotToBTru (Prior) on Feb 16, 2015 at 16:02 UTC
    printf "'%s'\n",join "'",unpack '(A2)*','fredx ' 'fr'ed'x'

    unpack is deciding to remove trailing spaces, I guess in the assumption that they are artifacts from pack.

    Dum Spiro Spero
      unpack is deciding to remove trailing spaces, I guess in the assumption that they are artifacts from pack.

      Same question: can anyone describe the use they made of that? Or even think of a use for it?

      In the end it all comes down to my need to chop an arbitrary length string into n-byte chunks; and the requirement to have the last chunk padded if it is shorter than n.

      It seems to me that this is a fairly common requirement -- think all the Digest::* modules that need to operate upon fixed-sized chunks of data -- and there isn't (AFAIK) a clean way to do that.

      And here we have a couple of templates that almost do it; but at the margins, do something that whilst they can be reasoned (with squinty eye's and big dollop of belief suspension), to be "doing the opposite of pack"; do things that there are no good uses for; whilst leaving the common requirement unserviced.

      That's just not very Perlish.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
      In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1116868]
Approved by marto
Front-paged by Discipulus
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (6)
As of 2024-03-19 07:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found