rlm@3
|
1 <?php
|
rlm@3
|
2 // +----------------------------------------------------------------------+
|
rlm@3
|
3 // | PHP version 5 |
|
rlm@3
|
4 // +----------------------------------------------------------------------+
|
rlm@3
|
5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen |
|
rlm@3
|
6 // +----------------------------------------------------------------------+
|
rlm@3
|
7 // | This source file is subject to version 2 of the GPL license, |
|
rlm@3
|
8 // | that is bundled with this package in the file license.txt and is |
|
rlm@3
|
9 // | available through the world-wide-web at the following url: |
|
rlm@3
|
10 // | http://www.gnu.org/copyleft/gpl.html |
|
rlm@3
|
11 // +----------------------------------------------------------------------+
|
rlm@3
|
12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org |
|
rlm@3
|
13 // +----------------------------------------------------------------------+
|
rlm@3
|
14 // | Authors: James Heinrich <infoØgetid3*org> |
|
rlm@3
|
15 // | Allan Hansen <ahØartemis*dk> |
|
rlm@3
|
16 // +----------------------------------------------------------------------+
|
rlm@3
|
17 // | module.archive.gzip.php |
|
rlm@3
|
18 // | module for analyzing GZIP files |
|
rlm@3
|
19 // | dependencies: NONE |
|
rlm@3
|
20 // +----------------------------------------------------------------------+
|
rlm@3
|
21 // | FLV module by Seth Kaufman <sethØwhirl-i.gig*com> |
|
rlm@3
|
22 // | |
|
rlm@3
|
23 // | * version 0.1 (26 June 2005) |
|
rlm@3
|
24 // | |
|
rlm@3
|
25 // | minor modifications by James Heinrich <infoØgetid3*org> |
|
rlm@3
|
26 // | * version 0.1.1 (15 July 2005) |
|
rlm@3
|
27 // | |
|
rlm@3
|
28 // | Support for On2 VP6 codec and meta information by |
|
rlm@3
|
29 // | Steve Webster <steve.websterØfeaturecreep*com> |
|
rlm@3
|
30 // | * version 0.2 (22 February 2006) |
|
rlm@3
|
31 // | |
|
rlm@3
|
32 // | Modified to not read entire file into memory |
|
rlm@3
|
33 // | by James Heinrich <infoØgetid3*org> |
|
rlm@3
|
34 // | * version 0.3 (15 June 2006) |
|
rlm@3
|
35 // | |
|
rlm@3
|
36 // | Modifications by Allan Hansen <ahØartemis*dk> |
|
rlm@3
|
37 // | Adapted module for PHP5 and getID3 2.0.0. |
|
rlm@3
|
38 // +----------------------------------------------------------------------+
|
rlm@3
|
39 //
|
rlm@3
|
40 // $Id: module.audio-video.flv.php,v 1.7 2006/11/10 11:20:12 ah Exp $
|
rlm@3
|
41
|
rlm@3
|
42
|
rlm@3
|
43
|
rlm@3
|
44 class getid3_flv extends getid3_handler
|
rlm@3
|
45 {
|
rlm@3
|
46
|
rlm@3
|
47 const TAG_AUDIO = 8;
|
rlm@3
|
48 const TAG_VIDEO = 9;
|
rlm@3
|
49 const TAG_META = 18;
|
rlm@3
|
50
|
rlm@3
|
51 const VIDEO_H263 = 2;
|
rlm@3
|
52 const VIDEO_SCREEN = 3;
|
rlm@3
|
53 const VIDEO_VP6 = 4;
|
rlm@3
|
54
|
rlm@3
|
55
|
rlm@3
|
56 public function Analyze()
|
rlm@3
|
57 {
|
rlm@3
|
58 $info = &$this->getid3->info;
|
rlm@3
|
59
|
rlm@3
|
60 $info['flv'] = array ();
|
rlm@3
|
61 $info_flv = &$info['flv'];
|
rlm@3
|
62
|
rlm@3
|
63 fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
|
rlm@3
|
64
|
rlm@3
|
65 $flv_data_length = $info['avdataend'] - $info['avdataoffset'];
|
rlm@3
|
66 $flv_header = fread($this->getid3->fp, 5);
|
rlm@3
|
67
|
rlm@3
|
68 $info['fileformat'] = 'flv';
|
rlm@3
|
69 $info_flv['header']['signature'] = substr($flv_header, 0, 3);
|
rlm@3
|
70 $info_flv['header']['version'] = getid3_lib::BigEndian2Int(substr($flv_header, 3, 1));
|
rlm@3
|
71 $type_flags = getid3_lib::BigEndian2Int(substr($flv_header, 4, 1));
|
rlm@3
|
72
|
rlm@3
|
73 $info_flv['header']['hasAudio'] = (bool) ($type_flags & 0x04);
|
rlm@3
|
74 $info_flv['header']['hasVideo'] = (bool) ($type_flags & 0x01);
|
rlm@3
|
75
|
rlm@3
|
76 $frame_size_data_length = getid3_lib::BigEndian2Int(fread($this->getid3->fp, 4));
|
rlm@3
|
77 $flv_header_frame_length = 9;
|
rlm@3
|
78 if ($frame_size_data_length > $flv_header_frame_length) {
|
rlm@3
|
79 fseek($this->getid3->fp, $frame_size_data_length - $flv_header_frame_length, SEEK_CUR);
|
rlm@3
|
80 }
|
rlm@3
|
81
|
rlm@3
|
82 $duration = 0;
|
rlm@3
|
83 while ((ftell($this->getid3->fp) + 1) < $info['avdataend']) {
|
rlm@3
|
84
|
rlm@3
|
85 $this_tag_header = fread($this->getid3->fp, 16);
|
rlm@3
|
86
|
rlm@3
|
87 $previous_tag_length = getid3_lib::BigEndian2Int(substr($this_tag_header, 0, 4));
|
rlm@3
|
88 $tag_type = getid3_lib::BigEndian2Int(substr($this_tag_header, 4, 1));
|
rlm@3
|
89 $data_length = getid3_lib::BigEndian2Int(substr($this_tag_header, 5, 3));
|
rlm@3
|
90 $timestamp = getid3_lib::BigEndian2Int(substr($this_tag_header, 8, 3));
|
rlm@3
|
91 $last_header_byte = getid3_lib::BigEndian2Int(substr($this_tag_header, 15, 1));
|
rlm@3
|
92 $next_offset = ftell($this->getid3->fp) - 1 + $data_length;
|
rlm@3
|
93
|
rlm@3
|
94 switch ($tag_type) {
|
rlm@3
|
95
|
rlm@3
|
96 case getid3_flv::TAG_AUDIO:
|
rlm@3
|
97 if (!isset($info_flv['audio']['audioFormat'])) {
|
rlm@3
|
98 $info_flv['audio']['audioFormat'] = $last_header_byte & 0x07;
|
rlm@3
|
99 $info_flv['audio']['audioRate'] = ($last_header_byte & 0x30) / 0x10;
|
rlm@3
|
100 $info_flv['audio']['audioSampleSize'] = ($last_header_byte & 0x40) / 0x40;
|
rlm@3
|
101 $info_flv['audio']['audioType'] = ($last_header_byte & 0x80) / 0x80;
|
rlm@3
|
102 }
|
rlm@3
|
103 break;
|
rlm@3
|
104
|
rlm@3
|
105
|
rlm@3
|
106 case getid3_flv::TAG_VIDEO:
|
rlm@3
|
107 if (!isset($info_flv['video']['videoCodec'])) {
|
rlm@3
|
108 $info_flv['video']['videoCodec'] = $last_header_byte & 0x07;
|
rlm@3
|
109
|
rlm@3
|
110 $flv_video_header = fread($this->getid3->fp, 11);
|
rlm@3
|
111
|
rlm@3
|
112 if ($info_flv['video']['videoCodec'] != getid3_flv::VIDEO_VP6) {
|
rlm@3
|
113
|
rlm@3
|
114 $picture_size_type = (getid3_lib::BigEndian2Int(substr($flv_video_header, 3, 2))) >> 7;
|
rlm@3
|
115 $picture_size_type = $picture_size_type & 0x0007;
|
rlm@3
|
116 $info_flv['header']['videoSizeType'] = $picture_size_type;
|
rlm@3
|
117
|
rlm@3
|
118 switch ($picture_size_type) {
|
rlm@3
|
119 case 0:
|
rlm@3
|
120 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 2));
|
rlm@3
|
121 $picture_size_enc <<= 1;
|
rlm@3
|
122 $info['video']['resolution_x'] = ($picture_size_enc & 0xFF00) >> 8;
|
rlm@3
|
123 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 6, 2));
|
rlm@3
|
124 $picture_size_enc <<= 1;
|
rlm@3
|
125 $info['video']['resolution_y'] = ($picture_size_enc & 0xFF00) >> 8;
|
rlm@3
|
126 break;
|
rlm@3
|
127
|
rlm@3
|
128 case 1:
|
rlm@3
|
129 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 4));
|
rlm@3
|
130 $picture_size_enc <<= 1;
|
rlm@3
|
131 $info['video']['resolution_x'] = ($picture_size_enc & 0xFFFF0000) >> 16;
|
rlm@3
|
132
|
rlm@3
|
133 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 7, 4));
|
rlm@3
|
134 $picture_size_enc <<= 1;
|
rlm@3
|
135 $info['video']['resolution_y'] = ($picture_size_enc & 0xFFFF0000) >> 16;
|
rlm@3
|
136 break;
|
rlm@3
|
137
|
rlm@3
|
138 case 2:
|
rlm@3
|
139 $info['video']['resolution_x'] = 352;
|
rlm@3
|
140 $info['video']['resolution_y'] = 288;
|
rlm@3
|
141 break;
|
rlm@3
|
142
|
rlm@3
|
143 case 3:
|
rlm@3
|
144 $info['video']['resolution_x'] = 176;
|
rlm@3
|
145 $info['video']['resolution_y'] = 144;
|
rlm@3
|
146 break;
|
rlm@3
|
147
|
rlm@3
|
148 case 4:
|
rlm@3
|
149 $info['video']['resolution_x'] = 128;
|
rlm@3
|
150 $info['video']['resolution_y'] = 96;
|
rlm@3
|
151 break;
|
rlm@3
|
152
|
rlm@3
|
153 case 5:
|
rlm@3
|
154 $info['video']['resolution_x'] = 320;
|
rlm@3
|
155 $info['video']['resolution_y'] = 240;
|
rlm@3
|
156 break;
|
rlm@3
|
157
|
rlm@3
|
158 case 6:
|
rlm@3
|
159 $info['video']['resolution_x'] = 160;
|
rlm@3
|
160 $info['video']['resolution_y'] = 120;
|
rlm@3
|
161 break;
|
rlm@3
|
162
|
rlm@3
|
163 default:
|
rlm@3
|
164 $info['video']['resolution_x'] = 0;
|
rlm@3
|
165 $info['video']['resolution_y'] = 0;
|
rlm@3
|
166 break;
|
rlm@3
|
167 }
|
rlm@3
|
168 }
|
rlm@3
|
169 }
|
rlm@3
|
170 break;
|
rlm@3
|
171
|
rlm@3
|
172
|
rlm@3
|
173 // Meta tag
|
rlm@3
|
174 case getid3_flv::TAG_META:
|
rlm@3
|
175
|
rlm@3
|
176 fseek($this->getid3->fp, -1, SEEK_CUR);
|
rlm@3
|
177 $reader = new AMFReader(new AMFStream(fread($this->getid3->fp, $data_length)));
|
rlm@3
|
178 $event_name = $reader->readData();
|
rlm@3
|
179 $info['meta'][$event_name] = $reader->readData();
|
rlm@3
|
180 unset($reader);
|
rlm@3
|
181
|
rlm@3
|
182 $info['video']['frame_rate'] = @$info['meta']['onMetaData']['framerate'];
|
rlm@3
|
183 $info['video']['resolution_x'] = @$info['meta']['onMetaData']['width'];
|
rlm@3
|
184 $info['video']['resolution_y'] = @$info['meta']['onMetaData']['height'];
|
rlm@3
|
185 break;
|
rlm@3
|
186
|
rlm@3
|
187 default:
|
rlm@3
|
188 // noop
|
rlm@3
|
189 break;
|
rlm@3
|
190 }
|
rlm@3
|
191
|
rlm@3
|
192 if ($timestamp > $duration) {
|
rlm@3
|
193 $duration = $timestamp;
|
rlm@3
|
194 }
|
rlm@3
|
195
|
rlm@3
|
196 fseek($this->getid3->fp, $next_offset, SEEK_SET);
|
rlm@3
|
197 }
|
rlm@3
|
198
|
rlm@3
|
199 if ($info['playtime_seconds'] = $duration / 1000) {
|
rlm@3
|
200 $info['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds'];
|
rlm@3
|
201 }
|
rlm@3
|
202
|
rlm@3
|
203 if ($info_flv['header']['hasAudio']) {
|
rlm@3
|
204 $info['audio']['codec'] = $this->FLVaudioFormat($info_flv['audio']['audioFormat']);
|
rlm@3
|
205 $info['audio']['sample_rate'] = $this->FLVaudioRate($info_flv['audio']['audioRate']);
|
rlm@3
|
206 $info['audio']['bits_per_sample'] = $this->FLVaudioBitDepth($info_flv['audio']['audioSampleSize']);
|
rlm@3
|
207
|
rlm@3
|
208 $info['audio']['channels'] = $info_flv['audio']['audioType'] + 1; // 0=mono,1=stereo
|
rlm@3
|
209 $info['audio']['lossless'] = ($info_flv['audio']['audioFormat'] ? false : true); // 0=uncompressed
|
rlm@3
|
210 $info['audio']['dataformat'] = 'flv';
|
rlm@3
|
211 }
|
rlm@3
|
212 if (@$info_flv['header']['hasVideo']) {
|
rlm@3
|
213 $info['video']['codec'] = $this->FLVvideoCodec($info_flv['video']['videoCodec']);
|
rlm@3
|
214 $info['video']['dataformat'] = 'flv';
|
rlm@3
|
215 $info['video']['lossless'] = false;
|
rlm@3
|
216 }
|
rlm@3
|
217
|
rlm@3
|
218 return true;
|
rlm@3
|
219 }
|
rlm@3
|
220
|
rlm@3
|
221
|
rlm@3
|
222 public static function FLVaudioFormat($id) {
|
rlm@3
|
223
|
rlm@3
|
224 static $lookup = array(
|
rlm@3
|
225 0 => 'uncompressed',
|
rlm@3
|
226 1 => 'ADPCM',
|
rlm@3
|
227 2 => 'mp3',
|
rlm@3
|
228 5 => 'Nellymoser 8kHz mono',
|
rlm@3
|
229 6 => 'Nellymoser',
|
rlm@3
|
230 );
|
rlm@3
|
231 return (@$lookup[$id] ? @$lookup[$id] : false);
|
rlm@3
|
232 }
|
rlm@3
|
233
|
rlm@3
|
234
|
rlm@3
|
235 public static function FLVaudioRate($id) {
|
rlm@3
|
236
|
rlm@3
|
237 static $lookup = array(
|
rlm@3
|
238 0 => 5500,
|
rlm@3
|
239 1 => 11025,
|
rlm@3
|
240 2 => 22050,
|
rlm@3
|
241 3 => 44100,
|
rlm@3
|
242 );
|
rlm@3
|
243 return (@$lookup[$id] ? @$lookup[$id] : false);
|
rlm@3
|
244 }
|
rlm@3
|
245
|
rlm@3
|
246
|
rlm@3
|
247 public static function FLVaudioBitDepth($id) {
|
rlm@3
|
248
|
rlm@3
|
249 static $lookup = array(
|
rlm@3
|
250 0 => 8,
|
rlm@3
|
251 1 => 16,
|
rlm@3
|
252 );
|
rlm@3
|
253 return (@$lookup[$id] ? @$lookup[$id] : false);
|
rlm@3
|
254 }
|
rlm@3
|
255
|
rlm@3
|
256
|
rlm@3
|
257 public static function FLVvideoCodec($id) {
|
rlm@3
|
258
|
rlm@3
|
259 static $lookup = array(
|
rlm@3
|
260 getid3_flv::VIDEO_H263 => 'Sorenson H.263',
|
rlm@3
|
261 getid3_flv::VIDEO_SCREEN => 'Screen video',
|
rlm@3
|
262 getid3_flv::VIDEO_VP6 => 'On2 VP6',
|
rlm@3
|
263 );
|
rlm@3
|
264 return (@$lookup[$id] ? @$lookup[$id] : false);
|
rlm@3
|
265 }
|
rlm@3
|
266 }
|
rlm@3
|
267
|
rlm@3
|
268
|
rlm@3
|
269
|
rlm@3
|
270 class AMFStream
|
rlm@3
|
271 {
|
rlm@3
|
272 public $bytes;
|
rlm@3
|
273 public $pos;
|
rlm@3
|
274
|
rlm@3
|
275
|
rlm@3
|
276 public function AMFStream($bytes) {
|
rlm@3
|
277
|
rlm@3
|
278 $this->bytes = $bytes;
|
rlm@3
|
279 $this->pos = 0;
|
rlm@3
|
280 }
|
rlm@3
|
281
|
rlm@3
|
282
|
rlm@3
|
283 public function readByte() {
|
rlm@3
|
284
|
rlm@3
|
285 return getid3_lib::BigEndian2Int(substr($this->bytes, $this->pos++, 1));
|
rlm@3
|
286 }
|
rlm@3
|
287
|
rlm@3
|
288
|
rlm@3
|
289 public function readInt() {
|
rlm@3
|
290
|
rlm@3
|
291 return ($this->readByte() << 8) + $this->readByte();
|
rlm@3
|
292 }
|
rlm@3
|
293
|
rlm@3
|
294
|
rlm@3
|
295 public function readLong() {
|
rlm@3
|
296
|
rlm@3
|
297 return ($this->readByte() << 24) + ($this->readByte() << 16) + ($this->readByte() << 8) + $this->readByte();
|
rlm@3
|
298 }
|
rlm@3
|
299
|
rlm@3
|
300
|
rlm@3
|
301 public function readDouble() {
|
rlm@3
|
302
|
rlm@3
|
303 return getid3_lib::BigEndian2Float($this->read(8));
|
rlm@3
|
304 }
|
rlm@3
|
305
|
rlm@3
|
306
|
rlm@3
|
307 public function readUTF() {
|
rlm@3
|
308
|
rlm@3
|
309 $length = $this->readInt();
|
rlm@3
|
310 return $this->read($length);
|
rlm@3
|
311 }
|
rlm@3
|
312
|
rlm@3
|
313
|
rlm@3
|
314 public function readLongUTF() {
|
rlm@3
|
315
|
rlm@3
|
316 $length = $this->readLong();
|
rlm@3
|
317 return $this->read($length);
|
rlm@3
|
318 }
|
rlm@3
|
319
|
rlm@3
|
320
|
rlm@3
|
321 public function read($length) {
|
rlm@3
|
322
|
rlm@3
|
323 $val = substr($this->bytes, $this->pos, $length);
|
rlm@3
|
324 $this->pos += $length;
|
rlm@3
|
325 return $val;
|
rlm@3
|
326 }
|
rlm@3
|
327
|
rlm@3
|
328
|
rlm@3
|
329 public function peekByte() {
|
rlm@3
|
330
|
rlm@3
|
331 $pos = $this->pos;
|
rlm@3
|
332 $val = $this->readByte();
|
rlm@3
|
333 $this->pos = $pos;
|
rlm@3
|
334 return $val;
|
rlm@3
|
335 }
|
rlm@3
|
336
|
rlm@3
|
337
|
rlm@3
|
338 public function peekInt() {
|
rlm@3
|
339
|
rlm@3
|
340 $pos = $this->pos;
|
rlm@3
|
341 $val = $this->readInt();
|
rlm@3
|
342 $this->pos = $pos;
|
rlm@3
|
343 return $val;
|
rlm@3
|
344 }
|
rlm@3
|
345
|
rlm@3
|
346
|
rlm@3
|
347 public function peekLong() {
|
rlm@3
|
348
|
rlm@3
|
349 $pos = $this->pos;
|
rlm@3
|
350 $val = $this->readLong();
|
rlm@3
|
351 $this->pos = $pos;
|
rlm@3
|
352 return $val;
|
rlm@3
|
353 }
|
rlm@3
|
354
|
rlm@3
|
355
|
rlm@3
|
356 public function peekDouble() {
|
rlm@3
|
357
|
rlm@3
|
358 $pos = $this->pos;
|
rlm@3
|
359 $val = $this->readDouble();
|
rlm@3
|
360 $this->pos = $pos;
|
rlm@3
|
361 return $val;
|
rlm@3
|
362 }
|
rlm@3
|
363
|
rlm@3
|
364
|
rlm@3
|
365 public function peekUTF() {
|
rlm@3
|
366
|
rlm@3
|
367 $pos = $this->pos;
|
rlm@3
|
368 $val = $this->readUTF();
|
rlm@3
|
369 $this->pos = $pos;
|
rlm@3
|
370 return $val;
|
rlm@3
|
371 }
|
rlm@3
|
372
|
rlm@3
|
373
|
rlm@3
|
374 public function peekLongUTF() {
|
rlm@3
|
375
|
rlm@3
|
376 $pos = $this->pos;
|
rlm@3
|
377 $val = $this->readLongUTF();
|
rlm@3
|
378 $this->pos = $pos;
|
rlm@3
|
379 return $val;
|
rlm@3
|
380 }
|
rlm@3
|
381 }
|
rlm@3
|
382
|
rlm@3
|
383
|
rlm@3
|
384
|
rlm@3
|
385 class AMFReader
|
rlm@3
|
386 {
|
rlm@3
|
387 public $stream;
|
rlm@3
|
388
|
rlm@3
|
389 public function __construct($stream) {
|
rlm@3
|
390
|
rlm@3
|
391 $this->stream = $stream;
|
rlm@3
|
392 }
|
rlm@3
|
393
|
rlm@3
|
394
|
rlm@3
|
395 public function readData() {
|
rlm@3
|
396
|
rlm@3
|
397 $value = null;
|
rlm@3
|
398
|
rlm@3
|
399 $type = $this->stream->readByte();
|
rlm@3
|
400
|
rlm@3
|
401 switch($type) {
|
rlm@3
|
402 // Double
|
rlm@3
|
403 case 0:
|
rlm@3
|
404 $value = $this->readDouble();
|
rlm@3
|
405 break;
|
rlm@3
|
406
|
rlm@3
|
407 // Boolean
|
rlm@3
|
408 case 1:
|
rlm@3
|
409 $value = $this->readBoolean();
|
rlm@3
|
410 break;
|
rlm@3
|
411
|
rlm@3
|
412 // String
|
rlm@3
|
413 case 2:
|
rlm@3
|
414 $value = $this->readString();
|
rlm@3
|
415 break;
|
rlm@3
|
416
|
rlm@3
|
417 // Object
|
rlm@3
|
418 case 3:
|
rlm@3
|
419 $value = $this->readObject();
|
rlm@3
|
420 break;
|
rlm@3
|
421
|
rlm@3
|
422 // null
|
rlm@3
|
423 case 6:
|
rlm@3
|
424 return null;
|
rlm@3
|
425 break;
|
rlm@3
|
426
|
rlm@3
|
427 // Mixed array
|
rlm@3
|
428 case 8:
|
rlm@3
|
429 $value = $this->readMixedArray();
|
rlm@3
|
430 break;
|
rlm@3
|
431
|
rlm@3
|
432 // Array
|
rlm@3
|
433 case 10:
|
rlm@3
|
434 $value = $this->readArray();
|
rlm@3
|
435 break;
|
rlm@3
|
436
|
rlm@3
|
437 // Date
|
rlm@3
|
438 case 11:
|
rlm@3
|
439 $value = $this->readDate();
|
rlm@3
|
440 break;
|
rlm@3
|
441
|
rlm@3
|
442 // Long string
|
rlm@3
|
443 case 13:
|
rlm@3
|
444 $value = $this->readLongString();
|
rlm@3
|
445 break;
|
rlm@3
|
446
|
rlm@3
|
447 // XML (handled as string)
|
rlm@3
|
448 case 15:
|
rlm@3
|
449 $value = $this->readXML();
|
rlm@3
|
450 break;
|
rlm@3
|
451
|
rlm@3
|
452 // Typed object (handled as object)
|
rlm@3
|
453 case 16:
|
rlm@3
|
454 $value = $this->readTypedObject();
|
rlm@3
|
455 break;
|
rlm@3
|
456
|
rlm@3
|
457 // Long string
|
rlm@3
|
458 default:
|
rlm@3
|
459 $value = '(unknown or unsupported data type)';
|
rlm@3
|
460 break;
|
rlm@3
|
461 }
|
rlm@3
|
462
|
rlm@3
|
463 return $value;
|
rlm@3
|
464 }
|
rlm@3
|
465
|
rlm@3
|
466
|
rlm@3
|
467 public function readDouble() {
|
rlm@3
|
468
|
rlm@3
|
469 return $this->stream->readDouble();
|
rlm@3
|
470 }
|
rlm@3
|
471
|
rlm@3
|
472
|
rlm@3
|
473 public function readBoolean() {
|
rlm@3
|
474
|
rlm@3
|
475 return $this->stream->readByte() == 1;
|
rlm@3
|
476 }
|
rlm@3
|
477
|
rlm@3
|
478
|
rlm@3
|
479 public function readString() {
|
rlm@3
|
480
|
rlm@3
|
481 return $this->stream->readUTF();
|
rlm@3
|
482 }
|
rlm@3
|
483
|
rlm@3
|
484
|
rlm@3
|
485 public function readObject() {
|
rlm@3
|
486
|
rlm@3
|
487 // Get highest numerical index - ignored
|
rlm@3
|
488 $highestIndex = $this->stream->readLong();
|
rlm@3
|
489
|
rlm@3
|
490 $data = array();
|
rlm@3
|
491
|
rlm@3
|
492 while ($key = $this->stream->readUTF()) {
|
rlm@3
|
493 // Mixed array record ends with empty string (0x00 0x00) and 0x09
|
rlm@3
|
494 if (($key == '') && ($this->stream->peekByte() == 0x09)) {
|
rlm@3
|
495 // Consume byte
|
rlm@3
|
496 $this->stream->readByte();
|
rlm@3
|
497 break;
|
rlm@3
|
498 }
|
rlm@3
|
499
|
rlm@3
|
500 $data[$key] = $this->readData();
|
rlm@3
|
501 }
|
rlm@3
|
502
|
rlm@3
|
503 return $data;
|
rlm@3
|
504 }
|
rlm@3
|
505
|
rlm@3
|
506
|
rlm@3
|
507 public function readMixedArray() {
|
rlm@3
|
508
|
rlm@3
|
509 // Get highest numerical index - ignored
|
rlm@3
|
510 $highestIndex = $this->stream->readLong();
|
rlm@3
|
511
|
rlm@3
|
512 $data = array();
|
rlm@3
|
513
|
rlm@3
|
514 while ($key = $this->stream->readUTF()) {
|
rlm@3
|
515 // Mixed array record ends with empty string (0x00 0x00) and 0x09
|
rlm@3
|
516 if (($key == '') && ($this->stream->peekByte() == 0x09)) {
|
rlm@3
|
517 // Consume byte
|
rlm@3
|
518 $this->stream->readByte();
|
rlm@3
|
519 break;
|
rlm@3
|
520 }
|
rlm@3
|
521
|
rlm@3
|
522 if (is_numeric($key)) {
|
rlm@3
|
523 $key = (float) $key;
|
rlm@3
|
524 }
|
rlm@3
|
525
|
rlm@3
|
526 $data[$key] = $this->readData();
|
rlm@3
|
527 }
|
rlm@3
|
528
|
rlm@3
|
529 return $data;
|
rlm@3
|
530 }
|
rlm@3
|
531
|
rlm@3
|
532
|
rlm@3
|
533 public function readArray() {
|
rlm@3
|
534
|
rlm@3
|
535 $length = $this->stream->readLong();
|
rlm@3
|
536
|
rlm@3
|
537 $data = array();
|
rlm@3
|
538
|
rlm@3
|
539 for ($i = 0; $i < count($length); $i++) {
|
rlm@3
|
540 $data[] = $this->readData();
|
rlm@3
|
541 }
|
rlm@3
|
542
|
rlm@3
|
543 return $data;
|
rlm@3
|
544 }
|
rlm@3
|
545
|
rlm@3
|
546
|
rlm@3
|
547 public function readDate() {
|
rlm@3
|
548
|
rlm@3
|
549 $timestamp = $this->stream->readDouble();
|
rlm@3
|
550 $timezone = $this->stream->readInt();
|
rlm@3
|
551 return $timestamp;
|
rlm@3
|
552 }
|
rlm@3
|
553
|
rlm@3
|
554
|
rlm@3
|
555 public function readLongString() {
|
rlm@3
|
556
|
rlm@3
|
557 return $this->stream->readLongUTF();
|
rlm@3
|
558 }
|
rlm@3
|
559
|
rlm@3
|
560
|
rlm@3
|
561 public function readXML() {
|
rlm@3
|
562
|
rlm@3
|
563 return $this->stream->readLongUTF();
|
rlm@3
|
564 }
|
rlm@3
|
565
|
rlm@3
|
566
|
rlm@3
|
567 public function readTypedObject() {
|
rlm@3
|
568
|
rlm@3
|
569 $className = $this->stream->readUTF();
|
rlm@3
|
570 return $this->readObject();
|
rlm@3
|
571 }
|
rlm@3
|
572 }
|
rlm@3
|
573
|
rlm@3
|
574 ?> |