Completed
Push — master ( 754f44...8b05d7 )
by Michele
12:26 queued 02:29
created

Entry::getCHM()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace CHMLib;
4
5
use Exception;
6
7
/**
8
 * Represent an entry (file/directory) contained in a CHM file.
9
 */
10
class Entry
11
{
12
    /**
13
     * Is the content cache enabled?
14
     *
15
     * @var bool
16
     */
17
    protected static $contentCacheEnabled = false;
18
19
    /**
20
     * Is the content cache enabled?
21
     *
22
     * @return bool
23
     */
24 491
    public static function getContentCacheEnabled()
25
    {
26 491
        return static::$contentCacheEnabled;
27
    }
28
29
    /**
30
     * Enable/disable the content cache.
31
     *
32
     * @param bool $enabled
33
     */
34
    public static function setContentCacheEnabled($enabled)
35
    {
36
        static::$contentCacheEnabled = (bool) $enabled;
37
    }
38
39
    /**
40
     * Entry type: directory.
41
     *
42
     * @var int
43
     */
44
    const TYPE_DIRECTORY = 0x1;
45
46
    /**
47
     * Entry type: normal file.
48
     *
49
     * @var int
50
     */
51
    const TYPE_FILE = 0x2;
52
53
    /**
54
     * Entry type: special file.
55
     *
56
     * @var int
57
     */
58
    const TYPE_SPECIAL_FILE = 0x4;
59
60
    /**
61
     * Entry type: meta data.
62
     *
63
     * @var int
64
     */
65
    const TYPE_METADATA = 0x8;
66
67
    /**
68
     * The parent CHM file.
69
     *
70
     * @var CHM
71
     */
72
    protected $chm;
73
74
    /**
75
     * The path of this entry.
76
     *
77
     * @var string
78
     */
79
    protected $path;
80
81
    /**
82
     * The index of the content section that contains the data of this entry.
83
     *
84
     * @var int
85
     */
86
    protected $contentSectionIndex;
87
88
    /**
89
     * The offset of the entry data from the beginning of the content section this entry is in, after the section has been decompressed (if appropriate).
90
     *
91
     * @var int
92
     */
93
    protected $offset;
94
95
    /**
96
     * The length of the entry data after decompression (if appropriate).
97
     *
98
     * @var int
99
     */
100
    protected $length;
101
102
    /**
103
     * The type of this entry (one of the static::TYPE_... constants).
104
     *
105
     * @var int
106
     */
107
    protected $type;
108
109
    /**
110
     * The previously read contents of this entry.
111
     *
112
     * @var string|null
113
     */
114
    protected $cachedContents;
115
116
    /**
117
     * Initializes the instance.
118
     *
119
     * @param CHM $chm The parent CHM file.
120
     */
121 4
    public function __construct(CHM $chm)
122
    {
123 4
        $reader = $chm->getReader();
124 4
        $this->chm = $chm;
125 4
        $stringLength = $reader->readCompressedUInt32();
126 4
        $this->path = $reader->readString($stringLength);
127 4
        $this->contentSectionIndex = $reader->readCompressedUInt32();
128 4
        $this->offset = $reader->readCompressedUInt32();
129 4
        $this->length = $reader->readCompressedUInt32();
130 4
        $pathLength = strlen($this->path);
131 4
        if (substr($this->path, -1) === '/') {
132 4
            $this->type = static::TYPE_DIRECTORY;
133 4
        } elseif ($this->path[0] === '/') {
134 4
            if ($pathLength > 1 && ($this->path[1] === '#' || $this->path[1] === '$')) {
135 4
                $this->type = static::TYPE_SPECIAL_FILE;
136
            } else {
137 4
                $this->type = static::TYPE_FILE;
138
            }
139
        } else {
140 4
            $this->type = static::TYPE_METADATA;
141
        }
142 4
        $this->cachedContents = null;
143 4
    }
144
145
    /**
146
     * Get the parent CHM file.
147
     *
148
     * @return CHM
149
     */
150 7
    public function getCHM()
151
    {
152 7
        return $this->chm;
153
    }
154
155
    /**
156
     * Get the path of this entry.
157
     *
158
     * @return string
159
     */
160 4
    public function getPath()
161
    {
162 4
        return $this->path;
163
    }
164
165
    /**
166
     * Get the index of the content section that contains the data of this entry.
167
     *
168
     * @return int
169
     */
170 4
    public function getContentSectionIndex()
171
    {
172 4
        return $this->contentSectionIndex;
173
    }
174
175
    /**
176
     * Get the offset from the beginning of the content section this entry is in, after the section has been decompressed (if appropriate).
177
     *
178
     * @return int
179
     */
180 4
    public function getOffset()
181
    {
182 4
        return $this->offset;
183
    }
184
185
    /**
186
     * Get the length of the entry data after decompression (if appropriate).
187
     *
188
     * @return int
189
     */
190
    public function getLength()
191
    {
192
        return $this->length;
193
    }
194
195
    /**
196
     * Is this a directory entry?
197
     *
198
     * @return bool
199
     */
200 1
    public function isDirectory()
201
    {
202 1
        return (bool) ($this->type === static::TYPE_DIRECTORY);
203
    }
204
205
    /**
206
     * Is this a normal file entry?
207
     *
208
     * @return bool
209
     */
210
    public function isFile()
211
    {
212
        return (bool) ($this->type === static::TYPE_FILE);
213
    }
214
215
    /**
216
     * Is this a special file entry?
217
     *
218
     * @return bool
219
     */
220
    public function isSpecialFile()
221
    {
222
        return (bool) ($this->type === static::TYPE_SPECIAL_FILE);
223
    }
224
225
    /**
226
     * Is this a meta-data entry?
227
     *
228
     * @return bool
229
     */
230 3
    public function isMetaData()
231
    {
232 3
        return (bool) ($this->type === static::TYPE_METADATA);
233
    }
234
235
    /**
236
     * Get the type of this entry (one of the static::TYPE_... constants).
237
     *
238
     * @return int
239
     */
240
    public function getType()
241
    {
242 491
        return $this->type;
243
    }
244 491
245 491
    /**
246
     * Get the contents of this entry.
247
     *
248 491
     * @throws Exception Throws an Exception in case of errors.
249 491
     *
250
     * @return string
251
     */
252 491
    public function getContents()
253 491
    {
254
        $cacheEnabled = static::getContentCacheEnabled();
255
        if ($cacheEnabled && $this->cachedContents !== null) {
256 491
            $result = $this->cachedContents;
257
        } else {
258
            $section = $this->chm->getSectionByIndex($this->contentSectionIndex);
259
            if ($section === null) {
260
                throw new Exception("The CHM file does not contain a data section with index {$this->contentSectionIndex}");
261
            }
262
            $result = $section->getContents($this->offset, $this->length);
263
            $this->cachedContents = $cacheEnabled ? $result : null;
264
        }
265
266
        return $result;
267
    }
268
}
269