line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
############################################################################### |
2
|
|
|
|
|
|
|
#List.pm |
3
|
|
|
|
|
|
|
#Last Change: 2009-28-01 |
4
|
|
|
|
|
|
|
#Copyright (c) 2009 Marc-Seabstian "Maluku" Lucksch |
5
|
|
|
|
|
|
|
#Version 0.3 |
6
|
|
|
|
|
|
|
#################### |
7
|
|
|
|
|
|
|
#This file is part of the sofu.pm project, a parser library for an all-purpose |
8
|
|
|
|
|
|
|
#ASCII file format. More information can be found on the project web site |
9
|
|
|
|
|
|
|
#at http://sofu.sourceforge.net/ . |
10
|
|
|
|
|
|
|
# |
11
|
|
|
|
|
|
|
#sofu.pm is published under the terms of the MIT license, which basically means |
12
|
|
|
|
|
|
|
#"Do with it whatever you want". For more information, see the license.txt |
13
|
|
|
|
|
|
|
#file that should be enclosed with libsofu distributions. A copy of the license |
14
|
|
|
|
|
|
|
#is (at the time of this writing) also available at |
15
|
|
|
|
|
|
|
#http://www.opensource.org/licenses/mit-license.php . |
16
|
|
|
|
|
|
|
############################################################################### |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 NAME |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
Data::Sofu::Binary::Bin0200 - Driver for Sofu Binary version 0.2.0.0 |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 DESCRIPTION |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
Driver for C and C |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 Synopsis |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
See C |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=head1 SYNTAX |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
This Module is pure OO, exports nothing |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=cut |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
package Data::Sofu::Binary::Bin0200; |
39
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
50
|
|
40
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
38
|
|
41
|
1
|
|
|
1
|
|
6
|
use bytes; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
our $VERSION="0.3"; |
44
|
|
|
|
|
|
|
#We are really going to need these modules: |
45
|
1
|
|
|
1
|
|
40
|
use Encode; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
113
|
|
46
|
1
|
|
|
1
|
|
7
|
use Carp qw/confess/; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
55
|
|
47
|
|
|
|
|
|
|
require Data::Sofu; |
48
|
1
|
|
|
1
|
|
6
|
use base qw/Data::Sofu::Binary/; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
13742
|
|
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
#$SIG{__WARN__}=sub { confess @_;}; |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
=head1 METHODS |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
See also C for public methods. |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
All these methods are INTERNAL, not for use outside of this module... |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
Except pack(). |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=head2 new() |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
Creates a new Binary Driver using DRIVER or the latest one available. |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
require Data::Sofu::Binary; |
65
|
|
|
|
|
|
|
$bsofu = Data::Sofu::Binary->new("000_002_000_000"); Taking this driver; |
66
|
|
|
|
|
|
|
#You can call it directly: |
67
|
|
|
|
|
|
|
require Data::Sofu::Binary::Bin0200; |
68
|
|
|
|
|
|
|
$bsofu = Data::Sofu::Binary::Bin0200->new(); #The same |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=cut |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub new { |
73
|
7
|
|
|
7
|
1
|
15
|
my $class=shift; |
74
|
7
|
|
|
|
|
17
|
my $self={}; |
75
|
7
|
|
|
|
|
30
|
bless $self,$class; |
76
|
7
|
|
|
|
|
36
|
$self->{OBJECT}=0; |
77
|
7
|
|
|
|
|
24
|
$self->{COMMENTS}=[]; |
78
|
7
|
|
|
|
|
29
|
$self->{SUPPORTED}={"000_002_000_000"=>1}; |
79
|
7
|
|
|
|
|
52
|
return $self; |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=head2 encoding(ID) |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
Switches and/or detetect the encoding. |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
See pack() for more on encodings. |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=cut |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
sub encoding { #Switches the Encoding |
91
|
135
|
|
|
135
|
1
|
257
|
my $self=shift; |
92
|
135
|
|
|
|
|
363
|
my $id=shift; |
93
|
135
|
|
|
|
|
808
|
my @encoding = qw/UTF-8 UTF-7 UTF-16 UTF-16BE UTF-16LE UTF-32 UTF-32BE UTF-32LE null null ascii cp1252 latin1 Latin9 Latin10/; |
94
|
135
|
|
|
|
|
198
|
my %encoding; |
95
|
135
|
|
|
|
|
598
|
@encoding{map {lc $_} @encoding} = (0 .. 12); |
|
2025
|
|
|
|
|
5709
|
|
96
|
135
|
100
|
|
|
|
763
|
if (exists $encoding{lc $id}) { |
97
|
31
|
|
|
|
|
129
|
$self->{EncID}=$encoding{lc $id}; |
98
|
31
|
|
|
|
|
235
|
return $self->{Encoding}=$encoding[$self->{EncID}]; |
99
|
|
|
|
|
|
|
} |
100
|
104
|
50
|
|
|
|
352
|
if ($encoding[int $id]) { |
101
|
104
|
|
|
|
|
218
|
$self->{EncID}=$id; |
102
|
104
|
|
|
|
|
747
|
return $self->{Encoding}=$encoding[$id]; |
103
|
|
|
|
|
|
|
} |
104
|
0
|
|
|
|
|
0
|
$self->die("Unknown Encoding"); |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=head2 byteorder(BOM) |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
Internal method. |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
Switches the byteorder. |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
See pack() for more on byteorders. |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=cut |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
sub byteorder { |
120
|
58
|
|
|
58
|
1
|
91
|
my $self=shift; |
121
|
58
|
|
|
|
|
99
|
my $bo=shift; |
122
|
58
|
100
|
|
|
|
283
|
if ($bo =~ m/le/i) { #little Endian |
123
|
9
|
|
|
|
|
34
|
$self->{SHORT}="v"; |
124
|
9
|
|
|
|
|
28
|
$self->{LONG}="V"; |
125
|
9
|
|
|
|
|
65
|
return 0; |
126
|
|
|
|
|
|
|
} |
127
|
49
|
100
|
|
|
|
174
|
if ($bo =~ m/be/i) { #BIG Endian |
128
|
10
|
|
|
|
|
38
|
$self->{SHORT}="n"; |
129
|
10
|
|
|
|
|
26
|
$self->{LONG}="N"; |
130
|
10
|
|
|
|
|
71
|
return 0; |
131
|
|
|
|
|
|
|
} |
132
|
39
|
100
|
|
|
|
178
|
if ($bo=~m/7/) { #7-Bit Mode |
133
|
19
|
|
|
|
|
64
|
$self->{SHORT}=undef; |
134
|
19
|
|
|
|
|
187
|
$self->{LONG}=undef; |
135
|
19
|
|
|
|
|
86
|
$self->encoding(1); |
136
|
19
|
|
|
|
|
74
|
return 1; |
137
|
|
|
|
|
|
|
} |
138
|
20
|
50
|
|
|
|
57
|
if ($bo=~m/Force/i) { #7-Bit Mode without UTF-7 encoding |
139
|
0
|
|
|
|
|
0
|
$self->{SHORT}=undef; |
140
|
0
|
|
|
|
|
0
|
$self->{LONG}=undef; |
141
|
|
|
|
|
|
|
#$self->encoding(1); |
142
|
0
|
|
|
|
|
0
|
return 0; |
143
|
|
|
|
|
|
|
} |
144
|
20
|
|
|
|
|
51
|
$self->{SHORT}="S"; |
145
|
20
|
|
|
|
|
54
|
$self->{LONG}="L"; |
146
|
20
|
|
|
|
|
129
|
return 0; |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=head2 bom(BOM) |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
Internal method. |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
Detects the byteorder. |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
See pack() for more on byteorders. |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
=cut |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub bom { |
162
|
58
|
|
|
58
|
1
|
112
|
my $self=shift; |
163
|
58
|
|
|
|
|
109
|
my $bo=shift; |
164
|
58
|
100
|
|
|
|
176
|
if ($bo==1) { #Machine Order |
165
|
29
|
|
|
|
|
123
|
$self->{SHORT}="S"; |
166
|
29
|
|
|
|
|
73
|
$self->{LONG}="L"; |
167
|
29
|
|
|
|
|
67
|
return 0; |
168
|
|
|
|
|
|
|
} |
169
|
29
|
100
|
|
|
|
134
|
if ($bo==256) { #Wrong Order |
170
|
10
|
50
|
|
|
|
161
|
if (1 == CORE::unpack('S',pack('v',1))) {# We are little Endian |
171
|
10
|
|
|
|
|
34
|
$self->{SHORT}="n"; |
172
|
10
|
|
|
|
|
25
|
$self->{LONG}="N"; |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
else { |
175
|
0
|
|
|
|
|
0
|
$self->{SHORT}="v"; |
176
|
0
|
|
|
|
|
0
|
$self->{LONG}="V"; |
177
|
|
|
|
|
|
|
} |
178
|
10
|
|
|
|
|
31
|
return 0; |
179
|
|
|
|
|
|
|
} |
180
|
19
|
50
|
|
|
|
83
|
if ($bo==0) { #7-Bit Mode |
181
|
19
|
|
|
|
|
58
|
$self->{SHORT}=undef; |
182
|
19
|
|
|
|
|
40
|
$self->{LONG}=undef; |
183
|
19
|
|
|
|
|
87
|
$self->encoding(1); |
184
|
19
|
|
|
|
|
63
|
return 1; |
185
|
|
|
|
|
|
|
} |
186
|
0
|
|
|
|
|
0
|
$self->die("Unknown Byteorder: $bo, can't continue"); |
187
|
0
|
|
|
|
|
0
|
return 0; |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=head2 packShort(INT) |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
Packs one int-16 to binary using the set byteorder |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=cut |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
sub packShort { |
198
|
39
|
|
|
39
|
1
|
58
|
my $self=shift; |
199
|
39
|
|
|
|
|
89
|
my $i=shift; |
200
|
39
|
50
|
|
|
|
116
|
$self->die("Short too large: $i") if $i > 65535; |
201
|
39
|
50
|
|
|
|
356
|
return pack $self->{SHORT},$i if $self->{SHORT}; |
202
|
0
|
0
|
|
|
|
0
|
$self->die("Can't pack that Short in 7-Bit, too large: $i") if $i > 16383; |
203
|
0
|
|
|
|
|
0
|
return pack ("CC",($i&0x7F),($i&0x3F80)); |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
=head2 packLong(INT) |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
Packs one int-32 to binary using the set byteorder |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
=cut |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
sub packLong { |
213
|
4350
|
|
|
4350
|
1
|
7927
|
my $self=shift; |
214
|
4350
|
|
|
|
|
13224
|
my $i=shift; |
215
|
4350
|
50
|
|
|
|
10689
|
$self->die("Long too large: $i") if $i > 4294967295; |
216
|
4350
|
100
|
|
|
|
38257
|
return pack $self->{LONG},$i if $self->{LONG}; |
217
|
1425
|
50
|
|
|
|
4822
|
$self->die("Can't pack that Long in 7-Bit, too large: $i") if $i > 268435455; |
218
|
1425
|
|
|
|
|
14625
|
return pack ("CCCC",($i&0x7F),(($i&0x3F80) >> 7),(($i&0x1FC000) >> 14),(($i&0xFE00000) >> 21)); |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=head2 packendian() |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
Returns the byte order mark for this file. |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=cut |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
sub packendian { |
228
|
58
|
|
|
58
|
1
|
98
|
my $self=shift; |
229
|
58
|
100
|
|
|
|
182
|
if ($self->{SHORT}) { |
230
|
39
|
|
|
|
|
166
|
return $self->packShort(1); |
231
|
|
|
|
|
|
|
} |
232
|
19
|
|
|
|
|
67
|
return pack("S",0); |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=head2 packversion() |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
Returns the version of this driver to put in the file. |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
=cut |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
sub packversion { |
242
|
58
|
|
|
58
|
1
|
117
|
my $self=shift; |
243
|
58
|
|
|
|
|
148
|
return pack("CCCC",0,2,0,0); |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
=head2 packencoding() |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
Returns the current encoding to put in the output file. |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
=cut |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
sub packencoding { |
253
|
58
|
|
|
58
|
1
|
89
|
my $self=shift; |
254
|
58
|
|
|
|
|
290
|
return pack("C",$self->{EncID}); |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
=head2 getType() |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
Tries to find out what SofuObject to deserialise next |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
Returns: |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
0 for Undefined / undef |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
1 for Value / Scalar |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
2 for List / Array |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
3 for Map / Hash |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
4 for Reference / Ref |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
=cut |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
sub getType { |
276
|
1914
|
|
|
1914
|
1
|
2599
|
my $self=shift; |
277
|
1914
|
|
|
|
|
5567
|
my $type = $self->get(1); |
278
|
1914
|
50
|
|
|
|
4977
|
$self->die ("Unexpected End of File") unless $type; |
279
|
1914
|
100
|
|
|
|
7194
|
if ($type eq "S") { |
280
|
547
|
|
|
|
|
2123
|
my $str = $self->get(3); |
281
|
547
|
50
|
33
|
|
|
3497
|
$self->die("Incomplete Sofu-Mark") if not $str or $str ne "ofu"; |
282
|
547
|
|
|
|
|
1601
|
$type = $self->get(1); |
283
|
|
|
|
|
|
|
} |
284
|
1914
|
50
|
|
|
|
3478
|
$self->die("No Type found") unless defined $type; |
285
|
1914
|
|
|
|
|
3630
|
$type=CORE::unpack("C",$type); |
286
|
1914
|
50
|
|
|
|
4605
|
$self->die("Unknown Type: $type") if $type > 4; |
287
|
1914
|
|
|
|
|
3402
|
return $type; |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
=head2 objectprocess() |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
Postprocess the SofuObjects, sets References to their targets. |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
=cut |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
sub objectprocess { |
297
|
32
|
|
|
32
|
1
|
49
|
my $self=shift; |
298
|
32
|
|
|
|
|
162
|
$self->{Ref}->{""} = $self->{Ref}->{"->"} = $self->{Ref}->{"="}; |
299
|
32
|
|
|
|
|
122
|
foreach my $e (@{$$self{References}}) { |
|
32
|
|
|
|
|
154
|
|
300
|
160
|
50
|
|
|
|
455
|
next if $e->valid(); |
301
|
160
|
|
|
|
|
435
|
my $target = $e->follow().""; |
302
|
160
|
|
|
|
|
733
|
$target=~s/^@//; |
303
|
160
|
50
|
33
|
|
|
9242
|
$target="->".$target if $target and $target !~ m/^->/; |
304
|
160
|
50
|
|
|
|
846
|
$e->dangle($self->{Ref}->{$target}) if $self->{Ref}->{$target}; |
305
|
|
|
|
|
|
|
} |
306
|
|
|
|
|
|
|
} |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
=head2 postprocess() |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
Postprocess perl datastructures , sets References to their targets. |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=cut |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
sub postprocess { |
315
|
26
|
|
|
26
|
1
|
49
|
my $self=shift; |
316
|
26
|
|
|
|
|
516
|
$self->{Ref}->{""} = $self->{Ref}->{"->"} = $self->{Ref}->{"="}; |
317
|
26
|
|
|
|
|
45
|
foreach my $e (@{$$self{References}}) { |
|
26
|
|
|
|
|
124
|
|
318
|
|
|
|
|
|
|
#next; |
319
|
|
|
|
|
|
|
#print $$e; |
320
|
52
|
|
|
|
|
110
|
my $target = $$$e; |
321
|
52
|
|
|
|
|
279
|
$target=~s/^@//; |
322
|
52
|
50
|
33
|
|
|
487
|
$target="->".$target if $target and $target !~ m/^->/; |
323
|
52
|
|
|
|
|
94
|
$$e = undef; |
324
|
52
|
50
|
|
|
|
326
|
$$e = $self->{Ref}->{$target} if $self->{Ref}->{$target}; |
325
|
|
|
|
|
|
|
} |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=head2 getLong() |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
Decodes one Int-32 from the input stream according to the byteorder and returns it. |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
=cut |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
sub getLong { |
335
|
4408
|
|
|
4408
|
1
|
7625
|
my $self=shift; |
336
|
4408
|
|
|
|
|
6107
|
my $i=shift; |
337
|
4408
|
100
|
|
|
|
9527
|
return undef unless defined $i; |
338
|
4350
|
100
|
|
|
|
31271
|
return CORE::unpack($self->{LONG},$i) if $self->{LONG}; |
339
|
1425
|
|
|
|
|
4335
|
my @i = CORE::unpack("CCCC",$i); |
340
|
|
|
|
|
|
|
#print join(", ",@i),"\n"; |
341
|
1425
|
|
|
|
|
5400
|
return( (($i[0] & 0x7F) | (($i[1] & 0x7F) << 7) | (($i[2] & 0x7F) << 14) | (($i[3] & 0x7F) << 21)) ); |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=head2 getText() |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
Decodes one String according to encoding from the inputstream and returns it |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
=cut |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
sub getText { |
352
|
3886
|
|
|
3886
|
1
|
8289
|
my $self=shift; |
353
|
3886
|
|
|
|
|
11308
|
my $len=$self->getLong($self->get(4)); |
354
|
3886
|
100
|
|
|
|
53307
|
return undef unless defined $len; |
355
|
3828
|
100
|
|
|
|
12172
|
return "" if $len == 0; |
356
|
2030
|
|
|
|
|
11877
|
my $text = $self->get($len); |
357
|
2030
|
|
|
|
|
18428
|
return Encode::decode($self->{Encoding},$text,Encode::FB_CROAK); |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
} |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
=head2 getComment(TREE) |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
decodes one comment and sets it to TREE |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
TREE can be a string describing the tree or a Data::Sofu::Object. |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
=cut |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
sub getComment { |
370
|
1972
|
|
|
1972
|
1
|
4873
|
my $self=shift; |
371
|
1972
|
|
|
|
|
2284
|
my $tree=shift; |
372
|
1972
|
|
|
|
|
12706
|
my $t = $self->getText(); |
373
|
1972
|
50
|
|
|
|
18007
|
$self->die("Can't get Comment, EOF!") unless defined $t; |
374
|
1972
|
100
|
|
|
|
6495
|
return if $t eq ""; |
375
|
232
|
100
|
|
|
|
648
|
if (ref $tree) { |
376
|
128
|
|
|
|
|
898
|
$tree->setComment([split /\n/,$t]); |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
else { |
379
|
104
|
|
|
|
|
1011
|
$self->{COMMENTS}->{$tree}=[split /\n/,$t]; |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
=head2 unpackUndef(TREE) |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
Returns undef and packs it comment |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
=cut |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
sub unpackUndef { |
391
|
26
|
|
|
26
|
1
|
41
|
my $self=shift; |
392
|
26
|
|
|
|
|
47
|
my $tree=shift; |
393
|
26
|
|
|
|
|
58
|
$self->getComment($tree); |
394
|
26
|
|
|
|
|
81
|
return undef; |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
} |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
=head2 unpackScalar(TREE) |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
Decodes one scalar and its comment. |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
=cut |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
sub unpackScalar { |
406
|
546
|
|
|
546
|
1
|
710
|
my $self=shift; |
407
|
546
|
|
|
|
|
611
|
my $tree=shift; |
408
|
546
|
|
|
|
|
1623
|
$self->getComment($tree); |
409
|
546
|
|
|
|
|
4746
|
return $self->getText(); |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
} |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
=head2 unpackRef(TREE) |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
Decodes one ref and its comment. |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
=cut |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
sub unpackRef { |
421
|
52
|
|
|
52
|
1
|
13463
|
my $self=shift; |
422
|
52
|
|
|
|
|
73
|
my $tree=shift; |
423
|
52
|
|
|
|
|
142
|
$self->getComment($tree); |
424
|
52
|
|
|
|
|
137
|
my $x = $self->getText(); |
425
|
52
|
|
|
|
|
6128
|
return \$x; |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
} |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
=head2 unpackHash(TREE) |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
Decodes a hash, its comment and its content |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
=cut |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
sub unpackHash { |
437
|
78
|
|
|
78
|
1
|
156
|
my $self=shift; |
438
|
78
|
|
|
|
|
111
|
my $tree=shift; |
439
|
78
|
|
|
|
|
289
|
my %result=(); |
440
|
78
|
|
|
|
|
209
|
$self->getComment($tree); |
441
|
78
|
|
|
|
|
280
|
my $len=$self->getLong($self->get(4)); |
442
|
78
|
50
|
|
|
|
627
|
$self->die("Error while reading maplength, maybe EOF") unless defined $len; |
443
|
78
|
50
|
|
|
|
187
|
return {} if $len == 0; |
444
|
78
|
|
|
|
|
398
|
keys(%result) = $len; #Presetting the Hashsize |
445
|
78
|
|
|
|
|
283
|
for (my $i = 0;$i < $len;$i++) { |
446
|
104
|
|
|
|
|
256
|
my $key = $self->getText(); |
447
|
104
|
50
|
|
|
|
5172
|
$self->die("Error while reading key, maybe EOF") unless defined $key; |
448
|
104
|
|
|
|
|
3654
|
my $kkey = Data::Sofu::Sofukeyescape($key); |
449
|
104
|
|
|
|
|
293
|
my $type = $self->getType(); |
450
|
104
|
|
|
|
|
389
|
$result{$key} = $self->unpackType($type,"$tree->$kkey"); |
451
|
104
|
|
|
|
|
2300
|
$self->{Ref}->{"$tree->$kkey"}=$result{$key}; |
452
|
104
|
100
|
|
|
|
409
|
push @{$self->{References}},\$result{$key} if ($type == 4); |
|
26
|
|
|
|
|
148
|
|
453
|
|
|
|
|
|
|
} |
454
|
78
|
|
|
|
|
336
|
return \%result; |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
} |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
=head2 unpackArray(TREE) |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
Decodes an array, its comment and its content |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
=cut |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
sub unpackArray { |
467
|
156
|
|
|
156
|
1
|
221
|
my $self=shift; |
468
|
156
|
|
|
|
|
240
|
my $tree=shift; |
469
|
156
|
|
|
|
|
273
|
my @result=(); |
470
|
156
|
|
|
|
|
403
|
$self->getComment($tree); |
471
|
156
|
|
|
|
|
435
|
my $len=$self->getLong($self->get(4)); |
472
|
156
|
50
|
|
|
|
450
|
$self->die("Error while reading listlength, maybe EOF") unless defined $len; |
473
|
156
|
50
|
|
|
|
524
|
return {} if $len == 0; |
474
|
|
|
|
|
|
|
#die $len,"\n"; |
475
|
156
|
|
|
|
|
904
|
$#result = $len-1; #Grow the Array :) |
476
|
156
|
|
|
|
|
666
|
for (my $i = 0;$i < $len;$i++) { |
477
|
624
|
|
|
|
|
1439
|
my $type = $self->getType(); |
478
|
624
|
|
|
|
|
3710
|
$result[$i] = $self->unpackType($type,"$tree->$i"); |
479
|
624
|
|
|
|
|
37068
|
$self->{Ref}->{"$tree->$i"}=$result[$i]; |
480
|
624
|
100
|
|
|
|
3607
|
push @{$self->{References}},\$result[$i] if ($type == 4); |
|
26
|
|
|
|
|
138
|
|
481
|
|
|
|
|
|
|
} |
482
|
156
|
|
|
|
|
841
|
return \@result; |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
} |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
=head2 unpackType(TYPE,TREE) |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
Decodes a datastructure of TYPE. |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
=cut |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
sub unpackType { |
495
|
858
|
|
|
858
|
1
|
1954
|
my $self=shift; |
496
|
858
|
|
|
|
|
1156
|
my $type=shift; |
497
|
858
|
|
|
|
|
1242
|
my $tree=shift; |
498
|
858
|
100
|
|
|
|
4983
|
if ($type == 0) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
499
|
26
|
|
|
|
|
95
|
return $self->unpackUndef($tree); |
500
|
|
|
|
|
|
|
} |
501
|
|
|
|
|
|
|
elsif ($type == 1) { |
502
|
546
|
|
|
|
|
3348
|
return $self->unpackScalar($tree); |
503
|
|
|
|
|
|
|
} |
504
|
|
|
|
|
|
|
elsif ($type == 2) { |
505
|
156
|
|
|
|
|
414
|
return $self->unpackArray($tree); |
506
|
|
|
|
|
|
|
} |
507
|
|
|
|
|
|
|
elsif ($type == 3) { |
508
|
78
|
|
|
|
|
324
|
return $self->unpackHash($tree); |
509
|
|
|
|
|
|
|
} |
510
|
|
|
|
|
|
|
elsif ($type == 4) { |
511
|
52
|
|
|
|
|
152
|
return $self->unpackRef($tree); |
512
|
|
|
|
|
|
|
} |
513
|
|
|
|
|
|
|
} |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
=head2 unpack(BOM) |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
Starts unpacking using BOM, gets encoding and the contents |
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
=cut |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
sub unpack { |
524
|
26
|
|
|
26
|
1
|
70
|
my $self=shift; |
525
|
26
|
|
|
|
|
42
|
my $bom=shift; |
526
|
26
|
|
|
|
|
79
|
$self->{COMMENTS}={}; |
527
|
26
|
|
|
|
|
89
|
$self->{References}=[]; |
528
|
26
|
|
|
|
|
251
|
$self->{Ref}={}; |
529
|
26
|
|
|
|
|
674
|
$self->bom($bom); |
530
|
26
|
|
|
|
|
92
|
my $encoding = $self->get(1); |
531
|
26
|
50
|
|
|
|
77
|
$self->die("No Encoding!") unless defined $encoding; |
532
|
26
|
|
|
|
|
128
|
$self->encoding(CORE::unpack("C",$encoding)); |
533
|
26
|
|
|
|
|
70
|
my $tree=""; |
534
|
26
|
|
|
|
|
54
|
my %result=(); |
535
|
26
|
|
|
|
|
108
|
$self->getComment("="); |
536
|
26
|
|
|
|
|
92
|
while (defined (my $key = $self->getText())) { |
537
|
130
|
|
|
|
|
4912
|
my $kkey = Data::Sofu::Sofukeyescape($key); |
538
|
130
|
|
|
|
|
705
|
my $type = $self->getType(); |
539
|
130
|
|
|
|
|
588
|
$result{$key} = $self->unpackType($type,"$tree->$kkey"); |
540
|
130
|
|
|
|
|
1847
|
$self->{Ref}->{"$tree->$kkey"}=$result{$key}; |
541
|
130
|
50
|
|
|
|
537
|
push @{$self->{References}},\$result{$key} if ($type == 4); |
|
0
|
|
|
|
|
0
|
|
542
|
|
|
|
|
|
|
} |
543
|
26
|
|
|
|
|
107
|
$self->{Ref}->{"="}=\%result; |
544
|
26
|
|
|
|
|
136
|
$self->postprocess(); #Setting References right. |
545
|
26
|
|
|
|
|
215
|
return (\%result,$self->{COMMENTS}); |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
} |
548
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
=head2 unpackUndefined(TREE) |
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
Unpacks a Data::Sofu::Undefined and its comment. |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
=cut |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
sub unpackUndefined { |
557
|
32
|
|
|
32
|
1
|
76
|
my $self=shift; |
558
|
32
|
|
|
|
|
53
|
my $tree=shift; |
559
|
32
|
|
|
|
|
504
|
my $und = Data::Sofu::Undefined->new(); |
560
|
32
|
|
|
|
|
96
|
$self->getComment($und); |
561
|
32
|
|
|
|
|
115
|
return $und; |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
} |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
=head2 unpackValue(TREE) |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
Unpacks a Data::Sofu::Value, its content and its comment. |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
=cut |
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
sub unpackValue { |
573
|
576
|
|
|
576
|
1
|
808
|
my $self=shift; |
574
|
576
|
|
|
|
|
664
|
my $tree=shift; |
575
|
576
|
|
|
|
|
2556
|
my $value = Data::Sofu::Value->new(""); |
576
|
576
|
|
|
|
|
1340
|
$self->getComment($value); |
577
|
576
|
|
|
|
|
1151
|
$value->set($self->getText()); |
578
|
576
|
|
|
|
|
2114
|
return $value; |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
} |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
=head2 unpackReference(TREE) |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
Unpacks a Data::Sofu::Reference, its content and its comment. |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
=cut |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
sub unpackReference { |
590
|
160
|
|
|
160
|
1
|
234
|
my $self=shift; |
591
|
160
|
|
|
|
|
203
|
my $tree=shift; |
592
|
160
|
|
|
|
|
703
|
my $ref = Data::Sofu::Reference->new(); |
593
|
160
|
|
|
|
|
364
|
$self->getComment($ref); |
594
|
160
|
|
|
|
|
337
|
$ref->dangle($self->getText()); |
595
|
160
|
|
|
|
|
552
|
return $ref; |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
} |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
=head2 unpackMap(TREE) |
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
Unpacks a Data::Sofu::Map, its content and its comment. |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
=cut |
605
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
sub unpackMap { |
607
|
0
|
|
|
0
|
1
|
0
|
my $self=shift; |
608
|
0
|
|
|
|
|
0
|
my $tree=shift; |
609
|
0
|
|
|
|
|
0
|
my $map=Data::Sofu::Map->new(); |
610
|
0
|
|
|
|
|
0
|
$self->getComment($map); |
611
|
0
|
|
|
|
|
0
|
my $len=$self->getLong($self->get(4)); |
612
|
0
|
0
|
|
|
|
0
|
$self->die("Error while reading maplength, maybe EOF") unless defined $len; |
613
|
0
|
0
|
|
|
|
0
|
return $map if $len == 0; |
614
|
0
|
|
|
|
|
0
|
for (my $i = 0;$i < $len;$i++) { |
615
|
0
|
|
|
|
|
0
|
my $key = $self->getText(); |
616
|
0
|
0
|
|
|
|
0
|
$self->die("Error while reading key, maybe EOF") unless defined $key; |
617
|
0
|
|
|
|
|
0
|
my $kkey = Data::Sofu::Sofukeyescape($key); |
618
|
0
|
|
|
|
|
0
|
my $type = $self->getType(); |
619
|
0
|
|
|
|
|
0
|
my $res = $self->unpackObjectType($type,"$tree->$kkey"); |
620
|
0
|
|
|
|
|
0
|
$self->{Ref}->{"$tree->$kkey"}=$res; |
621
|
0
|
0
|
|
|
|
0
|
push @{$self->{References}},$res if ($type == 4); |
|
0
|
|
|
|
|
0
|
|
622
|
0
|
|
|
|
|
0
|
$map->setAttribute($key,$res); |
623
|
|
|
|
|
|
|
} |
624
|
0
|
|
|
|
|
0
|
return $map; |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
} |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
=head2 unpackMap2(TREE) |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
Unpacks a Data::Sofu::Map, its content and its comment. |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
(Speed optimized, but uses dirty tricks) |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
=cut |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
sub unpackMap2 { #faster version, using the perlinterface |
638
|
96
|
|
|
96
|
1
|
141
|
my $self=shift; |
639
|
96
|
|
|
|
|
139
|
my $tree=shift; |
640
|
96
|
|
|
|
|
214
|
my %result=(); |
641
|
96
|
|
|
|
|
154
|
my @order=(); |
642
|
96
|
|
|
|
|
346
|
my $map=Data::Sofu::Map->new(); |
643
|
96
|
|
|
|
|
251
|
$self->getComment($map); |
644
|
96
|
|
|
|
|
348
|
my $len=$self->getLong($self->get(4)); |
645
|
96
|
50
|
|
|
|
280
|
$self->die("Error while reading maplength, maybe EOF") unless defined $len; |
646
|
96
|
50
|
|
|
|
209
|
return $map if $len == 0; |
647
|
96
|
|
|
|
|
265
|
keys(%result) = $len; #Presetting the Hashsize |
648
|
96
|
|
|
|
|
377
|
$#order=($len-1); |
649
|
96
|
|
|
|
|
272
|
for (my $i = 0;$i < $len;$i++) { |
650
|
128
|
|
|
|
|
268
|
my $key = $self->getText(); |
651
|
128
|
50
|
|
|
|
4807
|
$self->die("Error while reading key, maybe EOF") unless defined $key; |
652
|
128
|
|
|
|
|
393
|
my $kkey = Data::Sofu::Sofukeyescape($key); |
653
|
128
|
|
|
|
|
371
|
my $type = $self->getType(); |
654
|
128
|
|
|
|
|
614
|
$result{$key} = $self->unpackObjectType($type,"$tree->$kkey"); |
655
|
|
|
|
|
|
|
#push @order,$key; |
656
|
128
|
|
|
|
|
376
|
$order[$i] = $key; |
657
|
128
|
|
|
|
|
957
|
$self->{Ref}->{"$tree->$kkey"}=$result{$key}; |
658
|
128
|
100
|
|
|
|
533
|
push @{$self->{References}},$result{$key} if ($type == 4); |
|
32
|
|
|
|
|
174
|
|
659
|
|
|
|
|
|
|
} |
660
|
96
|
|
|
|
|
235
|
$map->{Order}=\@order; |
661
|
96
|
|
|
|
|
201
|
$map->{Map}=\%result; |
662
|
96
|
|
|
|
|
2457
|
return $map; |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
} |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
=head2 unpackList(TREE) |
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
Unpacks a Data::Sofu::List, its content and its comment. |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
=cut |
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
sub unpackList { |
673
|
0
|
|
|
0
|
1
|
0
|
my $self=shift; |
674
|
0
|
|
|
|
|
0
|
my $tree=shift; |
675
|
0
|
|
|
|
|
0
|
my $list=Data::Sofu::List->new(); |
676
|
0
|
|
|
|
|
0
|
$self->getComment($list); |
677
|
0
|
|
|
|
|
0
|
my $len=$self->getLong($self->get(4)); |
678
|
0
|
0
|
|
|
|
0
|
$self->die("Error while reading listlength, maybe EOF") unless defined $len; |
679
|
0
|
0
|
|
|
|
0
|
return $list if $len == 0; |
680
|
0
|
|
|
|
|
0
|
for (my $i = 0;$i < $len;$i++) { |
681
|
0
|
|
|
|
|
0
|
my $type = $self->getType(); |
682
|
0
|
|
|
|
|
0
|
my $res = $self->unpackObjectType($type,"$tree->$i"); |
683
|
0
|
|
|
|
|
0
|
$self->{Ref}->{"$tree->$i"}=$res; |
684
|
0
|
0
|
|
|
|
0
|
push @{$self->{References}},$res if ($type == 4); |
|
0
|
|
|
|
|
0
|
|
685
|
0
|
|
|
|
|
0
|
$list->appendElement($res); |
686
|
|
|
|
|
|
|
} |
687
|
0
|
|
|
|
|
0
|
return $list; |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
} |
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
=head2 unpackList2(TREE) |
693
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
Unpacks a Data::Sofu::List, its content and its comment. |
695
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
(Speed optimized, but uses dirty tricks) |
697
|
|
|
|
|
|
|
|
698
|
|
|
|
|
|
|
=cut |
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
sub unpackList2 { #faster version, using the perlinterface |
702
|
192
|
|
|
192
|
1
|
251
|
my $self=shift; |
703
|
192
|
|
|
|
|
347
|
my $tree=shift; |
704
|
192
|
|
|
|
|
1093
|
my $list=Data::Sofu::List->new(); |
705
|
192
|
|
|
|
|
432
|
$self->getComment($list); |
706
|
192
|
|
|
|
|
240
|
my @result; |
707
|
192
|
|
|
|
|
579
|
my $len=$self->getLong($self->get(4)); |
708
|
192
|
50
|
|
|
|
692
|
$self->die("Error while reading listlength, maybe EOF") unless defined $len; |
709
|
192
|
50
|
|
|
|
459
|
return $list if $len == 0; |
710
|
|
|
|
|
|
|
#die $len,"\n"; |
711
|
192
|
|
|
|
|
662
|
$#result = $len-1; #Grow the Array :) |
712
|
192
|
|
|
|
|
787
|
for (my $i = 0;$i < $len;$i++) { |
713
|
768
|
|
|
|
|
1972
|
my $type = $self->getType(); |
714
|
768
|
|
|
|
|
2558
|
$result[$i] = $self->unpackObjectType($type,"$tree->$i"); |
715
|
768
|
|
|
|
|
3587
|
$self->{Ref}->{"$tree->$i"}=$result[$i]; |
716
|
768
|
100
|
|
|
|
2632
|
push @{$self->{References}},$result[$i] if ($type == 4); |
|
128
|
|
|
|
|
540
|
|
717
|
|
|
|
|
|
|
} |
718
|
192
|
|
|
|
|
447
|
$list->{List}=\@result; |
719
|
192
|
|
|
|
|
664
|
return $list; |
720
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
} |
722
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
=head2 unpackObjectType(TYPE,TREE) |
724
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
Unpacks a datastructure defined by TYPE |
726
|
|
|
|
|
|
|
|
727
|
|
|
|
|
|
|
=cut |
728
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
sub unpackObjectType { |
730
|
1056
|
|
|
1056
|
1
|
1505
|
my $self=shift; |
731
|
1056
|
|
|
|
|
1176
|
my $type=shift; |
732
|
1056
|
|
|
|
|
1221
|
my $tree=shift; |
733
|
1056
|
100
|
|
|
|
3600
|
if ($type == 0) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
734
|
32
|
|
|
|
|
117
|
return $self->unpackUndefined($tree); |
735
|
|
|
|
|
|
|
} |
736
|
|
|
|
|
|
|
elsif ($type == 1) { |
737
|
576
|
|
|
|
|
1384
|
return $self->unpackValue($tree); |
738
|
|
|
|
|
|
|
} |
739
|
|
|
|
|
|
|
elsif ($type == 2) { |
740
|
192
|
|
|
|
|
539
|
return $self->unpackList2($tree); |
741
|
|
|
|
|
|
|
} |
742
|
|
|
|
|
|
|
elsif ($type == 3) { |
743
|
96
|
|
|
|
|
336
|
return $self->unpackMap2($tree); |
744
|
|
|
|
|
|
|
} |
745
|
|
|
|
|
|
|
elsif ($type == 4) { |
746
|
160
|
|
|
|
|
360
|
return $self->unpackReference($tree); |
747
|
|
|
|
|
|
|
} |
748
|
|
|
|
|
|
|
} |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
=head2 unpackObject(BOM) |
752
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
Starts unpacking into a Data::Sofu::Object structure using BOM, gets encoding and the contents |
754
|
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
=cut |
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
sub unpackObject { |
759
|
32
|
|
|
32
|
1
|
62
|
my $self=shift; |
760
|
32
|
|
|
|
|
63
|
my $bom=shift; |
761
|
32
|
|
|
|
|
112
|
$self->{References}=[]; |
762
|
32
|
|
|
|
|
136
|
$self->{Ref}={}; |
763
|
32
|
|
|
|
|
696
|
$self->bom($bom); |
764
|
32
|
|
|
|
|
143
|
my $encoding = $self->get(1); |
765
|
32
|
50
|
|
|
|
226
|
$self->die("No Encoding!") unless defined $encoding; |
766
|
32
|
|
|
|
|
135
|
$self->encoding(CORE::unpack("C",$encoding)); |
767
|
32
|
|
|
|
|
74
|
my $tree=""; |
768
|
32
|
|
|
|
|
391
|
my $map = Data::Sofu::Map->new(); |
769
|
32
|
|
|
|
|
234
|
$self->getComment($map); |
770
|
32
|
|
|
|
|
121
|
while (defined (my $key = $self->getText())) { |
771
|
160
|
|
|
|
|
6113
|
my $kkey = Data::Sofu::Sofukeyescape($key); |
772
|
160
|
|
|
|
|
499
|
my $type = $self->getType(); |
773
|
160
|
|
|
|
|
655
|
my $res = $self->unpackObjectType($type,"$tree->$kkey"); |
774
|
160
|
|
|
|
|
624
|
$self->{Ref}->{"$tree->$kkey"}=$res; |
775
|
160
|
50
|
|
|
|
398
|
push @{$self->{References}},$res if ($type == 4); |
|
0
|
|
|
|
|
0
|
|
776
|
160
|
|
|
|
|
806
|
$map->setAttribute($key,$res); |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
} |
779
|
32
|
|
|
|
|
117
|
$self->{Ref}->{"="}=$map; |
780
|
32
|
|
|
|
|
100
|
$self->objectprocess(); #Setting References right. |
781
|
32
|
|
|
|
|
4625
|
return $map; |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
} |
784
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
=head2 packType(TYPE) |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
Encodes Type information and returns it. |
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
=cut |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
sub packType { |
793
|
1914
|
|
|
1914
|
1
|
3742
|
my $self=shift; |
794
|
1914
|
|
|
|
|
2758
|
my $type=shift; |
795
|
1914
|
|
|
|
|
2266
|
my $str=""; |
796
|
1914
|
100
|
|
|
|
7524
|
if ($self->{Mark}) { |
797
|
759
|
100
|
|
|
|
2471
|
$str="Sofu" if rand() < $self->{Mark}; |
798
|
|
|
|
|
|
|
} |
799
|
1914
|
|
|
|
|
9136
|
return $str.pack("C",$type); |
800
|
|
|
|
|
|
|
} |
801
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
=head2 packText(STRING) |
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
Encodes a STRING using Encoding and returns it. |
805
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
=cut |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
sub packText { |
809
|
2268
|
|
|
2268
|
1
|
4415
|
my $self=shift; |
810
|
2268
|
|
|
|
|
3146
|
my $text=shift; |
811
|
2268
|
100
|
66
|
|
|
13880
|
return $self->packLong(0) if not defined $text or $text eq ""; |
812
|
2030
|
|
|
|
|
18677
|
$text = Encode::encode($self->{Encoding},$text,Encode::FB_CROAK); |
813
|
2030
|
|
|
|
|
107232
|
return $self->packLong(length($text)).$text; |
814
|
|
|
|
|
|
|
} |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
=head2 packData(DATA,TREE) |
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
Encodes one perl datastructure and its contents and returns it. |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
=cut |
821
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
sub packData { |
823
|
858
|
|
|
858
|
1
|
1238
|
my $self=shift; |
824
|
858
|
|
|
|
|
11836
|
my $data=shift; |
825
|
858
|
|
|
|
|
3228
|
my $tree=shift; |
826
|
858
|
|
|
|
|
2241
|
my $type=1; |
827
|
858
|
100
|
|
|
|
1669
|
if (ref $data) { |
828
|
286
|
|
|
|
|
396
|
my $r=ref $data; |
829
|
286
|
100
|
|
|
|
1826
|
if ($r eq "ARRAY") { |
|
|
50
|
|
|
|
|
|
830
|
156
|
|
|
|
|
238
|
$type=2; |
831
|
|
|
|
|
|
|
} |
832
|
|
|
|
|
|
|
elsif ($r eq "HASH") { |
833
|
130
|
|
|
|
|
184
|
$type=3; |
834
|
|
|
|
|
|
|
} |
835
|
|
|
|
|
|
|
else { |
836
|
0
|
|
|
|
|
0
|
$self->die("Unknown Datastructure, can only work with Arrays and Hashes but not $r"); |
837
|
|
|
|
|
|
|
} |
838
|
286
|
100
|
|
|
|
1294
|
if ($self->{SEEN}->{$data}) { |
839
|
52
|
|
|
|
|
135
|
return $self->packType(4).$self->packComment($tree).$self->packText("@".$self->{SEEN}->{$data}); |
840
|
|
|
|
|
|
|
} |
841
|
|
|
|
|
|
|
} |
842
|
|
|
|
|
|
|
else { |
843
|
572
|
100
|
|
|
|
1040
|
if (defined ($data)) { |
844
|
546
|
|
|
|
|
1380
|
return $self->packType(1).$self->packComment($tree).$self->packText($data); |
845
|
|
|
|
|
|
|
} |
846
|
|
|
|
|
|
|
else { |
847
|
26
|
|
|
|
|
78
|
return $self->packType(0).$self->packComment($tree); |
848
|
|
|
|
|
|
|
} |
849
|
|
|
|
|
|
|
} |
850
|
234
|
|
|
|
|
743
|
$self->{SEEN}->{$data}=$tree; |
851
|
234
|
100
|
|
|
|
728
|
if ($type==3) { |
852
|
78
|
|
|
|
|
201
|
return $self->packType(3).$self->packComment($tree).$self->packHash($data,$tree); |
853
|
|
|
|
|
|
|
} |
854
|
156
|
|
|
|
|
361
|
return $self->packType(2).$self->packComment($tree).$self->packArray($data,$tree); |
855
|
|
|
|
|
|
|
} |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
=head2 packArray(DATA,TREE) |
858
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
Encodes one perl array and its contents and returns it. |
860
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
=cut |
862
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
sub packArray { |
864
|
156
|
|
|
156
|
1
|
200
|
my $self=shift; |
865
|
156
|
|
|
|
|
193
|
my $data=shift; |
866
|
156
|
|
|
|
|
2094
|
my $tree=shift; |
867
|
156
|
|
|
|
|
191
|
my $str=$self->packLong(scalar @{$data}); |
|
156
|
|
|
|
|
569
|
|
868
|
156
|
|
|
|
|
262
|
my $i=0; |
869
|
156
|
|
|
|
|
456
|
foreach my $element (@{$data}) { |
|
156
|
|
|
|
|
699
|
|
870
|
624
|
|
|
|
|
2314
|
$str.=$self->packData($element,"$tree->".$i++); |
871
|
|
|
|
|
|
|
} |
872
|
156
|
|
|
|
|
2247
|
return $str; |
873
|
|
|
|
|
|
|
} |
874
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
=head2 packHash(DATA,TREE) |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
Encodes one perl hash and its contents and returns it. |
878
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
=cut |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
sub packHash { |
882
|
78
|
|
|
78
|
1
|
166
|
my $self=shift; |
883
|
78
|
|
|
|
|
108
|
my $data=shift; |
884
|
78
|
|
|
|
|
200
|
my $tree=shift; |
885
|
78
|
|
|
|
|
124
|
my $str=$self->packLong(scalar keys %{$data}); |
|
78
|
|
|
|
|
276
|
|
886
|
78
|
|
|
|
|
134
|
foreach my $key (keys %{$data}) { |
|
78
|
|
|
|
|
1123
|
|
887
|
104
|
|
|
|
|
2339
|
my $kkey = Data::Sofu::Sofukeyescape($key); |
888
|
104
|
|
|
|
|
312
|
$str.=$self->packText($key); |
889
|
104
|
|
|
|
|
515
|
$str.=$self->packData($data->{$key},"$tree->$kkey"); |
890
|
|
|
|
|
|
|
} |
891
|
78
|
|
|
|
|
463
|
return $str; |
892
|
|
|
|
|
|
|
} |
893
|
|
|
|
|
|
|
|
894
|
|
|
|
|
|
|
=head2 pack(TREE,[COMMENTS,[ENCODING,[BYTEORDER,[SOFUMARK]]]]) |
895
|
|
|
|
|
|
|
|
896
|
|
|
|
|
|
|
Packs a structure (TREE) into a string using the Sofu binary file format. |
897
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
Returns a string representing TREE. |
899
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
=over |
901
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
=item TREE |
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
Perl datastructure to pack. Can be a hash, array or scalar (or array of hashes of hashes of arrays or whatever). Anything NOT a hash will be converted to TREE={Value=>TREE}; |
905
|
|
|
|
|
|
|
|
906
|
|
|
|
|
|
|
It can also be a Data::Sofu::Object or derived (Data::Sofu::Map, Data::Sofu::List, Data::Sofu::Value, Data::Sofu::...). |
907
|
|
|
|
|
|
|
Anything not a Data::Sofu::Map will be converted to one (A Map with one attribute called "Value" that holds TREE). |
908
|
|
|
|
|
|
|
|
909
|
|
|
|
|
|
|
=item COMMENTS |
910
|
|
|
|
|
|
|
|
911
|
|
|
|
|
|
|
Comment hash (as returned by Data::Sofu::getSofucomments() or Data::Sofu->new()->comments() after any file was read). |
912
|
|
|
|
|
|
|
|
913
|
|
|
|
|
|
|
Can be undef or {}. |
914
|
|
|
|
|
|
|
|
915
|
|
|
|
|
|
|
=item ENCODING |
916
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
Specifies the encoding of the strings in the binary sofu file, which can be: |
918
|
|
|
|
|
|
|
|
919
|
|
|
|
|
|
|
=over |
920
|
|
|
|
|
|
|
|
921
|
|
|
|
|
|
|
=item C<"0"> or C<"UTF-8"> |
922
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
This is default. |
924
|
|
|
|
|
|
|
|
925
|
|
|
|
|
|
|
Normal UTF-8 encoding (supports almost all chars) |
926
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
=item C<"1"> or C<"UTF-7"> |
928
|
|
|
|
|
|
|
|
929
|
|
|
|
|
|
|
This is default for byteorder = 7Bit (See below) |
930
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
7Bit encoding (if your transport stream isn't 8-Bit safe |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
=item C<"2"> or C<"UTF-16"> |
934
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
UTF 16 with byte order mark in EVERY string. |
936
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
Byteoder depends on your machine |
938
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
=item C<"3"> or C<"UTF-16BE"> |
940
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
No BOM, always BigEndian |
942
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
=item C<"4"> or C<"UTF-16LE"> |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
No BOM, always LittleEndian |
946
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
=item C<"5"> or C<"UTF-32"> |
948
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
UTF-32 with byte order mark in EVERY string. |
950
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
Byteoder depends on your machine |
952
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
=item C<"6"> or C<"UTF-32BE"> |
954
|
|
|
|
|
|
|
|
955
|
|
|
|
|
|
|
No BOM, always BigEndian |
956
|
|
|
|
|
|
|
|
957
|
|
|
|
|
|
|
=item C<"7"> or C<"UTF-32LE"> |
958
|
|
|
|
|
|
|
|
959
|
|
|
|
|
|
|
No BOM, always LittleEndian |
960
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
=item C<"8","9"> |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
Reserved for future use |
964
|
|
|
|
|
|
|
|
965
|
|
|
|
|
|
|
=item C<"10"> or C<"ascii"> |
966
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
Normal ASCII encoding |
968
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
Might not support all characters and will warn about that. |
970
|
|
|
|
|
|
|
|
971
|
|
|
|
|
|
|
=item C<"11"> or C<"cp1252"> |
972
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
Windows Codepage 1252 |
974
|
|
|
|
|
|
|
|
975
|
|
|
|
|
|
|
Might not support all characters and will warn about that. |
976
|
|
|
|
|
|
|
|
977
|
|
|
|
|
|
|
=item C<"12"> or C<"latin1"> |
978
|
|
|
|
|
|
|
|
979
|
|
|
|
|
|
|
ISO Latin 1 |
980
|
|
|
|
|
|
|
|
981
|
|
|
|
|
|
|
Might not support all characters and will warn about that. |
982
|
|
|
|
|
|
|
|
983
|
|
|
|
|
|
|
=item C<"13"> or C<"latin9"> |
984
|
|
|
|
|
|
|
|
985
|
|
|
|
|
|
|
ISO Latin 9 |
986
|
|
|
|
|
|
|
|
987
|
|
|
|
|
|
|
Might not support all characters and will warn about that. |
988
|
|
|
|
|
|
|
|
989
|
|
|
|
|
|
|
=item C<"14"> or C<"latin10"> |
990
|
|
|
|
|
|
|
|
991
|
|
|
|
|
|
|
ISO Latin 10 |
992
|
|
|
|
|
|
|
|
993
|
|
|
|
|
|
|
Might not support all characters and will warn about that. |
994
|
|
|
|
|
|
|
|
995
|
|
|
|
|
|
|
=back |
996
|
|
|
|
|
|
|
|
997
|
|
|
|
|
|
|
=item BYTEORDER |
998
|
|
|
|
|
|
|
|
999
|
|
|
|
|
|
|
Defines how the integers of the binary file are encoded. |
1000
|
|
|
|
|
|
|
|
1001
|
|
|
|
|
|
|
=over |
1002
|
|
|
|
|
|
|
|
1003
|
|
|
|
|
|
|
=item C |
1004
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
Maschine order |
1006
|
|
|
|
|
|
|
|
1007
|
|
|
|
|
|
|
This is Default. |
1008
|
|
|
|
|
|
|
|
1009
|
|
|
|
|
|
|
BOM is placed to detect the order used. |
1010
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
=item C<"LE"> |
1012
|
|
|
|
|
|
|
|
1013
|
|
|
|
|
|
|
Little Endian |
1014
|
|
|
|
|
|
|
|
1015
|
|
|
|
|
|
|
BOM is placed to detect the order used. |
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
Use this to give it to machines which are using Little Endian and have to read the file alot |
1018
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
=item C<"BE"> |
1020
|
|
|
|
|
|
|
|
1021
|
|
|
|
|
|
|
Big Endian |
1022
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
BOM is placed to detect the order used. |
1024
|
|
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
Use this to give it to machines which are using Big Endian and have to read the file alot |
1026
|
|
|
|
|
|
|
|
1027
|
|
|
|
|
|
|
=item C<"7Bit"> |
1028
|
|
|
|
|
|
|
|
1029
|
|
|
|
|
|
|
Use this byteorder if you can't trust your transport stream to be 8-Bit save. |
1030
|
|
|
|
|
|
|
|
1031
|
|
|
|
|
|
|
Encoding is forced to be UTF-7. No byte in the file will be > 127. |
1032
|
|
|
|
|
|
|
|
1033
|
|
|
|
|
|
|
BOM is set to 00 00. |
1034
|
|
|
|
|
|
|
|
1035
|
|
|
|
|
|
|
=item C<"NOFORCE7Bit"> |
1036
|
|
|
|
|
|
|
|
1037
|
|
|
|
|
|
|
Use this byteorder if you can't trust your transport stream to be 8-Bit save but you want another enconding than UTF-7 |
1038
|
|
|
|
|
|
|
|
1039
|
|
|
|
|
|
|
Encoding is NOT forced to be UTF-7. |
1040
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
BOM is set to 00 00. |
1042
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
=back |
1044
|
|
|
|
|
|
|
|
1045
|
|
|
|
|
|
|
=item SOFUMARK |
1046
|
|
|
|
|
|
|
|
1047
|
|
|
|
|
|
|
Defines how often the string "Sofu" is placed in the file (to tell any user with a text-editor what type of file this one is). |
1048
|
|
|
|
|
|
|
|
1049
|
|
|
|
|
|
|
=over |
1050
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
=item C |
1052
|
|
|
|
|
|
|
|
1053
|
|
|
|
|
|
|
Only place one "Sofu" at the beginning of the file. |
1054
|
|
|
|
|
|
|
|
1055
|
|
|
|
|
|
|
This is default. |
1056
|
|
|
|
|
|
|
|
1057
|
|
|
|
|
|
|
=item C<"0" or ""> |
1058
|
|
|
|
|
|
|
|
1059
|
|
|
|
|
|
|
Place no string anywhere. |
1060
|
|
|
|
|
|
|
|
1061
|
|
|
|
|
|
|
=item C<< "1" or >1 >> |
1062
|
|
|
|
|
|
|
|
1063
|
|
|
|
|
|
|
Place a string on every place it is possible |
1064
|
|
|
|
|
|
|
|
1065
|
|
|
|
|
|
|
Warning, the file might get big. |
1066
|
|
|
|
|
|
|
|
1067
|
|
|
|
|
|
|
=item C<"0.000001" - "0.99999"> |
1068
|
|
|
|
|
|
|
|
1069
|
|
|
|
|
|
|
Place strings randomly. |
1070
|
|
|
|
|
|
|
|
1071
|
|
|
|
|
|
|
=back |
1072
|
|
|
|
|
|
|
|
1073
|
|
|
|
|
|
|
=back |
1074
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
B |
1076
|
|
|
|
|
|
|
|
1077
|
|
|
|
|
|
|
Encoding, Byteorder and encoding driver (and Sofumark of course) are saved in the binary file. So you don't need to specify them for reading files, in fact just give them the Data::Sofu's readSofu() and all will be fine. |
1078
|
|
|
|
|
|
|
|
1079
|
|
|
|
|
|
|
=cut |
1080
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
sub pack { #Built tree into b-stream |
1082
|
52
|
|
|
52
|
1
|
122
|
my $self=shift; |
1083
|
52
|
|
|
|
|
313
|
$self->{OFFSET}="while packing"; |
1084
|
52
|
|
|
|
|
351
|
$self->{SEEN}={}; |
1085
|
52
|
|
|
|
|
917
|
my $data=shift; |
1086
|
52
|
|
|
|
|
140
|
my $r = ref $data; |
1087
|
52
|
100
|
66
|
|
|
834
|
return $self->packObject($data,@_) if $r and $r =~ m/Data::Sofu::/ and $data->isa("Data::Sofu::Object"); |
|
|
|
66
|
|
|
|
|
1088
|
26
|
50
|
33
|
|
|
279
|
$data = {Value=>$data} unless ref $data and ref $data eq "HASH"; |
1089
|
|
|
|
|
|
|
#$self->die("Data format wrong, must be hashref") unless (ref $data and ref $data eq "HASH"); |
1090
|
26
|
|
|
|
|
103
|
$self->{SEEN}->{$data}="->"; |
1091
|
26
|
|
|
|
|
49
|
my $comments=shift; |
1092
|
26
|
50
|
|
|
|
86
|
$comments = {} unless defined $comments; |
1093
|
26
|
50
|
33
|
|
|
173
|
$self->die("Comment format wrong, must be hashref") unless (ref $comments and ref $comments eq "HASH"); |
1094
|
26
|
|
|
|
|
226
|
$self->{Comments}=$comments; |
1095
|
26
|
|
|
|
|
4674
|
my $tree; |
1096
|
|
|
|
|
|
|
#my $encoding=shift; |
1097
|
|
|
|
|
|
|
#my $byteorder=shift; |
1098
|
|
|
|
|
|
|
#$encoding=0 unless $encoding; |
1099
|
|
|
|
|
|
|
#$byteorder=0 unless $byteorder; |
1100
|
|
|
|
|
|
|
#$self->encoding($encoding) unless $self->byteorder($byteorder); |
1101
|
|
|
|
|
|
|
#my $mark=shift; |
1102
|
|
|
|
|
|
|
#$mark = undef unless $mark; |
1103
|
|
|
|
|
|
|
#$self->{Mark} = $mark; |
1104
|
|
|
|
|
|
|
#my $str = ""; |
1105
|
|
|
|
|
|
|
#$str.="Sofu" if $mark or not defined $mark; |
1106
|
|
|
|
|
|
|
#$str.=$self->packendian(); |
1107
|
|
|
|
|
|
|
#$str.=$self->packversion() |
1108
|
|
|
|
|
|
|
#$comments = {} unless defined $comments;; |
1109
|
|
|
|
|
|
|
#$str.=$self->packencoding(); |
1110
|
26
|
|
|
|
|
150
|
my $str=$self->packHeader(@_); |
1111
|
26
|
|
|
|
|
120
|
$str.=$self->packComment("="); |
1112
|
26
|
|
|
|
|
54
|
foreach my $key (keys %{$data}) { |
|
26
|
|
|
|
|
171
|
|
1113
|
130
|
|
|
|
|
331
|
$str.=$self->packText($key); |
1114
|
130
|
|
|
|
|
15124
|
$str.=$self->packData($data->{$key},"->".Data::Sofu::Sofukeyescape($key)); |
1115
|
|
|
|
|
|
|
} |
1116
|
|
|
|
|
|
|
|
1117
|
26
|
|
|
|
|
5093
|
return $str; |
1118
|
|
|
|
|
|
|
} |
1119
|
|
|
|
|
|
|
|
1120
|
|
|
|
|
|
|
=head2 packObject(TREE,[COMMENTS,[ENCODING,[BYTEORDER,[SOFUMARK]]]]) |
1121
|
|
|
|
|
|
|
|
1122
|
|
|
|
|
|
|
Same as pack() but for C's only |
1123
|
|
|
|
|
|
|
|
1124
|
|
|
|
|
|
|
Will be called by pack(). |
1125
|
|
|
|
|
|
|
|
1126
|
|
|
|
|
|
|
Comments are taken from COMMENTS and from the Objects itself. |
1127
|
|
|
|
|
|
|
|
1128
|
|
|
|
|
|
|
=cut |
1129
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
sub packObject { # Use the Object implemented Packer for now. |
1131
|
26
|
|
|
26
|
1
|
54
|
my $self=shift; |
1132
|
26
|
|
|
|
|
61
|
my $data=shift; |
1133
|
26
|
|
|
|
|
56
|
my $r = ref $data; |
1134
|
26
|
|
|
|
|
71
|
$self->{OFFSET}="while packing"; |
1135
|
26
|
|
|
|
|
69
|
$self->{SEEN}={}; |
1136
|
26
|
50
|
33
|
|
|
381
|
$self->die("Need an Object") unless $r and $r =~ m/Data::Sofu::/ and $data->isa("Data::Sofu::Object"); |
|
|
|
33
|
|
|
|
|
1137
|
|
|
|
|
|
|
#return $data->binaryPack(@_); |
1138
|
|
|
|
|
|
|
#die "Not implemented for now"; |
1139
|
26
|
50
|
|
|
|
169
|
unless ($data->isMap()) { |
1140
|
0
|
|
|
|
|
0
|
require Data::Sofu::Map; |
1141
|
0
|
|
|
|
|
0
|
my $x = Data::Sofu::Map->new(); |
1142
|
0
|
|
|
|
|
0
|
$x->setAttribute("Value",$data); |
1143
|
0
|
|
|
|
|
0
|
$data=$x; |
1144
|
|
|
|
|
|
|
} |
1145
|
26
|
|
|
|
|
111
|
$self->{SEEN}->{$data}="->"; |
1146
|
26
|
|
|
|
|
53
|
my $comments=shift; |
1147
|
26
|
50
|
|
|
|
94
|
$comments = {} unless defined $comments; |
1148
|
26
|
50
|
33
|
|
|
271
|
$self->die("Comment format wrong, must be hashref") unless (ref $comments and ref $comments eq "HASH"); |
1149
|
26
|
|
|
|
|
76
|
$self->{Comments}=$comments; |
1150
|
26
|
|
|
|
|
128
|
my $str=$self->packHeader(@_); |
1151
|
26
|
|
|
|
|
185
|
$str.=$self->packComment("=",$data->getComment()); |
1152
|
26
|
|
|
|
|
147
|
foreach my $key ($data->orderedKeys()) { |
1153
|
|
|
|
|
|
|
#print $key,"\n"; |
1154
|
130
|
|
|
|
|
415
|
my $kkey = Data::Sofu::Sofukeyescape($key); |
1155
|
130
|
|
|
|
|
363
|
$str.=$self->packText($key); |
1156
|
130
|
|
|
|
|
553
|
$str.=$self->packObjectData($data->object($key),"->$kkey"); |
1157
|
|
|
|
|
|
|
} |
1158
|
|
|
|
|
|
|
#die $str; |
1159
|
26
|
|
|
|
|
54720
|
return $str; |
1160
|
|
|
|
|
|
|
} |
1161
|
|
|
|
|
|
|
|
1162
|
|
|
|
|
|
|
|
1163
|
|
|
|
|
|
|
=head2 packObjectData(DATA,TREE) |
1164
|
|
|
|
|
|
|
|
1165
|
|
|
|
|
|
|
Encodes one Data::Sofu::Object and its contents and returns it. |
1166
|
|
|
|
|
|
|
|
1167
|
|
|
|
|
|
|
=cut |
1168
|
|
|
|
|
|
|
|
1169
|
|
|
|
|
|
|
sub packObjectData { |
1170
|
858
|
|
|
858
|
1
|
1120
|
my $self=shift; |
1171
|
858
|
|
|
|
|
1088
|
my $data=shift; |
1172
|
858
|
|
|
|
|
1103
|
my $tree=shift; |
1173
|
858
|
|
|
|
|
947
|
my $type=1; |
1174
|
858
|
|
|
|
|
1444
|
my $r = ref $data; |
1175
|
|
|
|
|
|
|
#Maybe call packData on unknown Datastructures..... :) |
1176
|
858
|
50
|
33
|
|
|
18660
|
die ("Unknown Datastructure, can only work with Arrays and Hashes but not $r") unless $r and $r =~ m/Data::Sofu/ and $r->isa("Data::Sofu::Object"); |
|
|
|
33
|
|
|
|
|
1177
|
858
|
|
|
|
|
1222
|
my $odata=$data; |
1178
|
858
|
100
|
66
|
|
|
2540
|
if ($data->isReference() and $data->valid()) { |
1179
|
130
|
|
|
|
|
362
|
$data=$data->follow(); |
1180
|
|
|
|
|
|
|
} |
1181
|
858
|
50
|
|
|
|
2365
|
if ($data->isReference()) { #Reference to a Reference not yet allowed! |
1182
|
0
|
|
|
|
|
0
|
confess("No Reference to a Reference allowed for now!"); |
1183
|
0
|
|
|
|
|
0
|
return $self->packType(4).$self->packComment($tree,$odata->getComment()).$self->packText("@".$data->follow()); |
1184
|
|
|
|
|
|
|
} |
1185
|
858
|
100
|
|
|
|
4208
|
if ($self->{SEEN}->{$data}) { |
1186
|
|
|
|
|
|
|
#Carp::cluck(); |
1187
|
|
|
|
|
|
|
#print "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; |
1188
|
130
|
|
|
|
|
323
|
return $self->packType(4).$self->packComment($tree,$odata->getComment()).$self->packText("@".$self->{SEEN}->{$data}); |
1189
|
|
|
|
|
|
|
} |
1190
|
728
|
|
|
|
|
2463
|
$self->{SEEN}->{$data}=$tree; |
1191
|
728
|
|
|
|
|
1671
|
$self->{SEEN}->{$odata}=$tree; |
1192
|
728
|
100
|
|
|
|
2290
|
if ($data->isValue()) { |
1193
|
468
|
|
|
|
|
1054
|
return $self->packType(1).$self->packComment($tree,$odata->getComment()).$self->packText($data->toString()); |
1194
|
|
|
|
|
|
|
} |
1195
|
260
|
100
|
|
|
|
881
|
if ($data->isMap()) { |
1196
|
78
|
|
|
|
|
217
|
return $self->packType(3).$self->packComment($tree,$odata->getComment()).$self->packMap($data,$tree); |
1197
|
|
|
|
|
|
|
} |
1198
|
182
|
100
|
|
|
|
603
|
if ($data->isList()) { |
1199
|
156
|
|
|
|
|
337
|
return $self->packType(2).$self->packComment($tree,$odata->getComment()).$self->packList($data,$tree); |
1200
|
|
|
|
|
|
|
} |
1201
|
26
|
|
|
|
|
73
|
return $self->packType(0).$self->packComment($tree,$odata->getComment()); |
1202
|
|
|
|
|
|
|
} |
1203
|
|
|
|
|
|
|
|
1204
|
|
|
|
|
|
|
=head2 packList(DATA,TREE) |
1205
|
|
|
|
|
|
|
|
1206
|
|
|
|
|
|
|
Encodes one Data::Sofu::List and its contents and returns it. |
1207
|
|
|
|
|
|
|
|
1208
|
|
|
|
|
|
|
=cut |
1209
|
|
|
|
|
|
|
|
1210
|
|
|
|
|
|
|
|
1211
|
|
|
|
|
|
|
sub packList { |
1212
|
156
|
|
|
156
|
1
|
208
|
my $self=shift; |
1213
|
156
|
|
|
|
|
188
|
my $data=shift; |
1214
|
156
|
|
|
|
|
196
|
my $tree=shift; |
1215
|
156
|
|
|
|
|
16353
|
my $str=$self->packLong($data->length()); |
1216
|
156
|
|
|
|
|
266
|
my $i=0; |
1217
|
156
|
|
|
|
|
502
|
while (my $element = $data->next()) { |
1218
|
624
|
|
|
|
|
2305
|
$str.=$self->packObjectData($element,"$tree->".$i++); |
1219
|
|
|
|
|
|
|
} |
1220
|
156
|
|
|
|
|
1483
|
return $str; |
1221
|
|
|
|
|
|
|
} |
1222
|
|
|
|
|
|
|
|
1223
|
|
|
|
|
|
|
=head2 packMap(DATA,TREE) |
1224
|
|
|
|
|
|
|
|
1225
|
|
|
|
|
|
|
Encodes one Data::Sofu::Map and its contents and returns it. |
1226
|
|
|
|
|
|
|
|
1227
|
|
|
|
|
|
|
=cut |
1228
|
|
|
|
|
|
|
|
1229
|
|
|
|
|
|
|
sub packMap { |
1230
|
78
|
|
|
78
|
1
|
106
|
my $self=shift; |
1231
|
78
|
|
|
|
|
110
|
my $data=shift; |
1232
|
78
|
|
|
|
|
116
|
my $tree=shift; |
1233
|
78
|
|
|
|
|
278
|
my $str=$self->packLong($data->length()); |
1234
|
|
|
|
|
|
|
#foreach my $key (keys %{$data}) { |
1235
|
|
|
|
|
|
|
#while (my ($key,$value) = $data->each()) { |
1236
|
78
|
|
|
|
|
281
|
foreach my $key ($data->orderedKeys()) { |
1237
|
|
|
|
|
|
|
#print $key,"\n"; |
1238
|
104
|
|
|
|
|
317
|
my $kkey = Data::Sofu::Sofukeyescape($key); |
1239
|
104
|
|
|
|
|
275
|
$str.=$self->packText($key); |
1240
|
104
|
|
|
|
|
509
|
$str.=$self->packObjectData($data->object($key),"$tree->$kkey"); |
1241
|
|
|
|
|
|
|
} |
1242
|
78
|
|
|
|
|
727
|
return $str; |
1243
|
|
|
|
|
|
|
} |
1244
|
|
|
|
|
|
|
|
1245
|
|
|
|
|
|
|
|
1246
|
|
|
|
|
|
|
=head2 packComment(TREE,ADD) |
1247
|
|
|
|
|
|
|
|
1248
|
|
|
|
|
|
|
Packs the comment for (TREE) + ADD and returns it. |
1249
|
|
|
|
|
|
|
|
1250
|
|
|
|
|
|
|
=cut |
1251
|
|
|
|
|
|
|
|
1252
|
|
|
|
|
|
|
sub packComment { |
1253
|
1768
|
|
|
1768
|
1
|
2928
|
my $self=shift; |
1254
|
1768
|
|
|
|
|
4355
|
my $tree=shift; |
1255
|
1768
|
|
|
|
|
5093
|
local $_; |
1256
|
1768
|
|
|
|
|
2573
|
my $add=shift; |
1257
|
1768
|
100
|
100
|
|
|
13567
|
if ($self->{Comments}->{$tree} or $add) { |
1258
|
|
|
|
|
|
|
#$self->die("Comment format wrong for $tree, must be Arrayref"); |
1259
|
208
|
|
|
|
|
375
|
my @comments = (); |
1260
|
208
|
100
|
66
|
|
|
1707
|
@comments = @{$self->{Comments}->{$tree}} if (ref $self->{Comments}->{$tree} and ref $self->{Comments}->{$tree} eq "ARRAY"); |
|
104
|
|
|
|
|
351
|
|
1261
|
208
|
50
|
66
|
|
|
1576
|
push @comments,@{$add} if $add and ref $add and ref $add eq "ARRAY"; |
|
104
|
|
66
|
|
|
272
|
|
1262
|
208
|
|
|
|
|
2103
|
return $self->packText(join("\n",@comments)); |
1263
|
|
|
|
|
|
|
} |
1264
|
|
|
|
|
|
|
else { |
1265
|
1560
|
|
|
|
|
3471
|
return $self->packLong(0); |
1266
|
|
|
|
|
|
|
} |
1267
|
|
|
|
|
|
|
|
1268
|
|
|
|
|
|
|
} |
1269
|
|
|
|
|
|
|
|
1270
|
|
|
|
|
|
|
=head2 packHeader([ENCODING,[BYTEORDER,[SOFUMARK]]]) |
1271
|
|
|
|
|
|
|
|
1272
|
|
|
|
|
|
|
Packs the header of the file and sets encoding and byteorder |
1273
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
=cut |
1275
|
|
|
|
|
|
|
|
1276
|
|
|
|
|
|
|
sub packHeader { |
1277
|
58
|
|
|
58
|
1
|
126
|
my $self=shift; |
1278
|
58
|
|
|
|
|
336
|
$self->{OFFSET}="while object packing"; |
1279
|
58
|
|
|
|
|
130
|
my $encoding=shift; |
1280
|
58
|
|
|
|
|
282
|
my $byteorder=shift; |
1281
|
58
|
100
|
|
|
|
200
|
$encoding=0 unless $encoding; |
1282
|
58
|
100
|
|
|
|
149
|
$byteorder=0 unless $byteorder; |
1283
|
58
|
100
|
|
|
|
409
|
$self->encoding($encoding) unless $self->byteorder($byteorder); |
1284
|
58
|
|
|
|
|
128
|
my $mark=shift; |
1285
|
|
|
|
|
|
|
#$mark = undef unless defined $mark; |
1286
|
58
|
|
|
|
|
161
|
$self->{Mark} = $mark; |
1287
|
|
|
|
|
|
|
#die $mark; |
1288
|
58
|
|
|
|
|
125
|
my $str = ""; |
1289
|
58
|
100
|
100
|
|
|
342
|
$str.="Sofu" if $mark or not defined $mark; |
1290
|
58
|
|
|
|
|
248
|
$str.=$self->packendian(); |
1291
|
58
|
|
|
|
|
212
|
$str.=$self->packversion(); |
1292
|
58
|
|
|
|
|
310
|
$str.=$self->packencoding(); |
1293
|
58
|
|
|
|
|
263
|
return $str; |
1294
|
|
|
|
|
|
|
} |
1295
|
|
|
|
|
|
|
|
1296
|
|
|
|
|
|
|
|
1297
|
|
|
|
|
|
|
=head1 BUGS |
1298
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
n/c |
1300
|
|
|
|
|
|
|
|
1301
|
|
|
|
|
|
|
=head1 SEE ALSO |
1302
|
|
|
|
|
|
|
|
1303
|
|
|
|
|
|
|
perl(1),L |
1304
|
|
|
|
|
|
|
|
1305
|
|
|
|
|
|
|
Data::Sofu::Object, Data::Sofu, Data::Sofu::Binary::* |
1306
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
|
1308
|
|
|
|
|
|
|
=cut |
1309
|
|
|
|
|
|
|
|
1310
|
|
|
|
|
|
|
1; |