diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2013-03-11 18:46:03 +0100 |
---|---|---|
committer | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2013-11-04 22:14:17 +0100 |
commit | 739a7ae0e9acb27227f5473a003833ea5a9c97ef (patch) | |
tree | 81f6dfd81b4343745b21a6c00c286791827175e4 /rbutil/rbutilqt/mspack/mspack.h | |
parent | 27111d83be815602ac35354e6a8e4e158c5968f9 (diff) | |
download | rockbox-739a7ae0e9acb27227f5473a003833ea5a9c97ef.tar.gz rockbox-739a7ae0e9acb27227f5473a003833ea5a9c97ef.zip |
Add libmspack to rbutil
Change-Id: I520c14131ec1e12013f106c13cba00aac058ad83
Reviewed-on: http://gerrit.rockbox.org/391
Reviewed-by: Dominik Riebeling <Dominik.Riebeling@gmail.com>
Diffstat (limited to 'rbutil/rbutilqt/mspack/mspack.h')
-rw-r--r-- | rbutil/rbutilqt/mspack/mspack.h | 2203 |
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 | ||
157 | extern "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. */ | ||
191 | extern 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 | */ | ||
222 | extern 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 | */ | ||
274 | struct 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 | */ | ||
465 | struct 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 | */ | ||
502 | extern 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 | */ | ||
509 | extern 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 | */ | ||
515 | extern 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 | */ | ||
520 | extern 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 | */ | ||
527 | extern 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 | */ | ||
534 | extern 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 | */ | ||
540 | extern 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 | */ | ||
545 | extern 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 | */ | ||
552 | extern 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 | */ | ||
559 | extern 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 | */ | ||
565 | extern 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 | */ | ||
570 | extern 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 | */ | ||
577 | extern 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 | */ | ||
584 | extern 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 | */ | ||
590 | extern 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 | */ | ||
595 | extern 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 | */ | ||
602 | extern 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 | */ | ||
609 | extern 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 | */ | ||
615 | extern 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 | */ | ||
620 | extern 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 | */ | ||
627 | extern 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 | */ | ||
634 | extern 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 | */ | ||
640 | extern 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 | */ | ||
645 | extern 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 | */ | ||
661 | struct 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 | */ | ||
768 | struct 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 | */ | ||
825 | struct 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 */ | ||
901 | struct 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 | */ | ||
912 | struct 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 | */ | ||
1147 | struct 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 | */ | ||
1173 | struct 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 | */ | ||
1190 | struct 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 | */ | ||
1203 | struct 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 | */ | ||
1227 | struct 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 | */ | ||
1325 | struct 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 | */ | ||
1373 | struct 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 | */ | ||
1532 | struct 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 */ | ||
1684 | struct mslit_compressor { | ||
1685 | int dummy; | ||
1686 | }; | ||
1687 | |||
1688 | /** TODO */ | ||
1689 | struct mslit_decompressor { | ||
1690 | int dummy; | ||
1691 | }; | ||
1692 | |||
1693 | |||
1694 | /* --- support for .HLP (MS Help) file format ------------------------------ */ | ||
1695 | |||
1696 | /** TODO */ | ||
1697 | struct mshlp_compressor { | ||
1698 | int dummy; | ||
1699 | }; | ||
1700 | |||
1701 | /** TODO */ | ||
1702 | struct 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 | */ | ||
1723 | struct 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 | */ | ||
1747 | struct 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 | */ | ||
1831 | struct 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 | */ | ||
1964 | struct 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 | */ | ||
1998 | struct 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 | */ | ||
2109 | struct 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 | ||