-
Notifications
You must be signed in to change notification settings - Fork 1
/
AttributeParser.pm
executable file
·65 lines (59 loc) · 1.74 KB
/
AttributeParser.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package AttributeParser;
use strict;
use warnings;
sub new { return bless {}, $_[0]; }
sub parse {
my %x;
my ($namelen, $namedata);
if (length($_[1])<12) {
printf("WARN: short attkey: %s\n", unpack("H*", $_[1]));
return \%x;
}
(
$x{pad},
$x{fileid},
$x{startBlock},
$namelen,
$namedata,
)= unpack("nNNna*", $_[1]);
if (2*$namelen!=length($namedata)) {
printf("WARN: attributekey: len=%04x, len(namedata)=%04x\n", 2*$namelen, length($namedata));
if (length($_[2])==0) {
$_[2]= substr($namedata, 2*$namelen);
$namedata= substr($namedata, 0, 2*$namelen);
}
}
$x{name}= main::unicode2ascii($namedata);
return \%x if @_==2; # key only
my $datalen;
if (length($_[2])<16) {
printf("WARN: short attribute: %s\n", unpack("H*", $_[2]));
return \%x;
}
(
$x{recordType},
undef,
undef,
$datalen,
$x{data},
)= unpack("NNNNa*", $_[2]);
if ($datalen==length($x{data})-1) {
$x{data}= substr($x{data},0,$datalen);
}
elsif (length($x{data})!=$datalen) {
printf("WARN: attributevalue: len=%04x, len(data)=%04x\n", $datalen, length($x{data}));
}
return \%x;
}
sub dump {
if (exists $_[1]{recordType}) {
return sprintf("cnid%08lx:%-40s => %08lx:%s", $_[1]{fileid}, "'".$_[1]{name}."'", $_[1]{recordType},
($_[1]{data} =~ /^[\x20-\x7e]{20}/) ? "'".$_[1]{data}."'" : unpack('H*', $_[1]{data}) );
}
else {
return sprintf("cnid%08lx:%08lx:%s", $_[1]{fileid}, $_[1]{startBlock}, "'".$_[1]{name}."'");
}
}
sub dumpStats {
}
1;