2010/8/22 Uri Guttman <u...@stemsystems.com>
>
> >>>>> "AQ" == Albert Q <albert.q.p...@gmail.com> writes:
>
> a quick comment. pack is most likely not a beginner issue. i am sure you
> will get help here but think about better forums for asking about
> pack. there are plenty. pack is powerful and sometimes dark magic even
> to experienced perl hackers (i know on very high level hacker who never
> used pack/unpack.).

but I only have this mailing list, and I think it is not a heigh level
problem :)

>  AQ> I have a text file containing hex strings such as: 12 34 56 78 90 ab cd 
> ef
>  AQ> now I want to change these hex strings to sequence of bytes with the
>  AQ> relative value of 0x12 0x34 0x56 ....
>
>  AQ> sub proc_file
>  AQ> {
>  AQ>     while(<$fin>)
>  AQ>     {
>  AQ>         my @values  = split /\s+/;
>  AQ>         print $fout join '' , map { pack 'H*', $_} @values;   # method 1
>  AQ>         print $fout pack 'H*', join '', @values;                   # 
> method
>  AQ> 2
>  AQ>         print $fout pack 'H*', @values;                            # 
> method
>  AQ> 3
>  AQ>     }
>  AQ> }
>
>  AQ> The result is that, both method 1 and method 2 works OK, but with method 
> 3,
>  AQ> I only get the first byte. For example,
>  AQ> if @values is 12 34 56 78
>  AQ> pack 'H*', @values will get a string with only one byte 0x12
>  AQ> from perlfun, I found that the pack function will gobble up that many 
> values
>  AQ> from the LIST except for some types, and 'H' is one of these types.
>  AQ> so, if I use
>  AQ> pack 'H*H*H*H*', @values;
>  AQ> I will get the correct result of 4 bytes 0x12 0x34 0x56 0x78
>
>  AQ> My question is, does there exist some other more simple way to accomplish
>  AQ> this transfrom, for example, just one modifier to tell the pack to use 
> all
>  AQ> items of the LIST?
>
> from the docs on pack:
>
>        The "h" and "H" fields pack a string that many nybbles (4-bit
>        groups, representable as hexadecimal digits, 0-9a-f) long.
>
>        If the input string of pack() is longer than needed, extra
>        characters are ignored.  A "*" for the repeat count of pack()
>        means to use all the characters of the input field.  On
>        unpack()ing the nybbles are converted to a string of hexadecimal
>        digits.
>
> the point is that H and h pack into and from a single string. hex is
> usually in a string and the byte value is also a string.
>
> there is a newer feature (dunno which perl version got it first) which
> is subtemplating (like grouping in a regex. the docs say this:
>
>        A ()-group is a sub-TEMPLATE enclosed in parentheses.  A group
>        may take a repeat count, both as postfix, and for unpack() also
>        via the "/" template character.  Within each repetition of a
>        group, positioning with "@" starts again at 0. Therefore, the
>        result of
>
>        pack( '@1A((@2A)@3A)', 'a', 'b', 'c' )
>        is the string "\0a\0\0bc".
>
> so your solution is this:
>
> perl -le 'print unpack "H*", pack( "(H2)*", qw( 10 ab 9f ))'
> 10ab9f
>
> as you can see it takes a list of hex and pack and unpacks it as
> expected.
>
> uri
>
> --
> Uri Guttman  ------  ...@stemsystems.com  --------  http://www.sysarch.com --
> -----  Perl Code Review , Architecture, Development, Training, Support ------
> ---------  Gourmet Hot Cocoa Mix  ----  http://bestfriendscocoa.com ---------

Yes, it works well !

pack '(H*)*', @values   will get the correct result.

Thanks a lot !


--
missing the days we spend together

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to