libmspack 0.0.1

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