line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
5
|
|
|
5
|
|
101
|
use strict;
|
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
187
|
|
2
|
5
|
|
|
5
|
|
23
|
use warnings;
|
|
5
|
|
|
|
|
9
|
|
|
5
|
|
|
|
|
143
|
|
3
|
5
|
|
|
5
|
|
22
|
use Data::ParseBinary::Core;
|
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
15161
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
package Data::ParseBinary::Enum;
|
6
|
|
|
|
|
|
|
our @ISA = qw{Data::ParseBinary::Adapter};
|
7
|
|
|
|
|
|
|
# TODO: implement as macro in terms of SymmetricMapping (macro)
|
8
|
|
|
|
|
|
|
# that is implemented as MappingAdapter
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
sub _init {
|
11
|
29
|
|
|
29
|
|
85
|
my ($self, @params) = @_;
|
12
|
29
|
|
|
|
|
46
|
my $decode = {};
|
13
|
29
|
|
|
|
|
39
|
my $encode = {};
|
14
|
29
|
|
|
|
|
44
|
$self->{have_default} = 0;
|
15
|
29
|
|
|
|
|
43
|
$self->{default_action} = undef;
|
16
|
29
|
|
|
|
|
70
|
while (@params) {
|
17
|
223
|
|
|
|
|
241
|
my $key = shift @params;
|
18
|
223
|
|
|
|
|
223
|
my $value = shift @params;
|
19
|
223
|
100
|
|
|
|
407
|
if ($key eq '_default_') {
|
20
|
14
|
|
|
|
|
28
|
$self->{have_default} = 1;
|
21
|
14
|
|
|
|
|
19
|
$self->{default_action} = $value;
|
22
|
14
|
100
|
|
|
|
37
|
if (ref $value) {
|
|
|
50
|
|
|
|
|
|
23
|
13
|
50
|
|
|
|
42
|
if ($value != $Data::ParseBinary::BaseConstruct::DefaultPass) {
|
24
|
0
|
|
|
|
|
0
|
die "Enum Error: got invalid value as default";
|
25
|
|
|
|
|
|
|
}
|
26
|
|
|
|
|
|
|
} elsif (exists $encode->{$value}) {
|
27
|
0
|
|
|
|
|
0
|
die "Enum Error: $value should not be defined as regular case";
|
28
|
|
|
|
|
|
|
} else {
|
29
|
1
|
|
|
|
|
3
|
$self->{default_value} = shift @params;
|
30
|
|
|
|
|
|
|
}
|
31
|
14
|
|
|
|
|
39
|
next;
|
32
|
|
|
|
|
|
|
}
|
33
|
209
|
|
|
|
|
407
|
$encode->{$key} = $value;
|
34
|
209
|
|
|
|
|
541
|
$decode->{$value} = $key;
|
35
|
|
|
|
|
|
|
}
|
36
|
29
|
|
|
|
|
50
|
$self->{encode} = $encode;
|
37
|
29
|
|
|
|
|
87
|
$self->{decode} = $decode;
|
38
|
|
|
|
|
|
|
}
|
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
sub _decode {
|
41
|
133
|
|
|
133
|
|
211
|
my ($self, $value) = @_;
|
42
|
133
|
100
|
|
|
|
411
|
if (exists $self->{decode}->{$value}) {
|
43
|
78
|
|
|
|
|
263
|
return $self->{decode}->{$value};
|
44
|
|
|
|
|
|
|
}
|
45
|
55
|
100
|
|
|
|
138
|
if ($self->{have_default}) {
|
46
|
54
|
100
|
66
|
|
|
326
|
if (ref($self->{default_action}) and $self->{default_action} == $Data::ParseBinary::BaseConstruct::DefaultPass) {
|
47
|
53
|
|
|
|
|
192
|
return $value;
|
48
|
|
|
|
|
|
|
}
|
49
|
1
|
|
|
|
|
5
|
return $self->{default_action};
|
50
|
|
|
|
|
|
|
}
|
51
|
1
|
|
|
|
|
16
|
die "Enum: unrecognized value $value, and no default defined";
|
52
|
|
|
|
|
|
|
}
|
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub _encode {
|
55
|
126
|
|
|
126
|
|
195
|
my ($self, $tvalue) = @_;
|
56
|
126
|
100
|
|
|
|
379
|
if (exists $self->{encode}->{$tvalue}) {
|
57
|
72
|
|
|
|
|
726
|
return $self->{encode}->{$tvalue};
|
58
|
|
|
|
|
|
|
}
|
59
|
54
|
50
|
|
|
|
129
|
if ($self->{have_default}) {
|
60
|
54
|
100
|
66
|
|
|
278
|
if (ref($self->{default_action}) and $self->{default_action} == $Data::ParseBinary::BaseConstruct::DefaultPass) {
|
61
|
53
|
|
|
|
|
171
|
return $tvalue;
|
62
|
|
|
|
|
|
|
}
|
63
|
1
|
|
|
|
|
4
|
return $self->{default_value};
|
64
|
|
|
|
|
|
|
}
|
65
|
0
|
|
|
|
|
0
|
die "Enum: unrecognized value $tvalue";
|
66
|
|
|
|
|
|
|
}
|
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
package Data::ParseBinary::FlagsEnum;
|
69
|
|
|
|
|
|
|
our @ISA = qw{Data::ParseBinary::Adapter};
|
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
sub _init {
|
72
|
4
|
|
|
4
|
|
24
|
my ($self, @mapping) = @_;
|
73
|
4
|
|
|
|
|
5
|
my @pairs;
|
74
|
4
|
50
|
|
|
|
16
|
die "FlagsEnum: Mapping should be even" if @mapping % 2 == 1;
|
75
|
4
|
|
|
|
|
12
|
while (@mapping) {
|
76
|
74
|
|
|
|
|
75
|
my $name = shift @mapping;
|
77
|
74
|
|
|
|
|
66
|
my $value = shift @mapping;
|
78
|
74
|
|
|
|
|
181
|
push @pairs, [$name, $value];
|
79
|
|
|
|
|
|
|
}
|
80
|
4
|
|
|
|
|
14
|
$self->{pairs} = \@pairs;
|
81
|
|
|
|
|
|
|
}
|
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
sub _decode {
|
84
|
15
|
|
|
15
|
|
24
|
my ($self, $value) = @_;
|
85
|
15
|
|
|
|
|
24
|
my $hash = {};
|
86
|
15
|
|
|
|
|
23
|
foreach my $rec (@{ $self->{pairs} }) {
|
|
15
|
|
|
|
|
81
|
|
87
|
435
|
100
|
|
|
|
847
|
$hash->{$rec->[0]} = 1 if $value & $rec->[1];
|
88
|
|
|
|
|
|
|
}
|
89
|
15
|
|
|
|
|
45
|
return $hash;
|
90
|
|
|
|
|
|
|
}
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub _encode {
|
93
|
2
|
|
|
2
|
|
5
|
my ($self, $tvalue) = @_;
|
94
|
2
|
|
|
|
|
4
|
my $value = 0;
|
95
|
2
|
|
|
|
|
3
|
foreach my $rec (@{ $self->{pairs} }) {
|
|
2
|
|
|
|
|
6
|
|
96
|
30
|
100
|
66
|
|
|
95
|
if (exists $tvalue->{$rec->[0]} and $tvalue->{$rec->[0]}) {
|
97
|
2
|
|
|
|
|
3
|
$value |= $rec->[1];
|
98
|
|
|
|
|
|
|
}
|
99
|
|
|
|
|
|
|
}
|
100
|
2
|
|
|
|
|
6
|
return $value;
|
101
|
|
|
|
|
|
|
}
|
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
package Data::ParseBinary::ExtractingAdapter;
|
104
|
|
|
|
|
|
|
our @ISA = qw{Data::ParseBinary::Adapter};
|
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
sub _init {
|
107
|
5
|
|
|
5
|
|
86
|
my ($self, $sub_name) = @_;
|
108
|
5
|
|
|
|
|
14
|
$self->{sub_name} = $sub_name;
|
109
|
|
|
|
|
|
|
}
|
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub _decode {
|
112
|
29
|
|
|
29
|
|
46
|
my ($self, $value) = @_;
|
113
|
29
|
|
|
|
|
83
|
return $value->{$self->{sub_name}};
|
114
|
|
|
|
|
|
|
}
|
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub _encode {
|
117
|
29
|
|
|
29
|
|
43
|
my ($self, $tvalue) = @_;
|
118
|
29
|
|
|
|
|
117
|
return {$self->{sub_name} => $tvalue};
|
119
|
|
|
|
|
|
|
}
|
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
package Data::ParseBinary::IndexingAdapter;
|
122
|
|
|
|
|
|
|
our @ISA = qw{Data::ParseBinary::Adapter};
|
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
sub _init {
|
125
|
0
|
|
|
0
|
|
0
|
my ($self, $index) = @_;
|
126
|
0
|
|
0
|
|
|
0
|
$self->{index} = $index || 0;
|
127
|
|
|
|
|
|
|
}
|
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
sub _decode {
|
130
|
0
|
|
|
0
|
|
0
|
my ($self, $value) = @_;
|
131
|
0
|
|
|
|
|
0
|
return $value->[$self->{index}];
|
132
|
|
|
|
|
|
|
}
|
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
sub _encode {
|
135
|
0
|
|
|
0
|
|
0
|
my ($self, $tvalue) = @_;
|
136
|
0
|
|
|
|
|
0
|
return [ ('') x $self->{index}, $tvalue ];
|
137
|
|
|
|
|
|
|
}
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
package Data::ParseBinary::JoinAdapter;
|
140
|
|
|
|
|
|
|
our @ISA = qw{Data::ParseBinary::Adapter};
|
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
sub _decode {
|
143
|
40
|
|
|
40
|
|
59
|
my ($self, $value) = @_;
|
144
|
40
|
|
|
|
|
163
|
return join '', @$value;
|
145
|
|
|
|
|
|
|
}
|
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
sub _encode {
|
148
|
37
|
|
|
37
|
|
62
|
my ($self, $tvalue) = @_;
|
149
|
37
|
|
|
|
|
306
|
return [split '', $tvalue];
|
150
|
|
|
|
|
|
|
}
|
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
package Data::ParseBinary::ConstAdapter;
|
153
|
|
|
|
|
|
|
our @ISA = qw{Data::ParseBinary::Adapter};
|
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub _init {
|
156
|
16
|
|
|
16
|
|
23
|
my ($self, $value) = @_;
|
157
|
16
|
|
|
|
|
45
|
$self->{value} = $value;
|
158
|
|
|
|
|
|
|
}
|
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub _decode {
|
161
|
31
|
|
|
31
|
|
54
|
my ($self, $value) = @_;
|
162
|
31
|
100
|
|
|
|
123
|
if (not $value eq $self->{value}) {
|
163
|
8
|
|
|
|
|
89
|
die "Const Error: expected $self->{value} got $value";
|
164
|
|
|
|
|
|
|
}
|
165
|
23
|
|
|
|
|
77
|
return $value;
|
166
|
|
|
|
|
|
|
}
|
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub _encode {
|
169
|
24
|
|
|
24
|
|
47
|
my ($self, $tvalue) = @_;
|
170
|
24
|
100
|
|
|
|
70
|
if (not defined $self->_get_name()) {
|
171
|
|
|
|
|
|
|
# if we don't have a name, then just use the value
|
172
|
3
|
|
|
|
|
14
|
return $self->{value};
|
173
|
|
|
|
|
|
|
}
|
174
|
21
|
100
|
100
|
|
|
107
|
if (defined $tvalue and $tvalue eq $self->{value}) {
|
175
|
14
|
|
|
|
|
54
|
return $self->{value};
|
176
|
|
|
|
|
|
|
}
|
177
|
7
|
100
|
|
|
|
86
|
die "Const Error: expected $self->{value} got ". (defined $tvalue ? $tvalue : "undef");
|
178
|
|
|
|
|
|
|
}
|
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
package Data::ParseBinary::LengthValueAdapter;
|
182
|
|
|
|
|
|
|
our @ISA = qw{Data::ParseBinary::Adapter};
|
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub _decode {
|
185
|
3
|
|
|
3
|
|
7
|
my ($self, $value) = @_;
|
186
|
3
|
|
|
|
|
9
|
return $value->[1];
|
187
|
|
|
|
|
|
|
}
|
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
sub _encode {
|
190
|
3
|
|
|
3
|
|
16
|
my ($self, $tvalue) = @_;
|
191
|
3
|
|
|
|
|
11
|
return [length($tvalue), $tvalue];
|
192
|
|
|
|
|
|
|
}
|
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
package Data::ParseBinary::PaddedStringAdapter;
|
195
|
|
|
|
|
|
|
our @ISA = qw{Data::ParseBinary::Adapter};
|
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
sub _init {
|
198
|
4
|
|
|
4
|
|
13
|
my ($self, %params) = @_;
|
199
|
4
|
50
|
|
|
|
16
|
if (not defined $params{length}) {
|
200
|
0
|
|
|
|
|
0
|
die "PaddedStringAdapter: you must specify length";
|
201
|
|
|
|
|
|
|
}
|
202
|
4
|
|
|
|
|
11
|
$self->{length} = $params{length};
|
203
|
4
|
|
|
|
|
8
|
$self->{encoding} = $params{encoding};
|
204
|
4
|
50
|
|
|
|
18
|
$self->{padchar} = defined $params{padchar} ? $params{padchar} : "\x00";
|
205
|
4
|
|
100
|
|
|
34
|
$self->{paddir} = $params{paddir} || "right";
|
206
|
4
|
|
50
|
|
|
23
|
$self->{trimdir} = $params{trimdir} || "right";
|
207
|
4
|
50
|
|
|
|
23
|
if (not grep($_ eq $self->{paddir}, qw{right left center})) {
|
208
|
0
|
|
|
|
|
0
|
die "PaddedStringAdapter: paddir should be one of {right left center}";
|
209
|
|
|
|
|
|
|
}
|
210
|
4
|
50
|
|
|
|
29
|
if (not grep($_ eq $self->{trimdir}, qw{right left})) {
|
211
|
0
|
|
|
|
|
0
|
die "PaddedStringAdapter: trimdir should be one of {right left}";
|
212
|
|
|
|
|
|
|
}
|
213
|
|
|
|
|
|
|
}
|
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
sub _decode {
|
216
|
11
|
|
|
11
|
|
23
|
my ($self, $value) = @_;
|
217
|
11
|
|
|
|
|
15
|
my $tvalue = $value;
|
218
|
11
|
|
|
|
|
25
|
my $char = $self->{padchar};
|
219
|
11
|
50
|
33
|
|
|
46
|
if ($self->{paddir} eq 'right' or $self->{paddir} eq 'center') {
|
|
|
0
|
0
|
|
|
|
|
220
|
11
|
|
|
|
|
193
|
$tvalue =~ s/$char*\z//;
|
221
|
|
|
|
|
|
|
} elsif ($self->{paddir} eq 'left' or $self->{paddir} eq 'center') {
|
222
|
0
|
|
|
|
|
0
|
$tvalue =~ s/\A$char*//;
|
223
|
|
|
|
|
|
|
}
|
224
|
11
|
|
|
|
|
34
|
return $tvalue;
|
225
|
|
|
|
|
|
|
}
|
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
sub _encode {
|
228
|
2
|
|
|
2
|
|
5
|
my ($self, $tvalue) = @_;
|
229
|
2
|
|
|
|
|
4
|
my $value = $tvalue;
|
230
|
|
|
|
|
|
|
|
231
|
2
|
50
|
|
|
|
24
|
if (length($value) < $self->{length}) {
|
232
|
2
|
|
|
|
|
5
|
my $add = $self->{length} - length($value);
|
233
|
2
|
|
|
|
|
5
|
my $char = $self->{padchar};
|
234
|
2
|
50
|
|
|
|
11
|
if ($self->{paddir} eq 'right') {
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
235
|
2
|
|
|
|
|
7
|
$value .= $char x $add;
|
236
|
|
|
|
|
|
|
} elsif ($self->{paddir} eq 'left') {
|
237
|
0
|
|
|
|
|
0
|
$value = ($char x $add) . $value;
|
238
|
|
|
|
|
|
|
} elsif ($self->{paddir} eq 'center') {
|
239
|
0
|
|
|
|
|
0
|
my $add_left = $add / 2;
|
240
|
0
|
0
|
|
|
|
0
|
my $add_right = $add_left + ($add % 2 == 0 ? 0 : 1);
|
241
|
0
|
|
|
|
|
0
|
$value = ($char x $add_left) . $value . ($char x $add_right);
|
242
|
|
|
|
|
|
|
}
|
243
|
|
|
|
|
|
|
}
|
244
|
2
|
50
|
|
|
|
11
|
if (length($value) > $self->{length}) {
|
245
|
0
|
|
|
|
|
0
|
my $remove = length($value) - $self->{length};
|
246
|
0
|
0
|
|
|
|
0
|
if ($self->{trimdir} eq 'right') {
|
|
|
0
|
|
|
|
|
|
247
|
0
|
|
|
|
|
0
|
substr($value, $self->{length}, $remove, '');
|
248
|
|
|
|
|
|
|
} elsif ($self->{trimdir} eq 'left') {
|
249
|
0
|
|
|
|
|
0
|
substr($value, 0, $remove, '');
|
250
|
|
|
|
|
|
|
}
|
251
|
|
|
|
|
|
|
}
|
252
|
2
|
|
|
|
|
8
|
return $value;
|
253
|
|
|
|
|
|
|
}
|
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
#package Data::ParseBinary::StringAdapter;
|
256
|
|
|
|
|
|
|
#our @ISA = qw{Data::ParseBinary::Adapter};
|
257
|
|
|
|
|
|
|
#
|
258
|
|
|
|
|
|
|
#sub _init {
|
259
|
|
|
|
|
|
|
# my ($self, $encoding) = @_;
|
260
|
|
|
|
|
|
|
# $self->{encoding} = $encoding;
|
261
|
|
|
|
|
|
|
#}
|
262
|
|
|
|
|
|
|
#
|
263
|
|
|
|
|
|
|
#sub _decode {
|
264
|
|
|
|
|
|
|
# my ($self, $value) = @_;
|
265
|
|
|
|
|
|
|
# my $tvalue;
|
266
|
|
|
|
|
|
|
# if ($self->{encoding}) {
|
267
|
|
|
|
|
|
|
# die "TODO: Should implement different encodings";
|
268
|
|
|
|
|
|
|
# } else {
|
269
|
|
|
|
|
|
|
# $tvalue = $value;
|
270
|
|
|
|
|
|
|
# }
|
271
|
|
|
|
|
|
|
# return $tvalue;
|
272
|
|
|
|
|
|
|
#}
|
273
|
|
|
|
|
|
|
#
|
274
|
|
|
|
|
|
|
#sub _encode {
|
275
|
|
|
|
|
|
|
# my ($self, $tvalue) = @_;
|
276
|
|
|
|
|
|
|
# my $value;
|
277
|
|
|
|
|
|
|
# if ($self->{encoding}) {
|
278
|
|
|
|
|
|
|
# die "TODO: Should implement different encodings";
|
279
|
|
|
|
|
|
|
# } else {
|
280
|
|
|
|
|
|
|
# $value = $tvalue;
|
281
|
|
|
|
|
|
|
# }
|
282
|
|
|
|
|
|
|
# return $value;
|
283
|
|
|
|
|
|
|
#}
|
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
package Data::ParseBinary::CStringAdapter;
|
286
|
|
|
|
|
|
|
our @ISA = qw{Data::ParseBinary::Adapter};
|
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
sub _init {
|
289
|
11
|
|
|
11
|
|
19
|
my ($self, $terminators) = @_;
|
290
|
11
|
|
|
|
|
171
|
$self->{regex} = qr/[$terminators]*\z/;
|
291
|
11
|
|
|
|
|
51
|
$self->{terminator} = substr($terminators, 0, 1);
|
292
|
|
|
|
|
|
|
}
|
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
sub _decode {
|
295
|
29
|
|
|
29
|
|
50
|
my ($self, $value) = @_;
|
296
|
29
|
|
|
|
|
292
|
$value =~ s/$self->{regex}//;
|
297
|
29
|
|
|
|
|
85
|
return $value;
|
298
|
|
|
|
|
|
|
}
|
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
sub _encode {
|
301
|
27
|
|
|
27
|
|
46
|
my ($self, $tvalue) = @_;
|
302
|
27
|
|
|
|
|
240
|
return $tvalue . $self->{terminator};
|
303
|
|
|
|
|
|
|
}
|
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
package Data::ParseBinary::LamdaValidator;
|
306
|
|
|
|
|
|
|
our @ISA = qw{Data::ParseBinary::Validator};
|
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
sub _init {
|
309
|
8
|
|
|
8
|
|
15
|
my ($self, @params) = @_;
|
310
|
8
|
|
|
|
|
23
|
$self->{coderef} = shift @params;
|
311
|
|
|
|
|
|
|
}
|
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
sub _validate {
|
314
|
8
|
|
|
8
|
|
14
|
my ($self, $value) = @_;
|
315
|
8
|
|
|
|
|
20
|
return $self->{coderef}->($value);
|
316
|
|
|
|
|
|
|
}
|
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
package Data::ParseBinary::FirstUnitAndTheRestAdapter;
|
319
|
|
|
|
|
|
|
our @ISA = qw{Data::ParseBinary::Adapter};
|
320
|
|
|
|
|
|
|
# this adapter move from a length of bytes, to one unit and the rest
|
321
|
|
|
|
|
|
|
# as an array
|
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
sub _init {
|
324
|
5
|
|
|
5
|
|
10
|
my ($self, $unit_length, $first_name, $the_rest) = @_;
|
325
|
5
|
|
50
|
|
|
21
|
$first_name ||= 'FirstUnit';
|
326
|
5
|
|
50
|
|
|
19
|
$the_rest ||= 'TheRest';
|
327
|
5
|
|
|
|
|
11
|
$self->{unit_length} = $unit_length;
|
328
|
5
|
|
|
|
|
8
|
$self->{first_name} = $first_name;
|
329
|
5
|
|
|
|
|
14
|
$self->{the_rest} = $the_rest;
|
330
|
|
|
|
|
|
|
}
|
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
sub _decode {
|
333
|
17
|
|
|
17
|
|
24
|
my ($self, $value) = @_;
|
334
|
17
|
|
|
|
|
30
|
$value = join('', $value->{$self->{first_name}}, @{ $value->{$self->{the_rest}} } );
|
|
17
|
|
|
|
|
42
|
|
335
|
17
|
|
|
|
|
43
|
return $value;
|
336
|
|
|
|
|
|
|
}
|
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
sub _encode {
|
339
|
17
|
|
|
17
|
|
25
|
my ($self, $tvalue) = @_;
|
340
|
17
|
|
|
|
|
28
|
my $u_len = $self->{unit_length};
|
341
|
17
|
50
|
|
|
|
49
|
die "Length of input should be dividable by unit_length" unless length($tvalue) % $u_len == 0;
|
342
|
17
|
|
|
|
|
163
|
my @units = map substr($tvalue, $_*$u_len, $u_len), 0..(length($tvalue) / $u_len - 1);
|
343
|
17
|
|
|
|
|
34
|
my $first = shift @units;
|
344
|
17
|
|
|
|
|
70
|
my $value = { $self->{first_name} => $first, $self->{the_rest} => \@units };
|
345
|
17
|
|
|
|
|
51
|
return $value;
|
346
|
|
|
|
|
|
|
}
|
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
package Data::ParseBinary::CharacterEncodingAdapter;
|
349
|
|
|
|
|
|
|
our @ISA = qw{Data::ParseBinary::Adapter};
|
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
sub _init {
|
352
|
9
|
|
|
9
|
|
16
|
my ($self, $encoding) = @_;
|
353
|
9
|
|
|
|
|
21
|
$self->{encoding} = $encoding;
|
354
|
9
|
|
|
|
|
104
|
require Encode;
|
355
|
|
|
|
|
|
|
}
|
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
sub _decode {
|
358
|
23
|
|
|
23
|
|
33
|
my ($self, $octets) = @_;
|
359
|
23
|
|
|
|
|
74
|
my $string = Encode::decode($self->{encoding}, $octets);
|
360
|
23
|
|
|
|
|
636
|
return $string;
|
361
|
|
|
|
|
|
|
}
|
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
sub _encode {
|
364
|
23
|
|
|
23
|
|
37
|
my ($self, $string) = @_;
|
365
|
23
|
|
|
|
|
73
|
my $octets = Encode::encode($self->{encoding}, $string);
|
366
|
23
|
|
|
|
|
134984
|
return $octets;
|
367
|
|
|
|
|
|
|
}
|
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
package Data::ParseBinary::ExtendedNumberAdapter;
|
370
|
|
|
|
|
|
|
our @ISA = qw{Data::ParseBinary::Adapter};
|
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
sub _init {
|
373
|
0
|
|
|
0
|
|
|
my ($self, $is_signed, $is_bigendian) = @_;
|
374
|
0
|
|
|
|
|
|
$self->{is_signed} = $is_signed;
|
375
|
0
|
|
|
|
|
|
$self->{is_bigendian} = $is_bigendian;
|
376
|
0
|
|
|
|
|
|
require Math::BigInt;
|
377
|
|
|
|
|
|
|
}
|
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
sub _decode {
|
380
|
0
|
|
|
0
|
|
|
my ($self, $value) = @_;
|
381
|
0
|
0
|
|
|
|
|
if (not $self->{is_bigendian}) {
|
382
|
0
|
|
|
|
|
|
$value = join '', reverse split '', $value;
|
383
|
|
|
|
|
|
|
}
|
384
|
0
|
|
|
|
|
|
my $is_negative;
|
385
|
0
|
0
|
|
|
|
|
if ($self->{is_signed}) {
|
386
|
0
|
|
|
|
|
|
my $first_char = ord($value);
|
387
|
0
|
0
|
|
|
|
|
if ($first_char > 127) {
|
388
|
0
|
|
|
|
|
|
$value = ~$value;
|
389
|
0
|
|
|
|
|
|
$is_negative = 1;
|
390
|
|
|
|
|
|
|
}
|
391
|
|
|
|
|
|
|
}
|
392
|
|
|
|
|
|
|
|
393
|
0
|
|
|
|
|
|
my $hexed = unpack "H*", $value;
|
394
|
0
|
|
|
|
|
|
my $number = Math::BigInt->new("0x$hexed");
|
395
|
0
|
0
|
|
|
|
|
if ($is_negative) {
|
396
|
0
|
|
|
|
|
|
$number->binc()->bneg();
|
397
|
|
|
|
|
|
|
}
|
398
|
0
|
|
|
|
|
|
return $number;
|
399
|
|
|
|
|
|
|
}
|
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
sub _encode {
|
402
|
0
|
|
|
0
|
|
|
my ($self, $number) = @_;
|
403
|
0
|
|
|
|
|
|
$number = Math::BigInt->new($number);
|
404
|
|
|
|
|
|
|
|
405
|
0
|
|
|
|
|
|
my $is_negative;
|
406
|
0
|
0
|
|
|
|
|
if ($self->{is_signed}) {
|
407
|
0
|
0
|
|
|
|
|
if ($number->sign() eq '-') {
|
408
|
0
|
|
|
|
|
|
$is_negative = 1;
|
409
|
0
|
|
|
|
|
|
$number->binc()->babs();
|
410
|
|
|
|
|
|
|
}
|
411
|
|
|
|
|
|
|
} else {
|
412
|
0
|
0
|
|
|
|
|
if ($number->sign() eq '-') {
|
413
|
0
|
|
|
|
|
|
die "Was given a negative number for unsigned integer";
|
414
|
|
|
|
|
|
|
}
|
415
|
|
|
|
|
|
|
}
|
416
|
|
|
|
|
|
|
|
417
|
0
|
|
|
|
|
|
my $hexed = $number->as_hex();
|
418
|
0
|
|
|
|
|
|
substr($hexed, 0, 2, '');
|
419
|
0
|
|
|
|
|
|
my $packed = pack "H*", ("0"x(16-length($hexed))).$hexed;
|
420
|
0
|
0
|
|
|
|
|
if ($is_negative) {
|
421
|
0
|
|
|
|
|
|
$packed = ~$packed;
|
422
|
|
|
|
|
|
|
}
|
423
|
0
|
0
|
|
|
|
|
if (not $self->{is_bigendian}) {
|
424
|
0
|
|
|
|
|
|
$packed = join '', reverse split '', $packed;
|
425
|
|
|
|
|
|
|
}
|
426
|
0
|
|
|
|
|
|
return $packed;
|
427
|
|
|
|
|
|
|
}
|
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
1; |