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