34 #include <sys/types.h>
45 #include "BESUncompress3Z.h"
46 #include "BESInternalError.h"
63 BESDEBUG(
"bes",
"BESUncompress3Z::uncompress - src=" << src.c_str() << endl );
65 srcFile = open(src.c_str(), O_RDONLY);
68 string err =
"Unable to open the compressed file " + src +
": ";
69 char *serr = strerror(my_errno);
74 err.append(
"unknown error occurred");
83 BESDEBUG(
"bes",
"BESUncompress3Z::uncompress - start decompress" << endl);
85 #define FIRSTBYTE (unsigned char)'\037'
86 #define SECONDBYTE (unsigned char)'\235'
89 #define BLOCK_MODE 0x80
90 #define MAXCODE(n) (1L << (n))
95 #define HSIZE (1<<HBITS)
96 #define HMASK (HSIZE-1)
98 #define de_stack ((unsigned char *)&(htab[HSIZE-1]))
99 #define BYTEORDER 0000
102 unsigned char htab[HSIZE * 4];
103 unsigned short codetab[HSIZE];
105 int block_mode = BLOCK_MODE;
107 unsigned char inbuf[BUFSIZ + 64];
108 unsigned char outbuf[BUFSIZ + 2048];
109 unsigned char *stackp;
127 BESDEBUG(
"bes",
"BESUncompress3Z::uncompress - read file" << endl);;
131 while (insize < 3 && (rsize = read(srcFile, inbuf + insize, BUFSIZ)) > 0) {
134 BESDEBUG(
"bes",
"BESUncompress3Z::uncompress - insize: " << insize << endl);;
139 if ((insize < 3) || (inbuf[0] != FIRSTBYTE) || (inbuf[1] != SECONDBYTE)) {
140 BESDEBUG(
"bes",
"BESUncompress3Z::uncompress - not a compress file" << endl);;
142 string err =
"Could not read file ";
149 string err = src.c_str();
150 err +=
": not in compressed format";
155 string err =
"unknown error";
164 maxbits = inbuf[2] & BIT_MASK;
165 block_mode = inbuf[2] & BLOCK_MODE;
166 maxmaxcode = MAXCODE(maxbits);
168 if (maxbits > BITS) {
169 string err = src.c_str();
170 err +=
": compressed with ";
172 err +=
" bits, can only handle";
178 maxcode = MAXCODE(n_bits = INIT_BITS) - 1;
179 bitmask = (1 << n_bits) - 1;
185 free_ent = ((block_mode) ? FIRST : 256);
187 BESDEBUG(
"bes",
"BESUncompress3Z::uncompress - entering loop" << endl);
189 memset(codetab, 0, 256);
191 for (code = 255; code >= 0; --code) {
192 ((
unsigned char *) (htab))[code] = (
unsigned char) code;
202 int e = insize - (o = (posbits >> 3));
204 for (i = 0; i < e; ++i)
205 inbuf[i] = inbuf[i + o];
211 if ((
unsigned int)insize <
sizeof(inbuf) - BUFSIZ) {
212 if ((rsize = read(srcFile, inbuf + insize, BUFSIZ)) < 0) {
213 string err =
"Could not read file ";
222 inbits = ((rsize > 0) ? (insize - insize % n_bits) << 3 : (insize << 3) - (n_bits - 1));
224 while (inbits > posbits) {
225 if (free_ent > maxcode) {
226 posbits = ((posbits - 1) + ((n_bits << 3) - (posbits - 1 + (n_bits << 3)) % (n_bits << 3)));
229 if (n_bits == maxbits)
230 maxcode = maxmaxcode;
232 maxcode = MAXCODE(n_bits) - 1;
234 bitmask = (1 << n_bits) - 1;
238 unsigned char*p = &inbuf[posbits >> 3];
240 code = ((((long) (p[0])) | ((
long) (p[1]) << 8) | ((long) (p[2]) << 16)) >> (posbits & 0x7)) & bitmask;
246 string err =
"oldcode:-1 code: ";
248 err +=
" !!!! uncompress: corrupt input!!!";
252 outbuf[outpos++] = (
unsigned char) (finchar = (
int) (oldcode = code));
257 if (code == CLEAR && block_mode) {
258 memset(codetab, 0, 256);
259 free_ent = FIRST - 1;
260 posbits = ((posbits - 1) + ((n_bits << 3) - (posbits - 1 + (n_bits << 3)) % (n_bits << 3)));
261 maxcode = MAXCODE( n_bits = INIT_BITS ) - 1;
262 bitmask = (1 << n_bits) - 1;
270 if (code >= free_ent) {
271 if (code > free_ent) {
274 p = &inbuf[posbits >> 3];
276 string err =
"uncompress: corrupt input";
281 *--stackp = (
unsigned char) finchar;
286 while ((
unsigned long) code >= (
unsigned long) 256) {
287 *--stackp = htab[code];
288 code = codetab[code];
291 *--stackp = (
unsigned char) (finchar = htab[code]);
296 if (outpos + (i = (de_stack - stackp)) >= BUFSIZ) {
299 if (i > BUFSIZ - outpos) {
304 memcpy(outbuf + outpos, stackp, i);
308 if (outpos >= BUFSIZ) {
309 if (write(fd, outbuf, outpos) != outpos) {
310 string err =
"uncompress: write eror";
317 }
while ((i = (de_stack - stackp)) > 0);
320 memcpy(outbuf + outpos, stackp, i);
325 if ((code = free_ent) < maxmaxcode) {
326 codetab[code] = (
unsigned short) oldcode;
327 htab[code] = (
unsigned char) finchar;
337 if (outpos > 0 && write(fd, outbuf, outpos) != outpos) {
338 string err =
"uncompress: write eror";
345 BESDEBUG(
"bes",
"BESUncompress3Z::uncompress - end decompres" << endl);