Zip64ExtendedInformation::parse()   C
last analyzed

Complexity

Conditions 12
Paths 51

Size

Total Lines 44
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 12

Importance

Changes 0
Metric Value
cc 12
eloc 26
nc 51
nop 2
dl 0
loc 44
ccs 26
cts 26
cp 1
crap 12
rs 5.1612
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace morgue\zip\extraField;
4
5
use morgue\zip\CentralDirectoryHeader;
6
use morgue\zip\ExtraField;
7
use morgue\zip\ExtraFieldInterface;
8
use const morgue\zip\MAX_INT_16;
9
use const morgue\zip\MAX_INT_32;
10
11
/**
12
 * see 4.5.3 - Zip64 Extended Information Extra Field
13
 */
14
final class Zip64ExtendedInformation implements ExtraFieldInterface
15
{
16
    const ID = 0x0001;
17
18
    const MIN_SIZE = 4;
19
    const MAX_SIZE = 32;
20
21
    /**
22
     * Original uncompressed file size
23
     * @var int
24
     */
25
    private $originalSize;
26
27
    /**
28
     * Size of compressed data
29
     * @var int
30
     */
31
    private $compressedSize;
32
33
    /**
34
     * Offset of local header record
35
     * @var int
36
     */
37
    private $relativeHeaderOffset;
38
39
    /**
40
     * Number of the disk on which this file starts
41
     * @var int
42
     */
43
    private $diskStartNumber;
44
45 2161
    public function __construct(int $originalSize = null, int $compressedSize = null, int $relativeHeaderOffset = null, int $diskStartNumber = null)
46
    {
47 2161
        $this->originalSize = $originalSize;
48 2161
        $this->compressedSize = $compressedSize;
49 2161
        $this->relativeHeaderOffset = $relativeHeaderOffset;
50 2161
        $this->diskStartNumber = $diskStartNumber;
51 2161
    }
52
53 1082
    public static function parse(string $input, $context = null)
54
    {
55 1082
        $requiredLength = 0;
56 1082
        $unpackString = 'vheaderId/vdataLength';
57
58 1082
        if ($context instanceof CentralDirectoryHeader) {
59 1082
            if ($context->getUncompressedSize() === MAX_INT_32) {
60 540
                $unpackString .= '/PoriginalSize';
61 540
                $requiredLength += 8;
62
            }
63
64 1082
            if ($context->getCompressedSize() === MAX_INT_32) {
65 541
                $unpackString .= '/PcompressedSize';
66 541
                $requiredLength += 8;
67
            }
68
69 1082
            if ($context->getRelativeOffsetOfLocalHeader() === MAX_INT_32) {
70 540
                $unpackString .= '/PrelativeHeaderOffset';
71 540
                $requiredLength += 8;
72
            }
73
74 1082
            if ($context->getDiskNumberStart() === MAX_INT_16) {
75 648
                $unpackString .= '/VdiskStartNumber';
76 648
                $requiredLength += 4;
77
            }
78
        }
79
80 1082
        if (\strlen($input) !== $requiredLength + ExtraField::MIN_LENGTH) {
81 1
            throw new \InvalidArgumentException("Trying to parse '$unpackString' that needs $requiredLength bytes, got only " . (\strlen($input) - ExtraField::MIN_LENGTH));
82
        }
83
84 1081
        $parsed = \unpack($unpackString, $input);
85
86 1081
        if ($parsed['headerId'] !== self::ID) {
87 1
            throw new \InvalidArgumentException("Invalid header ID!");
88
        }
89
90 1080
        return new self(
91 1080
            (isset($parsed['originalSize'])         ? $parsed['originalSize']         : null),
92 1080
            (isset($parsed['compressedSize'])       ? $parsed['compressedSize']       : null),
93 1080
            (isset($parsed['relativeHeaderOffset']) ? $parsed['relativeHeaderOffset'] : null),
94 1080
            (isset($parsed['diskStartNumber'])      ? $parsed['diskStartNumber']      : null)
95
        );
96
    }
97
98 1080
    public function getHeaderId()
99
    {
100 1080
        return self::ID;
101
    }
102
103 1080
    public function getDataSize()
104
    {
105 1080
        return ($this->originalSize !== null ? 8 : 0)
106 1080
            + ($this->compressedSize !== null ? 8 : 0)
107 1080
            + ($this->relativeHeaderOffset !== null ? 8 : 0)
108 1080
            + ($this->diskStartNumber !== null ? 4 : 0)
109
        ;
110
    }
111
112 1080
    public function getData()
113
    {
114 1080
        return ($this->originalSize !== null ? \pack('P', $this->originalSize) : '')
115 1080
            . ($this->compressedSize !== null ? \pack('P', $this->compressedSize) : '')
116 1080
            . ($this->relativeHeaderOffset !== null ? \pack('P', $this->relativeHeaderOffset) : '')
117 1080
            . ($this->diskStartNumber !== null ? \pack('V', $this->diskStartNumber) : '')
118
        ;
119
    }
120
121
    /**
122
     * @return int|null
123
     */
124 1081
    public function getOriginalSize()
125
    {
126 1081
        return $this->originalSize;
127
    }
128
129
    /**
130
     * @param int $originalSize
131
     * @return Zip64ExtendedInformation
132
     */
133 1
    public function setOriginalSize(int $originalSize): Zip64ExtendedInformation
134
    {
135 1
        $obj = clone $this;
136 1
        $obj->originalSize = $originalSize;
137 1
        return $obj;
138
    }
139
140
    /**
141
     * @return int|null
142
     */
143 1081
    public function getCompressedSize()
144
    {
145 1081
        return $this->compressedSize;
146
    }
147
148
    /**
149
     * @param int $compressedSize
150
     * @return Zip64ExtendedInformation
151
     */
152 1
    public function setCompressedSize(int $compressedSize): Zip64ExtendedInformation
153
    {
154 1
        $obj = clone $this;
155 1
        $obj->compressedSize = $compressedSize;
156 1
        return $obj;
157
    }
158
159
    /**
160
     * @return int|null
161
     */
162 1081
    public function getRelativeHeaderOffset()
163
    {
164 1081
        return $this->relativeHeaderOffset;
165
    }
166
167
    /**
168
     * @param int $relativeHeaderOffset
169
     * @return Zip64ExtendedInformation
170
     */
171 1
    public function setRelativeHeaderOffset(int $relativeHeaderOffset): Zip64ExtendedInformation
172
    {
173 1
        $obj = clone $this;
174 1
        $obj->relativeHeaderOffset = $relativeHeaderOffset;
175 1
        return $obj;
176
    }
177
178
    /**
179
     * @return int|null
180
     */
181 1081
    public function getDiskStartNumber()
182
    {
183 1081
        return $this->diskStartNumber;
184
    }
185
186
    /**
187
     * @param int $diskStartNumber
188
     * @return Zip64ExtendedInformation
189
     */
190 1
    public function setDiskStartNumber(int $diskStartNumber): Zip64ExtendedInformation
191
    {
192 1
        $obj = clone $this;
193 1
        $obj->diskStartNumber = $diskStartNumber;
194 1
        return $obj;
195
    }
196
}
197