in reply to Problems Getting the Template Correct when Using unpack()

As I understand it, everything is a fixed-width field except the  $data field, the width of which must be computed based on total record length. If so, try this:

use strict; use warnings; use Data::Dump qw(dd); use constant FIXED_FIELDS => 'C3 C3 C a6'; my @data = ( 0x2E, 0x75, 0x0A, 0x04, 0x00, 0x00, 0x00, 0x10, 0x57, 0x56, 0x32, 0x20, 0x20, 0x20, 0x80, 0x49, 0x3D, 0x34, 0x32, 0x37, 0x20, 0x4C, 0x61, 0x6D, 0x70, 0x20, 0x64, 0x69, 0x6D, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3D, 0x32, 0x20, 0x5B, 0x53, 0x43, 0x41, 0x54, 0x53, 0x3D, 0x30, 0x5D, 0x2E, ); my $inbuf = pack 'C*', @data; dd $inbuf; my $total_len = length $inbuf; my $body_len = unpack 'C', $inbuf; my $total_fixed_len = length pack FIXED_FIELDS; dd $total_len, $body_len, $total_fixed_len; my $data_len = $body_len - $total_fixed_len; my $unpacker = "x[C] ${ \FIXED_FIELDS } a$data_len C"; my ($year, $mon, $day, $hour, $min, $sec, $rec_type_idx, $source_name, $data, $tail_len) = unpack $unpacker, $inbuf; my $date_str = sprintf("%s/%s/%s", $day, $mon, $year+1900); my $time_str = sprintf("%02d:%02d:%02d", $hour, $min, $sec); $rec_type_idx &= 0x1F; # Only use b0-b6 printf(" Format: '%s' \n", $unpacker); printf(" \$body_len: %02Xx = %d \n", $body_len, $body_len); printf(" \$date_str: %s \n", $date_str); printf(" \$time_str: %s \n", $time_str); printf("\$rec_type_idx: %02Xx = %d \n", $rec_type_idx, $rec_type_idx); printf(" \$source_name: !%s! \n", $source_name); printf(" \$data: !%s! \n", $data); printf(" \$tail_len: %02Xx = %d \n", $tail_len, $tail_len); printf("\n");
Output:
c:\@Work\Perl\monks\ozboomer>perl unpack_1.pl ".u\n\4\0\0\0\20WV2 \x80I=427 Lamp dim state=2 [SCATS=0]." (48, 46, 13) Format: 'x[C] C3 C3 C a6 a33 C' $body_len: 2Ex = 46 $date_str: 4/10/2017 $time_str: 00:00:00 $rec_type_idx: 10x = 16 $source_name: !WV2 ! $data: !ÇI=427 Lamp dim state=2 [SCATS=0]! $tail_len: 2Ex = 46

Update:

*Note: The 'C' near the start of the $data output is actually a 080x value. I didn't want to post a binary value here.
I don't understand this statement in the OP, so I'm ignoring it.


Give a man a fish:  <%-{-{-{-<

Replies are listed 'Best First'.
Re^2: Problems Getting the Template Correct when Using unpack()
by ozboomer (Friar) on Oct 10, 2017 at 10:38 UTC

    I still have to work my way through these notes... Fanx!

    ...but to clarify what I was talking about re:

    $data: !CI=427 Lamp dim state=2 SCATS=0.!

    What I wrote was a mistake...

    What I meant to say was: I show a "C" character (ASCII decimal 67, 0x43) at the start of the '$data' list of characters, when in the @data array you'll see it's actually a "special" character (ASCII decimal 128, 0x80).

    I simply wasn't sure if the "special" character would upset some display thing if I included that unusual character in my posting... tha's all.

    "Sorry about that, Chief...

      ... I show a "C" character ... it's actually a "special" character (... 0x80).

      Is this character always a 0x80 character? If it's always the same, do you really care about extracting this character (which looks like some kind of delimiter/placeholder)? If it varies, how does it vary?

      I was thinking about a regex-based solution, and a constant 0x80 in the middle of the record could be a nice little anchor.

      Update: Added  <blockquote> block to start of node.


      Give a man a fish:  <%-{-{-{-<

        No, it's something that can be a part of a message string OR it can be a flags byte, so at times, will need further processing... but thanks for the thought..