1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace CHMLib\Header; |
4
|
|
|
|
5
|
|
|
use Exception; |
6
|
|
|
use CHMLib\Reader\Reader; |
7
|
|
|
use CHMLib\Windows\Language; |
8
|
|
|
use CHMLib\Exception\UnexpectedHeaderException; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* The directory header of a CHM file. |
12
|
|
|
*/ |
13
|
|
|
class ITSP extends VersionedHeader |
14
|
|
|
{ |
15
|
|
|
/** |
16
|
|
|
* The directory chunk size. |
17
|
|
|
* |
18
|
|
|
* @var int |
19
|
|
|
*/ |
20
|
|
|
protected $directoryChunkSize; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* The "density" of the QuickRef section (usually 2). |
24
|
|
|
* |
25
|
|
|
* @var int |
26
|
|
|
* |
27
|
|
|
* @example quickRef = 1 + 2 * quickRefDensity; |
28
|
|
|
*/ |
29
|
|
|
protected $quickRefDensity; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* The depth of the index tree (1: no index; 2 one level of PMGI chunks). |
33
|
|
|
* |
34
|
|
|
* @var int |
35
|
|
|
*/ |
36
|
|
|
protected $indexDepth; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* The chunk number of the root index chunk (-1: none, though at least sometimes this is 0 even if there is no index chunk - probably a bug). |
40
|
|
|
* |
41
|
|
|
* @var int |
42
|
|
|
*/ |
43
|
|
|
protected $rootIndexChunkNumber; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* The chunk number of the first PMGL (listing) chunk. |
47
|
|
|
* |
48
|
|
|
* @var int |
49
|
|
|
*/ |
50
|
|
|
protected $firstPMGLChunkNumber; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* The chunk number of the last PMGL (listing) chunk. |
54
|
|
|
* |
55
|
|
|
* @var int |
56
|
|
|
*/ |
57
|
|
|
protected $lastPMGLChunkNumber; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* The total number of directory chunks. |
61
|
|
|
* |
62
|
|
|
* @var int |
63
|
|
|
*/ |
64
|
|
|
protected $numberOfDirectoryChunks; |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* The language of the program that generated the CHM file. |
68
|
|
|
* |
69
|
|
|
* @var Language |
70
|
|
|
*/ |
71
|
|
|
protected $generatorLanguage; |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* The system GUID (it should be '{5D02926A-212E-11D0-9DF9-00A0C922E6EC}'). |
75
|
|
|
* |
76
|
|
|
* @var string |
77
|
|
|
*/ |
78
|
|
|
protected $systemGUID; |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Initialize the instance. |
82
|
|
|
* |
83
|
|
|
* @param Reader $reader The reader that provides the data. |
84
|
|
|
* |
85
|
|
|
* @throws UnexpectedHeaderException Throws an UnexpectedHeaderException if the header signature is not valid. |
86
|
|
|
* @throws Exception Throws an Exception in case of errors. |
87
|
|
|
*/ |
88
|
4 |
|
public function __construct(Reader $reader) |
89
|
|
|
{ |
90
|
4 |
|
parent::__construct($reader); |
91
|
4 |
|
if ($this->headerSignature !== 'ITSP') { |
92
|
|
|
throw UnexpectedHeaderException::create('ITSP', $this->headerSignature); |
93
|
|
|
} |
94
|
4 |
|
if ($this->headerVersion !== 1) { |
95
|
|
|
throw new Exception('Unsupported ITSP version number: '.$this->headerVersion); |
96
|
|
|
} |
97
|
4 |
|
/* Unknown (10) */ $reader->readUInt32(); |
|
|
|
|
98
|
4 |
|
$this->directoryChunkSize = $reader->readUInt32(); |
99
|
4 |
|
$this->quickRefDensity = $reader->readUInt32(); |
100
|
4 |
|
$this->indexDepth = $reader->readUInt32(); |
101
|
4 |
|
$this->rootIndexChunkNumber = $reader->readInt32(); |
102
|
4 |
|
$this->firstPMGLChunkNumber = $reader->readUInt32(); |
103
|
4 |
|
$this->lastPMGLChunkNumber = $reader->readUInt32(); |
104
|
4 |
|
/* Unknown (-1) */ $reader->readInt32(); |
|
|
|
|
105
|
4 |
|
$this->numberOfDirectoryChunks = $reader->readUInt32(); |
106
|
4 |
|
$this->generatorLanguage = new Language($reader->readUInt32()); |
107
|
4 |
|
$this->systemGUID = $reader->readGUID(); |
108
|
4 |
|
/* Again the size of this header (84) */ $reader->readUInt32(); |
109
|
4 |
|
/* Unknown (-1) */ $reader->readInt32(); |
|
|
|
|
110
|
4 |
|
/* Unknown (-1) */ $reader->readInt32(); |
|
|
|
|
111
|
4 |
|
/* Unknown (-1) */ $reader->readInt32(); |
|
|
|
|
112
|
4 |
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* Get the directory chunk size. |
116
|
|
|
* |
117
|
|
|
* @return int |
118
|
|
|
*/ |
119
|
4 |
|
public function getDirectoryChunkSize() |
120
|
|
|
{ |
121
|
4 |
|
return $this->directoryChunkSize; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Get the "density" of the QuickRef section (usually 2). |
126
|
|
|
* |
127
|
|
|
* @return int |
128
|
|
|
* |
129
|
|
|
* @example quickRef = 1 + 2 * quickRefDensity |
130
|
|
|
*/ |
131
|
|
|
public function getQuickRefDensity() |
132
|
|
|
{ |
133
|
|
|
return $this->quickRefDensity; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* Get the depth of the index tree (1: no index; 2 one level of PMGI chunks). |
138
|
|
|
* |
139
|
|
|
* @return int |
140
|
|
|
*/ |
141
|
|
|
public function getIndexDepth() |
142
|
|
|
{ |
143
|
|
|
return $this->indexDepth; |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* Get the chunk number of the root index chunk (-1: none, though at least sometimes this is 0 even if there is no index chunk - probably a bug). |
148
|
|
|
* |
149
|
|
|
* @return int |
150
|
|
|
*/ |
151
|
|
|
public function getRootIndexChunkNumber() |
152
|
|
|
{ |
153
|
|
|
return $this->rootIndexChunkNumber; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* Get the chunk number of the first PMGL (listing) chunk. |
158
|
|
|
* |
159
|
|
|
* @return int |
160
|
|
|
*/ |
161
|
4 |
|
public function getFirstPMGLChunkNumber() |
162
|
|
|
{ |
163
|
4 |
|
return $this->firstPMGLChunkNumber; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Get the chunk number of the last PMGL (listing) chunk. |
168
|
|
|
* |
169
|
|
|
* @return int |
170
|
|
|
*/ |
171
|
4 |
|
public function getLastPMGLChunkNumber() |
172
|
|
|
{ |
173
|
4 |
|
return $this->lastPMGLChunkNumber; |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* Get the total number of directory chunks. |
178
|
|
|
* |
179
|
|
|
* @return int |
180
|
|
|
*/ |
181
|
4 |
|
public function getNumberOfDirectoryChunks() |
182
|
|
|
{ |
183
|
4 |
|
return $this->numberOfDirectoryChunks; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* Get the language of the program that generated the CHM file. |
188
|
|
|
* |
189
|
|
|
* @return Language |
190
|
|
|
*/ |
191
|
|
|
public function getGeneratorLanguage() |
192
|
|
|
{ |
193
|
|
|
return $this->generatorLanguage; |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* Get the system GUID (it should be '{5D02926A-212E-11D0-9DF9-00A0C922E6EC}'). |
198
|
|
|
* |
199
|
|
|
* @return string |
200
|
|
|
*/ |
201
|
|
|
public function getSystemGUID() |
202
|
|
|
{ |
203
|
|
|
return $this->systemGUID; |
204
|
|
|
} |
205
|
|
|
} |
206
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.