summaryrefslogtreecommitdiff
path: root/utils/rbutilqt/mspack/mspack.h
diff options
context:
space:
mode:
Diffstat (limited to 'utils/rbutilqt/mspack/mspack.h')
-rw-r--r--utils/rbutilqt/mspack/mspack.h2385
1 files changed, 2385 insertions, 0 deletions
diff --git a/utils/rbutilqt/mspack/mspack.h b/utils/rbutilqt/mspack/mspack.h
new file mode 100644
index 0000000000..3e99624463
--- /dev/null
+++ b/utils/rbutilqt/mspack/mspack.h
@@ -0,0 +1,2385 @@
1/* libmspack -- a library for working with Microsoft compression formats.
2 * (C) 2003-2019 Stuart Caie <kyzer@cabextract.org.uk>
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/** \mainpage
18 *
19 * \section intro Introduction
20 *
21 * libmspack is a library which provides compressors and decompressors,
22 * archivers and dearchivers for Microsoft compression formats.
23 *
24 * \section formats Formats supported
25 *
26 * The following file formats are supported:
27 * - SZDD files, which use LZSS compression
28 * - KWAJ files, which use LZSS, LZSS+Huffman or deflate compression
29 * - .HLP (MS Help) files, which use LZSS compression
30 * - .CAB (MS Cabinet) files, which use deflate, LZX or Quantum compression
31 * - .CHM (HTML Help) files, which use LZX compression
32 * - .LIT (MS EBook) files, which use LZX compression and DES encryption
33 * - .LZX (Exchange Offline Addressbook) files, which use LZX compression
34 *
35 * To determine the capabilities of the library, and the binary
36 * compatibility version of any particular compressor or decompressor, use
37 * the mspack_version() function. The UNIX library interface version is
38 * defined as the highest-versioned library component.
39 *
40 * \section starting Getting started
41 *
42 * The macro MSPACK_SYS_SELFTEST() should be used to ensure the library can
43 * be used. In particular, it checks if the caller is using 32-bit file I/O
44 * when the library is compiled for 64-bit file I/O and vice versa.
45 *
46 * If compiled normally, the library includes basic file I/O and memory
47 * management functionality using the standard C library. This can be
48 * customised and replaced entirely by creating a mspack_system structure.
49 *
50 * A compressor or decompressor for the required format must be
51 * instantiated before it can be used. Each construction function takes
52 * one parameter, which is either a pointer to a custom mspack_system
53 * structure, or NULL to use the default. The instantiation returned, if
54 * not NULL, contains function pointers (methods) to work with the given
55 * file format.
56 *
57 * For compression:
58 * - mspack_create_cab_compressor() creates a mscab_compressor
59 * - mspack_create_chm_compressor() creates a mschm_compressor
60 * - mspack_create_lit_compressor() creates a mslit_compressor
61 * - mspack_create_hlp_compressor() creates a mshlp_compressor
62 * - mspack_create_szdd_compressor() creates a msszdd_compressor
63 * - mspack_create_kwaj_compressor() creates a mskwaj_compressor
64 * - mspack_create_oab_compressor() creates a msoab_compressor
65 *
66 * For decompression:
67 * - mspack_create_cab_decompressor() creates a mscab_decompressor
68 * - mspack_create_chm_decompressor() creates a mschm_decompressor
69 * - mspack_create_lit_decompressor() creates a mslit_decompressor
70 * - mspack_create_hlp_decompressor() creates a mshlp_decompressor
71 * - mspack_create_szdd_decompressor() creates a msszdd_decompressor
72 * - mspack_create_kwaj_decompressor() creates a mskwaj_decompressor
73 * - mspack_create_oab_decompressor() creates a msoab_decompressor
74 *
75 * Once finished working with a format, each kind of
76 * compressor/decompressor has its own specific destructor:
77 * - mspack_destroy_cab_compressor()
78 * - mspack_destroy_cab_decompressor()
79 * - mspack_destroy_chm_compressor()
80 * - mspack_destroy_chm_decompressor()
81 * - mspack_destroy_lit_compressor()
82 * - mspack_destroy_lit_decompressor()
83 * - mspack_destroy_hlp_compressor()
84 * - mspack_destroy_hlp_decompressor()
85 * - mspack_destroy_szdd_compressor()
86 * - mspack_destroy_szdd_decompressor()
87 * - mspack_destroy_kwaj_compressor()
88 * - mspack_destroy_kwaj_decompressor()
89 * - mspack_destroy_oab_compressor()
90 * - mspack_destroy_oab_decompressor()
91 *
92 * Destroying a compressor or decompressor does not destroy any objects,
93 * structures or handles that have been created using that compressor or
94 * decompressor. Ensure that everything created or opened is destroyed or
95 * closed before compressor/decompressor is itself destroyed.
96 *
97 * \section errors Error codes
98 *
99 * All compressors and decompressors use the same set of error codes. Most
100 * methods return an error code directly. For methods which do not
101 * return error codes directly, the error code can be obtained with the
102 * last_error() method.
103 *
104 * - #MSPACK_ERR_OK is used to indicate success. This error code is defined
105 * as zero, all other code are non-zero.
106 * - #MSPACK_ERR_ARGS indicates that a method was called with inappropriate
107 * arguments.
108 * - #MSPACK_ERR_OPEN indicates that mspack_system::open() failed.
109 * - #MSPACK_ERR_READ indicates that mspack_system::read() failed.
110 * - #MSPACK_ERR_WRITE indicates that mspack_system::write() failed.
111 * - #MSPACK_ERR_SEEK indicates that mspack_system::seek() failed.
112 * - #MSPACK_ERR_NOMEMORY indicates that mspack_system::alloc() failed.
113 * - #MSPACK_ERR_SIGNATURE indicates that the file being read does not
114 * have the correct "signature". It is probably not a valid file for
115 * whatever format is being read.
116 * - #MSPACK_ERR_DATAFORMAT indicates that the file being used or read
117 * is corrupt.
118 * - #MSPACK_ERR_CHECKSUM indicates that a data checksum has failed.
119 * - #MSPACK_ERR_CRUNCH indicates an error occured during compression.
120 * - #MSPACK_ERR_DECRUNCH indicates an error occured during decompression.
121 *
122 * \section threading Multi-threading
123 *
124 * libmspack methods are reentrant and multithreading-safe when each
125 * thread has its own compressor or decompressor.
126
127 * You should not call multiple methods simultaneously on a single
128 * compressor or decompressor instance.
129 *
130 * If this may happen, you can either use one compressor or
131 * decompressor per thread, or you can use your preferred lock,
132 * semaphore or mutex library to ensure no more than one method on a
133 * compressor/decompressor is called simultaneously. libmspack will
134 * not do this locking for you.
135 *
136 * Example of incorrect behaviour:
137 * - thread 1 calls mspack_create_cab_decompressor()
138 * - thread 1 calls open()
139 * - thread 1 calls extract() for one file
140 * - thread 2 simultaneously calls extract() for another file
141 *
142 * Correct behaviour:
143 * - thread 1 calls mspack_create_cab_decompressor()
144 * - thread 2 calls mspack_create_cab_decompressor()
145 * - thread 1 calls its own open() / extract()
146 * - thread 2 simultaneously calls its own open() / extract()
147 *
148 * Also correct behaviour:
149 * - thread 1 calls mspack_create_cab_decompressor()
150 * - thread 1 locks a mutex for with the decompressor before
151 * calling any methods on it, and unlocks the mutex after each
152 * method returns.
153 * - thread 1 can share the results of open() with thread 2, and both
154 * can call extract(), provided they both guard against simultaneous
155 * use of extract(), and any other methods, with the mutex
156 */
157
158#ifndef LIB_MSPACK_H
159#define LIB_MSPACK_H 1
160
161#ifdef __cplusplus
162extern "C" {
163#endif
164
165#include <sys/types.h>
166#include <stdlib.h>
167
168/**
169 * System self-test function, to ensure both library and calling program
170 * can use one another.
171 *
172 * A result of MSPACK_ERR_OK means the library and caller are
173 * compatible. Any other result indicates that the library and caller are
174 * not compatible and should not be used. In particular, a value of
175 * MSPACK_ERR_SEEK means the library and caller use different off_t
176 * datatypes.
177 *
178 * It should be used like so:
179 *
180 * @code
181 * int selftest_result;
182 * MSPACK_SYS_SELFTEST(selftest_result);
183 * if (selftest_result != MSPACK_ERR_OK) {
184 * fprintf(stderr, "incompatible with this build of libmspack\n");
185 * exit(0);
186 * }
187 * @endcode
188 *
189 * @param result an int variable to store the result of the self-test
190 */
191#define MSPACK_SYS_SELFTEST(result) do { \
192 (result) = mspack_sys_selftest_internal(sizeof(off_t)); \
193} while (0)
194
195/** Part of the MSPACK_SYS_SELFTEST() macro, must not be used directly. */
196extern int mspack_sys_selftest_internal(int);
197
198/**
199 * Enquire about the binary compatibility version of a specific interface in
200 * the library. Currently, the following interfaces are defined:
201 *
202 * - #MSPACK_VER_LIBRARY: the overall library
203 * - #MSPACK_VER_SYSTEM: the mspack_system interface
204 * - #MSPACK_VER_MSCABD: the mscab_decompressor interface
205 * - #MSPACK_VER_MSCABC: the mscab_compressor interface
206 * - #MSPACK_VER_MSCHMD: the mschm_decompressor interface
207 * - #MSPACK_VER_MSCHMC: the mschm_compressor interface
208 * - #MSPACK_VER_MSLITD: the mslit_decompressor interface
209 * - #MSPACK_VER_MSLITC: the mslit_compressor interface
210 * - #MSPACK_VER_MSHLPD: the mshlp_decompressor interface
211 * - #MSPACK_VER_MSHLPC: the mshlp_compressor interface
212 * - #MSPACK_VER_MSSZDDD: the msszdd_decompressor interface
213 * - #MSPACK_VER_MSSZDDC: the msszdd_compressor interface
214 * - #MSPACK_VER_MSKWAJD: the mskwaj_decompressor interface
215 * - #MSPACK_VER_MSKWAJC: the mskwaj_compressor interface
216 * - #MSPACK_VER_MSOABD: the msoab_decompressor interface
217 * - #MSPACK_VER_MSOABC: the msoab_compressor interface
218 *
219 * The result of the function should be interpreted as follows:
220 * - -1: this interface is completely unknown to the library
221 * - 0: this interface is known, but non-functioning
222 * - 1: this interface has all basic functionality
223 * - 2, 3, ...: this interface has additional functionality, clearly marked
224 * in the documentation as "version 2", "version 3" and so on.
225 *
226 * @param entity the interface to request current version of
227 * @return the version of the requested interface
228 */
229extern int mspack_version(int entity);
230
231/** Pass to mspack_version() to get the overall library version */
232#define MSPACK_VER_LIBRARY (0)
233/** Pass to mspack_version() to get the mspack_system version */
234#define MSPACK_VER_SYSTEM (1)
235/** Pass to mspack_version() to get the mscab_decompressor version */
236#define MSPACK_VER_MSCABD (2)
237/** Pass to mspack_version() to get the mscab_compressor version */
238#define MSPACK_VER_MSCABC (3)
239/** Pass to mspack_version() to get the mschm_decompressor version */
240#define MSPACK_VER_MSCHMD (4)
241/** Pass to mspack_version() to get the mschm_compressor version */
242#define MSPACK_VER_MSCHMC (5)
243/** Pass to mspack_version() to get the mslit_decompressor version */
244#define MSPACK_VER_MSLITD (6)
245/** Pass to mspack_version() to get the mslit_compressor version */
246#define MSPACK_VER_MSLITC (7)
247/** Pass to mspack_version() to get the mshlp_decompressor version */
248#define MSPACK_VER_MSHLPD (8)
249/** Pass to mspack_version() to get the mshlp_compressor version */
250#define MSPACK_VER_MSHLPC (9)
251/** Pass to mspack_version() to get the msszdd_decompressor version */
252#define MSPACK_VER_MSSZDDD (10)
253/** Pass to mspack_version() to get the msszdd_compressor version */
254#define MSPACK_VER_MSSZDDC (11)
255/** Pass to mspack_version() to get the mskwaj_decompressor version */
256#define MSPACK_VER_MSKWAJD (12)
257/** Pass to mspack_version() to get the mskwaj_compressor version */
258#define MSPACK_VER_MSKWAJC (13)
259/** Pass to mspack_version() to get the msoab_decompressor version */
260#define MSPACK_VER_MSOABD (14)
261/** Pass to mspack_version() to get the msoab_compressor version */
262#define MSPACK_VER_MSOABC (15)
263
264/* --- file I/O abstraction ------------------------------------------------ */
265
266/**
267 * A structure which abstracts file I/O and memory management.
268 *
269 * The library always uses the mspack_system structure for interaction
270 * with the file system and to allocate, free and copy all memory. It also
271 * uses it to send literal messages to the library user.
272 *
273 * When the library is compiled normally, passing NULL to a compressor or
274 * decompressor constructor will result in a default mspack_system being
275 * used, where all methods are implemented with the standard C library.
276 * However, all constructors support being given a custom created
277 * mspack_system structure, with the library user's own methods. This
278 * allows for more abstract interaction, such as reading and writing files
279 * directly to memory, or from a network socket or pipe.
280 *
281 * Implementors of an mspack_system structure should read all
282 * documentation entries for every structure member, and write methods
283 * which conform to those standards.
284 */
285struct mspack_system {
286 /**
287 * Opens a file for reading, writing, appending or updating.
288 *
289 * @param self a self-referential pointer to the mspack_system
290 * structure whose open() method is being called. If
291 * this pointer is required by close(), read(), write(),
292 * seek() or tell(), it should be stored in the result
293 * structure at this time.
294 * @param filename the file to be opened. It is passed directly from the
295 * library caller without being modified, so it is up to
296 * the caller what this parameter actually represents.
297 * @param mode one of #MSPACK_SYS_OPEN_READ (open an existing file
298 * for reading), #MSPACK_SYS_OPEN_WRITE (open a new file
299 * for writing), #MSPACK_SYS_OPEN_UPDATE (open an existing
300 * file for reading/writing from the start of the file) or
301 * #MSPACK_SYS_OPEN_APPEND (open an existing file for
302 * reading/writing from the end of the file)
303 * @return a pointer to a mspack_file structure. This structure officially
304 * contains no members, its true contents are up to the
305 * mspack_system implementor. It should contain whatever is needed
306 * for other mspack_system methods to operate. Returning the NULL
307 * pointer indicates an error condition.
308 * @see close(), read(), write(), seek(), tell(), message()
309 */
310 struct mspack_file * (*open)(struct mspack_system *self,
311 const char *filename,
312 int mode);
313
314 /**
315 * Closes a previously opened file. If any memory was allocated for this
316 * particular file handle, it should be freed at this time.
317 *
318 * @param file the file to close
319 * @see open()
320 */
321 void (*close)(struct mspack_file *file);
322
323 /**
324 * Reads a given number of bytes from an open file.
325 *
326 * @param file the file to read from
327 * @param buffer the location where the read bytes should be stored
328 * @param bytes the number of bytes to read from the file.
329 * @return the number of bytes successfully read (this can be less than
330 * the number requested), zero to mark the end of file, or less
331 * than zero to indicate an error. The library does not "retry"
332 * reads and assumes short reads are due to EOF, so you should
333 * avoid returning short reads because of transient errors.
334 * @see open(), write()
335 */
336 int (*read)(struct mspack_file *file,
337 void *buffer,
338 int bytes);
339
340 /**
341 * Writes a given number of bytes to an open file.
342 *
343 * @param file the file to write to
344 * @param buffer the location where the written bytes should be read from
345 * @param bytes the number of bytes to write to the file.
346 * @return the number of bytes successfully written, this can be less
347 * than the number requested. Zero or less can indicate an error
348 * where no bytes at all could be written. All cases where less
349 * bytes were written than requested are considered by the library
350 * to be an error.
351 * @see open(), read()
352 */
353 int (*write)(struct mspack_file *file,
354 void *buffer,
355 int bytes);
356
357 /**
358 * Seeks to a specific file offset within an open file.
359 *
360 * Sometimes the library needs to know the length of a file. It does
361 * this by seeking to the end of the file with seek(file, 0,
362 * MSPACK_SYS_SEEK_END), then calling tell(). Implementations may want
363 * to make a special case for this.
364 *
365 * Due to the potentially varying 32/64 bit datatype off_t on some
366 * architectures, the #MSPACK_SYS_SELFTEST macro MUST be used before
367 * using the library. If not, the error caused by the library passing an
368 * inappropriate stackframe to seek() is subtle and hard to trace.
369 *
370 * @param file the file to be seeked
371 * @param offset an offset to seek, measured in bytes
372 * @param mode one of #MSPACK_SYS_SEEK_START (the offset should be
373 * measured from the start of the file), #MSPACK_SYS_SEEK_CUR
374 * (the offset should be measured from the current file offset)
375 * or #MSPACK_SYS_SEEK_END (the offset should be measured from
376 * the end of the file)
377 * @return zero for success, non-zero for an error
378 * @see open(), tell()
379 */
380 int (*seek)(struct mspack_file *file,
381 off_t offset,
382 int mode);
383
384 /**
385 * Returns the current file position (in bytes) of the given file.
386 *
387 * @param file the file whose file position is wanted
388 * @return the current file position of the file
389 * @see open(), seek()
390 */
391 off_t (*tell)(struct mspack_file *file);
392
393 /**
394 * Used to send messages from the library to the user.
395 *
396 * Occasionally, the library generates warnings or other messages in
397 * plain english to inform the human user. These are informational only
398 * and can be ignored if not wanted.
399 *
400 * @param file may be a file handle returned from open() if this message
401 * pertains to a specific open file, or NULL if not related to
402 * a specific file.
403 * @param format a printf() style format string. It does NOT include a
404 * trailing newline.
405 * @see open()
406 */
407 void (*message)(struct mspack_file *file,
408 const char *format,
409 ...);
410
411 /**
412 * Allocates memory.
413 *
414 * @param self a self-referential pointer to the mspack_system
415 * structure whose alloc() method is being called.
416 * @param bytes the number of bytes to allocate
417 * @result a pointer to the requested number of bytes, or NULL if
418 * not enough memory is available
419 * @see free()
420 */
421 void * (*alloc)(struct mspack_system *self,
422 size_t bytes);
423
424 /**
425 * Frees memory.
426 *
427 * @param ptr the memory to be freed. NULL is accepted and ignored.
428 * @see alloc()
429 */
430 void (*free)(void *ptr);
431
432 /**
433 * Copies from one region of memory to another.
434 *
435 * The regions of memory are guaranteed not to overlap, are usually less
436 * than 256 bytes, and may not be aligned. Please note that the source
437 * parameter comes before the destination parameter, unlike the standard
438 * C function memcpy().
439 *
440 * @param src the region of memory to copy from
441 * @param dest the region of memory to copy to
442 * @param bytes the size of the memory region, in bytes
443 */
444 void (*copy)(void *src,
445 void *dest,
446 size_t bytes);
447
448 /**
449 * A null pointer to mark the end of mspack_system. It must equal NULL.
450 *
451 * Should the mspack_system structure extend in the future, this NULL
452 * will be seen, rather than have an invalid method pointer called.
453 */
454 void *null_ptr;
455};
456
457/** mspack_system::open() mode: open existing file for reading. */
458#define MSPACK_SYS_OPEN_READ (0)
459/** mspack_system::open() mode: open new file for writing */
460#define MSPACK_SYS_OPEN_WRITE (1)
461/** mspack_system::open() mode: open existing file for writing */
462#define MSPACK_SYS_OPEN_UPDATE (2)
463/** mspack_system::open() mode: open existing file for writing */
464#define MSPACK_SYS_OPEN_APPEND (3)
465
466/** mspack_system::seek() mode: seek relative to start of file */
467#define MSPACK_SYS_SEEK_START (0)
468/** mspack_system::seek() mode: seek relative to current offset */
469#define MSPACK_SYS_SEEK_CUR (1)
470/** mspack_system::seek() mode: seek relative to end of file */
471#define MSPACK_SYS_SEEK_END (2)
472
473/**
474 * A structure which represents an open file handle. The contents of this
475 * structure are determined by the implementation of the
476 * mspack_system::open() method.
477 */
478struct mspack_file {
479 int dummy;
480};
481
482/* --- error codes --------------------------------------------------------- */
483
484/** Error code: no error */
485#define MSPACK_ERR_OK (0)
486/** Error code: bad arguments to method */
487#define MSPACK_ERR_ARGS (1)
488/** Error code: error opening file */
489#define MSPACK_ERR_OPEN (2)
490/** Error code: error reading file */
491#define MSPACK_ERR_READ (3)
492/** Error code: error writing file */
493#define MSPACK_ERR_WRITE (4)
494/** Error code: seek error */
495#define MSPACK_ERR_SEEK (5)
496/** Error code: out of memory */
497#define MSPACK_ERR_NOMEMORY (6)
498/** Error code: bad "magic id" in file */
499#define MSPACK_ERR_SIGNATURE (7)
500/** Error code: bad or corrupt file format */
501#define MSPACK_ERR_DATAFORMAT (8)
502/** Error code: bad checksum or CRC */
503#define MSPACK_ERR_CHECKSUM (9)
504/** Error code: error during compression */
505#define MSPACK_ERR_CRUNCH (10)
506/** Error code: error during decompression */
507#define MSPACK_ERR_DECRUNCH (11)
508
509/* --- functions available in library -------------------------------------- */
510
511/** Creates a new CAB compressor.
512 * @param sys a custom mspack_system structure, or NULL to use the default
513 * @return a #mscab_compressor or NULL
514 */
515extern struct mscab_compressor *
516 mspack_create_cab_compressor(struct mspack_system *sys);
517
518/** Creates a new CAB decompressor.
519 * @param sys a custom mspack_system structure, or NULL to use the default
520 * @return a #mscab_decompressor or NULL
521 */
522extern struct mscab_decompressor *
523 mspack_create_cab_decompressor(struct mspack_system *sys);
524
525/** Destroys an existing CAB compressor.
526 * @param self the #mscab_compressor to destroy
527 */
528extern void mspack_destroy_cab_compressor(struct mscab_compressor *self);
529
530/** Destroys an existing CAB decompressor.
531 * @param self the #mscab_decompressor to destroy
532 */
533extern void mspack_destroy_cab_decompressor(struct mscab_decompressor *self);
534
535
536/** Creates a new CHM compressor.
537 * @param sys a custom mspack_system structure, or NULL to use the default
538 * @return a #mschm_compressor or NULL
539 */
540extern struct mschm_compressor *
541 mspack_create_chm_compressor(struct mspack_system *sys);
542
543/** Creates a new CHM decompressor.
544 * @param sys a custom mspack_system structure, or NULL to use the default
545 * @return a #mschm_decompressor or NULL
546 */
547extern struct mschm_decompressor *
548 mspack_create_chm_decompressor(struct mspack_system *sys);
549
550/** Destroys an existing CHM compressor.
551 * @param self the #mschm_compressor to destroy
552 */
553extern void mspack_destroy_chm_compressor(struct mschm_compressor *self);
554
555/** Destroys an existing CHM decompressor.
556 * @param self the #mschm_decompressor to destroy
557 */
558extern void mspack_destroy_chm_decompressor(struct mschm_decompressor *self);
559
560
561/** Creates a new LIT compressor.
562 * @param sys a custom mspack_system structure, or NULL to use the default
563 * @return a #mslit_compressor or NULL
564 */
565extern struct mslit_compressor *
566 mspack_create_lit_compressor(struct mspack_system *sys);
567
568/** Creates a new LIT decompressor.
569 * @param sys a custom mspack_system structure, or NULL to use the default
570 * @return a #mslit_decompressor or NULL
571 */
572extern struct mslit_decompressor *
573 mspack_create_lit_decompressor(struct mspack_system *sys);
574
575/** Destroys an existing LIT compressor.
576 * @param self the #mslit_compressor to destroy
577 */
578extern void mspack_destroy_lit_compressor(struct mslit_compressor *self);
579
580/** Destroys an existing LIT decompressor.
581 * @param self the #mslit_decompressor to destroy
582 */
583extern void mspack_destroy_lit_decompressor(struct mslit_decompressor *self);
584
585
586/** Creates a new HLP compressor.
587 * @param sys a custom mspack_system structure, or NULL to use the default
588 * @return a #mshlp_compressor or NULL
589 */
590extern struct mshlp_compressor *
591 mspack_create_hlp_compressor(struct mspack_system *sys);
592
593/** Creates a new HLP decompressor.
594 * @param sys a custom mspack_system structure, or NULL to use the default
595 * @return a #mshlp_decompressor or NULL
596 */
597extern struct mshlp_decompressor *
598 mspack_create_hlp_decompressor(struct mspack_system *sys);
599
600/** Destroys an existing hlp compressor.
601 * @param self the #mshlp_compressor to destroy
602 */
603extern void mspack_destroy_hlp_compressor(struct mshlp_compressor *self);
604
605/** Destroys an existing hlp decompressor.
606 * @param self the #mshlp_decompressor to destroy
607 */
608extern void mspack_destroy_hlp_decompressor(struct mshlp_decompressor *self);
609
610
611/** Creates a new SZDD compressor.
612 * @param sys a custom mspack_system structure, or NULL to use the default
613 * @return a #msszdd_compressor or NULL
614 */
615extern struct msszdd_compressor *
616 mspack_create_szdd_compressor(struct mspack_system *sys);
617
618/** Creates a new SZDD decompressor.
619 * @param sys a custom mspack_system structure, or NULL to use the default
620 * @return a #msszdd_decompressor or NULL
621 */
622extern struct msszdd_decompressor *
623 mspack_create_szdd_decompressor(struct mspack_system *sys);
624
625/** Destroys an existing SZDD compressor.
626 * @param self the #msszdd_compressor to destroy
627 */
628extern void mspack_destroy_szdd_compressor(struct msszdd_compressor *self);
629
630/** Destroys an existing SZDD decompressor.
631 * @param self the #msszdd_decompressor to destroy
632 */
633extern void mspack_destroy_szdd_decompressor(struct msszdd_decompressor *self);
634
635
636/** Creates a new KWAJ compressor.
637 * @param sys a custom mspack_system structure, or NULL to use the default
638 * @return a #mskwaj_compressor or NULL
639 */
640extern struct mskwaj_compressor *
641 mspack_create_kwaj_compressor(struct mspack_system *sys);
642
643/** Creates a new KWAJ decompressor.
644 * @param sys a custom mspack_system structure, or NULL to use the default
645 * @return a #mskwaj_decompressor or NULL
646 */
647extern struct mskwaj_decompressor *
648 mspack_create_kwaj_decompressor(struct mspack_system *sys);
649
650/** Destroys an existing KWAJ compressor.
651 * @param self the #mskwaj_compressor to destroy
652 */
653extern void mspack_destroy_kwaj_compressor(struct mskwaj_compressor *self);
654
655/** Destroys an existing KWAJ decompressor.
656 * @param self the #mskwaj_decompressor to destroy
657 */
658extern void mspack_destroy_kwaj_decompressor(struct mskwaj_decompressor *self);
659
660
661/** Creates a new OAB compressor.
662 * @param sys a custom mspack_system structure, or NULL to use the default
663 * @return a #msoab_compressor or NULL
664 */
665extern struct msoab_compressor *
666 mspack_create_oab_compressor(struct mspack_system *sys);
667
668/** Creates a new OAB decompressor.
669 * @param sys a custom mspack_system structure, or NULL to use the default
670 * @return a #msoab_decompressor or NULL
671 */
672extern struct msoab_decompressor *
673 mspack_create_oab_decompressor(struct mspack_system *sys);
674
675/** Destroys an existing OAB compressor.
676 * @param self the #msoab_compressor to destroy
677 */
678extern void mspack_destroy_oab_compressor(struct msoab_compressor *self);
679
680/** Destroys an existing OAB decompressor.
681 * @param self the #msoab_decompressor to destroy
682 */
683extern void mspack_destroy_oab_decompressor(struct msoab_decompressor *self);
684
685
686/* --- support for .CAB (MS Cabinet) file format --------------------------- */
687
688/**
689 * A structure which represents a single cabinet file.
690 *
691 * All fields are READ ONLY.
692 *
693 * If this cabinet is part of a merged cabinet set, the #files and #folders
694 * fields are common to all cabinets in the set, and will be identical.
695 *
696 * @see mscab_decompressor::open(), mscab_decompressor::close(),
697 * mscab_decompressor::search()
698 */
699struct mscabd_cabinet {
700 /**
701 * The next cabinet in a chained list, if this cabinet was opened with
702 * mscab_decompressor::search(). May be NULL to mark the end of the
703 * list.
704 */
705 struct mscabd_cabinet *next;
706
707 /**
708 * The filename of the cabinet. More correctly, the filename of the
709 * physical file that the cabinet resides in. This is given by the
710 * library user and may be in any format.
711 */
712 const char *filename;
713
714 /** The file offset of cabinet within the physical file it resides in. */
715 off_t base_offset;
716
717 /** The length of the cabinet file in bytes. */
718 unsigned int length;
719
720 /** The previous cabinet in a cabinet set, or NULL. */
721 struct mscabd_cabinet *prevcab;
722
723 /** The next cabinet in a cabinet set, or NULL. */
724 struct mscabd_cabinet *nextcab;
725
726 /** The filename of the previous cabinet in a cabinet set, or NULL. */
727 char *prevname;
728
729 /** The filename of the next cabinet in a cabinet set, or NULL. */
730 char *nextname;
731
732 /** The name of the disk containing the previous cabinet in a cabinet
733 * set, or NULL.
734 */
735 char *previnfo;
736
737 /** The name of the disk containing the next cabinet in a cabinet set,
738 * or NULL.
739 */
740 char *nextinfo;
741
742 /** A list of all files in the cabinet or cabinet set. */
743 struct mscabd_file *files;
744
745 /** A list of all folders in the cabinet or cabinet set. */
746 struct mscabd_folder *folders;
747
748 /**
749 * The set ID of the cabinet. All cabinets in the same set should have
750 * the same set ID.
751 */
752 unsigned short set_id;
753
754 /**
755 * The index number of the cabinet within the set. Numbering should
756 * start from 0 for the first cabinet in the set, and increment by 1 for
757 * each following cabinet.
758 */
759 unsigned short set_index;
760
761 /**
762 * The number of bytes reserved in the header area of the cabinet.
763 *
764 * If this is non-zero and flags has MSCAB_HDR_RESV set, this data can
765 * be read by the calling application. It is of the given length,
766 * located at offset (base_offset + MSCAB_HDR_RESV_OFFSET) in the
767 * cabinet file.
768 *
769 * @see flags
770 */
771 unsigned short header_resv;
772
773 /**
774 * Header flags.
775 *
776 * - MSCAB_HDR_PREVCAB indicates the cabinet is part of a cabinet set, and
777 * has a predecessor cabinet.
778 * - MSCAB_HDR_NEXTCAB indicates the cabinet is part of a cabinet set, and
779 * has a successor cabinet.
780 * - MSCAB_HDR_RESV indicates the cabinet has reserved header space.
781 *
782 * @see prevname, previnfo, nextname, nextinfo, header_resv
783 */
784 int flags;
785};
786
787/** Offset from start of cabinet to the reserved header data (if present). */
788#define MSCAB_HDR_RESV_OFFSET (0x28)
789
790/** Cabinet header flag: cabinet has a predecessor */
791#define MSCAB_HDR_PREVCAB (0x01)
792/** Cabinet header flag: cabinet has a successor */
793#define MSCAB_HDR_NEXTCAB (0x02)
794/** Cabinet header flag: cabinet has reserved header space */
795#define MSCAB_HDR_RESV (0x04)
796
797/**
798 * A structure which represents a single folder in a cabinet or cabinet set.
799 *
800 * All fields are READ ONLY.
801 *
802 * A folder is a single compressed stream of data. When uncompressed, it
803 * holds the data of one or more files. A folder may be split across more
804 * than one cabinet.
805 */
806struct mscabd_folder {
807 /**
808 * A pointer to the next folder in this cabinet or cabinet set, or NULL
809 * if this is the final folder.
810 */
811 struct mscabd_folder *next;
812
813 /**
814 * The compression format used by this folder.
815 *
816 * The macro MSCABD_COMP_METHOD() should be used on this field to get
817 * the algorithm used. The macro MSCABD_COMP_LEVEL() should be used to get
818 * the "compression level".
819 *
820 * @see MSCABD_COMP_METHOD(), MSCABD_COMP_LEVEL()
821 */
822 int comp_type;
823
824 /**
825 * The total number of data blocks used by this folder. This includes
826 * data blocks present in other files, if this folder spans more than
827 * one cabinet.
828 */
829 unsigned int num_blocks;
830};
831
832/**
833 * Returns the compression method used by a folder.
834 *
835 * @param comp_type a mscabd_folder::comp_type value
836 * @return one of #MSCAB_COMP_NONE, #MSCAB_COMP_MSZIP, #MSCAB_COMP_QUANTUM
837 * or #MSCAB_COMP_LZX
838 */
839#define MSCABD_COMP_METHOD(comp_type) ((comp_type) & 0x0F)
840/**
841 * Returns the compression level used by a folder.
842 *
843 * @param comp_type a mscabd_folder::comp_type value
844 * @return the compression level. This is only defined by LZX and Quantum
845 * compression
846 */
847#define MSCABD_COMP_LEVEL(comp_type) (((comp_type) >> 8) & 0x1F)
848
849/** Compression mode: no compression. */
850#define MSCAB_COMP_NONE (0)
851/** Compression mode: MSZIP (deflate) compression. */
852#define MSCAB_COMP_MSZIP (1)
853/** Compression mode: Quantum compression */
854#define MSCAB_COMP_QUANTUM (2)
855/** Compression mode: LZX compression */
856#define MSCAB_COMP_LZX (3)
857
858/**
859 * A structure which represents a single file in a cabinet or cabinet set.
860 *
861 * All fields are READ ONLY.
862 */
863struct mscabd_file {
864 /**
865 * The next file in the cabinet or cabinet set, or NULL if this is the
866 * final file.
867 */
868 struct mscabd_file *next;
869
870 /**
871 * The filename of the file.
872 *
873 * A null terminated string of up to 255 bytes in length, it may be in
874 * either ISO-8859-1 or UTF8 format, depending on the file attributes.
875 *
876 * @see attribs
877 */
878 char *filename;
879
880 /** The uncompressed length of the file, in bytes. */
881 unsigned int length;
882
883 /**
884 * File attributes.
885 *
886 * The following attributes are defined:
887 * - #MSCAB_ATTRIB_RDONLY indicates the file is write protected.
888 * - #MSCAB_ATTRIB_HIDDEN indicates the file is hidden.
889 * - #MSCAB_ATTRIB_SYSTEM indicates the file is a operating system file.
890 * - #MSCAB_ATTRIB_ARCH indicates the file is "archived".
891 * - #MSCAB_ATTRIB_EXEC indicates the file is an executable program.
892 * - #MSCAB_ATTRIB_UTF_NAME indicates the filename is in UTF8 format rather
893 * than ISO-8859-1.
894 */
895 int attribs;
896
897 /** File's last modified time, hour field. */
898 char time_h;
899 /** File's last modified time, minute field. */
900 char time_m;
901 /** File's last modified time, second field. */
902 char time_s;
903
904 /** File's last modified date, day field. */
905 char date_d;
906 /** File's last modified date, month field. */
907 char date_m;
908 /** File's last modified date, year field. */
909 int date_y;
910
911 /** A pointer to the folder that contains this file. */
912 struct mscabd_folder *folder;
913
914 /** The uncompressed offset of this file in its folder. */
915 unsigned int offset;
916};
917
918/** mscabd_file::attribs attribute: file is read-only. */
919#define MSCAB_ATTRIB_RDONLY (0x01)
920/** mscabd_file::attribs attribute: file is hidden. */
921#define MSCAB_ATTRIB_HIDDEN (0x02)
922/** mscabd_file::attribs attribute: file is an operating system file. */
923#define MSCAB_ATTRIB_SYSTEM (0x04)
924/** mscabd_file::attribs attribute: file is "archived". */
925#define MSCAB_ATTRIB_ARCH (0x20)
926/** mscabd_file::attribs attribute: file is an executable program. */
927#define MSCAB_ATTRIB_EXEC (0x40)
928/** mscabd_file::attribs attribute: filename is UTF8, not ISO-8859-1. */
929#define MSCAB_ATTRIB_UTF_NAME (0x80)
930
931/** mscab_decompressor::set_param() parameter: search buffer size. */
932#define MSCABD_PARAM_SEARCHBUF (0)
933/** mscab_decompressor::set_param() parameter: repair MS-ZIP streams? */
934#define MSCABD_PARAM_FIXMSZIP (1)
935/** mscab_decompressor::set_param() parameter: size of decompression buffer */
936#define MSCABD_PARAM_DECOMPBUF (2)
937/** mscab_decompressor::set_param() parameter: salvage data from bad cabinets?
938 * If enabled, open() will skip file with bad folder indices or filenames
939 * rather than reject the whole cabinet, and extract() will limit rather than
940 * reject files with invalid offsets and lengths, and bad data block checksums
941 * will be ignored. Available only in CAB decoder version 2 and above.
942 */
943#define MSCABD_PARAM_SALVAGE (3)
944
945/** TODO */
946struct mscab_compressor {
947 int dummy;
948};
949
950/**
951 * A decompressor for .CAB (Microsoft Cabinet) files
952 *
953 * All fields are READ ONLY.
954 *
955 * @see mspack_create_cab_decompressor(), mspack_destroy_cab_decompressor()
956 */
957struct mscab_decompressor {
958 /**
959 * Opens a cabinet file and reads its contents.
960 *
961 * If the file opened is a valid cabinet file, all headers will be read
962 * and a mscabd_cabinet structure will be returned, with a full list of
963 * folders and files.
964 *
965 * In the case of an error occuring, NULL is returned and the error code
966 * is available from last_error().
967 *
968 * The filename pointer should be considered "in use" until close() is
969 * called on the cabinet.
970 *
971 * @param self a self-referential pointer to the mscab_decompressor
972 * instance being called
973 * @param filename the filename of the cabinet file. This is passed
974 * directly to mspack_system::open().
975 * @return a pointer to a mscabd_cabinet structure, or NULL on failure
976 * @see close(), search(), last_error()
977 */
978 struct mscabd_cabinet * (*open) (struct mscab_decompressor *self,
979 const char *filename);
980
981 /**
982 * Closes a previously opened cabinet or cabinet set.
983 *
984 * This closes a cabinet, all cabinets associated with it via the
985 * mscabd_cabinet::next, mscabd_cabinet::prevcab and
986 * mscabd_cabinet::nextcab pointers, and all folders and files. All
987 * memory used by these entities is freed.
988 *
989 * The cabinet pointer is now invalid and cannot be used again. All
990 * mscabd_folder and mscabd_file pointers from that cabinet or cabinet
991 * set are also now invalid, and cannot be used again.
992 *
993 * If the cabinet pointer given was created using search(), it MUST be
994 * the cabinet pointer returned by search() and not one of the later
995 * cabinet pointers further along the mscabd_cabinet::next chain.
996
997 * If extra cabinets have been added using append() or prepend(), these
998 * will all be freed, even if the cabinet pointer given is not the first
999 * cabinet in the set. Do NOT close() more than one cabinet in the set.
1000 *
1001 * The mscabd_cabinet::filename is not freed by the library, as it is
1002 * not allocated by the library. The caller should free this itself if
1003 * necessary, before it is lost forever.
1004 *
1005 * @param self a self-referential pointer to the mscab_decompressor
1006 * instance being called
1007 * @param cab the cabinet to close
1008 * @see open(), search(), append(), prepend()
1009 */
1010 void (*close)(struct mscab_decompressor *self,
1011 struct mscabd_cabinet *cab);
1012
1013 /**
1014 * Searches a regular file for embedded cabinets.
1015 *
1016 * This opens a normal file with the given filename and will search the
1017 * entire file for embedded cabinet files
1018 *
1019 * If any cabinets are found, the equivalent of open() is called on each
1020 * potential cabinet file at the offset it was found. All successfully
1021 * open()ed cabinets are kept in a list.
1022 *
1023 * The first cabinet found will be returned directly as the result of
1024 * this method. Any further cabinets found will be chained in a list
1025 * using the mscabd_cabinet::next field.
1026 *
1027 * In the case of an error occuring anywhere other than the simulated
1028 * open(), NULL is returned and the error code is available from
1029 * last_error().
1030 *
1031 * If no error occurs, but no cabinets can be found in the file, NULL is
1032 * returned and last_error() returns MSPACK_ERR_OK.
1033 *
1034 * The filename pointer should be considered in use until close() is
1035 * called on the cabinet.
1036 *
1037 * close() should only be called on the result of search(), not on any
1038 * subsequent cabinets in the mscabd_cabinet::next chain.
1039 *
1040 * @param self a self-referential pointer to the mscab_decompressor
1041 * instance being called
1042 * @param filename the filename of the file to search for cabinets. This
1043 * is passed directly to mspack_system::open().
1044 * @return a pointer to a mscabd_cabinet structure, or NULL
1045 * @see close(), open(), last_error()
1046 */
1047 struct mscabd_cabinet * (*search) (struct mscab_decompressor *self,
1048 const char *filename);
1049
1050 /**
1051 * Appends one mscabd_cabinet to another, forming or extending a cabinet
1052 * set.
1053 *
1054 * This will attempt to append one cabinet to another such that
1055 * <tt>(cab->nextcab == nextcab) && (nextcab->prevcab == cab)</tt> and
1056 * any folders split between the two cabinets are merged.
1057 *
1058 * The cabinets MUST be part of a cabinet set -- a cabinet set is a
1059 * cabinet that spans more than one physical cabinet file on disk -- and
1060 * must be appropriately matched.
1061 *
1062 * It can be determined if a cabinet has further parts to load by
1063 * examining the mscabd_cabinet::flags field:
1064 *
1065 * - if <tt>(flags & MSCAB_HDR_PREVCAB)</tt> is non-zero, there is a
1066 * predecessor cabinet to open() and prepend(). Its MS-DOS
1067 * case-insensitive filename is mscabd_cabinet::prevname
1068 * - if <tt>(flags & MSCAB_HDR_NEXTCAB)</tt> is non-zero, there is a
1069 * successor cabinet to open() and append(). Its MS-DOS case-insensitive
1070 * filename is mscabd_cabinet::nextname
1071 *
1072 * If the cabinets do not match, an error code will be returned. Neither
1073 * cabinet has been altered, and both should be closed seperately.
1074 *
1075 * Files and folders in a cabinet set are a single entity. All cabinets
1076 * in a set use the same file list, which is updated as cabinets in the
1077 * set are added. All pointers to mscabd_folder and mscabd_file
1078 * structures in either cabinet must be discarded and re-obtained after
1079 * merging.
1080 *
1081 * @param self a self-referential pointer to the mscab_decompressor
1082 * instance being called
1083 * @param cab the cabinet which will be appended to,
1084 * predecessor of nextcab
1085 * @param nextcab the cabinet which will be appended,
1086 * successor of cab
1087 * @return an error code, or MSPACK_ERR_OK if successful
1088 * @see prepend(), open(), close()
1089 */
1090 int (*append) (struct mscab_decompressor *self,
1091 struct mscabd_cabinet *cab,
1092 struct mscabd_cabinet *nextcab);
1093
1094 /**
1095 * Prepends one mscabd_cabinet to another, forming or extending a
1096 * cabinet set.
1097 *
1098 * This will attempt to prepend one cabinet to another, such that
1099 * <tt>(cab->prevcab == prevcab) && (prevcab->nextcab == cab)</tt>. In
1100 * all other respects, it is identical to append(). See append() for the
1101 * full documentation.
1102 *
1103 * @param self a self-referential pointer to the mscab_decompressor
1104 * instance being called
1105 * @param cab the cabinet which will be prepended to,
1106 * successor of prevcab
1107 * @param prevcab the cabinet which will be prepended,
1108 * predecessor of cab
1109 * @return an error code, or MSPACK_ERR_OK if successful
1110 * @see append(), open(), close()
1111 */
1112 int (*prepend) (struct mscab_decompressor *self,
1113 struct mscabd_cabinet *cab,
1114 struct mscabd_cabinet *prevcab);
1115
1116 /**
1117 * Extracts a file from a cabinet or cabinet set.
1118 *
1119 * This extracts a compressed file in a cabinet and writes it to the given
1120 * filename.
1121 *
1122 * The MS-DOS filename of the file, mscabd_file::filename, is NOT USED
1123 * by extract(). The caller must examine this MS-DOS filename, copy and
1124 * change it as necessary, create directories as necessary, and provide
1125 * the correct filename as a parameter, which will be passed unchanged
1126 * to the decompressor's mspack_system::open()
1127 *
1128 * If the file belongs to a split folder in a multi-part cabinet set,
1129 * and not enough parts of the cabinet set have been loaded and appended
1130 * or prepended, an error will be returned immediately.
1131 *
1132 * @param self a self-referential pointer to the mscab_decompressor
1133 * instance being called
1134 * @param file the file to be decompressed
1135 * @param filename the filename of the file being written to
1136 * @return an error code, or MSPACK_ERR_OK if successful
1137 */
1138 int (*extract)(struct mscab_decompressor *self,
1139 struct mscabd_file *file,
1140 const char *filename);
1141
1142 /**
1143 * Sets a CAB decompression engine parameter.
1144 *
1145 * The following parameters are defined:
1146 * - #MSCABD_PARAM_SEARCHBUF: How many bytes should be allocated as a
1147 * buffer when using search()? The minimum value is 4. The default
1148 * value is 32768.
1149 * - #MSCABD_PARAM_FIXMSZIP: If non-zero, extract() will ignore bad
1150 * checksums and recover from decompression errors in MS-ZIP
1151 * compressed folders. The default value is 0 (don't recover).
1152 * - #MSCABD_PARAM_DECOMPBUF: How many bytes should be used as an input
1153 * bit buffer by decompressors? The minimum value is 4. The default
1154 * value is 4096.
1155 *
1156 * @param self a self-referential pointer to the mscab_decompressor
1157 * instance being called
1158 * @param param the parameter to set
1159 * @param value the value to set the parameter to
1160 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there
1161 * is a problem with either parameter or value.
1162 * @see search(), extract()
1163 */
1164 int (*set_param)(struct mscab_decompressor *self,
1165 int param,
1166 int value);
1167
1168 /**
1169 * Returns the error code set by the most recently called method.
1170 *
1171 * This is useful for open() and search(), which do not return an error
1172 * code directly.
1173 *
1174 * @param self a self-referential pointer to the mscab_decompressor
1175 * instance being called
1176 * @return the most recent error code
1177 * @see open(), search()
1178 */
1179 int (*last_error)(struct mscab_decompressor *self);
1180};
1181
1182/* --- support for .CHM (HTMLHelp) file format ----------------------------- */
1183
1184/**
1185 * A structure which represents a file to be placed in a CHM helpfile.
1186 *
1187 * A contiguous array of these structures should be passed to
1188 * mschm_compressor::generate(). The array list is terminated with an
1189 * entry whose mschmc_file::section field is set to #MSCHMC_ENDLIST, the
1190 * other fields in this entry are ignored.
1191 */
1192struct mschmc_file {
1193 /** One of #MSCHMC_ENDLIST, #MSCHMC_UNCOMP or #MSCHMC_MSCOMP. */
1194 int section;
1195
1196 /** The filename of the source file that will be added to the CHM. This
1197 * is passed directly to mspack_system::open(). */
1198 const char *filename;
1199
1200 /** The full path and filename of the file within the CHM helpfile, a
1201 * UTF-1 encoded null-terminated string. */
1202 char *chm_filename;
1203
1204 /** The length of the file, in bytes. This will be adhered to strictly
1205 * and a read error will be issued if this many bytes cannot be read
1206 * from the real file at CHM generation time. */
1207 off_t length;
1208};
1209
1210/**
1211 * A structure which represents a section of a CHM helpfile.
1212 *
1213 * All fields are READ ONLY.
1214 *
1215 * Not used directly, but used as a generic base type for
1216 * mschmd_sec_uncompressed and mschmd_sec_mscompressed.
1217 */
1218struct mschmd_section {
1219 /** A pointer to the CHM helpfile that contains this section. */
1220 struct mschmd_header *chm;
1221
1222 /**
1223 * The section ID. Either 0 for the uncompressed section
1224 * mschmd_sec_uncompressed, or 1 for the LZX compressed section
1225 * mschmd_sec_mscompressed. No other section IDs are known.
1226 */
1227 unsigned int id;
1228};
1229
1230/**
1231 * A structure which represents the uncompressed section of a CHM helpfile.
1232 *
1233 * All fields are READ ONLY.
1234 */
1235struct mschmd_sec_uncompressed {
1236 /** Generic section data. */
1237 struct mschmd_section base;
1238
1239 /** The file offset of where this section begins in the CHM helpfile. */
1240 off_t offset;
1241};
1242
1243/**
1244 * A structure which represents the LZX compressed section of a CHM helpfile.
1245 *
1246 * All fields are READ ONLY.
1247 */
1248struct mschmd_sec_mscompressed {
1249 /** Generic section data. */
1250 struct mschmd_section base;
1251
1252 /** A pointer to the meta-file which represents all LZX compressed data. */
1253 struct mschmd_file *content;
1254
1255 /** A pointer to the file which contains the LZX control data. */
1256 struct mschmd_file *control;
1257
1258 /** A pointer to the file which contains the LZX reset table. */
1259 struct mschmd_file *rtable;
1260
1261 /** A pointer to the file which contains the LZX span information.
1262 * Available only in CHM decoder version 2 and above.
1263 */
1264 struct mschmd_file *spaninfo;
1265};
1266
1267/**
1268 * A structure which represents a CHM helpfile.
1269 *
1270 * All fields are READ ONLY.
1271 */
1272struct mschmd_header {
1273 /** The version of the CHM file format used in this file. */
1274 unsigned int version;
1275
1276 /**
1277 * The "timestamp" of the CHM helpfile.
1278 *
1279 * It is the lower 32 bits of a 64-bit value representing the number of
1280 * centiseconds since 1601-01-01 00:00:00 UTC, plus 42. It is not useful
1281 * as a timestamp, but it is useful as a semi-unique ID.
1282 */
1283 unsigned int timestamp;
1284
1285 /**
1286 * The default Language and Country ID (LCID) of the user who ran the
1287 * HTMLHelp Compiler. This is not the language of the CHM file itself.
1288 */
1289 unsigned int language;
1290
1291 /**
1292 * The filename of the CHM helpfile. This is given by the library user
1293 * and may be in any format.
1294 */
1295 const char *filename;
1296
1297 /** The length of the CHM helpfile, in bytes. */
1298 off_t length;
1299
1300 /** A list of all non-system files in the CHM helpfile. */
1301 struct mschmd_file *files;
1302
1303 /**
1304 * A list of all system files in the CHM helpfile.
1305 *
1306 * System files are files which begin with "::". They are meta-files
1307 * generated by the CHM creation process.
1308 */
1309 struct mschmd_file *sysfiles;
1310
1311 /** The section 0 (uncompressed) data in this CHM helpfile. */
1312 struct mschmd_sec_uncompressed sec0;
1313
1314 /** The section 1 (MSCompressed) data in this CHM helpfile. */
1315 struct mschmd_sec_mscompressed sec1;
1316
1317 /** The file offset of the first PMGL/PMGI directory chunk. */
1318 off_t dir_offset;
1319
1320 /** The number of PMGL/PMGI directory chunks in this CHM helpfile. */
1321 unsigned int num_chunks;
1322
1323 /** The size of each PMGL/PMGI chunk, in bytes. */
1324 unsigned int chunk_size;
1325
1326 /** The "density" of the quick-reference section in PMGL/PMGI chunks. */
1327 unsigned int density;
1328
1329 /** The depth of the index tree.
1330 *
1331 * - if 1, there are no PMGI chunks, only PMGL chunks.
1332 * - if 2, there is 1 PMGI chunk. All chunk indices point to PMGL chunks.
1333 * - if 3, the root PMGI chunk points to secondary PMGI chunks, which in
1334 * turn point to PMGL chunks.
1335 * - and so on...
1336 */
1337 unsigned int depth;
1338
1339 /**
1340 * The number of the root PMGI chunk.
1341 *
1342 * If there is no index in the CHM helpfile, this will be 0xFFFFFFFF.
1343 */
1344 unsigned int index_root;
1345
1346 /**
1347 * The number of the first PMGL chunk. Usually zero.
1348 * Available only in CHM decoder version 2 and above.
1349 */
1350 unsigned int first_pmgl;
1351
1352 /**
1353 * The number of the last PMGL chunk. Usually num_chunks-1.
1354 * Available only in CHM decoder version 2 and above.
1355 */
1356 unsigned int last_pmgl;
1357
1358 /**
1359 * A cache of loaded chunks, filled in by mschm_decoder::fast_find().
1360 * Available only in CHM decoder version 2 and above.
1361 */
1362 unsigned char **chunk_cache;
1363};
1364
1365/**
1366 * A structure which represents a file stored in a CHM helpfile.
1367 *
1368 * All fields are READ ONLY.
1369 */
1370struct mschmd_file {
1371 /**
1372 * A pointer to the next file in the list, or NULL if this is the final
1373 * file.
1374 */
1375 struct mschmd_file *next;
1376
1377 /**
1378 * A pointer to the section that this file is located in. Indirectly,
1379 * it also points to the CHM helpfile the file is located in.
1380 */
1381 struct mschmd_section *section;
1382
1383 /** The offset within the section data that this file is located at. */
1384 off_t offset;
1385
1386 /** The length of this file, in bytes */
1387 off_t length;
1388
1389 /** The filename of this file -- a null terminated string in UTF-8. */
1390 char *filename;
1391};
1392
1393/** mschmc_file::section value: end of CHM file list */
1394#define MSCHMC_ENDLIST (0)
1395/** mschmc_file::section value: this file is in the Uncompressed section */
1396#define MSCHMC_UNCOMP (1)
1397/** mschmc_file::section value: this file is in the MSCompressed section */
1398#define MSCHMC_MSCOMP (2)
1399
1400/** mschm_compressor::set_param() parameter: "timestamp" header */
1401#define MSCHMC_PARAM_TIMESTAMP (0)
1402/** mschm_compressor::set_param() parameter: "language" header */
1403#define MSCHMC_PARAM_LANGUAGE (1)
1404/** mschm_compressor::set_param() parameter: LZX window size */
1405#define MSCHMC_PARAM_LZXWINDOW (2)
1406/** mschm_compressor::set_param() parameter: intra-chunk quickref density */
1407#define MSCHMC_PARAM_DENSITY (3)
1408/** mschm_compressor::set_param() parameter: whether to create indices */
1409#define MSCHMC_PARAM_INDEX (4)
1410
1411/**
1412 * A compressor for .CHM (Microsoft HTMLHelp) files.
1413 *
1414 * All fields are READ ONLY.
1415 *
1416 * @see mspack_create_chm_compressor(), mspack_destroy_chm_compressor()
1417 */
1418struct mschm_compressor {
1419 /**
1420 * Generates a CHM help file.
1421 *
1422 * The help file will contain up to two sections, an Uncompressed
1423 * section and potentially an MSCompressed (LZX compressed)
1424 * section.
1425 *
1426 * While the contents listing of a CHM file is always in lexical order,
1427 * the file list passed in will be taken as the correct order for files
1428 * within the sections. It is in your interest to place similar files
1429 * together for better compression.
1430 *
1431 * There are two modes of generation, to use a temporary file or not to
1432 * use one. See use_temporary_file() for the behaviour of generate() in
1433 * these two different modes.
1434 *
1435 * @param self a self-referential pointer to the mschm_compressor
1436 * instance being called
1437 * @param file_list an array of mschmc_file structures, terminated
1438 * with an entry whose mschmc_file::section field is
1439 * #MSCHMC_ENDLIST. The order of the list is
1440 * preserved within each section. The length of any
1441 * mschmc_file::chm_filename string cannot exceed
1442 * roughly 4096 bytes. Each source file must be able
1443 * to supply as many bytes as given in the
1444 * mschmc_file::length field.
1445 * @param output_file the file to write the generated CHM helpfile to.
1446 * This is passed directly to mspack_system::open()
1447 * @return an error code, or MSPACK_ERR_OK if successful
1448 * @see use_temporary_file() set_param()
1449 */
1450 int (*generate)(struct mschm_compressor *self,
1451 struct mschmc_file file_list[],
1452 const char *output_file);
1453
1454 /**
1455 * Specifies whether a temporary file is used during CHM generation.
1456 *
1457 * The CHM file format includes data about the compressed section (such
1458 * as its overall size) that is stored in the output CHM file prior to
1459 * the compressed section itself. This unavoidably requires that the
1460 * compressed section has to be generated, before these details can be
1461 * set. There are several ways this can be handled. Firstly, the
1462 * compressed section could be generated entirely in memory before
1463 * writing any of the output CHM file. This approach is not used in
1464 * libmspack, as the compressed section can exceed the addressable
1465 * memory space on most architectures.
1466 *
1467 * libmspack has two options, either to write these unknowable sections
1468 * with blank data, generate the compressed section, then re-open the
1469 * output file for update once the compressed section has been
1470 * completed, or to write the compressed section to a temporary file,
1471 * then write the entire output file at once, performing a simple
1472 * file-to-file copy for the compressed section.
1473 *
1474 * The simple solution of buffering the entire compressed section in
1475 * memory can still be used, if desired. As the temporary file's
1476 * filename is passed directly to mspack_system::open(), it is possible
1477 * for a custom mspack_system implementation to hold this file in memory,
1478 * without writing to a disk.
1479 *
1480 * If a temporary file is set, generate() performs the following
1481 * sequence of events: the temporary file is opened for writing, the
1482 * compression algorithm writes to the temporary file, the temporary
1483 * file is closed. Then the output file is opened for writing and the
1484 * temporary file is re-opened for reading. The output file is written
1485 * and the temporary file is read from. Both files are then closed. The
1486 * temporary file itself is not deleted. If that is desired, the
1487 * temporary file should be deleted after the completion of generate(),
1488 * if it exists.
1489 *
1490 * If a temporary file is set not to be used, generate() performs the
1491 * following sequence of events: the output file is opened for writing,
1492 * then it is written and closed. The output file is then re-opened for
1493 * update, the appropriate sections are seek()ed to and re-written, then
1494 * the output file is closed.
1495 *
1496 * @param self a self-referential pointer to the
1497 * mschm_compressor instance being called
1498 * @param use_temp_file non-zero if the temporary file should be used,
1499 * zero if the temporary file should not be used.
1500 * @param temp_file a file to temporarily write compressed data to,
1501 * before opening it for reading and copying the
1502 * contents to the output file. This is passed
1503 * directly to mspack_system::open().
1504 * @return an error code, or MSPACK_ERR_OK if successful
1505 * @see generate()
1506 */
1507 int (*use_temporary_file)(struct mschm_compressor *self,
1508 int use_temp_file,
1509 const char *temp_file);
1510 /**
1511 * Sets a CHM compression engine parameter.
1512 *
1513 * The following parameters are defined:
1514
1515 * - #MSCHMC_PARAM_TIMESTAMP: Sets the "timestamp" of the CHM file
1516 * generated. This is not a timestamp, see mschmd_header::timestamp
1517 * for a description. If this timestamp is 0, generate() will use its
1518 * own algorithm for making a unique ID, based on the lengths and
1519 * names of files in the CHM itself. Defaults to 0, any value between
1520 * 0 and (2^32)-1 is valid.
1521 * - #MSCHMC_PARAM_LANGUAGE: Sets the "language" of the CHM file
1522 * generated. This is not the language used in the CHM file, but the
1523 * language setting of the user who ran the HTMLHelp compiler. It
1524 * defaults to 0x0409. The valid range is between 0x0000 and 0x7F7F.
1525 * - #MSCHMC_PARAM_LZXWINDOW: Sets the size of the LZX history window,
1526 * which is also the interval at which the compressed data stream can be
1527 * randomly accessed. The value is not a size in bytes, but a power of
1528 * two. The default value is 16 (which makes the window 2^16 bytes, or
1529 * 64 kilobytes), the valid range is from 15 (32 kilobytes) to 21 (2
1530 * megabytes).
1531 * - #MSCHMC_PARAM_DENSITY: Sets the "density" of quick reference
1532 * entries stored at the end of directory listing chunk. Each chunk is
1533 * 4096 bytes in size, and contains as many file entries as there is
1534 * room for. At the other end of the chunk, a list of "quick reference"
1535 * pointers is included. The offset of every 'N'th file entry is given a
1536 * quick reference, where N = (2^density) + 1. The default density is
1537 * 2. The smallest density is 0 (N=2), the maximum is 10 (N=1025). As
1538 * each file entry requires at least 5 bytes, the maximum number of
1539 * entries in a single chunk is roughly 800, so the maximum value 10
1540 * can be used to indicate there are no quickrefs at all.
1541 * - #MSCHMC_PARAM_INDEX: Sets whether or not to include quick lookup
1542 * index chunk(s), in addition to normal directory listing chunks. A
1543 * value of zero means no index chunks will be created, a non-zero value
1544 * means index chunks will be created. The default is zero, "don't
1545 * create an index".
1546 *
1547 * @param self a self-referential pointer to the mschm_compressor
1548 * instance being called
1549 * @param param the parameter to set
1550 * @param value the value to set the parameter to
1551 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there
1552 * is a problem with either parameter or value.
1553 * @see generate()
1554 */
1555 int (*set_param)(struct mschm_compressor *self,
1556 int param,
1557 int value);
1558
1559 /**
1560 * Returns the error code set by the most recently called method.
1561 *
1562 * @param self a self-referential pointer to the mschm_compressor
1563 * instance being called
1564 * @return the most recent error code
1565 * @see set_param(), generate()
1566 */
1567 int (*last_error)(struct mschm_compressor *self);
1568};
1569
1570/**
1571 * A decompressor for .CHM (Microsoft HTMLHelp) files
1572 *
1573 * All fields are READ ONLY.
1574 *
1575 * @see mspack_create_chm_decompressor(), mspack_destroy_chm_decompressor()
1576 */
1577struct mschm_decompressor {
1578 /**
1579 * Opens a CHM helpfile and reads its contents.
1580 *
1581 * If the file opened is a valid CHM helpfile, all headers will be read
1582 * and a mschmd_header structure will be returned, with a full list of
1583 * files.
1584 *
1585 * In the case of an error occuring, NULL is returned and the error code
1586 * is available from last_error().
1587 *
1588 * The filename pointer should be considered "in use" until close() is
1589 * called on the CHM helpfile.
1590 *
1591 * @param self a self-referential pointer to the mschm_decompressor
1592 * instance being called
1593 * @param filename the filename of the CHM helpfile. This is passed
1594 * directly to mspack_system::open().
1595 * @return a pointer to a mschmd_header structure, or NULL on failure
1596 * @see close()
1597 */
1598 struct mschmd_header *(*open)(struct mschm_decompressor *self,
1599 const char *filename);
1600
1601 /**
1602 * Closes a previously opened CHM helpfile.
1603 *
1604 * This closes a CHM helpfile, frees the mschmd_header and all
1605 * mschmd_file structures associated with it (if any). This works on
1606 * both helpfiles opened with open() and helpfiles opened with
1607 * fast_open().
1608 *
1609 * The CHM header pointer is now invalid and cannot be used again. All
1610 * mschmd_file pointers referencing that CHM are also now invalid, and
1611 * cannot be used again.
1612 *
1613 * @param self a self-referential pointer to the mschm_decompressor
1614 * instance being called
1615 * @param chm the CHM helpfile to close
1616 * @see open(), fast_open()
1617 */
1618 void (*close)(struct mschm_decompressor *self,
1619 struct mschmd_header *chm);
1620
1621 /**
1622 * Extracts a file from a CHM helpfile.
1623 *
1624 * This extracts a file from a CHM helpfile and writes it to the given
1625 * filename. The filename of the file, mscabd_file::filename, is not
1626 * used by extract(), but can be used by the caller as a guide for
1627 * constructing an appropriate filename.
1628 *
1629 * This method works both with files found in the mschmd_header::files
1630 * and mschmd_header::sysfiles list and mschmd_file structures generated
1631 * on the fly by fast_find().
1632 *
1633 * @param self a self-referential pointer to the mschm_decompressor
1634 * instance being called
1635 * @param file the file to be decompressed
1636 * @param filename the filename of the file being written to
1637 * @return an error code, or MSPACK_ERR_OK if successful
1638 */
1639 int (*extract)(struct mschm_decompressor *self,
1640 struct mschmd_file *file,
1641 const char *filename);
1642
1643 /**
1644 * Returns the error code set by the most recently called method.
1645 *
1646 * This is useful for open() and fast_open(), which do not return an
1647 * error code directly.
1648 *
1649 * @param self a self-referential pointer to the mschm_decompressor
1650 * instance being called
1651 * @return the most recent error code
1652 * @see open(), extract()
1653 */
1654 int (*last_error)(struct mschm_decompressor *self);
1655
1656 /**
1657 * Opens a CHM helpfile quickly.
1658 *
1659 * If the file opened is a valid CHM helpfile, only essential headers
1660 * will be read. A mschmd_header structure will be still be returned, as
1661 * with open(), but the mschmd_header::files field will be NULL. No
1662 * files details will be automatically read. The fast_find() method
1663 * must be used to obtain file details.
1664 *
1665 * In the case of an error occuring, NULL is returned and the error code
1666 * is available from last_error().
1667 *
1668 * The filename pointer should be considered "in use" until close() is
1669 * called on the CHM helpfile.
1670 *
1671 * @param self a self-referential pointer to the mschm_decompressor
1672 * instance being called
1673 * @param filename the filename of the CHM helpfile. This is passed
1674 * directly to mspack_system::open().
1675 * @return a pointer to a mschmd_header structure, or NULL on failure
1676 * @see open(), close(), fast_find(), extract()
1677 */
1678 struct mschmd_header *(*fast_open)(struct mschm_decompressor *self,
1679 const char *filename);
1680
1681 /**
1682 * Finds file details quickly.
1683 *
1684 * Instead of reading all CHM helpfile headers and building a list of
1685 * files, fast_open() and fast_find() are intended for finding file
1686 * details only when they are needed. The CHM file format includes an
1687 * on-disk file index to allow this.
1688 *
1689 * Given a case-sensitive filename, fast_find() will search the on-disk
1690 * index for that file.
1691 *
1692 * If the file was found, the caller-provided mschmd_file structure will
1693 * be filled out like so:
1694 * - section: the correct value for the found file
1695 * - offset: the correct value for the found file
1696 * - length: the correct value for the found file
1697 * - all other structure elements: NULL or 0
1698 *
1699 * If the file was not found, MSPACK_ERR_OK will still be returned as the
1700 * result, but the caller-provided structure will be filled out like so:
1701 * - section: NULL
1702 * - offset: 0
1703 * - length: 0
1704 * - all other structure elements: NULL or 0
1705 *
1706 * This method is intended to be used in conjunction with CHM helpfiles
1707 * opened with fast_open(), but it also works with helpfiles opened
1708 * using the regular open().
1709 *
1710 * @param self a self-referential pointer to the mschm_decompressor
1711 * instance being called
1712 * @param chm the CHM helpfile to search for the file
1713 * @param filename the filename of the file to search for
1714 * @param f_ptr a pointer to a caller-provded mschmd_file structure
1715 * @param f_size <tt>sizeof(struct mschmd_file)</tt>
1716 * @return an error code, or MSPACK_ERR_OK if successful
1717 * @see open(), close(), fast_find(), extract()
1718 */
1719 int (*fast_find)(struct mschm_decompressor *self,
1720 struct mschmd_header *chm,
1721 const char *filename,
1722 struct mschmd_file *f_ptr,
1723 int f_size);
1724};
1725
1726/* --- support for .LIT (EBook) file format -------------------------------- */
1727
1728/** TODO */
1729struct mslit_compressor {
1730 int dummy;
1731};
1732
1733/** TODO */
1734struct mslit_decompressor {
1735 int dummy;
1736};
1737
1738
1739/* --- support for .HLP (MS Help) file format ------------------------------ */
1740
1741/** TODO */
1742struct mshlp_compressor {
1743 int dummy;
1744};
1745
1746/** TODO */
1747struct mshlp_decompressor {
1748 int dummy;
1749};
1750
1751
1752/* --- support for SZDD file format ---------------------------------------- */
1753
1754/** msszdd_compressor::set_param() parameter: the missing character */
1755#define MSSZDDC_PARAM_MISSINGCHAR (0)
1756
1757/** msszddd_header::format value - a regular SZDD file */
1758#define MSSZDD_FMT_NORMAL (0)
1759
1760/** msszddd_header::format value - a special QBasic SZDD file */
1761#define MSSZDD_FMT_QBASIC (1)
1762
1763/**
1764 * A structure which represents an SZDD compressed file.
1765 *
1766 * All fields are READ ONLY.
1767 */
1768struct msszddd_header {
1769 /** The file format; either #MSSZDD_FMT_NORMAL or #MSSZDD_FMT_QBASIC */
1770 int format;
1771
1772 /** The amount of data in the SZDD file once uncompressed. */
1773 off_t length;
1774
1775 /**
1776 * The last character in the filename, traditionally replaced with an
1777 * underscore to show the file is compressed. The null character is used
1778 * to show that this character has not been stored (e.g. because the
1779 * filename is not known). Generally, only characters that may appear in
1780 * an MS-DOS filename (except ".") are valid.
1781 */
1782 char missing_char;
1783};
1784
1785/**
1786 * A compressor for the SZDD file format.
1787 *
1788 * All fields are READ ONLY.
1789 *
1790 * @see mspack_create_szdd_compressor(), mspack_destroy_szdd_compressor()
1791 */
1792struct msszdd_compressor {
1793 /**
1794 * Reads an input file and creates a compressed output file in the
1795 * SZDD compressed file format. The SZDD compression format is quick
1796 * but gives poor compression. It is possible for the compressed output
1797 * file to be larger than the input file.
1798 *
1799 * Conventionally, SZDD compressed files have the final character in
1800 * their filename replaced with an underscore, to show they are
1801 * compressed. The missing character is stored in the compressed file
1802 * itself. This is due to the restricted filename conventions of MS-DOS,
1803 * most operating systems, such as UNIX, simply append another file
1804 * extension to the existing filename. As mspack does not deal with
1805 * filenames, this is left up to you. If you wish to set the missing
1806 * character stored in the file header, use set_param() with the
1807 * #MSSZDDC_PARAM_MISSINGCHAR parameter.
1808 *
1809 * "Stream" compression (where the length of the input data is not
1810 * known) is not possible. The length of the input data is stored in the
1811 * header of the SZDD file and must therefore be known before any data
1812 * is compressed. Due to technical limitations of the file format, the
1813 * maximum size of uncompressed file that will be accepted is 2147483647
1814 * bytes.
1815 *
1816 * @param self a self-referential pointer to the msszdd_compressor
1817 * instance being called
1818 * @param input the name of the file to compressed. This is passed
1819 * passed directly to mspack_system::open()
1820 * @param output the name of the file to write compressed data to.
1821 * This is passed directly to mspack_system::open().
1822 * @param length the length of the uncompressed file, or -1 to indicate
1823 * that this should be determined automatically by using
1824 * mspack_system::seek() on the input file.
1825 * @return an error code, or MSPACK_ERR_OK if successful
1826 * @see set_param()
1827 */
1828 int (*compress)(struct msszdd_compressor *self,
1829 const char *input,
1830 const char *output,
1831 off_t length);
1832
1833 /**
1834 * Sets an SZDD compression engine parameter.
1835 *
1836 * The following parameters are defined:
1837
1838 * - #MSSZDDC_PARAM_CHARACTER: the "missing character", the last character
1839 * in the uncompressed file's filename, which is traditionally replaced
1840 * with an underscore to show the file is compressed. Traditionally,
1841 * this can only be a character that is a valid part of an MS-DOS,
1842 * filename, but libmspack permits any character between 0x00 and 0xFF
1843 * to be stored. 0x00 is the default, and it represents "no character
1844 * stored".
1845 *
1846 * @param self a self-referential pointer to the msszdd_compressor
1847 * instance being called
1848 * @param param the parameter to set
1849 * @param value the value to set the parameter to
1850 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there
1851 * is a problem with either parameter or value.
1852 * @see compress()
1853 */
1854 int (*set_param)(struct msszdd_compressor *self,
1855 int param,
1856 int value);
1857
1858 /**
1859 * Returns the error code set by the most recently called method.
1860 *
1861 * @param self a self-referential pointer to the msszdd_compressor
1862 * instance being called
1863 * @return the most recent error code
1864 * @see compress()
1865 */
1866 int (*last_error)(struct mschm_decompressor *self);
1867};
1868
1869/**
1870 * A decompressor for SZDD compressed files.
1871 *
1872 * All fields are READ ONLY.
1873 *
1874 * @see mspack_create_szdd_decompressor(), mspack_destroy_szdd_decompressor()
1875 */
1876struct msszdd_decompressor {
1877 /**
1878 * Opens a SZDD file and reads the header.
1879 *
1880 * If the file opened is a valid SZDD file, all headers will be read and
1881 * a msszddd_header structure will be returned.
1882 *
1883 * In the case of an error occuring, NULL is returned and the error code
1884 * is available from last_error().
1885 *
1886 * The filename pointer should be considered "in use" until close() is
1887 * called on the SZDD file.
1888 *
1889 * @param self a self-referential pointer to the msszdd_decompressor
1890 * instance being called
1891 * @param filename the filename of the SZDD compressed file. This is
1892 * passed directly to mspack_system::open().
1893 * @return a pointer to a msszddd_header structure, or NULL on failure
1894 * @see close()
1895 */
1896 struct msszddd_header *(*open)(struct msszdd_decompressor *self,
1897 const char *filename);
1898
1899 /**
1900 * Closes a previously opened SZDD file.
1901 *
1902 * This closes a SZDD file and frees the msszddd_header associated with
1903 * it.
1904 *
1905 * The SZDD header pointer is now invalid and cannot be used again.
1906 *
1907 * @param self a self-referential pointer to the msszdd_decompressor
1908 * instance being called
1909 * @param szdd the SZDD file to close
1910 * @see open()
1911 */
1912 void (*close)(struct msszdd_decompressor *self,
1913 struct msszddd_header *szdd);
1914
1915 /**
1916 * Extracts the compressed data from a SZDD file.
1917 *
1918 * This decompresses the compressed SZDD data stream and writes it to
1919 * an output file.
1920 *
1921 * @param self a self-referential pointer to the msszdd_decompressor
1922 * instance being called
1923 * @param szdd the SZDD file to extract data from
1924 * @param filename the filename to write the decompressed data to. This
1925 * is passed directly to mspack_system::open().
1926 * @return an error code, or MSPACK_ERR_OK if successful
1927 */
1928 int (*extract)(struct msszdd_decompressor *self,
1929 struct msszddd_header *szdd,
1930 const char *filename);
1931
1932 /**
1933 * Decompresses an SZDD file to an output file in one step.
1934 *
1935 * This opens an SZDD file as input, reads the header, then decompresses
1936 * the compressed data immediately to an output file, finally closing
1937 * both the input and output file. It is more convenient to use than
1938 * open() then extract() then close(), if you do not need to know the
1939 * SZDD output size or missing character.
1940 *
1941 * @param self a self-referential pointer to the msszdd_decompressor
1942 * instance being called
1943 * @param input the filename of the input SZDD file. This is passed
1944 * directly to mspack_system::open().
1945 * @param output the filename to write the decompressed data to. This
1946 * is passed directly to mspack_system::open().
1947 * @return an error code, or MSPACK_ERR_OK if successful
1948 */
1949 int (*decompress)(struct msszdd_decompressor *self,
1950 const char *input,
1951 const char *output);
1952
1953 /**
1954 * Returns the error code set by the most recently called method.
1955 *
1956 * This is useful for open() which does not return an
1957 * error code directly.
1958 *
1959 * @param self a self-referential pointer to the msszdd_decompressor
1960 * instance being called
1961 * @return the most recent error code
1962 * @see open(), extract(), decompress()
1963 */
1964 int (*last_error)(struct msszdd_decompressor *self);
1965};
1966
1967/* --- support for KWAJ file format ---------------------------------------- */
1968
1969/** mskwaj_compressor::set_param() parameter: compression type */
1970#define MSKWAJC_PARAM_COMP_TYPE (0)
1971
1972/** mskwaj_compressor::set_param() parameter: include the length of the
1973 * uncompressed file in the header?
1974 */
1975#define MSKWAJC_PARAM_INCLUDE_LENGTH (1)
1976
1977/** KWAJ compression type: no compression. */
1978#define MSKWAJ_COMP_NONE (0)
1979/** KWAJ compression type: no compression, 0xFF XOR "encryption". */
1980#define MSKWAJ_COMP_XOR (1)
1981/** KWAJ compression type: LZSS (same method as SZDD) */
1982#define MSKWAJ_COMP_SZDD (2)
1983/** KWAJ compression type: LZ+Huffman compression */
1984#define MSKWAJ_COMP_LZH (3)
1985/** KWAJ compression type: MSZIP */
1986#define MSKWAJ_COMP_MSZIP (4)
1987
1988/** KWAJ optional header flag: decompressed file length is included */
1989#define MSKWAJ_HDR_HASLENGTH (0x01)
1990
1991/** KWAJ optional header flag: unknown 2-byte structure is included */
1992#define MSKWAJ_HDR_HASUNKNOWN1 (0x02)
1993
1994/** KWAJ optional header flag: unknown multi-sized structure is included */
1995#define MSKWAJ_HDR_HASUNKNOWN2 (0x04)
1996
1997/** KWAJ optional header flag: file name (no extension) is included */
1998#define MSKWAJ_HDR_HASFILENAME (0x08)
1999
2000/** KWAJ optional header flag: file extension is included */
2001#define MSKWAJ_HDR_HASFILEEXT (0x10)
2002
2003/** KWAJ optional header flag: extra text is included */
2004#define MSKWAJ_HDR_HASEXTRATEXT (0x20)
2005
2006/**
2007 * A structure which represents an KWAJ compressed file.
2008 *
2009 * All fields are READ ONLY.
2010 */
2011struct mskwajd_header {
2012 /** The compression type; should be one of #MSKWAJ_COMP_NONE,
2013 * #MSKWAJ_COMP_XOR, #MSKWAJ_COMP_SZDD or #MSKWAJ_COMP_LZH
2014 */
2015 unsigned short comp_type;
2016
2017 /** The offset in the file where the compressed data stream begins */
2018 off_t data_offset;
2019
2020 /** Flags indicating which optional headers were included. */
2021 int headers;
2022
2023 /** The amount of uncompressed data in the file, or 0 if not present. */
2024 off_t length;
2025
2026 /** output filename, or NULL if not present */
2027 char *filename;
2028
2029 /** extra uncompressed data (usually text) in the header.
2030 * This data can contain nulls so use extra_length to get the size.
2031 */
2032 char *extra;
2033
2034 /** length of extra uncompressed data in the header */
2035 unsigned short extra_length;
2036};
2037
2038/**
2039 * A compressor for the KWAJ file format.
2040 *
2041 * All fields are READ ONLY.
2042 *
2043 * @see mspack_create_kwaj_compressor(), mspack_destroy_kwaj_compressor()
2044 */
2045struct mskwaj_compressor {
2046 /**
2047 * Reads an input file and creates a compressed output file in the
2048 * KWAJ compressed file format. The KWAJ compression format is quick
2049 * but gives poor compression. It is possible for the compressed output
2050 * file to be larger than the input file.
2051 *
2052 * @param self a self-referential pointer to the mskwaj_compressor
2053 * instance being called
2054 * @param input the name of the file to compressed. This is passed
2055 * passed directly to mspack_system::open()
2056 * @param output the name of the file to write compressed data to.
2057 * This is passed directly to mspack_system::open().
2058 * @param length the length of the uncompressed file, or -1 to indicate
2059 * that this should be determined automatically by using
2060 * mspack_system::seek() on the input file.
2061 * @return an error code, or MSPACK_ERR_OK if successful
2062 * @see set_param()
2063 */
2064 int (*compress)(struct mskwaj_compressor *self,
2065 const char *input,
2066 const char *output,
2067 off_t length);
2068
2069 /**
2070 * Sets an KWAJ compression engine parameter.
2071 *
2072 * The following parameters are defined:
2073 *
2074 * - #MSKWAJC_PARAM_COMP_TYPE: the compression method to use. Must
2075 * be one of #MSKWAJC_COMP_NONE, #MSKWAJC_COMP_XOR, #MSKWAJ_COMP_SZDD
2076 * or #MSKWAJ_COMP_LZH. The default is #MSKWAJ_COMP_LZH.
2077 *
2078 * - #MSKWAJC_PARAM_INCLUDE_LENGTH: a boolean; should the compressed
2079 * output file should include the uncompressed length of the input
2080 * file in the header? This adds 4 bytes to the size of the output
2081 * file. A value of zero says "no", non-zero says "yes". The default
2082 * is "no".
2083 *
2084 * @param self a self-referential pointer to the mskwaj_compressor
2085 * instance being called
2086 * @param param the parameter to set
2087 * @param value the value to set the parameter to
2088 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there
2089 * is a problem with either parameter or value.
2090 * @see generate()
2091 */
2092 int (*set_param)(struct mskwaj_compressor *self,
2093 int param,
2094 int value);
2095
2096
2097 /**
2098 * Sets the original filename of the file before compression,
2099 * which will be stored in the header of the output file.
2100 *
2101 * The filename should be a null-terminated string, it must be an
2102 * MS-DOS "8.3" type filename (up to 8 bytes for the filename, then
2103 * optionally a "." and up to 3 bytes for a filename extension).
2104 *
2105 * If NULL is passed as the filename, no filename is included in the
2106 * header. This is the default.
2107 *
2108 * @param self a self-referential pointer to the mskwaj_compressor
2109 * instance being called
2110 * @param filename the original filename to use
2111 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if the
2112 * filename is too long
2113 */
2114 int (*set_filename)(struct mskwaj_compressor *self,
2115 const char *filename);
2116
2117 /**
2118 * Sets arbitrary data that will be stored in the header of the
2119 * output file, uncompressed. It can be up to roughly 64 kilobytes,
2120 * as the overall size of the header must not exceed 65535 bytes.
2121 * The data can contain null bytes if desired.
2122 *
2123 * If NULL is passed as the data pointer, or zero is passed as the
2124 * length, no extra data is included in the header. This is the
2125 * default.
2126 *
2127 * @param self a self-referential pointer to the mskwaj_compressor
2128 * instance being called
2129 * @param data a pointer to the data to be stored in the header
2130 * @param bytes the length of the data in bytes
2131 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS extra data
2132 * is too long
2133 */
2134 int (*set_extra_data)(struct mskwaj_compressor *self,
2135 void *data,
2136 size_t bytes);
2137
2138 /**
2139 * Returns the error code set by the most recently called method.
2140 *
2141 * @param self a self-referential pointer to the mskwaj_compressor
2142 * instance being called
2143 * @return the most recent error code
2144 * @see compress()
2145 */
2146 int (*last_error)(struct mschm_decompressor *self);
2147};
2148
2149/**
2150 * A decompressor for KWAJ compressed files.
2151 *
2152 * All fields are READ ONLY.
2153 *
2154 * @see mspack_create_kwaj_decompressor(), mspack_destroy_kwaj_decompressor()
2155 */
2156struct mskwaj_decompressor {
2157 /**
2158 * Opens a KWAJ file and reads the header.
2159 *
2160 * If the file opened is a valid KWAJ file, all headers will be read and
2161 * a mskwajd_header structure will be returned.
2162 *
2163 * In the case of an error occuring, NULL is returned and the error code
2164 * is available from last_error().
2165 *
2166 * The filename pointer should be considered "in use" until close() is
2167 * called on the KWAJ file.
2168 *
2169 * @param self a self-referential pointer to the mskwaj_decompressor
2170 * instance being called
2171 * @param filename the filename of the KWAJ compressed file. This is
2172 * passed directly to mspack_system::open().
2173 * @return a pointer to a mskwajd_header structure, or NULL on failure
2174 * @see close()
2175 */
2176 struct mskwajd_header *(*open)(struct mskwaj_decompressor *self,
2177 const char *filename);
2178
2179 /**
2180 * Closes a previously opened KWAJ file.
2181 *
2182 * This closes a KWAJ file and frees the mskwajd_header associated
2183 * with it. The KWAJ header pointer is now invalid and cannot be
2184 * used again.
2185 *
2186 * @param self a self-referential pointer to the mskwaj_decompressor
2187 * instance being called
2188 * @param kwaj the KWAJ file to close
2189 * @see open()
2190 */
2191 void (*close)(struct mskwaj_decompressor *self,
2192 struct mskwajd_header *kwaj);
2193
2194 /**
2195 * Extracts the compressed data from a KWAJ file.
2196 *
2197 * This decompresses the compressed KWAJ data stream and writes it to
2198 * an output file.
2199 *
2200 * @param self a self-referential pointer to the mskwaj_decompressor
2201 * instance being called
2202 * @param kwaj the KWAJ file to extract data from
2203 * @param filename the filename to write the decompressed data to. This
2204 * is passed directly to mspack_system::open().
2205 * @return an error code, or MSPACK_ERR_OK if successful
2206 */
2207 int (*extract)(struct mskwaj_decompressor *self,
2208 struct mskwajd_header *kwaj,
2209 const char *filename);
2210
2211 /**
2212 * Decompresses an KWAJ file to an output file in one step.
2213 *
2214 * This opens an KWAJ file as input, reads the header, then decompresses
2215 * the compressed data immediately to an output file, finally closing
2216 * both the input and output file. It is more convenient to use than
2217 * open() then extract() then close(), if you do not need to know the
2218 * KWAJ output size or output filename.
2219 *
2220 * @param self a self-referential pointer to the mskwaj_decompressor
2221 * instance being called
2222 * @param input the filename of the input KWAJ file. This is passed
2223 * directly to mspack_system::open().
2224 * @param output the filename to write the decompressed data to. This
2225 * is passed directly to mspack_system::open().
2226 * @return an error code, or MSPACK_ERR_OK if successful
2227 */
2228 int (*decompress)(struct mskwaj_decompressor *self,
2229 const char *input,
2230 const char *output);
2231
2232 /**
2233 * Returns the error code set by the most recently called method.
2234 *
2235 * This is useful for open() which does not return an
2236 * error code directly.
2237 *
2238 * @param self a self-referential pointer to the mskwaj_decompressor
2239 * instance being called
2240 * @return the most recent error code
2241 * @see open(), search()
2242 */
2243 int (*last_error)(struct mskwaj_decompressor *self);
2244};
2245
2246/* --- support for .LZX (Offline Address Book) file format ----------------- */
2247
2248/**
2249 * A compressor for the Offline Address Book (OAB) format.
2250 *
2251 * All fields are READ ONLY.
2252 *
2253 * @see mspack_create_oab_compressor(), mspack_destroy_oab_compressor()
2254 */
2255struct msoab_compressor {
2256 /**
2257 * Compress a full OAB file.
2258 *
2259 * The input file will be read and the compressed contents written to the
2260 * output file.
2261 *
2262 * @param self a self-referential pointer to the msoab_decompressor
2263 * instance being called
2264 * @param input the filename of the input file. This is passed
2265 * directly to mspack_system::open().
2266 * @param output the filename of the output file. This is passed
2267 * directly to mspack_system::open().
2268 * @return an error code, or MSPACK_ERR_OK if successful
2269 */
2270 int (*compress) (struct msoab_compressor *self,
2271 const char *input,
2272 const char *output);
2273
2274 /**
2275 * Generate a compressed incremental OAB patch file.
2276 *
2277 * The two uncompressed files "input" and "base" will be read, and an
2278 * incremental patch to generate "input" from "base" will be written to
2279 * the output file.
2280 *
2281 * @param self a self-referential pointer to the msoab_compressor
2282 * instance being called
2283 * @param input the filename of the input file containing the new
2284 * version of its contents. This is passed directly
2285 * to mspack_system::open().
2286 * @param base the filename of the original base file containing
2287 * the old version of its contents, against which the
2288 * incremental patch shall generated. This is passed
2289 * directly to mspack_system::open().
2290 * @param output the filename of the output file. This is passed
2291 * directly to mspack_system::open().
2292 * @return an error code, or MSPACK_ERR_OK if successful
2293 */
2294 int (*compress_incremental) (struct msoab_compressor *self,
2295 const char *input,
2296 const char *base,
2297 const char *output);
2298};
2299
2300/**
2301 * A decompressor for .LZX (Offline Address Book) files
2302 *
2303 * All fields are READ ONLY.
2304 *
2305 * @see mspack_create_oab_decompressor(), mspack_destroy_oab_decompressor()
2306 */
2307struct msoab_decompressor {
2308 /**
2309 * Decompresses a full Offline Address Book file.
2310 *
2311 * If the input file is a valid compressed Offline Address Book file,
2312 * it will be read and the decompressed contents will be written to
2313 * the output file.
2314 *
2315 * @param self a self-referential pointer to the msoab_decompressor
2316 * instance being called
2317 * @param input the filename of the input file. This is passed
2318 * directly to mspack_system::open().
2319 * @param output the filename of the output file. This is passed
2320 * directly to mspack_system::open().
2321 * @return an error code, or MSPACK_ERR_OK if successful
2322 */
2323 int (*decompress) (struct msoab_decompressor *self,
2324 const char *input,
2325 const char *output);
2326
2327 /**
2328 * Decompresses an Offline Address Book with an incremental patch file.
2329 *
2330 * This requires both a full UNCOMPRESSED Offline Address Book file to
2331 * act as the "base", and a compressed incremental patch file as input.
2332 * If the input file is valid, it will be decompressed with reference to
2333 * the base file, and the decompressed contents will be written to the
2334 * output file.
2335 *
2336 * There is no way to tell what the right base file is for the given
2337 * incremental patch, but if you get it wrong, this will usually result
2338 * in incorrect data being decompressed, which will then fail a checksum
2339 * test.
2340 *
2341 * @param self a self-referential pointer to the msoab_decompressor
2342 * instance being called
2343 * @param input the filename of the input file. This is passed
2344 * directly to mspack_system::open().
2345 * @param base the filename of the base file to which the
2346 * incremental patch shall be applied. This is passed
2347 * directly to mspack_system::open().
2348 * @param output the filename of the output file. This is passed
2349 * directly to mspack_system::open().
2350 * @return an error code, or MSPACK_ERR_OK if successful
2351 */
2352 int (*decompress_incremental) (struct msoab_decompressor *self,
2353 const char *input,
2354 const char *base,
2355 const char *output);
2356
2357 /**
2358 * Sets an OAB decompression engine parameter. Available only in OAB
2359 * decompressor version 2 and above.
2360 *
2361 * - #MSOABD_PARAM_DECOMPBUF: How many bytes should be used as an input
2362 * buffer by decompressors? The minimum value is 16. The default value
2363 * is 4096.
2364 *
2365 * @param self a self-referential pointer to the msoab_decompressor
2366 * instance being called
2367 * @param param the parameter to set
2368 * @param value the value to set the parameter to
2369 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there
2370 * is a problem with either parameter or value.
2371 */
2372 int (*set_param)(struct msoab_decompressor *self,
2373 int param,
2374 int value);
2375
2376};
2377
2378/** msoab_decompressor::set_param() parameter: size of decompression buffer */
2379#define MSOABD_PARAM_DECOMPBUF (0)
2380
2381#ifdef __cplusplus
2382}
2383#endif
2384
2385#endif