ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
ZipStream\File Class Reference
+ Collaboration diagram for ZipStream\File:

Public Member Functions

 __construct (ZipStream $zip, string $name, ?FileOptions $opt=null)
 
 processPath (string $path)
 
 processData (string $data)
 
 addFileHeader ()
 Create and send zip header for this file. More...
 
 addFileFooter ()
 Create and send data descriptor footer for this file. More...
 
 processStream (StreamInterface $stream)
 
 getCdrFile ()
 Send CDR record for specified file. More...
 
 getTotalLength ()
 

Static Public Member Functions

static filterFilename (string $filename)
 Strip characters that are not legal in Windows filenames to prevent compatibility issues. More...
 

Data Fields

const HASH_ALGORITHM = 'crc32b'
 
const BIT_ZERO_HEADER = 0x0008
 
const BIT_EFS_UTF8 = 0x0800
 
const COMPUTE = 1
 
const SEND = 2
 
 $name
 
 $opt
 
 $len
 
 $zlen
 
 $crc
 
 $hlen
 
 $ofs
 
 $bits
 
 $version
 
 $zip
 

Protected Member Functions

 buildZip64ExtraBlock (bool $force=false)
 
 processStreamWithZeroHeader (StreamInterface $stream)
 
 readStream (StreamInterface $stream, ?int $options=null)
 
 deflateInit ()
 
 deflateData (StreamInterface $stream, string &$data, ?int $options=null)
 
 deflateFinish (?int $options=null)
 
 processStreamWithComputedHeader (StreamInterface $stream)
 

Static Protected Member Functions

static dosTime (int $when)
 Convert a UNIX timestamp to a DOS timestamp. More...
 

Private Attributes

const CHUNKED_READ_BLOCK_SIZE = 1048576
 
 $deflate
 
 $hash
 
 $method
 
 $totalLength
 

Detailed Description

Definition at line 15 of file File.php.

Constructor & Destructor Documentation

◆ __construct()

ZipStream\File::__construct ( ZipStream  $zip,
string  $name,
?FileOptions  $opt = null 
)

Definition at line 93 of file File.php.

94 {
95 $this->zip = $zip;
96
97 $this->name = $name;
98 $this->opt = $opt ?: new FileOptions();
99 $this->method = $this->opt->getMethod();
100 $this->version = Version::STORE();
101 $this->ofs = new Bigint();
102 }

References $name.

Member Function Documentation

◆ addFileFooter()

ZipStream\File::addFileFooter ( )

Create and send data descriptor footer for this file.

Returns
void

Definition at line 303 of file File.php.

303 : void
304 {
305
306 if ($this->bits & self::BIT_ZERO_HEADER) {
307 // compressed and uncompressed size
308 $sizeFormat = 'V';
309 if ($this->zip->opt->isEnableZip64()) {
310 $sizeFormat = 'P';
311 }
312 $fields = [
314 ['V', $this->crc], // CRC32
315 [$sizeFormat, $this->zlen], // Length of compressed data
316 [$sizeFormat, $this->len], // Length of original data
317 ];
318
319 $footer = ZipStream::packFields($fields);
320 $this->zip->send($footer);
321 } else {
322 $footer = '';
323 }
324 $this->totalLength = $this->hlen->add($this->zlen)->add(Bigint::init(strlen($footer)));
325 $this->zip->addToCdr($this);
326 }
static init(int $value=0)
Get an instance.
Definition: Bigint.php:47
const DATA_DESCRIPTOR_SIGNATURE
Definition: ZipStream.php:93
static packFields(array $fields)
Create a format string and argument list for pack(), then call pack() and return the result.
Definition: ZipStream.php:416

References init().

+ Here is the call graph for this function:

◆ addFileHeader()

ZipStream\File::addFileHeader ( )

Create and send zip header for this file.

Returns
void
Exceptions

ZipStream\Exception\EncodingException

Definition at line 146 of file File.php.

146 : void
147 {
148 $name = static::filterFilename($this->name);
149
150 // calculate name length
151 $nameLength = strlen($name);
152
153 // create dos timestamp
154 $time = static::dosTime($this->opt->getTime()->getTimestamp());
155
156 $comment = $this->opt->getComment();
157
158 if (!mb_check_encoding($name, 'ASCII') ||
159 !mb_check_encoding($comment, 'ASCII')) {
160 // Sets Bit 11: Language encoding flag (EFS). If this bit is set,
161 // the filename and comment fields for this file
162 // MUST be encoded using UTF-8. (see APPENDIX D)
163 if (!mb_check_encoding($name, 'UTF-8') ||
164 !mb_check_encoding($comment, 'UTF-8')) {
165 throw new EncodingException(
166 'File name and comment should use UTF-8 ' .
167 'if one of them does not fit into ASCII range.'
168 );
169 }
170 $this->bits |= self::BIT_EFS_UTF8;
171 }
172
173 if ($this->method->equals(Method::DEFLATE())) {
174 $this->version = Version::DEFLATE();
175 }
176
177 $force = (boolean)($this->bits & self::BIT_ZERO_HEADER) &&
178 $this->zip->opt->isEnableZip64();
179
180 $footer = $this->buildZip64ExtraBlock($force);
181
182 // If this file will start over 4GB limit in ZIP file,
183 // CDR record will have to use Zip64 extension to describe offset
184 // to keep consistency we use the same value here
185 if ($this->zip->ofs->isOver32()) {
186 $this->version = Version::ZIP64();
187 }
188
189 $fields = [
191 ['v', $this->version->getValue()], // Version needed to Extract
192 ['v', $this->bits], // General purpose bit flags - data descriptor flag set
193 ['v', $this->method->getValue()], // Compression method
194 ['V', $time], // Timestamp (DOS Format)
195 ['V', $this->crc], // CRC32 of data (0 -> moved to data descriptor footer)
196 ['V', $this->zlen->getLowFF($force)], // Length of compressed data (forced to 0xFFFFFFFF for zero header)
197 ['V', $this->len->getLowFF($force)], // Length of original data (forced to 0xFFFFFFFF for zero header)
198 ['v', $nameLength], // Length of filename
199 ['v', strlen($footer)], // Extra data (see above)
200 ];
201
202 // pack fields and calculate "total" length
204
205 // print header and filename
206 $data = $header . $name . $footer;
207 $this->zip->send($data);
208
209 // save header length
210 $this->hlen = Bigint::init(strlen($data));
211 }
$comment
Definition: buildRTE.php:83
const BIT_EFS_UTF8
Definition: File.php:20
buildZip64ExtraBlock(bool $force=false)
Definition: File.php:265
const FILE_HEADER_SIGNATURE
The following signatures end with 0x4b50, which in ASCII isĀ PK, the initials of the inventor Phil Kat...
Definition: ZipStream.php:90
$time
Definition: cron.php:21
$data
Definition: bench.php:6

References $comment, $data, $header, $name, $time, and init().

+ Here is the call graph for this function:

◆ buildZip64ExtraBlock()

ZipStream\File::buildZip64ExtraBlock ( bool  $force = false)
protected

Definition at line 265 of file File.php.

265 : string
266 {
267
268 $fields = [];
269 if ($this->len->isOver32($force)) {
270 $fields[] = ['P', $this->len]; // Length of original data
271 }
272
273 if ($this->len->isOver32($force)) {
274 $fields[] = ['P', $this->zlen]; // Length of compressed data
275 }
276
277 if ($this->ofs->isOver32()) {
278 $fields[] = ['P', $this->ofs]; // Offset of local header record
279 }
280
281 if (!empty($fields)) {
282 if (!$this->zip->opt->isEnableZip64()) {
283 throw new OverflowException();
284 }
285
286 array_unshift(
287 $fields,
288 ['v', 0x0001], // 64 bit extension
289 ['v', count($fields) * 8] // Length of data block
290 );
291 $this->version = Version::ZIP64();
292 }
293
294 return ZipStream::packFields($fields);
295 }

◆ deflateData()

ZipStream\File::deflateData ( StreamInterface  $stream,
string &  $data,
?int  $options = null 
)
protected

Definition at line 378 of file File.php.

378 : void
379 {
380 if ($options & self::COMPUTE) {
381 $this->len = $this->len->add(Bigint::init(strlen($data)));
382 hash_update($this->hash, $data);
383 }
384 if ($this->deflate) {
385 $data = deflate_add(
386 $this->deflate,
387 $data,
388 $stream->eof()
389 ? ZLIB_FINISH
390 : ZLIB_NO_FLUSH
391 );
392 }
393 if ($options & self::COMPUTE) {
394 $this->zlen = $this->zlen->add(Bigint::init(strlen($data)));
395 }
396 }
$stream
PHP stream implementation.
hash(StreamInterface $stream, $algo, $rawOutput=false)
Calculate a hash of a Stream.
Definition: functions.php:406

References $data, PHPMailer\PHPMailer\$options, GuzzleHttp\Psr7\$stream, GuzzleHttp\Psr7\hash(), and init().

+ Here is the call graph for this function:

◆ deflateFinish()

ZipStream\File::deflateFinish ( ?int  $options = null)
protected

Definition at line 398 of file File.php.

398 : void
399 {
400 if ($options & self::COMPUTE) {
401 $this->crc = hexdec(hash_final($this->hash));
402 }
403 }

References PHPMailer\PHPMailer\$options, and GuzzleHttp\Psr7\hash().

+ Here is the call graph for this function:

◆ deflateInit()

ZipStream\File::deflateInit ( )
protected

Definition at line 367 of file File.php.

367 : void
368 {
369 $this->hash = hash_init(self::HASH_ALGORITHM);
370 if ($this->method->equals(Method::DEFLATE())) {
371 $this->deflate = deflate_init(
372 ZLIB_ENCODING_RAW,
373 ['level' => $this->opt->getDeflateLevel()]
374 );
375 }
376 }

References GuzzleHttp\Psr7\hash().

+ Here is the call graph for this function:

◆ dosTime()

static ZipStream\File::dosTime ( int  $when)
staticfinalprotected

Convert a UNIX timestamp to a DOS timestamp.

Parameters
int$when
Returns
int DOS Timestamp

Definition at line 235 of file File.php.

235 : int
236 {
237 // get date array for timestamp
238 $d = getdate($when);
239
240 // set lower-bound on dates
241 if ($d['year'] < 1980) {
242 $d = array(
243 'year' => 1980,
244 'mon' => 1,
245 'mday' => 1,
246 'hours' => 0,
247 'minutes' => 0,
248 'seconds' => 0
249 );
250 }
251
252 // remove extra years from 1980
253 $d['year'] -= 1980;
254
255 // return date string
256 return
257 ($d['year'] << 25) |
258 ($d['mon'] << 21) |
259 ($d['mday'] << 16) |
260 ($d['hours'] << 11) |
261 ($d['minutes'] << 5) |
262 ($d['seconds'] >> 1);
263 }
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296

References $d.

◆ filterFilename()

static ZipStream\File::filterFilename ( string  $filename)
static

Strip characters that are not legal in Windows filenames to prevent compatibility issues.

Parameters
string$filenameUnprocessed filename
Returns
string

Definition at line 220 of file File.php.

220 : string
221 {
222 // strip leading slashes from file name
223 // (fixes bug in windows archive viewer)
224 $filename = preg_replace('/^\\/+/', '', $filename);
225
226 return str_replace(['\\', ':', '*', '?', '"', '<', '>', '|'], '_', $filename);
227 }
$filename
Definition: buildRTE.php:89

References $filename.

◆ getCdrFile()

ZipStream\File::getCdrFile ( )

Send CDR record for specified file.

Returns
string

Definition at line 433 of file File.php.

433 : string
434 {
435 $name = static::filterFilename($this->name);
436
437 // get attributes
438 $comment = $this->opt->getComment();
439
440 // get dos timestamp
441 $time = static::dosTime($this->opt->getTime()->getTimestamp());
442
443 $footer = $this->buildZip64ExtraBlock();
444
445 $fields = [
446 ['V', ZipStream::CDR_FILE_SIGNATURE], // Central file header signature
447 ['v', ZipStream::ZIP_VERSION_MADE_BY], // Made by version
448 ['v', $this->version->getValue()], // Extract by version
449 ['v', $this->bits], // General purpose bit flags - data descriptor flag set
450 ['v', $this->method->getValue()], // Compression method
451 ['V', $time], // Timestamp (DOS Format)
452 ['V', $this->crc], // CRC32
453 ['V', $this->zlen->getLowFF()], // Compressed Data Length
454 ['V', $this->len->getLowFF()], // Original Data Length
455 ['v', strlen($name)], // Length of filename
456 ['v', strlen($footer)], // Extra data len (see above)
457 ['v', strlen($comment)], // Length of comment
458 ['v', 0], // Disk number
459 ['v', 0], // Internal File Attributes
460 ['V', 32], // External File Attributes
461 ['V', $this->ofs->getLowFF()] // Relative offset of local header
462 ];
463
464 // pack fields, then append name and comment
466
467 return $header . $name . $footer . $comment;
468 }
const ZIP_VERSION_MADE_BY
This number corresponds to the ZIP version/OS used (2 bytes) From: https://www.iana....
Definition: ZipStream.php:83
const CDR_FILE_SIGNATURE
Definition: ZipStream.php:91

References $comment, $header, $name, and $time.

Referenced by ZipStream\ZipStream\addToCdr().

+ Here is the caller graph for this function:

◆ getTotalLength()

ZipStream\File::getTotalLength ( )
Returns
Bigint

Definition at line 473 of file File.php.

473 : Bigint
474 {
475 return $this->totalLength;
476 }

Referenced by ZipStream\ZipStream\addToCdr().

+ Here is the caller graph for this function:

◆ processData()

ZipStream\File::processData ( string  $data)

Definition at line 124 of file File.php.

124 : void
125 {
126 $this->len = new Bigint(strlen($data));
127 $this->crc = crc32($data);
128
129 // compress data if needed
130 if ($this->method->equals(Method::DEFLATE())) {
131 $data = gzdeflate($data);
132 }
133
134 $this->zlen = new Bigint(strlen($data));
135 $this->addFileHeader();
136 $this->zip->send($data);
137 $this->addFileFooter();
138 }
addFileHeader()
Create and send zip header for this file.
Definition: File.php:146
addFileFooter()
Create and send data descriptor footer for this file.
Definition: File.php:303

References $data.

◆ processPath()

ZipStream\File::processPath ( string  $path)

Definition at line 104 of file File.php.

104 : void
105 {
106 if (!is_readable($path)) {
107 if (!file_exists($path)) {
108 throw new FileNotFoundException($path);
109 }
110 throw new FileNotReadableException($path);
111 }
112 if ($this->zip->isLargeFile($path) === false) {
113 $data = file_get_contents($path);
114 $this->processData($data);
115 } else {
116 $this->method = $this->zip->opt->getLargeFileMethod();
117
118 $stream = new DeflateStream(fopen($path, 'rb'));
119 $this->processStream($stream);
120 $stream->close();
121 }
122 }
$path
Definition: aliased.php:25
processStream(StreamInterface $stream)
Definition: File.php:328
processData(string $data)
Definition: File.php:124

References $data, $path, and GuzzleHttp\Psr7\$stream.

◆ processStream()

ZipStream\File::processStream ( StreamInterface  $stream)

Definition at line 328 of file File.php.

328 : void
329 {
330 $this->zlen = new Bigint();
331 $this->len = new Bigint();
332
333 if ($this->zip->opt->isZeroHeader()) {
334 $this->processStreamWithZeroHeader($stream);
335 } else {
336 $this->processStreamWithComputedHeader($stream);
337 }
338 }
processStreamWithZeroHeader(StreamInterface $stream)
Definition: File.php:340
processStreamWithComputedHeader(StreamInterface $stream)
Definition: File.php:405

References GuzzleHttp\Psr7\$stream.

◆ processStreamWithComputedHeader()

ZipStream\File::processStreamWithComputedHeader ( StreamInterface  $stream)
protected

Definition at line 405 of file File.php.

405 : void
406 {
407 $this->readStream($stream, self::COMPUTE);
408 $stream->rewind();
409
410 // incremental compression with deflate_add
411 // makes this second read unnecessary
412 // but it is only available from PHP 7.0
413 if (!$this->deflate && $stream instanceof DeflateStream && $this->method->equals(Method::DEFLATE())) {
414 $stream->addDeflateFilter($this->opt);
415 $this->zlen = new Bigint();
416 while (!$stream->eof()) {
417 $data = $stream->read(self::CHUNKED_READ_BLOCK_SIZE);
418 $this->zlen = $this->zlen->add(Bigint::init(strlen($data)));
419 }
420 $stream->rewind();
421 }
422
423 $this->addFileHeader();
424 $this->readStream($stream, self::SEND);
425 $this->addFileFooter();
426 }
readStream(StreamInterface $stream, ?int $options=null)
Definition: File.php:348

References $data, GuzzleHttp\Psr7\$stream, and init().

+ Here is the call graph for this function:

◆ processStreamWithZeroHeader()

ZipStream\File::processStreamWithZeroHeader ( StreamInterface  $stream)
protected

Definition at line 340 of file File.php.

340 : void
341 {
342 $this->bits |= self::BIT_ZERO_HEADER;
343 $this->addFileHeader();
344 $this->readStream($stream, self::COMPUTE | self::SEND);
345 $this->addFileFooter();
346 }
const BIT_ZERO_HEADER
Definition: File.php:19

References GuzzleHttp\Psr7\$stream.

◆ readStream()

ZipStream\File::readStream ( StreamInterface  $stream,
?int  $options = null 
)
protected

Definition at line 348 of file File.php.

348 : void
349 {
350 $this->deflateInit();
351 $total = 0;
352 $size = $this->opt->getSize();
353 while (!$stream->eof() && ($size === 0 || $total < $size)) {
354 $data = $stream->read(self::CHUNKED_READ_BLOCK_SIZE);
355 $total += strlen($data);
356 if ($size > 0 && $total > $size) {
357 $data = substr($data, 0 , strlen($data)-($total - $size));
358 }
359 $this->deflateData($stream, $data, $options);
360 if ($options & self::SEND) {
361 $this->zip->send($data);
362 }
363 }
364 $this->deflateFinish($options);
365 }
$size
Definition: RandomTest.php:84
$total
Definition: Utf8Test.php:87
deflateData(StreamInterface $stream, string &$data, ?int $options=null)
Definition: File.php:378
deflateFinish(?int $options=null)
Definition: File.php:398

References $data, PHPMailer\PHPMailer\$options, $size, GuzzleHttp\Psr7\$stream, and $total.

Field Documentation

◆ $bits

ZipStream\File::$bits

Definition at line 62 of file File.php.

◆ $crc

ZipStream\File::$crc

Definition at line 47 of file File.php.

◆ $deflate

ZipStream\File::$deflate
private

Definition at line 77 of file File.php.

◆ $hash

ZipStream\File::$hash
private

Definition at line 81 of file File.php.

◆ $hlen

ZipStream\File::$hlen

Definition at line 52 of file File.php.

◆ $len

ZipStream\File::$len

Definition at line 40 of file File.php.

◆ $method

ZipStream\File::$method
private

Definition at line 86 of file File.php.

◆ $name

ZipStream\File::$name

Definition at line 30 of file File.php.

◆ $ofs

ZipStream\File::$ofs

Definition at line 57 of file File.php.

◆ $opt

ZipStream\File::$opt

Definition at line 35 of file File.php.

◆ $totalLength

ZipStream\File::$totalLength
private

Definition at line 91 of file File.php.

◆ $version

ZipStream\File::$version

Definition at line 67 of file File.php.

◆ $zip

ZipStream\File::$zip

Definition at line 72 of file File.php.

◆ $zlen

ZipStream\File::$zlen

Definition at line 44 of file File.php.

◆ BIT_EFS_UTF8

const ZipStream\File::BIT_EFS_UTF8 = 0x0800

Definition at line 20 of file File.php.

◆ BIT_ZERO_HEADER

const ZipStream\File::BIT_ZERO_HEADER = 0x0008

Definition at line 19 of file File.php.

◆ CHUNKED_READ_BLOCK_SIZE

const ZipStream\File::CHUNKED_READ_BLOCK_SIZE = 1048576
private

Definition at line 25 of file File.php.

◆ COMPUTE

const ZipStream\File::COMPUTE = 1

Definition at line 22 of file File.php.

◆ HASH_ALGORITHM

const ZipStream\File::HASH_ALGORITHM = 'crc32b'

Definition at line 17 of file File.php.

◆ SEND

const ZipStream\File::SEND = 2

Definition at line 23 of file File.php.


The documentation for this class was generated from the following file: