use strict;
use warnings;
use Data::Dumper;
$Data::Dumper::Useqq = 1;
# Here is the header value given
my $hex = "0001000000004f914f1c0b0100425343413030000000050000434130303
+030300000000143413030303134000000024341303030323200000003434130303032
+3400000004434130303032390000000100224e43656c6c30000000020042534341303
+100000005000543413031303031000000064341303130303400000007434130313031
+30000000084341303130313500000009434130313031360000000100224e43656c6c3
+0000000030042534341303200000006000a";
# It appears to be incomplete, specifying 11 BSC blocks but only
# containing two, and an initial fragment of a third. So, pad it.
$hex .= "00" x 200;
# As the given data is hex, pack it to get a byte string
my $header = pack('H*', $hex);
# And lets have a look at that byte string
print Dumper($header);
#
# The specification for the header is:
#
# Header Record Id : 1 Byte
# File Format Version : 1 Byte
# Timestamp : 8 Bytes
# No. of BSCs : 1 Byte
# For each BSC ...
# BSC Id : 1 Byte
# Application Version : 1 Byte
# BSC Name : 2 Bytes
# Number of Cells : 2 Bytes
# For each Cell ...
# Cell Pointer : 2 Bytes
# Cell Name : 9 Bytes
# Number of Neighbour Cells : 2 Bytes
# For each Neighbour Cell to this BSC ...
# Cell Pointer : 2 Bytes
# Cell Name : 9 Bytes
#
#
# But, this doesn't stay in sync with the patterns evident
# in the given data. In particular, each cell appears to
# be represented in 11 bytes, and the neighbour cells
# appear to follow the cells, rather than being nested
# within the cells.
#
# It looks more like
#
# Header Record Id : 1 Byte
# File Format Version : 1 Byte
# Timestamp : 8 Bytes
# No. of BSCs : 1 Byte
# For each BSC ...
# BSC Id : 1 Byte
# Application Version : 1 Byte
# BSC Name : 9 Bytes
# Number of Cells : 2 Bytes
# For each Cell ...
# Cell Pointer : 2 Bytes
# Cell Name : 9 Bytes
# Unknown Byte
# Number of Neighbour Cells : 2 Bytes
# For each Neighbour Cell to this BSC ...
# Cell Pointer : 2 Bytes
# Cell Name : 9 Bytes
#
# This can be scanned as follows:
#
my @results =
unpack ("C C H16 C X C/( C C a9 C X C/( n a9 ) C C X C/(n a9) )",
+$header);
# And, we what we get out of it
print "Results:\n" . Dumper(\@results) . "\n";
This produces the following output:
$VAR1 = "\0\1\0\0\0\0O\221O\34\13\1\0BSCA00\0\0\0\5\0\0CA00000\0\0\0\1
+CA00014\0\
0\0\2CA00022\0\0\0\3CA00024\0\0\0\4CA00029\0\0\0\1\0\"NCell0\0\0\0\2\0
+BSCA01\0\0
\0\5\0\5CA01001\0\0\0\6CA01004\0\0\0\aCA01010\0\0\0\bCA01015\0\0\0\tCA
+01016\0\0\
0\1\0\"NCell0\0\0\0\3\0BSCA02\0\0\0\6\0\n\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+0\0\0\0\0\
0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+0\0\0\0\0\
0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+0\0\0\0\0\
0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+0\0\0\0\0\
0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+0\0\0\0\0\
0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
Results:
$VAR1 = [
0,
1,
"000000004f914f1c",
11,
1,
0,
"BSCA00\0\0\0",
5,
0,
"CA00000\0\0",
1,
"CA00014\0\0",
2,
"CA00022\0\0",
3,
"CA00024\0\0",
4,
"CA00029\0\0",
0,
1,
34,
"NCell0\0\0\0",
2,
0,
"BSCA01\0\0\0",
5,
5,
"CA01001\0\0",
6,
"CA01004\0\0",
7,
"CA01010\0\0",
8,
"CA01015\0\0",
9,
"CA01016\0\0",
0,
1,
34,
"NCell0\0\0\0",
3,
0,
"BSCA02\0\0\0",
6,
10,
"\0\0\0\0\0\0\0\0\0",
0,
"\0\0\0\0\0\0\0\0\0",
0,
"\0\0\0\0\0\0\0\0\0",
0,
"\0\0\0\0\0\0\0\0\0",
0,
"\0\0\0\0\0\0\0\0\0",
0,
"\0\0\0\0\0\0\0\0\0",
0,
0,
0,
0,
"\0\0\0\0\0\0\0\0\0",
0,
0,
0,
0,
0,
"\0\0\0\0\0\0\0\0\0",
0,
0,
0,
0,
0,
"\0\0\0\0\0\0\0\0\0",
0,
0,
0,
0,
0,
"\0\0\0\0\0\0\0\0\0",
0,
0,
0,
0,
0,
"\0\0\0\0\0\0\0\0\0",
0,
0,
0,
0,
0,
"\0\0\0\0\0\0\0\0\0",
0,
0,
0,
0,
0,
"\0\0\0\0\0\0\0\0\0",
0,
0,
0,
0,
0,
"\0\0\0\0\0\0\0\0\0",
0,
0,
0
];
While it is possible to use grouping and repeat counts in unpack to scan headers such as these, I don't find the resulting array to be very useful. I would use loops myself, and build a more accessible data structure. None the less, you might use this approach and adjust as necessary to accommodate whatever the exact structure of your header records is. This is, at least, a working example with somewhat reasonable looking results from the given data. |