source: branches/2.20_branch/NewView/IPFFileFormatUnit.pas

Last change on this file was 18, checked in by RBRi, 19 years ago

+ newview source

  • Property svn:eol-style set to native
File size: 13.2 KB
Line 
1Unit IPFFileFormatUnit;
2
3// NewView - a new OS/2 Help Viewer
4// Copyright 2003 Aaron Lawrence (aaronl at consultant dot com)
5// This software is released under the Gnu Public License - see readme.txt
6
7Interface
8
9// Definition of IPF file header and other structures
10
11uses
12 SysUtils;
13
14type
15 uint32 = longword;
16 uint16 = word;
17 uint8 = byte;
18 pUInt16 = ^ uint16;
19 pUInt32 = ^ uint32;
20 pUInt8 = ^ uint8;
21
22 PCharArray = array[ 0..0 ] of PCHar;
23 UInt32Array = array[ 0..0 ] of UInt32;
24 UInt16Array = array[ 0..0 ] of UInt16;
25 UInt8Array = array[ 0..0 ] of UInt8;
26
27 PCharArrayPointer = ^ PCharArray;
28 UInt32ArrayPointer = ^ UInt32Array;
29 UInt16ArrayPointer = ^ UInt16Array;
30 UInt8ArrayPointer = ^ UInt8Array;
31
32 TBooleanArray = array[ 0..0 ] of boolean;
33 BooleanArrayPointer = ^TBooleanArray;
34
35 EHelpFileException = class( Exception )
36 end;
37
38 EWindowsHelpFormatException = class( Exception )
39 end;
40
41var
42 ErrorCorruptHelpFile: string;
43
44const
45 INF_HEADER_ID = $5348;
46
47Type
48 THelpFileHeader = record
49 ID: uint16; // ID magic word (5348h = "HS")
50 unknown1: uint8; // unknown purpose, could be third letter of ID
51 flags: uint8; // probably a flag word...
52 // bit 0: set if INF style file
53 // bit 4: set if HLP style file
54 // patching this byte allows reading HLP files
55 // using the VIEW command, while help files
56 // seem to work with INF settings here as well.
57 hdrsize: uint16; // total size of header
58 unknown2: uint16; // unknown purpose
59
60 ntoc: uint16; // number of entries in the tocarray
61 tocstart: uint32; // file offset of the start of the toc
62 toclen: uint32; // number of bytes in file occupied by the toc
63 tocoffsetsstart: uint32; // file offset of the start of array of toc offsets
64 nres: uint16; // number of panels with ressource numbers
65 resstart: uint32; // 32 bit file offset of ressource number table
66 nname: uint16; // number of panels with textual name
67 namestart: uint32; // 32 bit file offset to panel name table
68 nindex: uint16; // number of index entries
69 indexstart: uint32; // 32 bit file offset to index table
70 indexlen: uint32; // size of index table
71 unknown3: array[ 0..9 ] of uint8; // unknown purpose
72 searchstart: uint32; // 31 bit file offset of full text search table
73 // Note: top bit indicates 32 bit search record!
74 searchlen: uint32; // size of full text search table
75 nslots: uint16; // number of "slots"
76 slotsstart: uint32; // file offset of the slots array
77 dictlen: uint32; // number of bytes occupied by the "dictionary"
78 ndict: uint16; // number of entries in the dictionary
79 dictstart: uint32; // file offset of the start of the dictionary
80 imgstart: uint32; // file offset of image data
81 unknown4: uint8; // unknown purpose
82 nlsstart: uint32; // 32 bit file offset of NLS table
83 nlslen: uint32; // size of NLS table
84 extstart: uint32; // 32 bit file offset of extended data block
85 reserved: array[ 0..2 ] of uint32; // for future use. set to zero.
86 title: array[ 0..47 ] of char; // ASCII title of database
87 end;
88 TPHelpFileHeader = ^ THelpFileHeader;
89
90 TExtendedHelpFileHeader = record
91 NumFontEntry: uint16; // FONT TABLE: Number entries
92 FontTableOffset: uint32; // FONT TABLE: Offset in file
93 NumDataBase: uint16; // DATA BASE: Number of files
94 DataBaseOffset: uint32; // DATA BASE: Offset in file
95 DataBaseSize: uint32; // DATA BASE: Size in bytes
96 EntryInGNameTable: uint16; // GLOBAL NAMES: Number entries
97 HelpPanelGNameTblOffset: uint32; // GLOBAL NAMES: Offset in file
98 StringsOffset: uint32; // STRINGS : Offset in file
99 StringsSize: uint16; // STRINGS : Total bytes of all strings
100 ChildPagesOffset: uint32; // CHILDPAGES : Offset in file
101 ChildPagesSize: uint32; // CHILDPAGES : Total bytes of all strings
102 NumGIndexEntry: uint32; // Total number of Global Index items
103 CtrlOffset: uint32; // CTRL BUTTONS : offset in file
104 CtrlSize: uint32; // CTRL BUTTONS : size in bytes
105 Reserved: array[0..3] of uint32; // For future use. Set to zero
106 end;
107 TPExtendedHelpFileHeader = ^ TExtendedHelpFileHeader;
108
109Type
110 TTOCEntryStart = record
111 length: uint8; // length of the entry including this byte
112 flags: uint8; // flag byte, description folows (MSB first)
113 // bit1 haschildren; // following nodes are a higher level
114 // bit1 hidden; // this entry doesn't appear in VIEW.EXE's
115 // presentation of the toc
116 // bit1 extended; // extended entry format
117 // bit1 stuff; // ??
118 // int4 level; // nesting level
119 numSlots: uint8; // number of "slots" occupied by the text for
120 // this toc entry
121 end;
122 pTTOCEntryStart = ^TTOCEntryStart;
123
124 TExtendedTOCEntry = record
125 w1: uint8;
126 w2: uint8;
127 end;
128 pExtendedTOCEntry = ^TExtendedTOCEntry;
129
130 TTOCEntryOffsetArray = array[ 0..0 ] of uint32;
131 pTTOCEntryOffsetArray = ^ TTOCEntryOffsetArray;
132
133Const
134 TOCEntryExtended = 32;
135 TOCEntryHidden = 64;
136 TOCEntryHasChildren = 128;
137
138type
139 THelpXYPair = record
140 Flags: uint8;
141 X: uint16;
142 Y: uint16;
143 end;
144 pHelpXYPair = ^ THelpXYPair;
145
146 TSlotHeader = record
147 stuff: uint8; // always 0??
148 localdictpos: uint32; // file offset of the local dictionary
149 nlocaldict: uint8; // number of entries in the local dict
150 ntext: uint16; // number of bytes in the text
151 end;
152 pSlotHeader = ^TSlotHeader;
153
154 THelpFontSpec = record
155 FaceName: array[ 0..32 ] of char;
156 Height: uint16;
157 Width: uint16;
158 Codepage: uint16;
159 end;
160 pTHelpFontSpec = ^ THelpFontSpec;
161
162// List of IPF escape codes.
163
164const
165 // Basic byte codes
166 IPF_END_PARA = $fa;
167 IPF_CENTER = $fb;
168 IPF_INVERT_SPACING = $fc;
169 IPF_LINEBREAK = $fd;
170 IPF_SPACE = $fe;
171 IPF_ESC = $ff; // followed by one of the ecXXX codes below
172
173 // FF XX
174 ecSetLeftMargin = $02;
175 ecHighlight1 = $04; // hp1,2,3,5,6,7
176 ecLinkStart = $05;
177 ecFootnoteLinkStart = $07;
178 ecLinkEnd = $08;
179 ecStartCharGraphics = $0b;
180 ecEndCharGraphics = $0c;
181 ecHighlight2 = $0d; // hp4,8,9
182 ecImage = $0e;
183 ecLinkedImage = $0f;
184 ecProgramLink = $10;
185 ecSetLeftMarginNewLine = $11;
186 ecSetLeftMarginFit = $12;
187 ecForegroundColor = $13;
188 ecBackgroundColor = $14;
189 ecFontChange = $19;
190 ecStartLines = $1a;
191 ecEndLines = $1b;
192 ecSetLeftMarginHere = $1c;
193 ecStartLinkByResourceID = $1d;
194 ecExternalLink = $1f;
195
196 // Subescape codes of
197 HPART_DEFINE = 0;
198 HPART_PT_HDREF = 1;
199 HPART_PT_FNREF = 2;
200 HPART_PT_SPREF = 3;
201 HPART_HDREF = 4;
202 HPART_FNREF = 5;
203 HPART_SPREF = 6;
204 HPART_LAUNCH = 7;
205 HPART_PT_LAUNCH = 8;
206 HPART_INFORM = 9;
207 HPART_PT_INFORM = 10;
208 // ?? 11 ??
209 HPART_EXTERN_PT_HDREF = 12;
210 HPART_EXTERN_PT_SPREF = 13;
211 HPART_EXTERN_HDREF = 14;
212 HPART_EXTERN_SPREF = 15;
213 HPART_GLOBAL_HDREF = 16;
214 HPART_GLOBAL_PT_HDREF = 17;
215
216// -----------------------------------------------------------
217// Operations on Int32 arrays, used for searching
218// These could be optimised heavily if needed.
219procedure AllocUInt32Array( Var pArray: UInt32ArrayPointer;
220 Size: longint );
221procedure FreeUInt32Array( Var pArray: UInt32ArrayPointer;
222 Size: longint );
223
224procedure FillUInt32Array( pArray: UInt32ArrayPointer;
225 Size: longint;
226 Value: UInt32 );
227
228procedure AddUInt32Array( pSource: UInt32ArrayPointer;
229 pDest: UInt32ArrayPointer;
230 Size: longint );
231
232// Dest = Dest + source * Multiplier
233procedure AddMultConstUInt32Array( pSource: UInt32ArrayPointer;
234 Multiplier: longint;
235 pDest: UInt32ArrayPointer;
236 Size: longint );
237
238procedure AndUInt32Array( pSource: UInt32ArrayPointer;
239 pDest: UInt32ArrayPointer;
240 Size: longint );
241
242// If both source and dest > 0 then
243// add source to dest
244procedure AndAddUInt32Array( pSource: UInt32ArrayPointer;
245 pDest: UInt32ArrayPointer;
246 Size: longint );
247
248// if Source > 0 then dest is set to 0
249procedure AndNotUInt32Array( pSource: UInt32ArrayPointer;
250 pDest: UInt32ArrayPointer;
251 Size: longint );
252
253// dest = dest or source;
254// if source > 0 then set dest to > 0
255procedure OrUInt32Array( pSource: UInt32ArrayPointer;
256 pDest: UInt32ArrayPointer;
257 Size: longint );
258
259// if source = 0 then dest set to >0
260procedure NotOrUInt32Array( pSource: UInt32ArrayPointer;
261 pDest: UInt32ArrayPointer;
262 Size: longint );
263
264procedure CopyUInt32Array( pSource: UInt32ArrayPointer;
265 pDest: UInt32ArrayPointer;
266 Size: longint );
267
268procedure ClearUInt32Array( pArray: UInt32ArrayPointer;
269 Size: longint );
270procedure SetUInt32Array( pArray: UInt32ArrayPointer;
271 Size: longint );
272
273// returns the result of ORing every array element.
274// Can be useful for debugging e.g. seeing at a glance
275// if any element is non-zero
276function OrAllUInt32Array( pArray: UInt32ArrayPointer;
277 Size: longint ): longint;
278
279
280Implementation
281
282uses
283 ACLUtility;
284
285// Operations on int32 arrays
286// -----------------------------------------------------------
287
288procedure AllocUInt32Array( Var pArray: UInt32ArrayPointer;
289 Size: longint );
290begin
291 GetMem( pArray,
292 Size
293 * sizeof( UInt32 ) );
294end;
295
296procedure FreeUInt32Array( Var pArray: UInt32ArrayPointer;
297 Size: longint );
298begin
299 FreeMem( pArray,
300 Size
301 * sizeof( UInt32 ) );
302end;
303
304// This is a nice fast implementation of filling an
305// array of dwords (Int32/longword)
306procedure FillUInt32Array( pArray: UInt32ArrayPointer;
307 Size: longint;
308 Value: UInt32 );
309begin
310 assert( Size >= 0 );
311 Asm
312 Mov EAX, Value
313 Mov EDI, pArray
314 Mov ECX, Size
315 CLD // direction = up
316 REP STOSD // store double word, until ECX = 0
317 End;
318end;
319
320procedure ClearUInt32Array( pArray: UInt32ArrayPointer;
321 Size: longint );
322begin
323 FillUInt32Array( pArray, Size, 0 );
324end;
325
326procedure SetUInt32Array( pArray: UInt32ArrayPointer;
327 Size: longint );
328begin
329 FillUInt32Array( pArray, Size, $ffffffff );
330end;
331
332procedure AddUInt32Array( pSource: UInt32ArrayPointer;
333 pDest: UInt32ArrayPointer;
334 Size: longint );
335var
336 i: longint;
337begin
338 for i := 0 to Size - 1 do
339 inc( pDest^[ i ], pSource^[ i ] );
340end;
341
342procedure AddMultConstUInt32Array( pSource: UInt32ArrayPointer;
343 Multiplier: longint;
344 pDest: UInt32ArrayPointer;
345 Size: longint );
346var
347 i: longint;
348begin
349 for i := 0 to Size - 1 do
350 inc( pDest^[ i ], pSource^[ i ] * Multiplier );
351end;
352
353procedure OrUInt32Array( pSource: UInt32ArrayPointer;
354 pDest: UInt32ArrayPointer;
355 Size: longint );
356var
357 i: longint;
358begin
359 for i := 0 to Size - 1 do
360 pDest^[ i ] := pDest^[ i ] or pSource^[ i ];
361end;
362
363procedure CopyUInt32Array( pSource: UInt32ArrayPointer;
364 pDest: UInt32ArrayPointer;
365 Size: longint );
366begin
367 MemCopy( pSource, pDest, Size * sizeof( uint32 ) );
368end;
369
370procedure NotOrUInt32Array( pSource: UInt32ArrayPointer;
371 pDest: UInt32ArrayPointer;
372 Size: longint );
373var
374 i: longint;
375begin
376 for i := 0 to Size - 1 do
377 if pSource^[ i ] = 0 then
378 pDest^[ i ] := 1;
379end;
380
381procedure AndUInt32Array( pSource: UInt32ArrayPointer;
382 pDest: UInt32ArrayPointer;
383 Size: longint );
384var
385 i: longint;
386begin
387 for i := 0 to Size - 1 do
388 pDest^[ i ] := pDest^[ i ] and pSource^[ i ];
389end;
390
391procedure AndAddUInt32Array( pSource: UInt32ArrayPointer;
392 pDest: UInt32ArrayPointer;
393 Size: longint );
394var
395 i: longint;
396begin
397 for i := 0 to Size - 1 do
398 if ( pSource^[ i ] > 0 )
399 and ( pDest^[ i ] > 0 ) then
400 inc( pDest^[ i ], pSource^[ i ] )
401 else
402 pDest^[ i ] := 0;
403end;
404
405procedure AndNotUInt32Array( pSource: UInt32ArrayPointer;
406 pDest: UInt32ArrayPointer;
407 Size: longint );
408var
409 i: longint;
410begin
411 for i := 0 to Size - 1 do
412 if pSource^[ i ] > 0 then
413 pDest^[ i ] := 0;
414end;
415
416function OrAllUInt32Array( pArray: UInt32ArrayPointer;
417 Size: longint ): longint;
418var
419 i: longint;
420begin
421 Result := 0;
422 for i := 0 to Size - 1 do
423 Result := Result or pArray^[ i ];
424end;
425
426Initialization
427End.
Note: See TracBrowser for help on using the repository browser.