Convert::Binary::C で C 構造体をバイナリ変換 (可変長配列)
C の可変長配列をバイナリ変換する。tag で dimension (配列長)を指定する。
ヘッダファイル
variable_array.h
typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; typedef unsigned long u_long; #pragma pack(1) struct top_t { u_char count; char data[1]; }; #pragma pack
変換前のデータ
# data my %test_data = ( count => 3, data => [ 0x0A, 0x0B, 0x0C ], );
dimension を直接指定
$c->tag( 'top_t.data', Dimension => 3 );
dimension をメンバで決定
$c->tag( 'top_t.data', Dimension => 'count' );
dimension を関数で決定
$c->tag( 'top_t.data', Dimension => sub { my $m = shift; return $m->{count}; } );
pack
my $packed = $c->pack( 'top_t', \%test_data ); print hexdump( data => $packed );
0x0000 : 03 0A 0B 0C : ....
unpack
my $unpacked = $c->unpack( 'top_t', $packed ); print Dumper($unpacked);
$VAR1 = { 'count' => 3, 'data' => [ 10, 11, 12 ] };
テストコード
#!/usr/bin/perl use strict; use warnings; use Carp; use Convert::Binary::C; use Data::Dumper; use Data::Hexdumper; my $c = Convert::Binary::C->new(); $c->configure( ByteOrder => 'BigEndian' ); $c->parse_file('./variable_array.h'); # data my %test_data = ( count => 3, data => [ 0x0A, 0x0B, 0x0C ], ); ### dimension を直接指定 print q{### $c->tag('top_t.data', Dimension => 3)}, $/; $c->tag( 'top_t.data', Dimension => 3 ); { # pack my $packed = $c->pack( 'top_t', \%test_data ); print '--- pack', $/; print hexdump( data => $packed ); # unpack my $unpacked = $c->unpack( 'top_t', $packed ); print '--- unpack', $/; print Dumper($unpacked); } $c->untag( 'top_t.data', 'Dimension' ); ### dimension をメンバで決定 print q{### $c->tag('top_t.data', Dimension => 'count')}, $/; $c->tag( 'top_t.data', Dimension => 'count' ); { # pack my $packed = $c->pack( 'top_t', \%test_data ); print '--- pack', $/; print hexdump( data => $packed ); # unpack my $unpacked = $c->unpack( 'top_t', $packed ); print '--- unpack', $/; print Dumper($unpacked); } $c->untag( 'top_t.data', 'Dimension' ); ### dimension を関数で決定 print q{### $c->tag('top_t.data', Dimension => sub)}, $/; $c->tag( 'top_t.data', Dimension => sub { my $m = shift; return $m->{count}; } ); { # pack my $packed = $c->pack( 'top_t', \%test_data ); print '--- pack', $/; print hexdump( data => $packed ); # unpack my $unpacked = $c->unpack( 'top_t', $packed ); print '--- unpack', $/; print Dumper($unpacked); } $c->untag( 'top_t.data', 'Dimension' );
### $c->tag('top_t.data', Dimension => 3) --- pack 0x0000 : 03 0A 0B 0C : .... --- unpack $VAR1 = { 'count' => 3, 'data' => [ 10, 11, 12 ] }; ### $c->tag('top_t.data', Dimension => 'count') --- pack 0x0000 : 03 0A 0B 0C : .... --- unpack $VAR1 = { 'count' => 3, 'data' => [ 10, 11, 12 ] }; ### $c->tag('top_t.data', Dimension => sub) --- pack 0x0000 : 03 0A 0B 0C : .... --- unpack $VAR1 = { 'count' => 3, 'data' => [ 10, 11, 12 ] };