Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re: Problems Getting the Template Correct when Using unpack()

by ozboomer (Friar)
on Oct 10, 2017 at 22:49 UTC ( [id://1201125]=note: print w/replies, xml ) Need Help??


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

One thing that may not be clear... is that the '$data' item is not always going to be a string, hence my attempt to use 'C' in the template.

For some values of the '$rec_type_idx', the '$data' item may contain text (as in the original example) but it can be actual binary data (including NULs) that needs further decoding.

  • Comment on Re: Problems Getting the Template Correct when Using unpack()

Replies are listed 'Best First'.
Re^2: Problems Getting the Template Correct when Using unpack()
by BillKSmith (Monsignor) on Oct 11, 2017 at 12:37 UTC
    Your specification of C33 returns a list of 33 unsigned numbers. You need an array to hold them. Another option is to use the array, but fill it with a list of characters ( use (a)33 ).
    C:\Users\Bill\forums\monks>type ozboomer.pl use strict; use warnings; my @data = ( 0x2E, 0x75, 0x0A, 0x04, 0x00, 0x00, 0x00, 0x10, 0x57, 0x5 +6, 0x32, 0x20, 0x20, 0x20, 0x80, 0x49, 0x3D, 0x34, 0x32, 0x3 +7, 0x20, 0x4C, 0x61, 0x6D, 0x70, 0x20, 0x64, 0x69, 0x6D, 0x2 +0, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3D, 0x32, 0x20, 0x5B, 0x5 +3, 0x43, 0x41, 0x54, 0x53, 0x3D, 0x30, 0x5D, 0x2E ); my @formats = ( "C8a6C33C1", "C8A6(A)33C1" ); my $inbuf = join('', map { chr($_) } @data); # Input buffer printf("\$inbuf: >%s<\n", $inbuf); printf("\n"); foreach my $fmt (@formats) { my $tmpbuf = $inbuf; # In case something's being corrupted my ($event_len, $tail_len); my ($year, $mon, $day); my ($hour, $min, $sec); my $rec_type_idx; my $source_name; my @data; ($event_len, $year, $mon, $day, $hour, $min, $sec, $rec_type_idx, $source_name, @data[0..32], $tail_len) = unpack( +$fmt, $tmp buf); 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", $fmt); printf(" \$event_len: %02Xx = %d\n", $event_len, $event_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", join(' ', @data)); printf(" \$tail_len: %02Xx = %d\n", $tail_len, $tail_len); printf("\n"); } C:\Users\Bill\forums\monks>perl ozboomer.pl $inbuf: >.u &#9830; &#9658;WV2 ÇI=427 Lamp dim state=2 [SCATS=0].< Format: C8a6C33C1 $event_len: 2Ex = 46 $date_str: 4/10/2017 $time_str: 00:00:00 $rec_type_idx: 10x = 16 $source_name: !WV2 ! $data: !128 73 61 52 50 55 32 76 97 109 112 32 100 105 109 32 +115 116 97 116 101 61 50 32 91 83 67 65 84 83 61 48 93! $tail_len: 2Ex = 46 Format: C8A6(A)33C1 $event_len: 2Ex = 46 $date_str: 4/10/2017 $time_str: 00:00:00 $rec_type_idx: 10x = 16 $source_name: !WV2! $data: !Ç I = 4 2 7 L a m p d i m s t a t e = 2 [ S C A T +S = 0 ]! $tail_len: 2Ex = 46

    I recommend that you do return $data as a string (use a33). Yes, you do need additional processing, but string processing is what perl does best.

    Bill

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1201125]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (5)
As of 2024-04-23 21:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found