CentralDirectoryHeader   F
last analyzed

Complexity

Total Complexity 67

Size/Duplication

Total Lines 888
Duplicated Lines 1.58 %

Coupling/Cohesion

Components 5
Dependencies 2

Test Coverage

Coverage 75.09%

Importance

Changes 0
Metric Value
dl 14
loc 888
ccs 211
cts 281
cp 0.7509
rs 2.4489
c 0
b 0
f 0
wmc 67
lcom 5
cbo 2

57 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 57 5
B parse() 0 52 4
A parseAdditionalData() 0 23 3
B marshal() 0 27 1
B createFromArchiveEntry() 0 25 1
A toArchiveEntry() 0 16 2
A getVariableLength() 0 4 1
A getVersionMadeBy() 0 4 1
A setVersionMadeBy() 0 6 1
A getVersionNeededToExtract() 0 4 1
A setVersionNeededToExtract() 0 6 1
A getGeneralPurposeBitFlags() 0 4 1
A setGeneralPurposeBitFlags() 0 6 1
A getCompressionMethod() 0 4 1
A setCompressionMethod() 0 6 1
A getLastModificationFileTime() 0 4 1
A setLastModificationFileTime() 0 6 1
A getLastModificationFileDate() 0 4 1
A setLastModificationFileDate() 0 6 1
A getCrc32() 0 4 1
A setCrc32() 0 6 1
A getCompressedSize() 0 4 1
A setCompressedSize() 0 6 1
A getUncompressedSize() 0 4 1
A setUncompressedSize() 0 6 1
A getFileNameLength() 0 4 1
A getExtraFieldLength() 0 4 1
A getFileCommentLength() 0 4 1
A getDiskNumberStart() 0 4 1
A setDiskNumberStart() 0 6 1
A getInternalFileAttributes() 0 4 1
A setInternalFileAttributes() 0 6 1
A getExternalFileAttributes() 0 4 1
A setExternalFileAttributes() 0 6 1
A getRelativeOffsetOfLocalHeader() 0 4 1
A setRelativeOffsetOfLocalHeader() 0 6 1
A getFileName() 0 4 1
A setFileName() 7 7 1
A getExtraField() 0 4 1
A setExtraField() 7 7 1
A getFileComment() 0 4 1
A setFileComment() 0 7 1
A getEncodingHost() 0 4 1
A setEncodingHost() 0 6 1
A getEncodingVersion() 0 4 1
A setEncodingVersion() 0 6 1
A getRequiredHost() 0 4 1
A setRequiredHost() 0 6 1
A getRequiredVersion() 0 4 1
A setRequiredVersion() 0 6 1
A getLastModification() 0 4 1
A setLastModification() 0 6 1
A getDosExternalAttributes() 0 4 1
A setDosExternalAttributes() 0 6 1
A getUnixExternalAttributes() 0 4 1
A setUnixExternalAttributes() 0 6 1
A isDirectory() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like CentralDirectoryHeader often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CentralDirectoryHeader, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace morgue\zip;
4
5
use morgue\archive\ArchiveEntry;
6
7
/**
8
 * This class represents a "central directory header" data structure as defined in the ZIP specification.
9
 * CentralDirectoryHeader objects are immutable so every setX() method will return a copy with modified fields,
10
 *  the original object remains unchanged.
11
 *
12
 * To create a CentralDirectoryHeader from its binary representation, call the parse() method and supply
13
 *  CentralDirectoryHeader::MIN_LENGTH bytes to read the fixed size fields.
14
 * getVariableLength() will yield the number of bytes required to parse the variable size fields.
15
 * Call parseAdditionalData() with that number of bytes will finalize the object which is immutable from that point on.
16
 */
17
final class CentralDirectoryHeader
18
{
19
    const SIGNATURE = 0x504b0102;
20
21
    /// Minimum length of this entry if neither file name, extra field nor file comment are set
22
    const MIN_LENGTH = 46;
23
24
    /// Maximum length of this entry file name, extra field and file comment have the maximum allowed length
25
    const MAX_LENGTH = self::MIN_LENGTH + self::FILE_NAME_MAX_LENGTH + self::EXTRA_FIELD_MAX_LENGTH + self::FILE_COMMENT_MAX_LENGTH;
26
27
    /// File name can not be longer than this (the length field has only 2 bytes)
28
    const FILE_NAME_MAX_LENGTH = (255 * 255) - 1;
29
30
    /// Extra field can not be longer than this (the length field has only 2 bytes)
31
    const EXTRA_FIELD_MAX_LENGTH = (255 * 255) - 1;
32
33
    /// File comment can not be longer than this (the length field has only 2 bytes)
34
    const FILE_COMMENT_MAX_LENGTH = (255 * 255) - 1;
35
36
    /**
37
     * @var int
38
     */
39
    private $versionMadeBy;
40
41
    /**
42
     * @var int
43
     */
44
    private $versionNeededToExtract;
45
46
    /**
47
     * @var int
48
     */
49
    private $generalPurposeBitFlags;
50
51
    /**
52
     * @var int
53
     */
54
    private $compressionMethod;
55
56
    /**
57
     * @var int
58
     */
59
    private $lastModificationFileTime;
60
61
    /**
62
     * @var int
63
     */
64
    private $lastModificationFileDate;
65
66
    /**
67
     * @var int
68
     */
69
    private $crc32;
70
71
    /**
72
     * @var int
73
     */
74
    private $compressedSize;
75
76
    /**
77
     * @var int
78
     */
79
    private $uncompressedSize;
80
81
    /**
82
     * @var int
83
     */
84
    private $fileNameLength;
85
86
    /**
87
     * @var int
88
     */
89
    private $extraFieldLength;
90
91
    /**
92
     * @var int
93
     */
94
    private $fileCommentLength;
95
96
    /**
97
     * @var int
98
     */
99
    private $diskNumberStart;
100
101
    /**
102
     * @var int
103
     */
104
    private $internalFileAttributes;
105
106
    /**
107
     * @var int
108
     */
109
    private $externalFileAttributes;
110
111
    /**
112
     * @var int
113
     */
114
    private $relativeOffsetOfLocalHeader;
115
116
    /**
117
     * @var string
118
     */
119
    private $fileName = "";
120
121
    /**
122
     * @var string
123
     */
124
    private $extraField = "";
125
126
    /**
127
     * @var string
128
     */
129
    private $fileComment = "";
130
131
    /**
132
     * File system or operating system of encoder.
133
     * One of the HOST_COMPATIBILITY_* constants.
134
     * @var int
135
     */
136
    private $encodingHost;
137
138
    /**
139
     * Maximum supported version of the encoding software.
140
     * @var int
141
     */
142
    private $encodingVersion;
143
144
    /**
145
     * Required host compatibility to decode.
146
     * One of the HOST_COMPATIBILITY_* constants.
147
     * @var int
148
     */
149
    private $requiredHost;
150
151
    /**
152
     * Zip format version required to decode.
153
     * @var int
154
     */
155
    private $requiredVersion;
156
157
    /**
158
     * @var \DateTimeInterface
159
     */
160
    private $lastModification;
161
162
    /**
163
     * @var int
164
     */
165
    private $dosExternalAttributes;
166
167
    /**
168
     * @var int
169
     */
170
    private $unixExternalAttributes;
171
172
    /**
173
     * @var bool
174
     */
175
    private $requireAdditionalData = false;
176
177
    /**
178
     * @var ExtraFieldInterface[]
179
     */
180
    private $extraFields = [];
181
182 2051
    public function __construct(
183
        int $versionMadeBy,
184
        int $versionNeededToExtract,
185
        int $generalPurposeBitFlags,
186
        int $compressionMethod,
187
        int $lastModificationFileTime,
188
        int $lastModificationFileDate,
189
        int $crc32,
190
        int $compressedSize,
191
        int $uncompressedSize,
192
        int $diskNumberStart,
193
        int $internalFileAttributes,
194
        int $externalFileAttributes,
195
        int $relativeOffsetOfLocalHeader,
196
        string $fileName = null,
197
        string $extraField = null,
198
        string $fileComment = null
199
    ) {
200 2051
        $this->versionMadeBy = $versionMadeBy;
201 2051
        $this->versionNeededToExtract = $versionNeededToExtract;
202 2051
        $this->generalPurposeBitFlags = $generalPurposeBitFlags;
203 2051
        $this->compressionMethod = $compressionMethod;
204 2051
        $this->lastModificationFileTime = $lastModificationFileTime;
205 2051
        $this->lastModificationFileDate = $lastModificationFileDate;
206 2051
        $this->lastModification = dos2DateTime($this->lastModificationFileTime, $this->lastModificationFileDate);
207 2051
        $this->crc32 = $crc32;
208 2051
        $this->compressedSize = $compressedSize;
209 2051
        $this->uncompressedSize = $uncompressedSize;
210 2051
        $this->diskNumberStart = $diskNumberStart;
211 2051
        $this->internalFileAttributes = $internalFileAttributes;
212 2051
        $this->externalFileAttributes = $externalFileAttributes;
213 2051
        $this->relativeOffsetOfLocalHeader = $relativeOffsetOfLocalHeader;
214
215 2051
        if ($fileName !== null) {
216
            $this->fileName = $fileName;
217
            $this->fileNameLength = \strlen($fileName);
218
        }
219 2051
        if ($extraField !== null) {
220
            $this->extraField = $extraField;
221
            $this->extraFieldLength = \strlen($extraField);
222
        }
223 2051
        if ($fileComment !== null) {
224
            $this->fileComment = $fileComment;
225
            $this->fileCommentLength = \strlen($fileComment);
226
        }
227
228 2051
        $this->encodingHost = ($this->versionMadeBy >> 8);
229 2051
        $this->encodingVersion = ($this->versionMadeBy & 255);
230 2051
        $this->requiredHost = ($this->versionNeededToExtract >> 8);
231 2051
        $this->requiredVersion = ($this->versionNeededToExtract & 255);
232
233 2051
        $this->dosExternalAttributes = ($this->externalFileAttributes & 255);
234
235 2051
        if ($this->encodingHost === HOST_COMPATIBILITY_UNIX) {
236 2048
            $this->unixExternalAttributes = ($this->externalFileAttributes >> 16);
237
        }
238 2051
    }
239
240
    /**
241
     * Parse the binary representation of a central directory header from $input, optionally start at $offset instead of the beginning of the string.
242
     * To complete the parsing process, parseAdditionalData() must be called with at least the number of bytes as input as returned by getRequireAdditionalData().
243
     * After the parseAdditionalData() call the object is immutable.
244
     *
245
     * @param string $input
246
     * @param int $offset
247
     * @return CentralDirectoryHeader
248
     */
249 2048
    public static function parse(string $input, int $offset = 0)
250
    {
251 2048
        if (\strlen($input) < ($offset+self::MIN_LENGTH)) {
252
            throw new \InvalidArgumentException("Not enough data to parse central directory header!");
253
        }
254
255 2048
        $parsed = \unpack(
256
            'Nsignature'
257
            . '/vversionMadeBy'
258
            . '/vversionNeededToExtract'
259
            . '/vgeneralPurposeBitFlags'
260
            . '/vcompressionMethod'
261
            . '/vlastModificationFileTime'
262
            . '/vlastModificationFileDate'
263
            . '/Vcrc32'
264
            . '/VcompressedSize'
265
            . '/VuncompressedSize'
266
            . '/vfileNameLength'
267
            . '/vextraFieldLength'
268
            . '/vfileCommentLength'
269
            . '/vdiskNumberStart'
270
            . '/vinternalFileAttributes'
271
            . '/VexternalFileAttributes'
272 2048
            . '/VrelativeOffsetOfLocalHeader',
273 2048
            ($offset ? \substr($input, $offset) : $input)
274
        );
275 2048
        if ($parsed['signature'] !== self::SIGNATURE) {
276
            throw new \InvalidArgumentException("Invalid signature for central directory header!");
277
        }
278
279 2048
        $centralDirectoryHeader = new static(
280 2048
            $parsed['versionMadeBy'],
281 2048
            $parsed['versionNeededToExtract'],
282 2048
            $parsed['generalPurposeBitFlags'],
283 2048
            $parsed['compressionMethod'],
284 2048
            $parsed['lastModificationFileTime'],
285 2048
            $parsed['lastModificationFileDate'],
286 2048
            $parsed['crc32'],
287 2048
            $parsed['compressedSize'],
288 2048
            $parsed['uncompressedSize'],
289 2048
            $parsed['diskNumberStart'],
290 2048
            $parsed['internalFileAttributes'],
291 2048
            $parsed['externalFileAttributes'],
292 2048
            $parsed['relativeOffsetOfLocalHeader']
293
        );
294 2048
        $centralDirectoryHeader->fileNameLength = $parsed['fileNameLength'];
295 2048
        $centralDirectoryHeader->extraFieldLength = $parsed['extraFieldLength'];
296 2048
        $centralDirectoryHeader->fileCommentLength = $parsed['fileCommentLength'];
297 2048
        $centralDirectoryHeader->requireAdditionalData = ($centralDirectoryHeader->fileNameLength + $centralDirectoryHeader->extraFieldLength + $centralDirectoryHeader->fileCommentLength > 0);
298
299 2048
        return $centralDirectoryHeader;
300
    }
301
302
    /**
303
     * After a new object has been created by parse(), this method must be called to initialize the file name, extra field and file comment entries which have dynamic field length.
304
     * The required number of bytes is written to the $requireAdditionalData attribute by parse().
305
     *
306
     * @param string $input
307
     * @param int $offset
308
     * @return int The number of bytes consumed (equals getVariableLength())
309
     */
310 2048
    public function parseAdditionalData(string $input, int $offset = 0) : int
311
    {
312 2048
        if (!$this->requireAdditionalData) {
313
            throw new \BadMethodCallException("No additional data required!");
314
        }
315
316 2048
        $variableLength = $this->fileNameLength + $this->extraFieldLength + $this->fileCommentLength;
317
318 2048
        if (\strlen($input) < ($offset + $variableLength)) {
319
            throw new \InvalidArgumentException("Not enough input to parse additional data!");
320
        }
321
322 2048
        $this->fileName = \substr($input, $offset, $this->fileNameLength);
323 2048
        $offset += $this->fileNameLength;
324 2048
        $extraField = \substr($input, $offset, $this->extraFieldLength);
325 2048
        $this->extraField = $extraField;
326 2048
        $offset += $this->extraFieldLength;
327 2048
        $this->extraFields = ExtraField::parseAll($extraField, $this);
328 2048
        $this->fileComment = \substr($input, $offset, $this->fileCommentLength);
329 2048
        $this->requireAdditionalData = false;
330
331 2048
        return $variableLength;
332
    }
333
334
    /**
335
     * Create the binary on disk representation
336
     *
337
     * @return string
338
     */
339
    public function marshal() : string
340
    {
341
        return \pack(
342
                'NvvvvvvVVVvvvvvVV',
343
                self::SIGNATURE,
344
                $this->versionMadeBy,
345
                $this->versionNeededToExtract,
346
                $this->generalPurposeBitFlags,
347
                $this->compressionMethod,
348
                $this->lastModificationFileTime,
349
                $this->lastModificationFileDate,
350
                $this->crc32,
351
                $this->compressedSize,
352
                $this->uncompressedSize,
353
                \strlen($this->fileName),
354
                \strlen($this->extraField),
355
                \strlen($this->fileComment),
356
                $this->diskNumberStart,
357
                $this->internalFileAttributes,
358
                $this->externalFileAttributes,
359
                $this->relativeOffsetOfLocalHeader
360
            )
361
            . $this->fileName
362
            . $this->extraField
363
            . $this->fileComment
364
            ;
365
    }
366
367
    /**
368
     * Initialize a new central directory header from the supplied archive entry object
369
     *
370
     * @param ArchiveEntry $archiveEntry
371
     * @return CentralDirectoryHeader
372
     */
373
    public static function createFromArchiveEntry(ArchiveEntry $archiveEntry) : self
374
    {
375
        list($modificationTime, $modificationDate) = dateTime2Dos($archiveEntry->getModificationTime());
376
377
        $obj = new self(
378
            0,
379
            0,
380
            0,
381
            COMPRESSION_METHOD_REVERSE_MAPPING[$archiveEntry->getTargetCompressionMethod()],
382
            $modificationTime,
383
            $modificationDate,
384
            $archiveEntry->getChecksumCrc32(),
385
            $archiveEntry->getTargetSize(),
386
            $archiveEntry->getUncompressedSize(),
387
            0,
388
            0,
389
            0,
390
            0,
391
            $archiveEntry->getName(),
392
            null,
393
            $archiveEntry->getComment()
394
        );
395
396
        return $obj;
397
    }
398
399
    /**
400
     * Create an archive entry from the data of this central directory header
401
     *
402
     * @return ArchiveEntry
403
     */
404
    public function toArchiveEntry() : ArchiveEntry
405
    {
406
        return (new ArchiveEntry($this->fileName))
407
            ->withCreationTime($this->lastModification)
408
            ->withModificationTime($this->lastModification)
409
            ->withSourceCompressionMethod(COMPRESSION_METHOD_MAPPING[$this->compressionMethod])
410
            ->withSourceSize($this->compressedSize)
411
            ->withTargetCompressionMethod(COMPRESSION_METHOD_MAPPING[$this->compressionMethod])
412
            ->withTargetSize($this->compressedSize)
413
            ->withChecksumCrc32($this->crc32)
414
            ->withUncompressedSize($this->uncompressedSize)
415
            ->withDosAttributes($this->dosExternalAttributes)
416
            ->withUnixAttributes($this->unixExternalAttributes)
417
            ->withComment($this->fileComment !== '' ? $this->fileComment : null)
418
            ;
419
    }
420
421
    /**
422
     * The number of bytes the fields with variable length require.
423
     *
424
     * @return int
425
     */
426 2048
    public function getVariableLength(): int
427
    {
428 2048
        return $this->fileNameLength + $this->extraFieldLength + $this->fileCommentLength;
429
    }
430
431
    /**
432
     * @return int
433
     */
434 1
    public function getVersionMadeBy(): int
435
    {
436 1
        return $this->versionMadeBy;
437
    }
438
439
    /**
440
     * @param int $versionMadeBy
441
     * @return CentralDirectoryHeader
442
     */
443 1
    public function setVersionMadeBy(int $versionMadeBy): CentralDirectoryHeader
444
    {
445 1
        $obj = clone $this;
446 1
        $obj->versionMadeBy = $versionMadeBy;
447 1
        return $obj;
448
    }
449
450
    /**
451
     * @return int
452
     */
453 1
    public function getVersionNeededToExtract(): int
454
    {
455 1
        return $this->versionNeededToExtract;
456
    }
457
458
    /**
459
     * @param int $versionNeededToExtract
460
     * @return CentralDirectoryHeader
461
     */
462 1
    public function setVersionNeededToExtract(int $versionNeededToExtract): CentralDirectoryHeader
463
    {
464 1
        $obj = clone $this;
465 1
        $obj->versionNeededToExtract = $versionNeededToExtract;
466 1
        return $obj;
467
    }
468
469
    /**
470
     * @return int
471
     */
472 1
    public function getGeneralPurposeBitFlags(): int
473
    {
474 1
        return $this->generalPurposeBitFlags;
475
    }
476
477
    /**
478
     * @param int $generalPurposeBitFlags
479
     * @return CentralDirectoryHeader
480
     */
481 1
    public function setGeneralPurposeBitFlags(int $generalPurposeBitFlags): CentralDirectoryHeader
482
    {
483 1
        $obj = clone $this;
484 1
        $obj->generalPurposeBitFlags = $generalPurposeBitFlags;
485 1
        return $obj;
486
    }
487
488
    /**
489
     * @return int
490
     */
491 376
    public function getCompressionMethod(): int
492
    {
493 376
        return $this->compressionMethod;
494
    }
495
496
    /**
497
     * @param int $compressionMethod
498
     * @return CentralDirectoryHeader
499
     */
500 1
    public function setCompressionMethod(int $compressionMethod): CentralDirectoryHeader
501
    {
502 1
        $obj = clone $this;
503 1
        $obj->compressionMethod = $compressionMethod;
504 1
        return $obj;
505
    }
506
507
    /**
508
     * @return int
509
     */
510 1
    public function getLastModificationFileTime(): int
511
    {
512 1
        return $this->lastModificationFileTime;
513
    }
514
515
    /**
516
     * @param int $lastModificationFileTime
517
     * @return CentralDirectoryHeader
518
     */
519 1
    public function setLastModificationFileTime(int $lastModificationFileTime): CentralDirectoryHeader
520
    {
521 1
        $obj = clone $this;
522 1
        $obj->lastModificationFileTime = $lastModificationFileTime;
523 1
        return $obj;
524
    }
525
526
    /**
527
     * @return int
528
     */
529 1
    public function getLastModificationFileDate(): int
530
    {
531 1
        return $this->lastModificationFileDate;
532
    }
533
534
    /**
535
     * @param int $lastModificationFileDate
536
     * @return CentralDirectoryHeader
537
     */
538 1
    public function setLastModificationFileDate(int $lastModificationFileDate): CentralDirectoryHeader
539
    {
540 1
        $obj = clone $this;
541 1
        $obj->lastModificationFileDate = $lastModificationFileDate;
542 1
        return $obj;
543
    }
544
545
    /**
546
     * @return int
547
     */
548 55
    public function getCrc32(): int
549
    {
550 55
        return $this->crc32;
551
    }
552
553
    /**
554
     * @param int $crc32
555
     * @return CentralDirectoryHeader
556
     */
557 1
    public function setCrc32(int $crc32): CentralDirectoryHeader
558
    {
559 1
        $obj = clone $this;
560 1
        $obj->crc32 = $crc32;
561 1
        return $obj;
562
    }
563
564
    /**
565
     * @return int
566
     */
567 1623
    public function getCompressedSize(): int
568
    {
569 1623
        return $this->compressedSize;
570
    }
571
572
    /**
573
     * @param int $compressedSize
574
     * @return CentralDirectoryHeader
575
     */
576 1
    public function setCompressedSize(int $compressedSize): CentralDirectoryHeader
577
    {
578 1
        $obj = clone $this;
579 1
        $obj->compressedSize = $compressedSize;
580 1
        return $obj;
581
    }
582
583
    /**
584
     * @return int
585
     */
586 1137
    public function getUncompressedSize(): int
587
    {
588 1137
        return $this->uncompressedSize;
589
    }
590
591
    /**
592
     * @param int $uncompressedSize
593
     * @return CentralDirectoryHeader
594
     */
595 1
    public function setUncompressedSize(int $uncompressedSize): CentralDirectoryHeader
596
    {
597 1
        $obj = clone $this;
598 1
        $obj->uncompressedSize = $uncompressedSize;
599 1
        return $obj;
600
    }
601
602
    /**
603
     * @return int
604
     */
605 1
    public function getFileNameLength(): int
606
    {
607 1
        return $this->fileNameLength;
608
    }
609
610
    /**
611
     * @return int
612
     */
613 1
    public function getExtraFieldLength(): int
614
    {
615 1
        return $this->extraFieldLength;
616
    }
617
618
    /**
619
     * @return int
620
     */
621 1
    public function getFileCommentLength(): int
622
    {
623 1
        return $this->fileCommentLength;
624
    }
625
626
    /**
627
     * @return int
628
     */
629 1083
    public function getDiskNumberStart(): int
630
    {
631 1083
        return $this->diskNumberStart;
632
    }
633
634
    /**
635
     * @param int $diskNumberStart
636
     * @return CentralDirectoryHeader
637
     */
638 1
    public function setDiskNumberStart(int $diskNumberStart): CentralDirectoryHeader
639
    {
640 1
        $obj = clone $this;
641 1
        $obj->diskNumberStart = $diskNumberStart;
642 1
        return $obj;
643
    }
644
645
    /**
646
     * @return int
647
     */
648 1
    public function getInternalFileAttributes(): int
649
    {
650 1
        return $this->internalFileAttributes;
651
    }
652
653
    /**
654
     * @param int $internalFileAttributes
655
     * @return CentralDirectoryHeader
656
     */
657 1
    public function setInternalFileAttributes(int $internalFileAttributes): CentralDirectoryHeader
658
    {
659 1
        $obj = clone $this;
660 1
        $obj->internalFileAttributes = $internalFileAttributes;
661 1
        return $obj;
662
    }
663
664
    /**
665
     * @return int
666
     */
667 55
    public function getExternalFileAttributes(): int
668
    {
669 55
        return $this->externalFileAttributes;
670
    }
671
672
    /**
673
     * @param int $externalFileAttributes
674
     * @return CentralDirectoryHeader
675
     */
676 1
    public function setExternalFileAttributes(int $externalFileAttributes): CentralDirectoryHeader
677
    {
678 1
        $obj = clone $this;
679 1
        $obj->externalFileAttributes = $externalFileAttributes;
680 1
        return $obj;
681
    }
682
683
    /**
684
     * @return int
685
     */
686 1404
    public function getRelativeOffsetOfLocalHeader(): int
687
    {
688 1404
        return $this->relativeOffsetOfLocalHeader;
689
    }
690
691
    /**
692
     * @param int $relativeOffsetOfLocalHeader
693
     * @return CentralDirectoryHeader
694
     */
695 1
    public function setRelativeOffsetOfLocalHeader(int $relativeOffsetOfLocalHeader): CentralDirectoryHeader
696
    {
697 1
        $obj = clone $this;
698 1
        $obj->relativeOffsetOfLocalHeader = $relativeOffsetOfLocalHeader;
699 1
        return $obj;
700
    }
701
702
    /**
703
     * @return string
704
     */
705 1892
    public function getFileName(): string
706
    {
707 1892
        return $this->fileName;
708
    }
709
710
    /**
711
     * @param string $fileName
712
     * @return CentralDirectoryHeader
713
     */
714 1 View Code Duplication
    public function setFileName(string $fileName): CentralDirectoryHeader
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
715
    {
716 1
        $obj = clone $this;
717 1
        $obj->fileName = $fileName;
718 1
        $obj->fileNameLength = \strlen($fileName);
719 1
        return $obj;
720
    }
721
722
    /**
723
     * @return string
724
     */
725 1
    public function getExtraField(): string
726
    {
727 1
        return $this->extraField;
728
    }
729
730
    /**
731
     * @param string $extraField
732
     * @return CentralDirectoryHeader
733
     */
734 1 View Code Duplication
    public function setExtraField(string $extraField): CentralDirectoryHeader
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
735
    {
736 1
        $obj = clone $this;
737 1
        $obj->extraField = $extraField;
738 1
        $obj->extraFieldLength = \strlen($extraField);
739 1
        return $obj;
740
    }
741
742
    /**
743
     * @return string
744
     */
745 73
    public function getFileComment(): string
746
    {
747 73
        return $this->fileComment;
748
    }
749
750
    /**
751
     * @param string $fileComment
752
     * @return CentralDirectoryHeader
753
     */
754 1
    public function setFileComment(string $fileComment): CentralDirectoryHeader
755
    {
756 1
        $obj = clone $this;
757 1
        $obj->fileComment = $fileComment;
758 1
        $obj->fileCommentLength = \strlen($fileComment);
759 1
        return $obj;
760
    }
761
762
    /**
763
     * @return int
764
     */
765 55
    public function getEncodingHost(): int
766
    {
767 55
        return $this->encodingHost;
768
    }
769
770
    /**
771
     * @param int $encodingHost
772
     * @return CentralDirectoryHeader
773
     */
774 1
    public function setEncodingHost(int $encodingHost): CentralDirectoryHeader
775
    {
776 1
        $obj = clone $this;
777 1
        $obj->encodingHost = $encodingHost;
778 1
        return $obj;
779
    }
780
781
    /**
782
     * @return int
783
     */
784 1
    public function getEncodingVersion(): int
785
    {
786 1
        return $this->encodingVersion;
787
    }
788
789
    /**
790
     * @param int $encodingVersion
791
     * @return CentralDirectoryHeader
792
     */
793 1
    public function setEncodingVersion(int $encodingVersion): CentralDirectoryHeader
794
    {
795 1
        $obj = clone $this;
796 1
        $obj->encodingVersion = $encodingVersion;
797 1
        return $obj;
798
    }
799
800
    /**
801
     * @return int
802
     */
803 1
    public function getRequiredHost(): int
804
    {
805 1
        return $this->requiredHost;
806
    }
807
808
    /**
809
     * @param int $requiredHost
810
     * @return CentralDirectoryHeader
811
     */
812 1
    public function setRequiredHost(int $requiredHost): CentralDirectoryHeader
813
    {
814 1
        $obj = clone $this;
815 1
        $obj->requiredHost = $requiredHost;
816 1
        return $obj;
817
    }
818
819
    /**
820
     * @return int
821
     */
822 1
    public function getRequiredVersion(): int
823
    {
824 1
        return $this->requiredVersion;
825
    }
826
827
    /**
828
     * @param int $requiredVersion
829
     * @return CentralDirectoryHeader
830
     */
831 1
    public function setRequiredVersion(int $requiredVersion): CentralDirectoryHeader
832
    {
833 1
        $obj = clone $this;
834 1
        $obj->requiredVersion = $requiredVersion;
835 1
        return $obj;
836
    }
837
838
    /**
839
     * @return \DateTimeInterface
840
     */
841 54
    public function getLastModification(): \DateTimeInterface
842
    {
843 54
        return $this->lastModification;
844
    }
845
846
    /**
847
     * @param \DateTimeInterface $lastModification
848
     * @return CentralDirectoryHeader
849
     */
850
    public function setLastModification(\DateTimeInterface $lastModification): CentralDirectoryHeader
851
    {
852
        $obj = clone $this;
853
        $obj->lastModification = $lastModification;
854
        return $obj;
855
    }
856
857
    /**
858
     * @return int
859
     */
860 1
    public function getDosExternalAttributes(): int
861
    {
862 1
        return $this->dosExternalAttributes;
863
    }
864
865
    /**
866
     * @param int $dosExternalAttributes
867
     * @return CentralDirectoryHeader
868
     */
869 1
    public function setDosExternalAttributes(int $dosExternalAttributes): CentralDirectoryHeader
870
    {
871 1
        $obj = clone $this;
872 1
        $obj->dosExternalAttributes = $dosExternalAttributes;
873 1
        return $obj;
874
    }
875
876
    /**
877
     * @return int|null
878
     */
879 1
    public function getUnixExternalAttributes()
880
    {
881 1
        return $this->unixExternalAttributes;
882
    }
883
884
    /**
885
     * @param int $unixExternalAttributes
886
     * @return CentralDirectoryHeader
887
     */
888 1
    public function setUnixExternalAttributes(int $unixExternalAttributes): CentralDirectoryHeader
889
    {
890 1
        $obj = clone $this;
891 1
        $obj->unixExternalAttributes = $unixExternalAttributes;
892 1
        return $obj;
893
    }
894
895
    /**
896
     * Whether this entry represents a directory or not
897
     *
898
     * @return bool
899
     */
900 822
    public function isDirectory() : bool
901
    {
902 822
        return (($this->dosExternalAttributes & DOS_ATTRIBUTE_DIRECTORY) !== 0);
903
    }
904
}
905