line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package File::Binary; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# importage |
4
|
73
|
|
|
73
|
|
2000968
|
use strict; |
|
73
|
|
|
|
|
183
|
|
|
73
|
|
|
|
|
3447
|
|
5
|
73
|
|
|
73
|
|
469
|
use Carp; |
|
73
|
|
|
|
|
142
|
|
|
73
|
|
|
|
|
7560
|
|
6
|
73
|
|
|
73
|
|
436
|
use Config; |
|
73
|
|
|
|
|
137
|
|
|
73
|
|
|
|
|
2627
|
|
7
|
73
|
|
|
73
|
|
76074
|
use IO::File; |
|
73
|
|
|
|
|
986973
|
|
|
73
|
|
|
|
|
11110
|
|
8
|
73
|
|
|
73
|
|
658
|
use vars qw(@EXPORT_OK $VERSION $BIG_ENDIAN $LITTLE_ENDIAN $NATIVE_ENDIAN $AUTOLOAD $DEBUG); |
|
73
|
|
|
|
|
156
|
|
|
73
|
|
|
|
|
17593
|
|
9
|
73
|
|
|
73
|
|
405
|
use Fcntl qw(:DEFAULT); |
|
73
|
|
|
|
|
154
|
|
|
73
|
|
|
|
|
199661
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
$VERSION='1.7'; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
# for seekable stuff |
14
|
|
|
|
|
|
|
$DEBUG = 0; |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
# set up some constants |
17
|
|
|
|
|
|
|
$BIG_ENDIAN = 2; |
18
|
|
|
|
|
|
|
$LITTLE_ENDIAN = 1; |
19
|
|
|
|
|
|
|
$NATIVE_ENDIAN = 0; |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# and export them |
22
|
|
|
|
|
|
|
@EXPORT_OK = qw($BIG_ENDIAN $LITTLE_ENDIAN $NATIVE_ENDIAN guess_endian); |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=head1 NAME |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
File::Binary - Binary file reading module |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head1 SYNOPSIS |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
use File::Binary qw($BIG_ENDIAN $LITTLE_ENDIAN $NATIVE_ENDIAN); |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
my $fb = File::Binary->new("myfile"); |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
$fb->get_ui8(); |
36
|
|
|
|
|
|
|
$fb->get_ui16(); |
37
|
|
|
|
|
|
|
$fb->get_ui32(); |
38
|
|
|
|
|
|
|
$fb->get_si8(); |
39
|
|
|
|
|
|
|
$fb->get_si16(); |
40
|
|
|
|
|
|
|
$fb->get_si32(); |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
$fb->close(); |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
$fb->open(">newfile"); |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
$fb->put_ui8(255); |
47
|
|
|
|
|
|
|
$fb->put_ui16(65535); |
48
|
|
|
|
|
|
|
$fb->put_ui32(4294967295); |
49
|
|
|
|
|
|
|
$fb->put_si8(-127); |
50
|
|
|
|
|
|
|
$fb->put_si16(-32767); |
51
|
|
|
|
|
|
|
$fb->put_si32(-2147483645); |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
$fb->close(); |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
$fb->open(IO::Scalar->new($somedata)); |
57
|
|
|
|
|
|
|
$fb->set_endian($BIG_ENDIAN); # force endianness |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
# do what they say on the tin |
60
|
|
|
|
|
|
|
$fb->seek($pos); |
61
|
|
|
|
|
|
|
$fb->tell(); |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# etc etc |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=head1 DESCRIPTION |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
B is a Binary file reading module, hence the name, |
69
|
|
|
|
|
|
|
and was originally used to write a suite of modules for manipulating |
70
|
|
|
|
|
|
|
Macromedia SWF files. |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
However it's grown beyond that and now actually, err, works. |
73
|
|
|
|
|
|
|
And is generalised. And EVERYTHING! Yay! |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
It has methods for reading and writing signed and unsigned 8, 16 and |
76
|
|
|
|
|
|
|
32 bit integers, at some point in the future I'll figure out a way of |
77
|
|
|
|
|
|
|
putting in methods for >32bit integers nicely but until then, patches |
78
|
|
|
|
|
|
|
welcome. |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
It hasn't retained backwards compatability with the old version of this |
81
|
|
|
|
|
|
|
module for cleanliness sakes and also because the old interface was |
82
|
|
|
|
|
|
|
pretty braindead. |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=head1 METHODS |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=head2 new |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
Pass in either a file name or something which isa an IO::Handle. |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=cut |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub new { |
93
|
289
|
|
|
289
|
1
|
21593
|
my ($class, $file) = @_; |
94
|
|
|
|
|
|
|
|
95
|
289
|
|
|
|
|
984
|
my $self = {}; |
96
|
|
|
|
|
|
|
|
97
|
289
|
|
|
|
|
2965
|
bless $self, $class; |
98
|
|
|
|
|
|
|
|
99
|
289
|
|
|
|
|
1350
|
$self->open($file); |
100
|
289
|
|
|
|
|
1125
|
$self->set_endian($NATIVE_ENDIAN); |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
|
103
|
289
|
|
|
|
|
2587
|
return $self; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=head2 open |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
Pass in either a file name or something which isa an IO::Handle. |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
Will try and set binmode for the handle on if possible (i.e |
111
|
|
|
|
|
|
|
if the object has a C method) otherwise you should do |
112
|
|
|
|
|
|
|
it yourself. |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=cut |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub open { |
117
|
289
|
|
|
289
|
1
|
813
|
my ($self, $file) = @_; |
118
|
|
|
|
|
|
|
|
119
|
289
|
|
|
|
|
508
|
my $fh; |
120
|
289
|
|
|
|
|
509
|
my $writeable = -1; |
121
|
|
|
|
|
|
|
|
122
|
289
|
100
|
66
|
|
|
2778
|
if (ref($file) =~ /^IO::/ && $file->isa('IO::Handle')) { |
123
|
72
|
|
|
|
|
200
|
$fh = $file; |
124
|
72
|
|
|
|
|
190
|
$writeable = 2; # read and write mode |
125
|
|
|
|
|
|
|
} else { |
126
|
217
|
|
50
|
|
|
1880
|
$fh = IO::File->new($file) || die "No such file $file\n"; |
127
|
217
|
100
|
|
|
|
1171682
|
if ($file =~ /^>/) { |
|
|
50
|
|
|
|
|
|
128
|
72
|
|
|
|
|
302
|
$writeable = 1; |
129
|
|
|
|
|
|
|
} elsif ($file =~ /^\+>/) { |
130
|
0
|
|
|
|
|
0
|
$writeable=2; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
} |
133
|
289
|
50
|
|
|
|
3629
|
$fh->binmode if $fh->can('binmode'); |
134
|
|
|
|
|
|
|
|
135
|
289
|
|
|
|
|
2946
|
$self->{_bitbuf} = ''; |
136
|
289
|
|
|
|
|
712
|
$self->{_bitpos} = 0; |
137
|
289
|
|
|
|
|
668
|
$self->{_fh} = $fh; |
138
|
289
|
|
|
|
|
1064
|
$self->{_fhpos} = 0; |
139
|
289
|
|
|
|
|
692
|
$self->{_flush} = 1; |
140
|
289
|
|
|
|
|
646
|
$self->{_writeable} = $writeable; |
141
|
289
|
100
|
|
|
|
2018
|
$self->{_is_seekable} = UNIVERSAL::isa($fh,'IO::Seekable')?1:0; |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
|
144
|
289
|
|
|
|
|
577
|
return $self; |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=head2 seek |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
Seek to a position. |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
Return our current position. If our file handle is not |
152
|
|
|
|
|
|
|
B it will return 0 and, if |
153
|
|
|
|
|
|
|
B<$File::Binary::DEBUG> is set to 1, there will be a warning. |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
You can optionally pass a whence option in the same way as |
156
|
|
|
|
|
|
|
the builtin Perl seek() method. It defaults to C. |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
Returns the current file position. |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=cut |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub seek { |
164
|
10
|
|
|
10
|
1
|
2585
|
my $self = shift; |
165
|
10
|
|
|
|
|
12
|
my $seek = shift; |
166
|
10
|
|
50
|
|
|
32
|
my $whence = shift || SEEK_SET; |
167
|
10
|
50
|
|
|
|
19
|
unless ($self->{_is_seekable}) { |
168
|
0
|
0
|
|
|
|
0
|
carp "FH is not seekable" if $DEBUG; |
169
|
0
|
|
|
|
|
0
|
return 0; |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
|
172
|
10
|
50
|
|
|
|
42
|
$self->{_fh}->seek($seek, $whence) if defined $seek; |
173
|
10
|
|
|
|
|
169
|
$self->_init_bits(); |
174
|
10
|
|
|
|
|
24
|
return $self->{_fh}->tell(); |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=head2 tell |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
Return our current position. If our file handle is not |
183
|
|
|
|
|
|
|
B then it will return 0 and, if |
184
|
|
|
|
|
|
|
B<$File::Binary::DEBUG> is set to 1, there will be a |
185
|
|
|
|
|
|
|
warning. |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=cut |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
sub tell { |
190
|
10
|
|
|
10
|
1
|
38
|
my $self = shift; |
191
|
10
|
50
|
|
|
|
22
|
unless ($self->{_is_seekable}) { |
192
|
0
|
0
|
|
|
|
0
|
carp "FH is not seekable" if $DEBUG; |
193
|
0
|
|
|
|
|
0
|
return 0; |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
|
196
|
10
|
|
|
|
|
35
|
return $self->{_fh}->tell(); |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=head2 set_flush |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
To flush or not to flush. That is the question |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=cut |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
sub set_flush { |
208
|
0
|
|
|
0
|
1
|
0
|
my ($self, $flush) = @_; |
209
|
|
|
|
|
|
|
|
210
|
0
|
|
|
|
|
0
|
$self->{_flush} = $flush; |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
=head2 set_endian |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
Set the how the module reads files. The options are |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
$BIG_ENDIAN |
219
|
|
|
|
|
|
|
$LITTLE_ENDIAN |
220
|
|
|
|
|
|
|
$NATIVE_ENDIAN |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
I will deduce the endianess of the current system. |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=cut |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
sub set_endian { |
228
|
578
|
|
|
578
|
1
|
3493
|
my ($self, $endian) = @_; |
229
|
|
|
|
|
|
|
|
230
|
578
|
|
66
|
|
|
2252
|
$endian ||= $NATIVE_ENDIAN; |
231
|
|
|
|
|
|
|
|
232
|
578
|
100
|
|
|
|
1999
|
$endian = guess_endian() if ($endian == $NATIVE_ENDIAN); |
233
|
|
|
|
|
|
|
|
234
|
578
|
100
|
|
|
|
1466
|
if ($endian == $BIG_ENDIAN) { |
235
|
144
|
|
|
|
|
1065
|
$self->{_ui16} = 'v'; |
236
|
144
|
|
|
|
|
280
|
$self->{_ui32} = 'V'; |
237
|
|
|
|
|
|
|
} else { |
238
|
434
|
|
|
|
|
1391
|
$self->{_ui16} = 'n'; |
239
|
434
|
|
|
|
|
1017
|
$self->{_ui32} = 'N'; |
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
|
242
|
578
|
|
|
|
|
1388
|
$self->{_endian} = $endian; |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
sub _init_bits { |
248
|
2904
|
|
|
2904
|
|
4518
|
my $self = shift; |
249
|
|
|
|
|
|
|
|
250
|
2904
|
50
|
|
|
|
6390
|
if ($self->{_writeable}) { |
251
|
2904
|
|
|
|
|
6071
|
$self->_init_bits_write(); |
252
|
|
|
|
|
|
|
} else { |
253
|
0
|
|
|
|
|
0
|
$self->_init_bits_read(); |
254
|
|
|
|
|
|
|
} |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
sub _init_bits_write { |
259
|
2904
|
|
|
2904
|
|
3341
|
my $self = shift; |
260
|
|
|
|
|
|
|
|
261
|
2904
|
|
|
|
|
4370
|
my $bits = $self->{'_bitbuf'}; |
262
|
|
|
|
|
|
|
|
263
|
2904
|
|
|
|
|
3943
|
my $len = length($bits); |
264
|
|
|
|
|
|
|
|
265
|
2904
|
50
|
|
|
|
10928
|
return if $len<=0; |
266
|
|
|
|
|
|
|
|
267
|
0
|
|
|
|
|
0
|
$self->{'_bitbuf'} = ''; |
268
|
0
|
|
|
|
|
0
|
$self->{_fh}->write(pack('B8', $bits.('0'x(8-$len)))); |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
sub _init_bits_read { |
273
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
274
|
|
|
|
|
|
|
|
275
|
0
|
|
|
|
|
0
|
$self->{_pos} = 0; |
276
|
0
|
|
|
|
|
0
|
$self->{_bits} = 0; |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
=head2 get_bytes |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
Get an arbitary number of bytes from the file. |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
=cut |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
sub get_bytes { |
288
|
2894
|
|
|
2894
|
1
|
3800
|
my ($self, $bytes) = @_; |
289
|
|
|
|
|
|
|
|
290
|
2894
|
|
|
|
|
3457
|
$bytes = int $bytes; |
291
|
|
|
|
|
|
|
|
292
|
2894
|
50
|
|
|
|
8247
|
carp("Must be positive number") if ($bytes <1); |
293
|
2894
|
50
|
|
|
|
6777
|
carp("This file has been opened in write mode.") if $self->{_writeable} == 1; |
294
|
|
|
|
|
|
|
|
295
|
2894
|
50
|
|
|
|
9989
|
$self->_init_bits() if $self->{_flush}; |
296
|
|
|
|
|
|
|
|
297
|
2894
|
|
|
|
|
12584
|
$self->{_fh}->read(my $data, $bytes); |
298
|
|
|
|
|
|
|
|
299
|
2894
|
|
|
|
|
1364887
|
$self->{_fhpos} += $bytes; |
300
|
|
|
|
|
|
|
|
301
|
2894
|
|
|
|
|
19219
|
return $data; |
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=head2 put_bytes |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
Write some bytes |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
=cut |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
sub put_bytes { |
312
|
958
|
|
|
958
|
1
|
1449
|
my ($self, $bytes) = @_; |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
|
315
|
958
|
50
|
|
|
|
2361
|
carp("This file has been opened in read mode.") unless $self->{_writeable}; |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
## TODO? |
318
|
|
|
|
|
|
|
#$self->_init_bits; |
319
|
958
|
|
|
|
|
5228
|
$self->{_fh}->write($bytes); |
320
|
|
|
|
|
|
|
} |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# we could use POSIX::ceil here but I ph34r the POSIX lib |
326
|
|
|
|
|
|
|
sub _round { |
327
|
958
|
|
50
|
958
|
|
2936
|
my $num = shift || 0; |
328
|
|
|
|
|
|
|
|
329
|
958
|
|
|
|
|
6078
|
return int ($num + 0.5 * ($num <=> 0 ) ); |
330
|
|
|
|
|
|
|
} |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
sub _get_num { |
337
|
2894
|
|
|
2894
|
|
5250
|
my ($self, $bytes, $template)=@_; |
338
|
|
|
|
|
|
|
|
339
|
2894
|
|
|
|
|
6881
|
unpack $template, $self->get_bytes($bytes); |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
sub _put_num { |
344
|
958
|
|
|
958
|
|
1469
|
my ($self, $num, $template) = @_; |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
|
347
|
958
|
|
|
|
|
2568
|
$self->put_bytes(pack($template, _round($num))); |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
## 8 bit |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
=head2 get_ui8 get_si8 put_ui8 put_si8 |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
read or write signed or unsigned 8 bit integers |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
=cut |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
sub get_ui8 { |
361
|
162
|
|
|
162
|
1
|
471
|
my $self = shift; |
362
|
162
|
|
|
|
|
457
|
$self->_get_num(1, 'C'); |
363
|
|
|
|
|
|
|
} |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
sub get_si8 { |
369
|
288
|
|
|
288
|
1
|
904
|
my $self = shift; |
370
|
288
|
|
|
|
|
838
|
$self->_get_num(1, 'c'); |
371
|
|
|
|
|
|
|
} |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
sub put_ui8 { |
376
|
54
|
|
|
54
|
1
|
24034
|
my ($self,$num) = @_; |
377
|
54
|
|
|
|
|
406
|
$self->_put_num($num, 'C'); |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
sub put_si8 { |
382
|
96
|
|
|
96
|
1
|
47195
|
my ($self,$num) = @_; |
383
|
96
|
|
|
|
|
268
|
$self->_put_num($num, 'c'); |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
} |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
## 16 bit |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
=head2 get_ui16 get_si16 put_ui16 put_si16 |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
read or write signed or unsigned 16 bit integers |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=cut |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
sub get_ui16 { |
397
|
828
|
|
|
828
|
1
|
2001
|
my $self = shift; |
398
|
828
|
|
|
|
|
2377
|
$self->_get_num(2, $self->{_ui16}); |
399
|
|
|
|
|
|
|
} |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
sub get_si16 { |
403
|
540
|
|
|
540
|
1
|
1552
|
my $self = shift; |
404
|
|
|
|
|
|
|
|
405
|
540
|
|
|
|
|
1207
|
my $num = $self->get_ui16(); |
406
|
540
|
100
|
|
|
|
1491
|
$num -= (1<<16) if $num>=(1<<15); |
407
|
|
|
|
|
|
|
|
408
|
540
|
|
|
|
|
2554
|
return $num; |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
sub put_ui16 { |
414
|
276
|
|
|
276
|
1
|
102004
|
my ($self,$num) = @_; |
415
|
|
|
|
|
|
|
|
416
|
276
|
|
|
|
|
1187
|
$self->_put_num($num, $self->{_ui16}); |
417
|
|
|
|
|
|
|
} |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
*put_si16 = \&put_ui16; |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
## 32 bit |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
=head2 get_ui32 get_s32 put_ui32 put_si32 |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
read or write signed or unsigned 32 bit integers |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
=cut |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
sub get_ui32 { |
434
|
1616
|
|
|
1616
|
1
|
2474
|
my $self = shift; |
435
|
1616
|
|
|
|
|
4847
|
return $self->_get_num(4, $self->{_ui32}); |
436
|
|
|
|
|
|
|
} |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
sub get_si32 { |
440
|
1076
|
|
|
1076
|
0
|
2369
|
my $self = shift; |
441
|
|
|
|
|
|
|
|
442
|
1076
|
|
|
|
|
2418
|
my $num = $self->get_ui32(); |
443
|
1076
|
100
|
|
|
|
2976
|
$num -= (2**32) if ($num>=(2**31)); |
444
|
1076
|
|
|
|
|
4482
|
return $num; |
445
|
|
|
|
|
|
|
} |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
sub put_ui32 { |
449
|
532
|
|
|
532
|
1
|
228919
|
my ($self, $num) = @_; |
450
|
|
|
|
|
|
|
|
451
|
532
|
|
|
|
|
1593
|
$self->_put_num($num, $self->{_ui32}); |
452
|
|
|
|
|
|
|
} |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
*put_si32 = \&put_ui32; |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
=head2 guess_endian |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
Guess the endianness of this system. Returns either I<$LITTLE_ENDIAN> |
462
|
|
|
|
|
|
|
or I<$BIG_ENDIAN> |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=cut |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
sub guess_endian { |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
#my $svalue = int rand (2**16)-1; |
470
|
|
|
|
|
|
|
#my $lvalue = int rand (2**32)-1; |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
#my $sp = pack("S", $svalue); |
473
|
|
|
|
|
|
|
#my $lp = pack("L", $lvalue); |
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
#if (unpack("V", $lp) == $lvalue && unpack("v", $sp) == $svalue) { |
477
|
|
|
|
|
|
|
# return $LITTLE_ENDIAN; |
478
|
|
|
|
|
|
|
#} elsif (unpack("N", $lp) == $lvalue && unpack("n", $sp) == $svalue) { |
479
|
|
|
|
|
|
|
# return $BIG_ENDIAN; |
480
|
|
|
|
|
|
|
#} else { |
481
|
|
|
|
|
|
|
# carp "Couldn't determine whether this machine is big-endian or little-endian\n"; |
482
|
|
|
|
|
|
|
#} |
483
|
|
|
|
|
|
|
|
484
|
289
|
|
|
289
|
1
|
86856
|
my $bo = $Config{'byteorder'}; |
485
|
|
|
|
|
|
|
|
486
|
289
|
50
|
33
|
|
|
278923
|
if (1234 == $bo or 12345678 == $bo) { |
|
|
0
|
0
|
|
|
|
|
487
|
289
|
|
|
|
|
868
|
return $LITTLE_ENDIAN; |
488
|
|
|
|
|
|
|
} elsif (4321 == $bo or 87654321 == $bo) { |
489
|
0
|
|
|
|
|
0
|
return $BIG_ENDIAN; |
490
|
|
|
|
|
|
|
} else { |
491
|
0
|
|
|
|
|
0
|
carp "Unsupported architecture (probably a Cray or weird order)\n"; |
492
|
|
|
|
|
|
|
} |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
} |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
=head2 close |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
Close the file up. The I object will then be useless |
501
|
|
|
|
|
|
|
until you open up another file; |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
=cut |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
sub close { |
506
|
289
|
|
|
289
|
1
|
30387
|
my $self = shift; |
507
|
289
|
|
|
|
|
2362
|
$self->{_fh}->close(); |
508
|
289
|
|
|
|
|
14268
|
$self = {}; |
509
|
|
|
|
|
|
|
} |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
=pod |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
=head1 BUGS |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
Can't do numbers greater than 32 bits. |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
Can't extract Floating Point or Fixed Point numbers. |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
Can't extract null terminated strings. |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
Needs tests for seeking and telling. |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
=head1 COPYING |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
(c)opyright 2002, Simon Wistow |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
Distributed under the same terms as Perl itself. |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
This software is under no warranty and will probably ruin your life, kill your friends, burn your house and bring about the apocalypse |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
=head1 AUTHOR |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
Copyright 2003, Simon Wistow |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
=cut |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
1; |