line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Licensed to the Apache Software Foundation (ASF) under one |
2
|
|
|
|
|
|
|
# or more contributor license agreements. See the NOTICE file |
3
|
|
|
|
|
|
|
# distributed with this work for additional information |
4
|
|
|
|
|
|
|
# regarding copyright ownership. The ASF licenses this file |
5
|
|
|
|
|
|
|
# to you under the Apache License, Version 2.0 (the |
6
|
|
|
|
|
|
|
# "License"); you may not use this file except in compliance |
7
|
|
|
|
|
|
|
# with the License. You may obtain a copy of the License at |
8
|
|
|
|
|
|
|
# |
9
|
|
|
|
|
|
|
# https://www.apache.org/licenses/LICENSE-2.0 |
10
|
|
|
|
|
|
|
# |
11
|
|
|
|
|
|
|
# Unless required by applicable law or agreed to in writing, |
12
|
|
|
|
|
|
|
# software distributed under the License is distributed on an |
13
|
|
|
|
|
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14
|
|
|
|
|
|
|
# KIND, either express or implied. See the License for the |
15
|
|
|
|
|
|
|
# specific language governing permissions and limitations |
16
|
|
|
|
|
|
|
# under the License. |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
use strict; |
19
|
2
|
|
|
2
|
|
1054
|
use warnings; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
46
|
|
20
|
2
|
|
|
2
|
|
8
|
|
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
37
|
|
21
|
|
|
|
|
|
|
use Config; |
22
|
2
|
|
|
2
|
|
9
|
use Encode(); |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
45
|
|
23
|
2
|
|
|
2
|
|
8
|
use Error::Simple; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
22
|
|
24
|
2
|
|
|
2
|
|
8
|
use Avro::Schema; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
10
|
|
25
|
2
|
|
|
2
|
|
101
|
|
|
2
|
|
|
|
|
10
|
|
|
2
|
|
|
|
|
3346
|
|
26
|
|
|
|
|
|
|
our $VERSION = '1.11.1'; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
our $complement = ~0x7F; |
29
|
|
|
|
|
|
|
unless ($Config{use64bitint}) { |
30
|
|
|
|
|
|
|
require Math::BigInt; |
31
|
|
|
|
|
|
|
$complement = Math::BigInt->new("0b" . ("1" x 57) . ("0" x 7)); |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=head2 decode(%param) |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
Resolve the given writer and reader_schema to decode the data provided by the |
37
|
|
|
|
|
|
|
reader. |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=over 4 |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
=item * writer_schema |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
The schema that was used to encode the data provided by the C<reader> |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
=item * reader_schema |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
The schema we want to use to decode the data. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=item * reader |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
An object implementing a straightforward interface. C<read($buf, $nbytes)> and |
52
|
|
|
|
|
|
|
C<seek($nbytes, $whence)> are expected. Typically a IO::String object or a |
53
|
|
|
|
|
|
|
IO::File object. It is expected that this calls will block the decoder, if not |
54
|
|
|
|
|
|
|
enough data is available for read. |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=back |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=cut |
59
|
|
|
|
|
|
|
my $class = shift; |
60
|
|
|
|
|
|
|
my %param = @_; |
61
|
1332
|
|
|
1332
|
1
|
2951
|
|
62
|
1332
|
|
|
|
|
2641
|
my ($writer_schema, $reader_schema, $reader) |
63
|
|
|
|
|
|
|
= @param{qw/writer_schema reader_schema reader/}; |
64
|
|
|
|
|
|
|
|
65
|
1332
|
|
|
|
|
2447
|
my $type = Avro::Schema->match( |
66
|
|
|
|
|
|
|
writer => $writer_schema, |
67
|
1332
|
100
|
|
|
|
2422
|
reader => $reader_schema, |
68
|
|
|
|
|
|
|
) or throw Avro::Schema::Error::Mismatch; |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
my $meth = "decode_$type"; |
71
|
|
|
|
|
|
|
return $class->$meth($writer_schema, $reader_schema, $reader); |
72
|
1331
|
|
|
|
|
2100
|
} |
73
|
1331
|
|
|
|
|
2301
|
|
74
|
|
|
|
|
|
|
my $class = shift; |
75
|
|
|
|
|
|
|
my ($schema, $reader) = @_; |
76
|
|
|
|
|
|
|
my $type = ref $schema ? $schema->type : $schema; |
77
|
2
|
|
|
2
|
0
|
3
|
my $meth = "skip_$type"; |
78
|
2
|
|
|
|
|
2
|
return $class->$meth($schema, $reader); |
79
|
2
|
50
|
|
|
|
5
|
} |
80
|
2
|
|
|
|
|
4
|
|
81
|
2
|
|
|
|
|
5
|
|
82
|
|
|
|
|
|
|
my $class = shift; |
83
|
|
|
|
|
|
|
my $reader = pop; |
84
|
1
|
|
|
1
|
0
|
3
|
$reader->read(my $bool, 1); |
85
|
|
|
|
|
|
|
return unpack 'C', $bool; |
86
|
0
|
|
|
0
|
0
|
0
|
} |
87
|
|
|
|
|
|
|
|
88
|
0
|
|
|
0
|
0
|
0
|
my $class = shift; |
89
|
0
|
|
|
|
|
0
|
my $reader = pop; |
90
|
0
|
|
|
|
|
0
|
return zigzag(unsigned_varint($reader)); |
91
|
0
|
|
|
|
|
0
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
my $class = shift; |
94
|
0
|
|
|
0
|
0
|
0
|
return decode_int($class, @_); |
95
|
|
|
|
|
|
|
} |
96
|
2084
|
|
|
2084
|
0
|
2171
|
|
97
|
2084
|
|
|
|
|
2065
|
my $class = shift; |
98
|
2084
|
|
|
|
|
2496
|
my $reader = pop; |
99
|
|
|
|
|
|
|
$reader->read(my $buf, 4); |
100
|
|
|
|
|
|
|
return unpack "f<", $buf; |
101
|
0
|
|
|
0
|
0
|
0
|
} |
102
|
|
|
|
|
|
|
|
103
|
2075
|
|
|
2075
|
0
|
2182
|
my $class = shift; |
104
|
2075
|
|
|
|
|
2557
|
my $reader = pop; |
105
|
|
|
|
|
|
|
$reader->read(my $buf, 8); |
106
|
|
|
|
|
|
|
return unpack "d<", $buf, |
107
|
0
|
|
|
0
|
0
|
0
|
} |
108
|
|
|
|
|
|
|
|
109
|
0
|
|
|
0
|
0
|
0
|
my $class = shift; |
110
|
0
|
|
|
|
|
0
|
my $reader = pop; |
111
|
0
|
|
|
|
|
0
|
my $size = decode_long($class, undef, undef, $reader); |
112
|
0
|
|
|
|
|
0
|
$reader->seek($size, 0); |
113
|
|
|
|
|
|
|
return; |
114
|
|
|
|
|
|
|
} |
115
|
0
|
|
|
0
|
0
|
0
|
|
116
|
|
|
|
|
|
|
my $class = shift; |
117
|
0
|
|
|
0
|
0
|
0
|
my $reader = pop; |
118
|
0
|
|
|
|
|
0
|
my $size = decode_long($class, undef, undef, $reader); |
119
|
0
|
|
|
|
|
0
|
$reader->read(my $buf, $size); |
120
|
0
|
|
|
|
|
0
|
return $buf; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
my $class = shift; |
124
|
2
|
|
|
2
|
0
|
2
|
my $reader = pop; |
125
|
2
|
|
|
|
|
2
|
my $bytes = decode_bytes($class, undef, undef, $reader); |
126
|
2
|
|
|
|
|
4
|
return Encode::decode_utf8($bytes); |
127
|
2
|
|
|
|
|
7
|
} |
128
|
2
|
|
|
|
|
38
|
|
129
|
|
|
|
|
|
|
my $class = shift; |
130
|
|
|
|
|
|
|
my ($schema, $reader) = @_; |
131
|
|
|
|
|
|
|
for my $field (@{ $schema->fields }){ |
132
|
1189
|
|
|
1189
|
0
|
1251
|
skip($class, $field->{type}, $reader); |
133
|
1189
|
|
|
|
|
1235
|
} |
134
|
1189
|
|
|
|
|
1523
|
} |
135
|
1189
|
|
|
|
|
2271
|
|
136
|
1189
|
|
|
|
|
5329
|
## 1.3.2 A record is encoded by encoding the values of its fields in the order |
137
|
|
|
|
|
|
|
## that they are declared. In other words, a record is encoded as just the |
138
|
|
|
|
|
|
|
## concatenation of the encodings of its fields. Field values are encoded per |
139
|
2
|
|
|
2
|
0
|
3
|
## their schema. |
140
|
|
|
|
|
|
|
my $class = shift; |
141
|
1172
|
|
|
1172
|
0
|
1357
|
my ($writer_schema, $reader_schema, $reader) = @_; |
142
|
1172
|
|
|
|
|
1211
|
my $record; |
143
|
1172
|
|
|
|
|
1516
|
|
144
|
1172
|
|
|
|
|
1799
|
my %extra_fields = %{ $reader_schema->fields_as_hash }; |
145
|
|
|
|
|
|
|
for my $field (@{ $writer_schema->fields }) { |
146
|
|
|
|
|
|
|
my $name = $field->{name}; |
147
|
|
|
|
|
|
|
my $w_field_schema = $field->{type}; |
148
|
0
|
|
|
0
|
0
|
0
|
my $r_field_schema = delete $extra_fields{$name}; |
149
|
0
|
|
|
|
|
0
|
|
150
|
0
|
|
|
|
|
0
|
## 1.3.2 if the writer's record contains a field with a name not |
|
0
|
|
|
|
|
0
|
|
151
|
0
|
|
|
|
|
0
|
## present in the reader's record, the writer's value for that field |
152
|
|
|
|
|
|
|
## is ignored. |
153
|
|
|
|
|
|
|
if (! $r_field_schema) { |
154
|
|
|
|
|
|
|
$class->skip($w_field_schema, $reader); |
155
|
|
|
|
|
|
|
next; |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
my $data = $class->decode( |
158
|
|
|
|
|
|
|
writer_schema => $w_field_schema, |
159
|
|
|
|
|
|
|
reader_schema => $r_field_schema->{type}, |
160
|
9
|
|
|
9
|
0
|
12
|
reader => $reader, |
161
|
9
|
|
|
|
|
14
|
); |
162
|
9
|
|
|
|
|
22
|
$record->{ $name } = $data; |
163
|
|
|
|
|
|
|
} |
164
|
9
|
|
|
|
|
10
|
|
|
9
|
|
|
|
|
20
|
|
165
|
9
|
|
|
|
|
15
|
for my $name (keys %extra_fields) { |
|
9
|
|
|
|
|
16
|
|
166
|
24
|
|
|
|
|
35
|
## 1.3.2. if the reader's record schema has a field with no default |
167
|
24
|
|
|
|
|
27
|
## value, and writer's schema does not have a field with the same |
168
|
24
|
|
|
|
|
36
|
## name, an error is signalled. |
169
|
|
|
|
|
|
|
unless (exists $extra_fields{$name}->{default}) { |
170
|
|
|
|
|
|
|
throw Avro::Schema::Error::Mismatch( |
171
|
|
|
|
|
|
|
"cannot resolve without default" |
172
|
|
|
|
|
|
|
); |
173
|
24
|
100
|
|
|
|
52
|
} |
174
|
2
|
|
|
|
|
5
|
## 1.3.2 ... else the default value is used |
175
|
2
|
|
|
|
|
3
|
$record->{ $name } = $extra_fields{$name}->{default}; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
return $record; |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
22
|
|
|
|
|
55
|
|
181
|
|
|
|
|
|
|
## 1.3.2 An enum is encoded by a int, representing the zero-based position of |
182
|
22
|
|
|
|
|
76
|
## the symbol in the schema. |
183
|
|
|
|
|
|
|
my $class = shift; |
184
|
|
|
|
|
|
|
my ($writer_schema, $reader_schema, $reader) = @_; |
185
|
9
|
|
|
|
|
26
|
my $index = decode_int($class, @_); |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
my $w_data = $writer_schema->symbols->[$index]; |
188
|
|
|
|
|
|
|
## 1.3.2 if the writer's symbol is not present in the reader's enum, |
189
|
2
|
100
|
|
|
|
5
|
## then an error is signalled. |
190
|
1
|
|
|
|
|
5
|
throw Avro::Schema::Error::Mismatch("enum unknown") |
191
|
|
|
|
|
|
|
unless $reader_schema->is_data_valid($w_data); |
192
|
|
|
|
|
|
|
return $w_data; |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
1
|
|
|
|
|
2
|
my $class = shift; |
196
|
|
|
|
|
|
|
my ($reader, $block_content) = @_; |
197
|
8
|
|
|
|
|
25
|
my $block_count = decode_long($class, undef, undef, $reader); |
198
|
|
|
|
|
|
|
while ($block_count) { |
199
|
|
|
|
|
|
|
if ($block_count < 0) { |
200
|
0
|
|
|
0
|
0
|
0
|
$reader->seek($block_count, 0); |
201
|
|
|
|
|
|
|
next; |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
else { |
204
|
|
|
|
|
|
|
for (1..$block_count) { |
205
|
5
|
|
|
5
|
0
|
6
|
$block_content->(); |
206
|
5
|
|
|
|
|
7
|
} |
207
|
5
|
|
|
|
|
10
|
} |
208
|
|
|
|
|
|
|
$block_count = decode_long($class, undef, undef, $reader); |
209
|
5
|
|
|
|
|
13
|
} |
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
|
212
|
5
|
100
|
|
|
|
11
|
my $class = shift; |
213
|
|
|
|
|
|
|
my ($schema, $reader) = @_; |
214
|
3
|
|
|
|
|
9
|
skip_block($reader, sub { $class->skip($schema->items, $reader) }); |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
## 1.3.2 Arrays are encoded as a series of blocks. Each block consists of a |
218
|
0
|
|
|
0
|
0
|
0
|
## long count value, followed by that many array items. A block with count zero |
219
|
0
|
|
|
|
|
0
|
## indicates the end of the array. Each item is encoded per the array's item |
220
|
0
|
|
|
|
|
0
|
## schema. |
221
|
0
|
|
|
|
|
0
|
## If a block's count is negative, its absolute value is used, and the count is |
222
|
0
|
0
|
|
|
|
0
|
## followed immediately by a long block size |
223
|
0
|
|
|
|
|
0
|
my $class = shift; |
224
|
0
|
|
|
|
|
0
|
my ($writer_schema, $reader_schema, $reader) = @_; |
225
|
|
|
|
|
|
|
my $block_count = decode_long($class, @_); |
226
|
|
|
|
|
|
|
my @array; |
227
|
0
|
|
|
|
|
0
|
my $writer_items = $writer_schema->items; |
228
|
0
|
|
|
|
|
0
|
my $reader_items = $reader_schema->items; |
229
|
|
|
|
|
|
|
while ($block_count) { |
230
|
|
|
|
|
|
|
my $block_size; |
231
|
0
|
|
|
|
|
0
|
if ($block_count < 0) { |
232
|
|
|
|
|
|
|
$block_count = -$block_count; |
233
|
|
|
|
|
|
|
$block_size = decode_long($class, @_); |
234
|
|
|
|
|
|
|
## XXX we can skip with $reader_schema? |
235
|
|
|
|
|
|
|
} |
236
|
0
|
|
|
0
|
0
|
0
|
for (1..$block_count) { |
237
|
0
|
|
|
|
|
0
|
push @array, $class->decode( |
238
|
0
|
|
|
0
|
|
0
|
writer_schema => $writer_items, |
|
0
|
|
|
|
|
0
|
|
239
|
|
|
|
|
|
|
reader_schema => $reader_items, |
240
|
|
|
|
|
|
|
reader => $reader, |
241
|
|
|
|
|
|
|
); |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
$block_count = decode_long($class, @_); |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
return \@array; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
318
|
|
|
318
|
0
|
364
|
my $class = shift; |
249
|
318
|
|
|
|
|
430
|
my ($schema, $reader) = @_; |
250
|
318
|
|
|
|
|
461
|
skip_block($reader, sub { |
251
|
318
|
|
|
|
|
369
|
skip_string($class, $reader); |
252
|
318
|
|
|
|
|
510
|
$class->skip($schema->values, $reader); |
253
|
318
|
|
|
|
|
482
|
}); |
254
|
318
|
|
|
|
|
577
|
} |
255
|
318
|
|
|
|
|
337
|
|
256
|
318
|
50
|
|
|
|
457
|
## 1.3.2 Maps are encoded as a series of blocks. Each block consists of a long |
257
|
0
|
|
|
|
|
0
|
## count value, followed by that many key/value pairs. A block with count zero |
258
|
0
|
|
|
|
|
0
|
## indicates the end of the map. Each item is encoded per the map's value |
259
|
|
|
|
|
|
|
## schema. |
260
|
|
|
|
|
|
|
## |
261
|
318
|
|
|
|
|
574
|
## If a block's count is negative, its absolute value is used, and the count is |
262
|
848
|
|
|
|
|
7933
|
## followed immediately by a long block size indicating the number of bytes in |
263
|
|
|
|
|
|
|
## the block. This block size permits fast skipping through data, e.g., when |
264
|
|
|
|
|
|
|
## projecting a record to a subset of its fields. |
265
|
|
|
|
|
|
|
my $class = shift; |
266
|
|
|
|
|
|
|
my ($writer_schema, $reader_schema, $reader) = @_; |
267
|
|
|
|
|
|
|
my %hash; |
268
|
318
|
|
|
|
|
4606
|
|
269
|
|
|
|
|
|
|
my $block_count = decode_long($class, @_); |
270
|
318
|
|
|
|
|
1152
|
my $writer_values = $writer_schema->values; |
271
|
|
|
|
|
|
|
my $reader_values = $reader_schema->values; |
272
|
|
|
|
|
|
|
while ($block_count) { |
273
|
|
|
|
|
|
|
my $block_size; |
274
|
0
|
|
|
0
|
0
|
0
|
if ($block_count < 0) { |
275
|
0
|
|
|
|
|
0
|
$block_count = -$block_count; |
276
|
|
|
|
|
|
|
$block_size = decode_long($class, @_); |
277
|
0
|
|
|
0
|
|
0
|
## XXX we can skip with $reader_schema? |
278
|
0
|
|
|
|
|
0
|
} |
279
|
0
|
|
|
|
|
0
|
for (1..$block_count) { |
280
|
|
|
|
|
|
|
my $key = decode_string($class, @_); |
281
|
|
|
|
|
|
|
unless (defined $key && length $key) { |
282
|
|
|
|
|
|
|
throw Avro::Schema::Error::Parse("key of map is invalid"); |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
$hash{$key} = $class->decode( |
285
|
|
|
|
|
|
|
writer_schema => $writer_values, |
286
|
|
|
|
|
|
|
reader_schema => $reader_values, |
287
|
|
|
|
|
|
|
reader => $reader, |
288
|
|
|
|
|
|
|
); |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
$block_count = decode_long($class, @_); |
291
|
|
|
|
|
|
|
} |
292
|
112
|
|
|
112
|
0
|
134
|
return \%hash; |
293
|
112
|
|
|
|
|
149
|
} |
294
|
112
|
|
|
|
|
143
|
|
295
|
|
|
|
|
|
|
my $class = shift; |
296
|
112
|
|
|
|
|
167
|
my ($schema, $reader) = @_; |
297
|
112
|
|
|
|
|
202
|
my $idx = decode_long($class, undef, undef, $reader); |
298
|
112
|
|
|
|
|
201
|
my $union_schema = $schema->schemas->[$idx] |
299
|
112
|
|
|
|
|
180
|
or throw Avro::Schema::Error::Parse("union union member"); |
300
|
112
|
|
|
|
|
141
|
$class->skip($union_schema, $reader); |
301
|
112
|
50
|
|
|
|
184
|
} |
302
|
0
|
|
|
|
|
0
|
|
303
|
0
|
|
|
|
|
0
|
## 1.3.2 A union is encoded by first writing an int value indicating the |
304
|
|
|
|
|
|
|
## zero-based position within the union of the schema of its value. The value |
305
|
|
|
|
|
|
|
## is then encoded per the indicated schema within the union. |
306
|
112
|
|
|
|
|
202
|
my $class = shift; |
307
|
333
|
|
|
|
|
471
|
my ($writer_schema, $reader_schema, $reader) = @_; |
308
|
333
|
50
|
33
|
|
|
5049
|
my $idx = decode_long($class, @_); |
309
|
0
|
|
|
|
|
0
|
my $union_schema = $writer_schema->schemas->[$idx]; |
310
|
|
|
|
|
|
|
## XXX TODO: schema resolution |
311
|
333
|
|
|
|
|
589
|
# The first schema in the reader's union that matches the selected writer's |
312
|
|
|
|
|
|
|
# union schema is recursively resolved against it. if none match, an error |
313
|
|
|
|
|
|
|
# is signalled. |
314
|
|
|
|
|
|
|
return $class->decode( |
315
|
|
|
|
|
|
|
reader_schema => $union_schema, |
316
|
|
|
|
|
|
|
writer_schema => $union_schema, |
317
|
112
|
|
|
|
|
187
|
reader => $reader, |
318
|
|
|
|
|
|
|
); |
319
|
112
|
|
|
|
|
365
|
} |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
my $class = shift; |
322
|
|
|
|
|
|
|
my ($schema, $reader) = @_; |
323
|
0
|
|
|
0
|
0
|
0
|
$reader->seek($schema->size, 0); |
324
|
0
|
|
|
|
|
0
|
} |
325
|
0
|
|
|
|
|
0
|
|
326
|
0
|
0
|
|
|
|
0
|
## 1.3.2 Fixed instances are encoded using the number of bytes declared in the |
327
|
|
|
|
|
|
|
## schema. |
328
|
0
|
|
|
|
|
0
|
my $class = shift; |
329
|
|
|
|
|
|
|
my ($writer_schema, $reader_schema, $reader) = @_; |
330
|
|
|
|
|
|
|
$reader->read(my $buf, $writer_schema->size); |
331
|
|
|
|
|
|
|
return $buf; |
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
my $int = shift; |
335
|
3
|
|
|
3
|
0
|
5
|
if (1 & $int) { |
336
|
3
|
|
|
|
|
3
|
## odd values are encoded negative ints |
337
|
3
|
|
|
|
|
7
|
return -( 1 + ($int >> 1) ); |
338
|
3
|
|
|
|
|
7
|
} |
339
|
|
|
|
|
|
|
## even values are positive natural left shifted one bit |
340
|
|
|
|
|
|
|
else { |
341
|
|
|
|
|
|
|
return $int >> 1; |
342
|
|
|
|
|
|
|
} |
343
|
3
|
|
|
|
|
5
|
} |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
my $reader = shift; |
346
|
|
|
|
|
|
|
my $int = 0; |
347
|
|
|
|
|
|
|
my $more; |
348
|
|
|
|
|
|
|
my $shift = 0; |
349
|
|
|
|
|
|
|
do { |
350
|
|
|
|
|
|
|
$reader->read(my $buf, 1); |
351
|
0
|
|
|
0
|
0
|
0
|
my $byte = ord $buf; |
352
|
0
|
|
|
|
|
0
|
my $value = $byte & 0x7F; |
353
|
0
|
|
|
|
|
0
|
$int |= $value << $shift; |
354
|
|
|
|
|
|
|
$shift += 7; |
355
|
|
|
|
|
|
|
$more = $byte & 0x80; |
356
|
|
|
|
|
|
|
} until (! $more); |
357
|
|
|
|
|
|
|
return $int; |
358
|
|
|
|
|
|
|
} |
359
|
12
|
|
|
12
|
0
|
14
|
|
360
|
12
|
|
|
|
|
19
|
1; |