Getting position from unpack (was: "join on space instead of comma")

Discussion in 'Perl Misc' started by J. Romano, Aug 14, 2004.

  1. J. Romano

    J. Romano Guest

    Tassilo v. Parseval wrote:

    > here's one that I find useful, namely the '/' construct.
    > The template preceeding the slash is used as a count
    > argument for the template following the slash:


    <code snipped>

    > Note how this can be combined with @:
    >
    > my @x = unpack '@2c/C', "\x03\x00\x01\xff\x03";
    > print "@x\n",
    > __END__
    > 255


    Before that thread, I wasn't aware that I could use '@' like that
    to start the position of unpacking. Before I learned about '@', I
    would always use substr() to remove the beginning part of the string
    that I wanted to ignore.

    But that brings me to another question, one that concerns the usage
    of the '/' construct. I've used that construct before, but I could
    never find an easy way to figure out my offset into the string after
    I've used it.

    Let me clarify with an example. Say I have the following piece of
    code:

    my $string = "\x00\x01\x03\x00\x01\xff\x01\x0f";
    # or I could say: my $sring = v0.1.3.0.1.255.1.15;
    my @x = unpack '@2 c/C', $string;

    That would make @x have three elements: 0, 1, and 255.

    Now let's say that, after examining the contents of @x, I decide to
    read in data for @y, starting where @x left off:

    my @y = unpack '@6 c/C', $string;

    That would make @y have only one element: 15.

    However, in order to know that the second unpack command must start
    at offset 6, I would have to calculate how many elements are in @x,
    multiply that number by the space each element in @x takes (that is,
    took up in the packed string), and add it to 2 (the first unpack()
    offset) and add 1 (for the 'c' construct). (This may not be too
    complicated to do now, but it would be much more difficult to do with
    a more complex unpack string, like "w/(c4 i L Z20)".)

    Is there a way for an unpack string to return the offset so that a
    second unpack string can use it with the '@' construct? This would
    make dealing with variable-length extractions (for example, with 'w/'
    and 'Z*') much easier. I have read the "perldoc -f pack" and "perldoc
    perlpacktut" pages but couldn't find anything about it (but maybe I
    missed something).

    Thanks in advance for any help.

    -- Jean-Luc
     
    J. Romano, Aug 14, 2004
    #1
    1. Advertising

  2. J. Romano

    Anno Siegel Guest

    J. Romano <> wrote in comp.lang.perl.misc:
    > Tassilo v. Parseval wrote:
    >
    > > here's one that I find useful, namely the '/' construct.
    > > The template preceeding the slash is used as a count
    > > argument for the template following the slash:

    >
    > <code snipped>
    >
    > > Note how this can be combined with @:
    > >
    > > my @x = unpack '@2c/C', "\x03\x00\x01\xff\x03";
    > > print "@x\n",
    > > __END__
    > > 255

    >
    > Before that thread, I wasn't aware that I could use '@' like that
    > to start the position of unpacking. Before I learned about '@', I
    > would always use substr() to remove the beginning part of the string
    > that I wanted to ignore.
    >
    > But that brings me to another question, one that concerns the usage
    > of the '/' construct. I've used that construct before, but I could
    > never find an easy way to figure out my offset into the string after
    > I've used it.
    >
    > Let me clarify with an example. Say I have the following piece of
    > code:
    >
    > my $string = "\x00\x01\x03\x00\x01\xff\x01\x0f";
    > # or I could say: my $sring = v0.1.3.0.1.255.1.15;
    > my @x = unpack '@2 c/C', $string;
    >
    > That would make @x have three elements: 0, 1, and 255.
    >
    > Now let's say that, after examining the contents of @x, I decide to
    > read in data for @y, starting where @x left off:
    >
    > my @y = unpack '@6 c/C', $string;
    >
    > That would make @y have only one element: 15.
    >
    > However, in order to know that the second unpack command must start
    > at offset 6, I would have to calculate how many elements are in @x,


    [snip discussion]

    That's hard to do, though I think there's a module that calculates the
    length of the storage image of pack/unpack templates.

    In this case it isn't even necessary. Just make a copy of the rest of the
    string using an additional "a*" template.

    my $string = "\x00\x01\x03\x00\x01\xff\x01\x0f";
    my @x = unpack '@2 c/C a*', $string;
    $string = pop @x;

    Now $string contains whatever wasn't consumed by the template before
    "a*". So

    my @y = unpack 'c/C', $string;

    gives the right result without explicitly calculating an offset.

    Anno
     
    Anno Siegel, Aug 15, 2004
    #2
    1. Advertising

  3. J. Romano

    J. Romano Guest

    -berlin.de (Anno Siegel) wrote in message news:<cfnsin$87c$-Berlin.DE>...
    >
    > In this case it isn't even necessary. Just make a copy of the rest
    > of the string using an additional "a*" template.
    >
    > my $string = "\x00\x01\x03\x00\x01\xff\x01\x0f";
    > my @x = unpack '@2 c/C a*', $string;
    > $string = pop @x;


    Hey, thanks, Anno! Your solution is a lot more elegant (and works
    far better) than the one I was thinking about.

    Of course, if I wanted to find the position after the "@2 c/C"
    template without modifying $string, I could do so very easily (by
    basically using your technique) like this:

    my $string = "\x00\x01\x03\x00\x01\xff\x01\x0f";
    my @x = unpack "@2 c/C a*", $string;
    my $position = length($string) - length(pop @x);

    That way I can start unpacking $string again at $position.

    Thanks again!

    -- Jean-Luc
     
    J. Romano, Aug 18, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Luqman
    Replies:
    1
    Views:
    662
    Luqman
    Feb 7, 2006
  2. James Wong
    Replies:
    4
    Views:
    516
    James Wong
    Jul 14, 2004
  3. LHradowy

    join on space instead of comma

    LHradowy, Aug 4, 2004, in forum: Perl Misc
    Replies:
    9
    Views:
    125
    Tassilo v. Parseval
    Aug 11, 2004
  4. Replies:
    9
    Views:
    90
    Brian McCauley
    Apr 12, 2008
  5. Replies:
    1
    Views:
    163
Loading...

Share This Page