line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package SWF::BinStream;
|
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
8
|
use strict;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
58
|
|
4
|
1
|
|
|
1
|
|
8
|
use vars qw($VERSION);
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
74
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
$VERSION="0.11";
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
##
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
package SWF::BinStream::Read;
|
11
|
|
|
|
|
|
|
|
12
|
1
|
|
|
1
|
|
6
|
use Carp;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
75
|
|
13
|
1
|
|
|
1
|
|
958
|
use Data::TemporaryBag;
|
|
1
|
|
|
|
|
58852
|
|
|
1
|
|
|
|
|
1522
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
sub new {
|
17
|
1
|
|
|
1
|
|
4
|
my ($class, $initialdata, $shortsub, $version) = @_;
|
18
|
0
|
|
|
0
|
|
0
|
my $self = bless {
|
19
|
|
|
|
|
|
|
'_bits' => '',
|
20
|
|
|
|
|
|
|
'_stream' =>Data::TemporaryBag->new,
|
21
|
|
|
|
|
|
|
'_shortsub' =>$shortsub||sub{0},
|
22
|
1
|
|
50
|
|
|
6
|
'_pos' => 0,
|
|
|
|
50
|
|
|
|
|
23
|
|
|
|
|
|
|
'_codec' => [],
|
24
|
|
|
|
|
|
|
'_version' => $version||5,
|
25
|
|
|
|
|
|
|
'_lock_version' => 0,
|
26
|
|
|
|
|
|
|
}, $class;
|
27
|
1
|
50
|
|
|
|
53
|
$self->add_stream($initialdata) if $initialdata ne '';
|
28
|
1
|
|
|
|
|
12
|
$self;
|
29
|
|
|
|
|
|
|
}
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub Version {
|
32
|
1
|
|
|
1
|
|
23
|
my ($self, $ver) = @_;
|
33
|
|
|
|
|
|
|
|
34
|
1
|
50
|
|
|
|
4
|
if (defined $ver) {
|
35
|
1
|
50
|
|
|
|
14
|
croak "Can't change SWF version " if $self->{_lock_version};
|
36
|
1
|
|
|
|
|
3
|
$self->{_version} = $ver;
|
37
|
|
|
|
|
|
|
}
|
38
|
1
|
|
|
|
|
4
|
$self->{_version};
|
39
|
|
|
|
|
|
|
}
|
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
sub _lock_version {
|
42
|
0
|
|
|
0
|
|
0
|
shift->{_lock_version} = 1;
|
43
|
|
|
|
|
|
|
}
|
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub add_stream {
|
46
|
2
|
|
|
2
|
|
4
|
my ($self, $data) = @_;
|
47
|
|
|
|
|
|
|
|
48
|
2
|
|
|
|
|
3
|
for my $codec ( @{$self->{'_codec'}} ) {
|
|
2
|
|
|
|
|
9
|
|
49
|
1
|
|
|
|
|
8
|
$data = $codec->decode($data);
|
50
|
|
|
|
|
|
|
}
|
51
|
2
|
|
|
|
|
13
|
$self->{'_stream'}->add($data);
|
52
|
|
|
|
|
|
|
}
|
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub _require {
|
55
|
98
|
|
|
98
|
|
177
|
my ($self, $bytes) = @_;
|
56
|
|
|
|
|
|
|
{
|
57
|
98
|
|
|
|
|
4519
|
my $len=$self->{'_stream'}->length;
|
|
98
|
|
|
|
|
264
|
|
58
|
|
|
|
|
|
|
|
59
|
98
|
50
|
|
|
|
454
|
if ($len < $bytes) {
|
60
|
0
|
0
|
|
|
|
0
|
$self->{'_shortsub'}->($self, $bytes-$len) and redo;
|
61
|
0
|
|
|
|
|
0
|
croak "Stream ran short ";
|
62
|
|
|
|
|
|
|
}
|
63
|
|
|
|
|
|
|
}
|
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
}
|
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub Length {
|
68
|
9
|
|
|
9
|
|
37
|
return $_[0]->{'_stream'}->length;
|
69
|
|
|
|
|
|
|
}
|
70
|
|
|
|
|
|
|
|
71
|
24
|
|
|
24
|
|
156
|
sub tell {$_[0]->{'_pos'}};
|
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub get_string {
|
74
|
92
|
|
|
92
|
|
264
|
my ($self, $bytes, $fNoFlush) = @_;
|
75
|
|
|
|
|
|
|
|
76
|
92
|
100
|
|
|
|
189
|
flush_bits($self) unless $fNoFlush;
|
77
|
92
|
|
|
|
|
141
|
_require($self, $bytes);
|
78
|
92
|
|
|
|
|
249
|
$self->{'_pos'}+=$bytes;
|
79
|
92
|
|
|
|
|
259
|
$self->{'_stream'}->substr(0, $bytes, '');
|
80
|
|
|
|
|
|
|
}
|
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
sub lookahead_string {
|
83
|
0
|
|
|
0
|
|
0
|
my ($self, $offset, $bytes) = @_;
|
84
|
|
|
|
|
|
|
|
85
|
0
|
|
|
|
|
0
|
_require($self, $offset);
|
86
|
0
|
|
|
|
|
0
|
$self->{'_stream'}->substr($offset, $bytes);
|
87
|
|
|
|
|
|
|
}
|
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub get_UI8 {
|
90
|
12
|
|
|
12
|
|
28
|
unpack 'C', get_string(shift, 1);
|
91
|
|
|
|
|
|
|
}
|
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
sub lookahead_UI8 {
|
94
|
0
|
|
|
0
|
|
0
|
unpack 'C', lookahead_string(@_[0, 1], 1);
|
95
|
|
|
|
|
|
|
}
|
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub get_SI8 {
|
98
|
0
|
|
|
0
|
|
0
|
unpack 'c', get_string(shift, 1);
|
99
|
|
|
|
|
|
|
}
|
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
sub lookahead_SI8 {
|
102
|
0
|
|
|
0
|
|
0
|
unpack 'c', lookahead_string(@_[0, 1], 1);
|
103
|
|
|
|
|
|
|
}
|
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub get_UI16 {
|
106
|
11
|
|
|
11
|
|
141
|
unpack 'v', get_string(shift, 2);
|
107
|
|
|
|
|
|
|
}
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub lookahead_UI16 {
|
110
|
0
|
|
|
0
|
|
0
|
unpack 'v', lookahead_string(@_[0, 1], 2);
|
111
|
|
|
|
|
|
|
}
|
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
sub get_SI16 {
|
114
|
0
|
|
|
0
|
|
0
|
my $w = &get_UI16;
|
115
|
0
|
0
|
|
|
|
0
|
$w -= (1<<16) if $w>=(1<<15);
|
116
|
0
|
|
|
|
|
0
|
$w;
|
117
|
|
|
|
|
|
|
}
|
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
sub lookahead_SI16 {
|
120
|
0
|
|
|
0
|
|
0
|
my $w = &lookahead_UI16;
|
121
|
0
|
0
|
|
|
|
0
|
$w -= (1<<16) if $w>=(1<<15);
|
122
|
0
|
|
|
|
|
0
|
$w;
|
123
|
|
|
|
|
|
|
}
|
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
sub get_UI32 {
|
126
|
2
|
|
|
2
|
|
10
|
unpack 'V', get_string(shift, 4);
|
127
|
|
|
|
|
|
|
}
|
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
sub lookahead_UI32 {
|
130
|
0
|
|
|
0
|
|
0
|
unpack 'V', lookahead_string(@_[0, 1], 4);
|
131
|
|
|
|
|
|
|
}
|
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub get_SI32 {
|
134
|
0
|
|
|
0
|
|
0
|
my $ww = &get_UI32;
|
135
|
0
|
0
|
|
|
|
0
|
$ww -= (2**32) if $ww>=(2**31);
|
136
|
0
|
|
|
|
|
0
|
$ww;
|
137
|
|
|
|
|
|
|
}
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
sub lookahead_SI32 {
|
140
|
0
|
|
|
0
|
|
0
|
my $ww = &lookahead_UI32;
|
141
|
0
|
0
|
|
|
|
0
|
$ww -= (2**32) if $ww>=(2**31);
|
142
|
0
|
|
|
|
|
0
|
$ww;
|
143
|
|
|
|
|
|
|
}
|
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub flush_bits {
|
146
|
44
|
|
|
44
|
|
98
|
$_[0]->{'_bits'}='';
|
147
|
|
|
|
|
|
|
}
|
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
sub get_bits {
|
150
|
81
|
|
|
81
|
|
100
|
my ($self, $bits) = @_;
|
151
|
81
|
|
|
|
|
119
|
my $len = length($self->{'_bits'});
|
152
|
|
|
|
|
|
|
|
153
|
81
|
100
|
|
|
|
154
|
if ( $len < $bits) {
|
154
|
57
|
|
|
|
|
87
|
my $slen = (($bits - $len - 1) >>3) + 1;
|
155
|
57
|
|
|
|
|
145
|
$self->{'_bits'}.=join '', unpack('B8' x $slen, $self->get_string($slen, 'NoFlush'));
|
156
|
|
|
|
|
|
|
}
|
157
|
81
|
|
|
|
|
3175
|
unpack('N', pack('B32', '0' x (32-$bits).substr($self->{'_bits'}, 0, $bits, '')));
|
158
|
|
|
|
|
|
|
}
|
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub get_sbits {
|
161
|
44
|
|
|
44
|
|
52
|
my ($self, $bits) = @_;
|
162
|
|
|
|
|
|
|
|
163
|
44
|
|
|
|
|
64
|
my $b = &get_bits;
|
164
|
44
|
100
|
|
|
|
146
|
$b -= (2**$bits) if $b>=(2**($bits-1));
|
165
|
44
|
|
|
|
|
228
|
$b;
|
166
|
|
|
|
|
|
|
}
|
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub close {
|
169
|
0
|
|
|
0
|
|
0
|
my $self = shift;
|
170
|
|
|
|
|
|
|
|
171
|
0
|
|
|
|
|
0
|
for my $codec ( @{$self->{'_codec'}} ) {
|
|
0
|
|
|
|
|
0
|
|
172
|
0
|
|
|
|
|
0
|
$codec->close;
|
173
|
|
|
|
|
|
|
}
|
174
|
0
|
|
|
|
|
0
|
$self->{'_stream'}->clear;
|
175
|
|
|
|
|
|
|
}
|
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
sub add_codec {
|
179
|
1
|
|
|
1
|
|
4
|
my ($self, $codec) = @_;
|
180
|
|
|
|
|
|
|
|
181
|
1
|
50
|
|
|
|
1141
|
require "SWF/BinStream/Codec/${codec}.pm" or croak "Can't find codec '$codec'";
|
182
|
|
|
|
|
|
|
|
183
|
1
|
50
|
|
|
|
14
|
my $m = "SWF::BinStream::Codec::${codec}::Read"->new or croak "Can't find codec '$codec' ";
|
184
|
|
|
|
|
|
|
|
185
|
1
|
|
|
|
|
3
|
push @{$self->{'_codec'}}, $m;
|
|
1
|
|
|
|
|
4
|
|
186
|
|
|
|
|
|
|
|
187
|
1
|
50
|
|
|
|
6
|
if (( my $old_stream = $self->{'_stream'})->length > 0) {
|
188
|
1
|
|
|
|
|
12
|
my $new_stream = Data::TemporaryBag->new;
|
189
|
|
|
|
|
|
|
|
190
|
1
|
|
|
|
|
13
|
while ($old_stream->length > 0) {
|
191
|
1
|
|
|
|
|
9
|
$new_stream->add($m->decode($old_stream->substr(0, 1024, '')));
|
192
|
|
|
|
|
|
|
}
|
193
|
1
|
|
|
|
|
17
|
$self->{'_stream'} = $new_stream;
|
194
|
|
|
|
|
|
|
}
|
195
|
|
|
|
|
|
|
}
|
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
1;
|
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
package SWF::BinStream::Write;
|
200
|
|
|
|
|
|
|
|
201
|
1
|
|
|
1
|
|
12
|
use Carp;
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
551
|
|
202
|
1
|
|
|
1
|
|
8
|
use Data::TemporaryBag;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8018
|
|
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
sub new {
|
205
|
9
|
|
|
9
|
|
15
|
my ($class, $version) = @_;
|
206
|
9
|
|
50
|
|
|
41
|
bless { '_bits' => '',
|
207
|
|
|
|
|
|
|
'_stream' => Data::TemporaryBag->new,
|
208
|
|
|
|
|
|
|
'_pos' => 0,
|
209
|
|
|
|
|
|
|
'_flushsize' => 0,
|
210
|
|
|
|
|
|
|
'_mark' => {},
|
211
|
|
|
|
|
|
|
'_codec' => [],
|
212
|
|
|
|
|
|
|
'_version' => $version || 5,
|
213
|
|
|
|
|
|
|
'_lock_version' => 0,
|
214
|
|
|
|
|
|
|
'_framecount' => 0,
|
215
|
|
|
|
|
|
|
}, $class;
|
216
|
|
|
|
|
|
|
}
|
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
sub Version {
|
219
|
10
|
|
|
10
|
|
14
|
my ($self, $ver) = @_;
|
220
|
|
|
|
|
|
|
|
221
|
10
|
50
|
|
|
|
24
|
if (defined $ver) {
|
222
|
0
|
0
|
|
|
|
0
|
croak "Can't change SWF version " if $self->{_lock_version};
|
223
|
0
|
|
|
|
|
0
|
$self->{_version} = $ver;
|
224
|
|
|
|
|
|
|
}
|
225
|
10
|
|
|
|
|
45
|
$self->{_version};
|
226
|
|
|
|
|
|
|
}
|
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
sub _lock_version {
|
229
|
0
|
|
|
0
|
|
0
|
shift->{_lock_version} = 1;
|
230
|
|
|
|
|
|
|
}
|
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub autoflush {
|
233
|
1
|
|
|
1
|
|
3
|
my ($self, $size, $flushsub)=@_;
|
234
|
|
|
|
|
|
|
|
235
|
1
|
|
|
|
|
8
|
$self->{'_flushsize'}=$size;
|
236
|
1
|
|
|
|
|
4
|
$self->{'_flushsub'}=$flushsub;
|
237
|
|
|
|
|
|
|
}
|
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
sub _write_stream {
|
240
|
37
|
|
|
37
|
|
56
|
my ($self, $data) = @_;
|
241
|
|
|
|
|
|
|
|
242
|
37
|
|
|
|
|
43
|
for my $codec ( @{$self->{'_codec'}} ) {
|
|
37
|
|
|
|
|
87
|
|
243
|
4
|
|
|
|
|
98
|
$data = $codec->encode($data);
|
244
|
|
|
|
|
|
|
}
|
245
|
37
|
100
|
|
|
|
96
|
return if $data eq '';
|
246
|
|
|
|
|
|
|
|
247
|
34
|
|
|
|
|
120
|
$self->{'_stream'}->add($data);
|
248
|
|
|
|
|
|
|
|
249
|
34
|
50
|
66
|
|
|
590
|
if ($self->{'_flushsize'}>0 and $self->{'_stream'}->length >= $self->{'_flushsize'}) {
|
250
|
0
|
|
|
|
|
0
|
$self->flush_stream($self->{'_flushsize'});
|
251
|
|
|
|
|
|
|
}
|
252
|
|
|
|
|
|
|
}
|
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
sub flush_stream {
|
255
|
15
|
|
|
15
|
|
102
|
my ($self, $size)=@_;
|
256
|
15
|
|
|
|
|
19
|
my $str;
|
257
|
|
|
|
|
|
|
|
258
|
15
|
50
|
66
|
|
|
53
|
if ( !$size or $size>$self->Length ) {
|
259
|
15
|
|
|
|
|
95
|
$self->flush_bits;
|
260
|
|
|
|
|
|
|
}
|
261
|
|
|
|
|
|
|
|
262
|
15
|
100
|
|
|
|
33
|
if ($size) {
|
263
|
14
|
|
|
|
|
53
|
$str = $self->{'_stream'}->substr( 0, $size, '');
|
264
|
14
|
|
|
|
|
392
|
$self->{'_pos'} += length($str);
|
265
|
|
|
|
|
|
|
} else {
|
266
|
1
|
|
|
|
|
7
|
$str=$self->{'_stream'}->value;
|
267
|
1
|
|
|
|
|
26
|
$self->{'_pos'}+=length($str);
|
268
|
1
|
|
|
|
|
19
|
$self->{'_stream'}=Data::TemporaryBag->new;
|
269
|
|
|
|
|
|
|
}
|
270
|
|
|
|
|
|
|
|
271
|
15
|
100
|
|
|
|
55
|
$self->{'_flushsub'}->($self, $str) if defined $self->{'_flushsub'};
|
272
|
|
|
|
|
|
|
|
273
|
15
|
|
|
|
|
53
|
$str;
|
274
|
|
|
|
|
|
|
}
|
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
sub flush_bits {
|
277
|
52
|
|
|
52
|
|
65
|
my $self = $_[0];
|
278
|
52
|
|
|
|
|
91
|
my $bits = $self->{'_bits'};
|
279
|
52
|
|
|
|
|
60
|
my $len = length($bits);
|
280
|
|
|
|
|
|
|
|
281
|
52
|
100
|
|
|
|
130
|
return if $len<=0;
|
282
|
4
|
|
|
|
|
10
|
$self->{'_bits'}='';
|
283
|
4
|
|
|
|
|
28
|
$self->_write_stream(pack('B8', $bits.('0'x(8-$len))));
|
284
|
|
|
|
|
|
|
}
|
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
sub Length {
|
287
|
30
|
|
|
30
|
|
118
|
return $_[0]->{'_stream'}->length;
|
288
|
|
|
|
|
|
|
}
|
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
sub tell {
|
291
|
16
|
|
|
16
|
|
23
|
my $self=shift;
|
292
|
16
|
|
|
|
|
51
|
my $pos= $self->{'_pos'} + $self->Length;
|
293
|
16
|
100
|
|
|
|
319
|
$pos++ if length($self->{'_bits'})>0;
|
294
|
16
|
|
|
|
|
43
|
$pos;
|
295
|
|
|
|
|
|
|
}
|
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
sub mark {
|
298
|
8
|
|
|
8
|
|
13
|
my ($self, $key, $obj)=@_;
|
299
|
|
|
|
|
|
|
|
300
|
8
|
50
|
|
|
|
18
|
if (not defined $key) {
|
|
|
0
|
|
|
|
|
|
301
|
8
|
|
|
|
|
14
|
return %{$self->{_mark}};
|
|
8
|
|
|
|
|
31
|
|
302
|
|
|
|
|
|
|
} elsif (not defined $obj) {
|
303
|
0
|
0
|
|
|
|
0
|
return wantarray ? $self->{_mark}{$key}[0] : @{$self->{_mark}{$key}};
|
|
0
|
|
|
|
|
0
|
|
304
|
|
|
|
|
|
|
} else {
|
305
|
0
|
|
|
|
|
0
|
push @{$self->{_mark}{$key}}, $self->tell, $obj;
|
|
0
|
|
|
|
|
0
|
|
306
|
|
|
|
|
|
|
}
|
307
|
|
|
|
|
|
|
}
|
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
sub sub_stream {
|
310
|
8
|
|
|
8
|
|
15
|
my $self=shift;
|
311
|
8
|
|
|
|
|
24
|
my $sub_stream=SWF::BinStream::Write->new($self->Version);
|
312
|
8
|
|
|
|
|
161
|
$sub_stream->{_parent}=$self;
|
313
|
8
|
|
|
|
|
33
|
bless $sub_stream, 'SWF::BinStream::Write::SubStream';
|
314
|
|
|
|
|
|
|
}
|
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
sub set_string {
|
317
|
33
|
|
|
33
|
|
54
|
my ($self, $str) = @_;
|
318
|
|
|
|
|
|
|
|
319
|
33
|
|
|
|
|
74
|
$self->flush_bits;
|
320
|
33
|
|
|
|
|
75
|
$self->_write_stream($str);
|
321
|
|
|
|
|
|
|
}
|
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
sub _round {
|
324
|
184
|
|
|
184
|
|
209
|
my $a=shift;
|
325
|
|
|
|
|
|
|
|
326
|
184
|
100
|
|
|
|
414
|
return 0 unless $a;
|
327
|
145
|
|
|
|
|
493
|
return int($a+0.5*($a<=>0));
|
328
|
|
|
|
|
|
|
}
|
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
sub set_UI8 {
|
331
|
12
|
|
|
12
|
|
29
|
$_[0]->set_string(pack('C', _round($_[1])));
|
332
|
|
|
|
|
|
|
}
|
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
sub set_SI8 {
|
335
|
0
|
|
|
0
|
|
0
|
$_[0]->set_string(pack('c', _round($_[1])));
|
336
|
|
|
|
|
|
|
}
|
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
sub set_UI16 {
|
339
|
11
|
|
|
11
|
|
34
|
$_[0]->set_string(pack('v', _round($_[1])));
|
340
|
|
|
|
|
|
|
}
|
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
*set_SI16 = \&set_UI16;
|
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
#sub set_SI16 {
|
345
|
|
|
|
|
|
|
# my ($self, $num) = @_;
|
346
|
|
|
|
|
|
|
# $num += (1<<16) if $num<0;
|
347
|
|
|
|
|
|
|
# $self->set_UI16($num);
|
348
|
|
|
|
|
|
|
#}
|
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
sub set_UI32 {
|
351
|
2
|
|
|
2
|
|
6
|
$_[0]->set_string(pack('V', _round($_[1])));
|
352
|
|
|
|
|
|
|
}
|
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
*set_SI32 = \&set_UI32;
|
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
#sub set_SI32 {
|
357
|
|
|
|
|
|
|
# my ($self, $num) = @_;
|
358
|
|
|
|
|
|
|
# $num += (2**32) if $num<0;
|
359
|
|
|
|
|
|
|
# $self->set_UI32($num);
|
360
|
|
|
|
|
|
|
#}
|
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
sub set_bits {
|
363
|
71
|
|
|
71
|
|
101
|
my ($self, $num, $nbits) = @_;
|
364
|
71
|
50
|
|
|
|
140
|
return unless $nbits;
|
365
|
71
|
|
|
|
|
144
|
$self->{'_bits'} .= substr(unpack('B*',pack('N', _round($num))), -$nbits);
|
366
|
71
|
|
|
|
|
115
|
my $s = '';
|
367
|
71
|
|
|
|
|
178
|
while (length($self->{'_bits'})>=8) {
|
368
|
73
|
|
|
|
|
258
|
$s .= pack('B8', substr($self->{'_bits'}, 0,8, ''));
|
369
|
|
|
|
|
|
|
}
|
370
|
71
|
100
|
|
|
|
260
|
$self->{'_stream'}->add($s) if $s ne '';
|
371
|
|
|
|
|
|
|
}
|
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
sub set_sbits {
|
374
|
44
|
|
|
44
|
|
59
|
my ($self, $num, $nbits) = @_;
|
375
|
44
|
|
|
|
|
69
|
$num=_round($num);
|
376
|
44
|
100
|
|
|
|
92
|
$num += (2**$nbits) if $num<0;
|
377
|
44
|
|
|
|
|
90
|
$self->set_bits($num, $nbits);
|
378
|
|
|
|
|
|
|
}
|
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
sub set_bits_list {
|
381
|
0
|
|
|
0
|
|
0
|
my ($self, $nbitsbit, @param) = @_;
|
382
|
0
|
|
|
|
|
0
|
my $nbits=get_maxbits_of_bits_list(@param);
|
383
|
0
|
|
|
|
|
0
|
my $i;
|
384
|
|
|
|
|
|
|
|
385
|
0
|
|
|
|
|
0
|
$self->set_bits($nbits, $nbitsbit);
|
386
|
0
|
|
|
|
|
0
|
foreach $i (@param) {
|
387
|
0
|
|
|
|
|
0
|
$self->set_bits($i, $nbits);
|
388
|
|
|
|
|
|
|
}
|
389
|
|
|
|
|
|
|
}
|
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
sub set_sbits_list {
|
392
|
4
|
|
|
4
|
|
9
|
my ($self, $nbitsbit, @param) = @_;
|
393
|
4
|
|
|
|
|
11
|
my $nbits=get_maxbits_of_sbits_list(@param);
|
394
|
4
|
|
|
|
|
6
|
my $i;
|
395
|
|
|
|
|
|
|
|
396
|
4
|
|
|
|
|
15
|
$self->set_bits($nbits, $nbitsbit);
|
397
|
4
|
|
|
|
|
19
|
foreach $i (@param) {
|
398
|
12
|
|
|
|
|
104
|
$self->set_sbits($i, $nbits);
|
399
|
|
|
|
|
|
|
}
|
400
|
|
|
|
|
|
|
}
|
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
sub get_maxbits_of_bits_list {
|
403
|
12
|
|
|
12
|
|
25
|
my (@param)=@_;
|
404
|
12
|
|
|
|
|
13
|
my $max=shift;
|
405
|
12
|
|
|
|
|
14
|
my $i;
|
406
|
|
|
|
|
|
|
|
407
|
12
|
|
|
|
|
19
|
foreach $i(@param) {
|
408
|
44
|
100
|
|
|
|
93
|
$max=$i if $max<$i;
|
409
|
|
|
|
|
|
|
}
|
410
|
12
|
|
|
|
|
20
|
$i = 0;
|
411
|
12
|
|
|
|
|
1332
|
$i++ while ($max >= 2**$i);
|
412
|
12
|
|
|
|
|
38
|
return $i;
|
413
|
|
|
|
|
|
|
}
|
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
sub get_maxbits_of_sbits_list {
|
416
|
12
|
|
|
12
|
|
16
|
my $z = 0;
|
417
|
12
|
100
|
100
|
|
|
20
|
return (get_maxbits_of_bits_list(map{my $r=_round($_);$z ||= ($r!=0);($r<0)?(~$r):$r} @_)+$z);
|
|
44
|
|
|
|
|
71
|
|
|
44
|
|
|
|
|
187
|
|
|
44
|
|
|
|
|
111
|
|
418
|
|
|
|
|
|
|
}
|
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
sub close {
|
421
|
1
|
|
|
1
|
|
3
|
my $self = shift;
|
422
|
|
|
|
|
|
|
|
423
|
1
|
|
|
|
|
6
|
my $data = $self->flush_stream;
|
424
|
1
|
|
|
|
|
3
|
my $rest = '';
|
425
|
1
|
|
|
|
|
2
|
for my $codec ( @{$self->{'_codec'}} ) {
|
|
1
|
|
|
|
|
4
|
|
426
|
1
|
|
|
|
|
7
|
$rest = $codec->close($rest);
|
427
|
|
|
|
|
|
|
}
|
428
|
1
|
50
|
|
|
|
12
|
$self->{'_flushsub'}->($self, $rest) if defined $self->{'_flushsub'};
|
429
|
|
|
|
|
|
|
|
430
|
1
|
|
|
|
|
4
|
$data .= $rest;
|
431
|
1
|
|
|
|
|
3
|
$data;
|
432
|
|
|
|
|
|
|
}
|
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
sub add_codec {
|
435
|
1
|
|
|
1
|
|
3
|
my ($self, $codec) = @_;
|
436
|
|
|
|
|
|
|
|
437
|
1
|
50
|
|
|
|
3021
|
require "SWF/BinStream/Codec/${codec}.pm" or croak "Can't find codec '$codec'";
|
438
|
|
|
|
|
|
|
|
439
|
1
|
50
|
|
|
|
14
|
my $m = "SWF::BinStream::Codec::${codec}::Write"->new or croak "Can't find codec '$codec'";
|
440
|
|
|
|
|
|
|
|
441
|
1
|
|
|
|
|
4
|
push @{$self->{'_codec'}}, $m;
|
|
1
|
|
|
|
|
11
|
|
442
|
|
|
|
|
|
|
}
|
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
package SWF::BinStream::Write::SubStream;
|
445
|
|
|
|
|
|
|
|
446
|
1
|
|
|
1
|
|
16
|
use vars qw(@ISA);
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
422
|
|
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
@ISA=('SWF::BinStream::Write');
|
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
sub flush_stream {
|
451
|
8
|
|
|
8
|
|
14
|
my $self = shift;
|
452
|
8
|
|
|
|
|
451
|
my $p_tell = $self->{_parent}->tell;
|
453
|
|
|
|
|
|
|
|
454
|
8
|
|
|
|
|
33
|
while ((my $data = $self->SUPER::flush_stream(1024)) ne '') {
|
455
|
6
|
|
|
|
|
18
|
$self->{_parent}->set_string($data);
|
456
|
|
|
|
|
|
|
}
|
457
|
|
|
|
|
|
|
|
458
|
8
|
|
|
|
|
38
|
my @marks=$self->mark;
|
459
|
8
|
|
|
|
|
24
|
while (@marks) {
|
460
|
0
|
|
|
|
|
0
|
my $key = shift @marks;
|
461
|
0
|
|
|
|
|
0
|
my $mark = shift @marks;
|
462
|
0
|
|
|
|
|
0
|
$mark->[$_*2] += $p_tell for (0..@$mark/2-1);
|
463
|
0
|
|
|
|
|
0
|
push @{$self->{_parent}->{_mark}{$key}}, @$mark;
|
|
0
|
|
|
|
|
0
|
|
464
|
|
|
|
|
|
|
}
|
465
|
8
|
|
|
|
|
55
|
undef $self;
|
466
|
|
|
|
|
|
|
}
|
467
|
|
|
|
|
|
|
|
468
|
0
|
|
|
0
|
|
|
sub autoflush {} # Ignore autoflush.
|
469
|
0
|
|
|
0
|
|
|
sub add_codec {warn "Can't add codec to the sub stream"}
|
470
|
|
|
|
|
|
|
*SWF::BinStream::Write::SubStream::close = \&flush_stream;
|
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
1;
|
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
__END__
|