libmspack 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +5 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/README.md +75 -0
- data/Rakefile +22 -0
- data/UNLICENSE +24 -0
- data/ext/Rakefile +16 -0
- data/ext/i386-windows/libmspack.dll +0 -0
- data/ext/libmspack/AUTHORS +12 -0
- data/ext/libmspack/COPYING.LIB +504 -0
- data/ext/libmspack/ChangeLog +491 -0
- data/ext/libmspack/Makefile.am +100 -0
- data/ext/libmspack/NEWS +0 -0
- data/ext/libmspack/README +130 -0
- data/ext/libmspack/TODO +8 -0
- data/ext/libmspack/cleanup.sh +9 -0
- data/ext/libmspack/configure.ac +50 -0
- data/ext/libmspack/debian/changelog +6 -0
- data/ext/libmspack/debian/control +14 -0
- data/ext/libmspack/debian/rules +101 -0
- data/ext/libmspack/doc/Doxyfile.in +22 -0
- data/ext/libmspack/doc/Makefile.in +14 -0
- data/ext/libmspack/doc/szdd_kwaj_format.html +331 -0
- data/ext/libmspack/libmspack.pc.in +10 -0
- data/ext/libmspack/mspack/cab.h +127 -0
- data/ext/libmspack/mspack/cabc.c +24 -0
- data/ext/libmspack/mspack/cabd.c +1444 -0
- data/ext/libmspack/mspack/chm.h +122 -0
- data/ext/libmspack/mspack/chmc.c +24 -0
- data/ext/libmspack/mspack/chmd.c +1392 -0
- data/ext/libmspack/mspack/crc32.c +95 -0
- data/ext/libmspack/mspack/crc32.h +17 -0
- data/ext/libmspack/mspack/des.h +15 -0
- data/ext/libmspack/mspack/hlp.h +33 -0
- data/ext/libmspack/mspack/hlpc.c +24 -0
- data/ext/libmspack/mspack/hlpd.c +24 -0
- data/ext/libmspack/mspack/kwaj.h +118 -0
- data/ext/libmspack/mspack/kwajc.c +24 -0
- data/ext/libmspack/mspack/kwajd.c +561 -0
- data/ext/libmspack/mspack/lit.h +35 -0
- data/ext/libmspack/mspack/litc.c +24 -0
- data/ext/libmspack/mspack/litd.c +24 -0
- data/ext/libmspack/mspack/lzss.h +66 -0
- data/ext/libmspack/mspack/lzssd.c +93 -0
- data/ext/libmspack/mspack/lzx.h +221 -0
- data/ext/libmspack/mspack/lzxc.c +18 -0
- data/ext/libmspack/mspack/lzxd.c +895 -0
- data/ext/libmspack/mspack/mspack.def +28 -0
- data/ext/libmspack/mspack/mspack.h +2353 -0
- data/ext/libmspack/mspack/mszip.h +126 -0
- data/ext/libmspack/mspack/mszipc.c +18 -0
- data/ext/libmspack/mspack/mszipd.c +514 -0
- data/ext/libmspack/mspack/oab.h +60 -0
- data/ext/libmspack/mspack/oabc.c +24 -0
- data/ext/libmspack/mspack/oabd.c +408 -0
- data/ext/libmspack/mspack/qtm.h +128 -0
- data/ext/libmspack/mspack/qtmc.c +18 -0
- data/ext/libmspack/mspack/qtmd.c +489 -0
- data/ext/libmspack/mspack/readbits.h +207 -0
- data/ext/libmspack/mspack/readhuff.h +173 -0
- data/ext/libmspack/mspack/sha.h +15 -0
- data/ext/libmspack/mspack/system.c +239 -0
- data/ext/libmspack/mspack/system.h +124 -0
- data/ext/libmspack/mspack/szdd.h +39 -0
- data/ext/libmspack/mspack/szddc.c +24 -0
- data/ext/libmspack/mspack/szddd.c +247 -0
- data/ext/libmspack/rebuild.sh +8 -0
- data/ext/libmspack/test/cabd_c10 +19 -0
- data/ext/libmspack/test/cabd_compare +34 -0
- data/ext/libmspack/test/cabd_md5.c +161 -0
- data/ext/libmspack/test/cabd_memory.c +179 -0
- data/ext/libmspack/test/cabd_test.c +386 -0
- data/ext/libmspack/test/cabrip.c +81 -0
- data/ext/libmspack/test/chmd_compare +38 -0
- data/ext/libmspack/test/chmd_find.c +95 -0
- data/ext/libmspack/test/chmd_md5.c +67 -0
- data/ext/libmspack/test/chmd_order.c +144 -0
- data/ext/libmspack/test/chminfo.c +284 -0
- data/ext/libmspack/test/chmx.c +216 -0
- data/ext/libmspack/test/error.h +22 -0
- data/ext/libmspack/test/expand.c +79 -0
- data/ext/libmspack/test/md5.c +457 -0
- data/ext/libmspack/test/md5.h +165 -0
- data/ext/libmspack/test/md5_fh.h +123 -0
- data/ext/libmspack/test/msdecompile_md5 +24 -0
- data/ext/libmspack/test/msexpand_md5 +39 -0
- data/ext/libmspack/test/multifh.c +435 -0
- data/ext/libmspack/test/oabx.c +41 -0
- data/ext/libmspack/test/test_files/cabd/1.pl +84 -0
- data/ext/libmspack/test/test_files/cabd/2.pl +75 -0
- data/ext/libmspack/test/test_files/cabd/bad_folderindex.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_nofiles.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_nofolders.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_signature.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt1.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt2.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt3.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt4.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt5.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/normal_255c_filename.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/normal_2files_1folder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nodata.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nofiles.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nofolder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortextheader.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfile1.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfile2.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfolder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortheader.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nofname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_noninfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nonname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nopinfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nopname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortfname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortninfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortnname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortpinfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortpname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_---.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_--D.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_-F-.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_-FD.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_H--.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_H-D.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_HF-.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_HFD.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/search_basic.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/search_tricky1.cab +0 -0
- data/ext/libmspack/winbuild.sh +26 -0
- data/ext/x86_64-windows/libmspack.dll +0 -0
- data/lib/libmspack/constants.rb +9 -0
- data/lib/libmspack/exceptions.rb +12 -0
- data/lib/libmspack/mscab.rb +722 -0
- data/lib/libmspack/mschm.rb +301 -0
- data/lib/libmspack/mshlp.rb +15 -0
- data/lib/libmspack/mskwaj.rb +124 -0
- data/lib/libmspack/mslit.rb +18 -0
- data/lib/libmspack/msoab.rb +36 -0
- data/lib/libmspack/mspack.rb +208 -0
- data/lib/libmspack/msszdd.rb +81 -0
- data/lib/libmspack/system.rb +84 -0
- data/lib/libmspack/version.rb +4 -0
- data/lib/libmspack.rb +121 -0
- data/libmspack.gemspec +33 -0
- data/spec/libmspack_spec.rb +26 -0
- data/spec/spec_helper.rb +5 -0
- metadata +309 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
/* This file is part of libmspack.
|
2
|
+
* (C) 2003-2010 Stuart Caie.
|
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
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
8
|
+
*/
|
9
|
+
|
10
|
+
#ifndef MSPACK_READHUFF_H
|
11
|
+
#define MSPACK_READHUFF_H 1
|
12
|
+
|
13
|
+
/* This implements a fast Huffman tree decoding system.
|
14
|
+
*/
|
15
|
+
|
16
|
+
#if !(defined(BITS_ORDER_MSB) || defined(BITS_ORDER_LSB))
|
17
|
+
# error "readhuff.h is used in conjunction with readbits.h, include that first"
|
18
|
+
#endif
|
19
|
+
#if !(defined(TABLEBITS) && defined(MAXSYMBOLS))
|
20
|
+
# error "define TABLEBITS(tbl) and MAXSYMBOLS(tbl) before using readhuff.h"
|
21
|
+
#endif
|
22
|
+
#if !(defined(HUFF_TABLE) && defined(HUFF_LEN))
|
23
|
+
# error "define HUFF_TABLE(tbl) and HUFF_LEN(tbl) before using readhuff.h"
|
24
|
+
#endif
|
25
|
+
#ifndef HUFF_ERROR
|
26
|
+
# error "define HUFF_ERROR before using readhuff.h"
|
27
|
+
#endif
|
28
|
+
#ifndef HUFF_MAXBITS
|
29
|
+
# define HUFF_MAXBITS 16
|
30
|
+
#endif
|
31
|
+
|
32
|
+
/* Decodes the next huffman symbol from the input bitstream into var.
|
33
|
+
* Do not use this macro on a table unless build_decode_table() succeeded.
|
34
|
+
*/
|
35
|
+
#define READ_HUFFSYM(tbl, var) do { \
|
36
|
+
ENSURE_BITS(HUFF_MAXBITS); \
|
37
|
+
sym = HUFF_TABLE(tbl, PEEK_BITS(TABLEBITS(tbl))); \
|
38
|
+
if (sym >= MAXSYMBOLS(tbl)) HUFF_TRAVERSE(tbl); \
|
39
|
+
(var) = sym; \
|
40
|
+
i = HUFF_LEN(tbl, sym); \
|
41
|
+
REMOVE_BITS(i); \
|
42
|
+
} while (0)
|
43
|
+
|
44
|
+
#ifdef BITS_ORDER_LSB
|
45
|
+
# define HUFF_TRAVERSE(tbl) do { \
|
46
|
+
i = TABLEBITS(tbl) - 1; \
|
47
|
+
do { \
|
48
|
+
if (i++ > HUFF_MAXBITS) HUFF_ERROR; \
|
49
|
+
sym = HUFF_TABLE(tbl, \
|
50
|
+
(sym << 1) | ((bit_buffer >> i) & 1)); \
|
51
|
+
} while (sym >= MAXSYMBOLS(tbl)); \
|
52
|
+
} while (0)
|
53
|
+
#else
|
54
|
+
#define HUFF_TRAVERSE(tbl) do { \
|
55
|
+
i = 1 << (BITBUF_WIDTH - TABLEBITS(tbl)); \
|
56
|
+
do { \
|
57
|
+
if ((i >>= 1) == 0) HUFF_ERROR; \
|
58
|
+
sym = HUFF_TABLE(tbl, \
|
59
|
+
(sym << 1) | ((bit_buffer & i) ? 1 : 0)); \
|
60
|
+
} while (sym >= MAXSYMBOLS(tbl)); \
|
61
|
+
} while (0)
|
62
|
+
#endif
|
63
|
+
|
64
|
+
/* make_decode_table(nsyms, nbits, length[], table[])
|
65
|
+
*
|
66
|
+
* This function was originally coded by David Tritscher.
|
67
|
+
* It builds a fast huffman decoding table from
|
68
|
+
* a canonical huffman code lengths table.
|
69
|
+
*
|
70
|
+
* nsyms = total number of symbols in this huffman tree.
|
71
|
+
* nbits = any symbols with a code length of nbits or less can be decoded
|
72
|
+
* in one lookup of the table.
|
73
|
+
* length = A table to get code lengths from [0 to nsyms-1]
|
74
|
+
* table = The table to fill up with decoded symbols and pointers.
|
75
|
+
* Should be ((1<<nbits) + (nsyms*2)) in length.
|
76
|
+
*
|
77
|
+
* Returns 0 for OK or 1 for error
|
78
|
+
*/
|
79
|
+
static int make_decode_table(unsigned int nsyms, unsigned int nbits,
|
80
|
+
unsigned char *length, unsigned short *table)
|
81
|
+
{
|
82
|
+
register unsigned short sym, next_symbol;
|
83
|
+
register unsigned int leaf, fill;
|
84
|
+
#ifdef BITS_ORDER_LSB
|
85
|
+
register unsigned int reverse;
|
86
|
+
#endif
|
87
|
+
register unsigned char bit_num;
|
88
|
+
unsigned int pos = 0; /* the current position in the decode table */
|
89
|
+
unsigned int table_mask = 1 << nbits;
|
90
|
+
unsigned int bit_mask = table_mask >> 1; /* don't do 0 length codes */
|
91
|
+
|
92
|
+
/* fill entries for codes short enough for a direct mapping */
|
93
|
+
for (bit_num = 1; bit_num <= nbits; bit_num++) {
|
94
|
+
for (sym = 0; sym < nsyms; sym++) {
|
95
|
+
if (length[sym] != bit_num) continue;
|
96
|
+
#ifdef BITS_ORDER_MSB
|
97
|
+
leaf = pos;
|
98
|
+
#else
|
99
|
+
/* reverse the significant bits */
|
100
|
+
fill = length[sym]; reverse = pos >> (nbits - fill); leaf = 0;
|
101
|
+
do {leaf <<= 1; leaf |= reverse & 1; reverse >>= 1;} while (--fill);
|
102
|
+
#endif
|
103
|
+
|
104
|
+
if((pos += bit_mask) > table_mask) return 1; /* table overrun */
|
105
|
+
|
106
|
+
/* fill all possible lookups of this symbol with the symbol itself */
|
107
|
+
#ifdef BITS_ORDER_MSB
|
108
|
+
for (fill = bit_mask; fill-- > 0;) table[leaf++] = sym;
|
109
|
+
#else
|
110
|
+
fill = bit_mask; next_symbol = 1 << bit_num;
|
111
|
+
do { table[leaf] = sym; leaf += next_symbol; } while (--fill);
|
112
|
+
#endif
|
113
|
+
}
|
114
|
+
bit_mask >>= 1;
|
115
|
+
}
|
116
|
+
|
117
|
+
/* exit with success if table is now complete */
|
118
|
+
if (pos == table_mask) return 0;
|
119
|
+
|
120
|
+
/* mark all remaining table entries as unused */
|
121
|
+
for (sym = pos; sym < table_mask; sym++) {
|
122
|
+
#ifdef BITS_ORDER_MSB
|
123
|
+
table[sym] = 0xFFFF;
|
124
|
+
#else
|
125
|
+
reverse = sym; leaf = 0; fill = nbits;
|
126
|
+
do { leaf <<= 1; leaf |= reverse & 1; reverse >>= 1; } while (--fill);
|
127
|
+
table[leaf] = 0xFFFF;
|
128
|
+
#endif
|
129
|
+
}
|
130
|
+
|
131
|
+
/* next_symbol = base of allocation for long codes */
|
132
|
+
next_symbol = ((table_mask >> 1) < nsyms) ? nsyms : (table_mask >> 1);
|
133
|
+
|
134
|
+
/* give ourselves room for codes to grow by up to 16 more bits.
|
135
|
+
* codes now start at bit nbits+16 and end at (nbits+16-codelength) */
|
136
|
+
pos <<= 16;
|
137
|
+
table_mask <<= 16;
|
138
|
+
bit_mask = 1 << 15;
|
139
|
+
|
140
|
+
for (bit_num = nbits+1; bit_num <= HUFF_MAXBITS; bit_num++) {
|
141
|
+
for (sym = 0; sym < nsyms; sym++) {
|
142
|
+
if (length[sym] != bit_num) continue;
|
143
|
+
|
144
|
+
#ifdef BITS_ORDER_MSB
|
145
|
+
leaf = pos >> 16;
|
146
|
+
#else
|
147
|
+
/* leaf = the first nbits of the code, reversed */
|
148
|
+
reverse = pos >> 16; leaf = 0; fill = nbits;
|
149
|
+
do {leaf <<= 1; leaf |= reverse & 1; reverse >>= 1;} while (--fill);
|
150
|
+
#endif
|
151
|
+
for (fill = 0; fill < (bit_num - nbits); fill++) {
|
152
|
+
/* if this path hasn't been taken yet, 'allocate' two entries */
|
153
|
+
if (table[leaf] == 0xFFFF) {
|
154
|
+
table[(next_symbol << 1) ] = 0xFFFF;
|
155
|
+
table[(next_symbol << 1) + 1 ] = 0xFFFF;
|
156
|
+
table[leaf] = next_symbol++;
|
157
|
+
}
|
158
|
+
|
159
|
+
/* follow the path and select either left or right for next bit */
|
160
|
+
leaf = table[leaf] << 1;
|
161
|
+
if ((pos >> (15-fill)) & 1) leaf++;
|
162
|
+
}
|
163
|
+
table[leaf] = sym;
|
164
|
+
|
165
|
+
if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
|
166
|
+
}
|
167
|
+
bit_mask >>= 1;
|
168
|
+
}
|
169
|
+
|
170
|
+
/* full table? */
|
171
|
+
return (pos == table_mask) ? 0 : 1;
|
172
|
+
}
|
173
|
+
#endif
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/* This file is part of libmspack.
|
2
|
+
* (C) 2003-2004 Stuart Caie.
|
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
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
8
|
+
*/
|
9
|
+
|
10
|
+
#ifndef MSPACK_LZSS_H
|
11
|
+
#define MSPACK_LZSS_H 1
|
12
|
+
|
13
|
+
/* SHA-1 message digest definitions */
|
14
|
+
|
15
|
+
#endif
|
@@ -0,0 +1,239 @@
|
|
1
|
+
/* This file is part of libmspack.
|
2
|
+
* (C) 2003-2004 Stuart Caie.
|
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
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
8
|
+
*/
|
9
|
+
|
10
|
+
#ifdef HAVE_CONFIG_H
|
11
|
+
# include <config.h>
|
12
|
+
#endif
|
13
|
+
|
14
|
+
#include <system.h>
|
15
|
+
|
16
|
+
#ifndef LARGEFILE_SUPPORT
|
17
|
+
const char *largefile_msg = "library not compiled to support large files.";
|
18
|
+
#endif
|
19
|
+
|
20
|
+
|
21
|
+
int mspack_version(int entity) {
|
22
|
+
switch (entity) {
|
23
|
+
/* CHM decoder version 1 -> 2 changes:
|
24
|
+
* - added mschmd_sec_mscompressed::spaninfo
|
25
|
+
* - added mschmd_header::first_pmgl
|
26
|
+
* - added mschmd_header::last_pmgl
|
27
|
+
* - added mschmd_header::chunk_cache;
|
28
|
+
*/
|
29
|
+
case MSPACK_VER_MSCHMD:
|
30
|
+
return 2;
|
31
|
+
case MSPACK_VER_LIBRARY:
|
32
|
+
case MSPACK_VER_SYSTEM:
|
33
|
+
case MSPACK_VER_MSCABD:
|
34
|
+
case MSPACK_VER_MSSZDDD:
|
35
|
+
case MSPACK_VER_MSKWAJD:
|
36
|
+
case MSPACK_VER_MSOABD:
|
37
|
+
return 1;
|
38
|
+
case MSPACK_VER_MSCABC:
|
39
|
+
case MSPACK_VER_MSCHMC:
|
40
|
+
case MSPACK_VER_MSLITD:
|
41
|
+
case MSPACK_VER_MSLITC:
|
42
|
+
case MSPACK_VER_MSHLPD:
|
43
|
+
case MSPACK_VER_MSHLPC:
|
44
|
+
case MSPACK_VER_MSSZDDC:
|
45
|
+
case MSPACK_VER_MSKWAJC:
|
46
|
+
case MSPACK_VER_MSOABC:
|
47
|
+
return 0;
|
48
|
+
}
|
49
|
+
return -1;
|
50
|
+
}
|
51
|
+
|
52
|
+
int mspack_sys_selftest_internal(int offt_size) {
|
53
|
+
return (sizeof(off_t) == offt_size) ? MSPACK_ERR_OK : MSPACK_ERR_SEEK;
|
54
|
+
}
|
55
|
+
|
56
|
+
/* validates a system structure */
|
57
|
+
int mspack_valid_system(struct mspack_system *sys) {
|
58
|
+
return (sys != NULL) && (sys->open != NULL) && (sys->close != NULL) &&
|
59
|
+
(sys->read != NULL) && (sys->write != NULL) && (sys->seek != NULL) &&
|
60
|
+
(sys->tell != NULL) && (sys->message != NULL) && (sys->alloc != NULL) &&
|
61
|
+
(sys->free != NULL) && (sys->copy != NULL) && (sys->null_ptr == NULL);
|
62
|
+
}
|
63
|
+
|
64
|
+
/* returns the length of a file opened for reading */
|
65
|
+
int mspack_sys_filelen(struct mspack_system *system,
|
66
|
+
struct mspack_file *file, off_t *length)
|
67
|
+
{
|
68
|
+
off_t current;
|
69
|
+
|
70
|
+
if (!system || !file || !length) return MSPACK_ERR_OPEN;
|
71
|
+
|
72
|
+
/* get current offset */
|
73
|
+
current = system->tell(file);
|
74
|
+
|
75
|
+
/* seek to end of file */
|
76
|
+
if (system->seek(file, (off_t) 0, MSPACK_SYS_SEEK_END)) {
|
77
|
+
return MSPACK_ERR_SEEK;
|
78
|
+
}
|
79
|
+
|
80
|
+
/* get offset of end of file */
|
81
|
+
*length = system->tell(file);
|
82
|
+
|
83
|
+
/* seek back to original offset */
|
84
|
+
if (system->seek(file, current, MSPACK_SYS_SEEK_START)) {
|
85
|
+
return MSPACK_ERR_SEEK;
|
86
|
+
}
|
87
|
+
|
88
|
+
return MSPACK_ERR_OK;
|
89
|
+
}
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
/* definition of mspack_default_system -- if the library is compiled with
|
94
|
+
* MSPACK_NO_DEFAULT_SYSTEM, no default system will be provided. Otherwise,
|
95
|
+
* an appropriate default system (e.g. the standard C library, or some native
|
96
|
+
* API calls)
|
97
|
+
*/
|
98
|
+
|
99
|
+
#ifdef MSPACK_NO_DEFAULT_SYSTEM
|
100
|
+
struct mspack_system *mspack_default_system = NULL;
|
101
|
+
#else
|
102
|
+
|
103
|
+
/* implementation of mspack_default_system for standard C library */
|
104
|
+
|
105
|
+
#include <stdio.h>
|
106
|
+
#include <stdlib.h>
|
107
|
+
#include <string.h>
|
108
|
+
#include <stdarg.h>
|
109
|
+
|
110
|
+
struct mspack_file_p {
|
111
|
+
FILE *fh;
|
112
|
+
const char *name;
|
113
|
+
};
|
114
|
+
|
115
|
+
static struct mspack_file *msp_open(struct mspack_system *self,
|
116
|
+
const char *filename, int mode)
|
117
|
+
{
|
118
|
+
struct mspack_file_p *fh;
|
119
|
+
const char *fmode;
|
120
|
+
|
121
|
+
switch (mode) {
|
122
|
+
case MSPACK_SYS_OPEN_READ: fmode = "rb"; break;
|
123
|
+
case MSPACK_SYS_OPEN_WRITE: fmode = "wb"; break;
|
124
|
+
case MSPACK_SYS_OPEN_UPDATE: fmode = "r+b"; break;
|
125
|
+
case MSPACK_SYS_OPEN_APPEND: fmode = "ab"; break;
|
126
|
+
default: return NULL;
|
127
|
+
}
|
128
|
+
|
129
|
+
if ((fh = (struct mspack_file_p *) malloc(sizeof(struct mspack_file_p)))) {
|
130
|
+
fh->name = filename;
|
131
|
+
if ((fh->fh = fopen(filename, fmode))) return (struct mspack_file *) fh;
|
132
|
+
free(fh);
|
133
|
+
}
|
134
|
+
return NULL;
|
135
|
+
}
|
136
|
+
|
137
|
+
static void msp_close(struct mspack_file *file) {
|
138
|
+
struct mspack_file_p *self = (struct mspack_file_p *) file;
|
139
|
+
if (self) {
|
140
|
+
fclose(self->fh);
|
141
|
+
free(self);
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
static int msp_read(struct mspack_file *file, void *buffer, int bytes) {
|
146
|
+
struct mspack_file_p *self = (struct mspack_file_p *) file;
|
147
|
+
if (self && buffer && bytes >= 0) {
|
148
|
+
size_t count = fread(buffer, 1, (size_t) bytes, self->fh);
|
149
|
+
if (!ferror(self->fh)) return (int) count;
|
150
|
+
}
|
151
|
+
return -1;
|
152
|
+
}
|
153
|
+
|
154
|
+
static int msp_write(struct mspack_file *file, void *buffer, int bytes) {
|
155
|
+
struct mspack_file_p *self = (struct mspack_file_p *) file;
|
156
|
+
if (self && buffer && bytes >= 0) {
|
157
|
+
size_t count = fwrite(buffer, 1, (size_t) bytes, self->fh);
|
158
|
+
if (!ferror(self->fh)) return (int) count;
|
159
|
+
}
|
160
|
+
return -1;
|
161
|
+
}
|
162
|
+
|
163
|
+
static int msp_seek(struct mspack_file *file, off_t offset, int mode) {
|
164
|
+
struct mspack_file_p *self = (struct mspack_file_p *) file;
|
165
|
+
if (self) {
|
166
|
+
switch (mode) {
|
167
|
+
case MSPACK_SYS_SEEK_START: mode = SEEK_SET; break;
|
168
|
+
case MSPACK_SYS_SEEK_CUR: mode = SEEK_CUR; break;
|
169
|
+
case MSPACK_SYS_SEEK_END: mode = SEEK_END; break;
|
170
|
+
default: return -1;
|
171
|
+
}
|
172
|
+
#ifdef HAVE_FSEEKO
|
173
|
+
return fseeko(self->fh, offset, mode);
|
174
|
+
#else
|
175
|
+
return fseek(self->fh, offset, mode);
|
176
|
+
#endif
|
177
|
+
}
|
178
|
+
return -1;
|
179
|
+
}
|
180
|
+
|
181
|
+
static off_t msp_tell(struct mspack_file *file) {
|
182
|
+
struct mspack_file_p *self = (struct mspack_file_p *) file;
|
183
|
+
#ifdef HAVE_FSEEKO
|
184
|
+
return (self) ? (off_t) ftello(self->fh) : 0;
|
185
|
+
#else
|
186
|
+
return (self) ? (off_t) ftell(self->fh) : 0;
|
187
|
+
#endif
|
188
|
+
}
|
189
|
+
|
190
|
+
static void msp_msg(struct mspack_file *file, const char *format, ...) {
|
191
|
+
va_list ap;
|
192
|
+
if (file) fprintf(stderr, "%s: ", ((struct mspack_file_p *) file)->name);
|
193
|
+
va_start(ap, format);
|
194
|
+
vfprintf(stderr, format, ap);
|
195
|
+
va_end(ap);
|
196
|
+
fputc((int) '\n', stderr);
|
197
|
+
fflush(stderr);
|
198
|
+
}
|
199
|
+
|
200
|
+
static void *msp_alloc(struct mspack_system *self, size_t bytes) {
|
201
|
+
#ifdef DEBUG
|
202
|
+
/* make uninitialised data obvious */
|
203
|
+
char *buf = malloc(bytes + 8);
|
204
|
+
if (buf) memset(buf, 0xDC, bytes);
|
205
|
+
*((size_t *)buf) = bytes;
|
206
|
+
return &buf[8];
|
207
|
+
#else
|
208
|
+
return malloc(bytes);
|
209
|
+
#endif
|
210
|
+
}
|
211
|
+
|
212
|
+
static void msp_free(void *buffer) {
|
213
|
+
#ifdef DEBUG
|
214
|
+
char *buf = buffer;
|
215
|
+
size_t bytes;
|
216
|
+
if (buf) {
|
217
|
+
buf -= 8;
|
218
|
+
bytes = *((size_t *)buf);
|
219
|
+
/* make freed data obvious */
|
220
|
+
memset(buf, 0xED, bytes);
|
221
|
+
free(buf);
|
222
|
+
}
|
223
|
+
#else
|
224
|
+
free(buffer);
|
225
|
+
#endif
|
226
|
+
}
|
227
|
+
|
228
|
+
static void msp_copy(void *src, void *dest, size_t bytes) {
|
229
|
+
memcpy(dest, src, bytes);
|
230
|
+
}
|
231
|
+
|
232
|
+
static struct mspack_system msp_system = {
|
233
|
+
&msp_open, &msp_close, &msp_read, &msp_write, &msp_seek,
|
234
|
+
&msp_tell, &msp_msg, &msp_alloc, &msp_free, &msp_copy, NULL
|
235
|
+
};
|
236
|
+
|
237
|
+
struct mspack_system *mspack_default_system = &msp_system;
|
238
|
+
|
239
|
+
#endif
|
@@ -0,0 +1,124 @@
|
|
1
|
+
/* This file is part of libmspack.
|
2
|
+
* (C) 2003-2004 Stuart Caie.
|
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
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
8
|
+
*/
|
9
|
+
|
10
|
+
#ifndef MSPACK_SYSTEM_H
|
11
|
+
#define MSPACK_SYSTEM_H 1
|
12
|
+
|
13
|
+
#ifdef __cplusplus
|
14
|
+
extern "C" {
|
15
|
+
#endif
|
16
|
+
|
17
|
+
/* ensure config.h is read before mspack.h */
|
18
|
+
#ifdef HAVE_CONFIG_H
|
19
|
+
# include <config.h>
|
20
|
+
#endif
|
21
|
+
|
22
|
+
#include <mspack.h>
|
23
|
+
|
24
|
+
/* fix for problem with GCC 4 and glibc (thanks to Ville Skytta)
|
25
|
+
* http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=150429
|
26
|
+
*/
|
27
|
+
#ifdef read
|
28
|
+
# undef read
|
29
|
+
#endif
|
30
|
+
|
31
|
+
#ifdef DEBUG
|
32
|
+
# include <stdio.h>
|
33
|
+
/* Old GCCs don't have __func__, but __FUNCTION__:
|
34
|
+
* http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
|
35
|
+
*/
|
36
|
+
# if __STDC_VERSION__ < 199901L
|
37
|
+
# if __GNUC__ >= 2
|
38
|
+
# define __func__ __FUNCTION__
|
39
|
+
# else
|
40
|
+
# define __func__ "<unknown>"
|
41
|
+
# endif
|
42
|
+
# endif
|
43
|
+
# define D(x) do { printf("%s:%d (%s) ",__FILE__, __LINE__, __func__); \
|
44
|
+
printf x ; fputc('\n', stdout); fflush(stdout);} while (0);
|
45
|
+
#else
|
46
|
+
# define D(x)
|
47
|
+
#endif
|
48
|
+
|
49
|
+
/* CAB supports searching through files over 4GB in size, and the CHM file
|
50
|
+
* format actively uses 64-bit offsets. These can only be fully supported
|
51
|
+
* if the system the code runs on supports large files. If not, the library
|
52
|
+
* will work as normal using only 32-bit arithmetic, but if an offset
|
53
|
+
* greater than 2GB is detected, an error message indicating the library
|
54
|
+
* can't support the file should be printed.
|
55
|
+
*/
|
56
|
+
#ifdef HAVE_LIMITS_H
|
57
|
+
# include <limits.h>
|
58
|
+
#endif
|
59
|
+
|
60
|
+
#if ((defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS >= 64) || \
|
61
|
+
(defined(FILESIZEBITS) && FILESIZEBITS >= 64) || \
|
62
|
+
(defined(SIZEOF_OFF_T) && SIZEOF_OFF_T >= 8) || \
|
63
|
+
defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE))
|
64
|
+
# define LARGEFILE_SUPPORT
|
65
|
+
# define LD "lld"
|
66
|
+
# define LU "llu"
|
67
|
+
#else
|
68
|
+
extern const char *largefile_msg;
|
69
|
+
# define LD "ld"
|
70
|
+
# define LU "lu"
|
71
|
+
#endif
|
72
|
+
|
73
|
+
/* endian-neutral reading of little-endian data */
|
74
|
+
#define __egi32(a,n) ( ((((unsigned char *) a)[n+3]) << 24) | \
|
75
|
+
((((unsigned char *) a)[n+2]) << 16) | \
|
76
|
+
((((unsigned char *) a)[n+1]) << 8) | \
|
77
|
+
((((unsigned char *) a)[n+0])))
|
78
|
+
#define EndGetI64(a) ((((unsigned long long int) __egi32(a,4)) << 32) | \
|
79
|
+
((unsigned int) __egi32(a,0)))
|
80
|
+
#define EndGetI32(a) __egi32(a,0)
|
81
|
+
#define EndGetI16(a) ((((a)[1])<<8)|((a)[0]))
|
82
|
+
|
83
|
+
/* endian-neutral reading of big-endian data */
|
84
|
+
#define EndGetM32(a) (((((unsigned char *) a)[0]) << 24) | \
|
85
|
+
((((unsigned char *) a)[1]) << 16) | \
|
86
|
+
((((unsigned char *) a)[2]) << 8) | \
|
87
|
+
((((unsigned char *) a)[3])))
|
88
|
+
#define EndGetM16(a) ((((a)[0])<<8)|((a)[1]))
|
89
|
+
|
90
|
+
extern struct mspack_system *mspack_default_system;
|
91
|
+
|
92
|
+
/* returns the length of a file opened for reading */
|
93
|
+
extern int mspack_sys_filelen(struct mspack_system *system,
|
94
|
+
struct mspack_file *file, off_t *length);
|
95
|
+
|
96
|
+
/* validates a system structure */
|
97
|
+
extern int mspack_valid_system(struct mspack_system *sys);
|
98
|
+
|
99
|
+
#if HAVE_STRINGS_H
|
100
|
+
# include <strings.h>
|
101
|
+
#endif
|
102
|
+
|
103
|
+
#if HAVE_STRING_H
|
104
|
+
# include <string.h>
|
105
|
+
#endif
|
106
|
+
|
107
|
+
#if HAVE_MEMCMP
|
108
|
+
# define mspack_memcmp memcmp
|
109
|
+
#else
|
110
|
+
/* inline memcmp() */
|
111
|
+
static inline int mspack_memcmp(const void *s1, const void *s2, size_t n) {
|
112
|
+
unsigned char *c1 = (unsigned char *) s1;
|
113
|
+
unsigned char *c2 = (unsigned char *) s2;
|
114
|
+
if (n == 0) return 0;
|
115
|
+
while (--n && (*c1 == *c2)) c1++, c2++;
|
116
|
+
return *c1 - *c2;
|
117
|
+
}
|
118
|
+
#endif
|
119
|
+
|
120
|
+
#ifdef __cplusplus
|
121
|
+
}
|
122
|
+
#endif
|
123
|
+
|
124
|
+
#endif
|
@@ -0,0 +1,39 @@
|
|
1
|
+
/* This file is part of libmspack.
|
2
|
+
* (C) 2003-2004 Stuart Caie.
|
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
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
8
|
+
*/
|
9
|
+
|
10
|
+
#ifndef MSPACK_SZDD_H
|
11
|
+
#define MSPACK_SZDD_H 1
|
12
|
+
|
13
|
+
#include <lzss.h>
|
14
|
+
|
15
|
+
/* input buffer size during decompression - not worth parameterising IMHO */
|
16
|
+
#define SZDD_INPUT_SIZE (2048)
|
17
|
+
|
18
|
+
/* SZDD compression definitions */
|
19
|
+
|
20
|
+
struct msszdd_compressor_p {
|
21
|
+
struct msszdd_compressor base;
|
22
|
+
struct mspack_system *system;
|
23
|
+
int error;
|
24
|
+
};
|
25
|
+
|
26
|
+
/* SZDD decompression definitions */
|
27
|
+
|
28
|
+
struct msszdd_decompressor_p {
|
29
|
+
struct msszdd_decompressor base;
|
30
|
+
struct mspack_system *system;
|
31
|
+
int error;
|
32
|
+
};
|
33
|
+
|
34
|
+
struct msszddd_header_p {
|
35
|
+
struct msszddd_header base;
|
36
|
+
struct mspack_file *fh;
|
37
|
+
};
|
38
|
+
|
39
|
+
#endif
|
@@ -0,0 +1,24 @@
|
|
1
|
+
/* This file is part of libmspack.
|
2
|
+
* (C) 2003-2004 Stuart Caie.
|
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
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
8
|
+
*/
|
9
|
+
|
10
|
+
/* SZDD compression implementation */
|
11
|
+
|
12
|
+
#include <system.h>
|
13
|
+
#include <szdd.h>
|
14
|
+
|
15
|
+
struct msszdd_compressor *
|
16
|
+
mspack_create_szdd_compressor(struct mspack_system *sys)
|
17
|
+
{
|
18
|
+
/* todo */
|
19
|
+
return NULL;
|
20
|
+
}
|
21
|
+
|
22
|
+
void mspack_destroy_szdd_compressor(struct msszdd_compressor *self) {
|
23
|
+
/* todo */
|
24
|
+
}
|