/* ------------------------------------------------------------------------ */
-/* LHa for UNIX */
-/* slice.c -- sliding dictionary with percolating update */
-/* */
-/* Modified Nobutaka Watazaki */
-/* */
-/* Ver. 1.14d Exchanging a search algorithm 1997.01.11 T.Okamoto */
+/* LHa for UNIX */
+/* slide.c -- sliding dictionary with percolating update */
+/* */
+/* Modified Nobutaka Watazaki */
+/* */
+/* Ver. 1.14d Exchanging a search algorithm 1997.01.11 T.Okamoto */
/* ------------------------------------------------------------------------ */
#if 0
#include "lha.h"
-
#ifdef DEBUG
FILE *fout = NULL;
static int noslide = 1;
#endif
-/* ------------------------------------------------------------------------ */
-
-static unsigned long encoded_origsize;
-
-/* ------------------------------------------------------------------------ */
-
-static unsigned int *hash;
-static unsigned int *prev;
-
-/* static unsigned char *text; */
-unsigned char *too_flag;
-
+/* variables for hash */
+struct hash {
+ unsigned int pos;
+ int too_flag; /* if 1, matching candidate is too many */
+} *hash;
+static unsigned int *prev; /* previous posiion associated with hash */
+
+/* hash function: it represents 3 letters from `pos' on `text' */
+#define INIT_HASH(pos) \
+ ((( (text[(pos)] << 5) \
+ ^ text[(pos) + 1] ) << 5) \
+ ^ text[(pos) + 2] ) & (unsigned)(HSHSIZ - 1);
+#define NEXT_HASH(hash,pos) \
+ (((hash) << 5) \
+ ^ text[(pos) + 2] ) & (unsigned)(HSHSIZ - 1);
static struct encode_option encode_define[2] = {
#if defined(__STDC__) || defined(AIX)
- /* lh1 */
- {(void (*) ()) output_dyn,
- (void (*) ()) encode_start_fix,
- (void (*) ()) encode_end_dyn},
- /* lh4, 5,6 */
- {(void (*) ()) output_st1,
- (void (*) ()) encode_start_st1,
- (void (*) ()) encode_end_st1}
+ /* lh1 */
+ {(void (*) ()) output_dyn,
+ (void (*) ()) encode_start_fix,
+ (void (*) ()) encode_end_dyn},
+ /* lh4, 5, 6, 7 */
+ {(void (*) ()) output_st1,
+ (void (*) ()) encode_start_st1,
+ (void (*) ()) encode_end_st1}
#else
- /* lh1 */
- {(int (*) ()) output_dyn,
- (int (*) ()) encode_start_fix,
- (int (*) ()) encode_end_dyn},
- /* lh4, 5,6 */
- {(int (*) ()) output_st1,
- (int (*) ()) encode_start_st1,
- (int (*) ()) encode_end_st1}
+ /* lh1 */
+ {(int (*) ()) output_dyn,
+ (int (*) ()) encode_start_fix,
+ (int (*) ()) encode_end_dyn},
+ /* lh4, 5, 6, 7 */
+ {(int (*) ()) output_st1,
+ (int (*) ()) encode_start_st1,
+ (int (*) ()) encode_end_st1}
#endif
};
static struct decode_option decode_define[] = {
- /* lh1 */
- {decode_c_dyn, decode_p_st0, decode_start_fix},
- /* lh2 */
- {decode_c_dyn, decode_p_dyn, decode_start_dyn},
- /* lh3 */
- {decode_c_st0, decode_p_st0, decode_start_st0},
- /* lh4 */
- {decode_c_st1, decode_p_st1, decode_start_st1},
- /* lh5 */
- {decode_c_st1, decode_p_st1, decode_start_st1},
- /* lh6 */
- {decode_c_st1, decode_p_st1, decode_start_st1},
- /* lh7 */
- {decode_c_st1, decode_p_st1, decode_start_st1},
- /* lzs */
- {decode_c_lzs, decode_p_lzs, decode_start_lzs},
- /* lz5 */
- {decode_c_lz5, decode_p_lz5, decode_start_lz5}
+ /* lh1 */
+ {decode_c_dyn, decode_p_st0, decode_start_fix},
+ /* lh2 */
+ {decode_c_dyn, decode_p_dyn, decode_start_dyn},
+ /* lh3 */
+ {decode_c_st0, decode_p_st0, decode_start_st0},
+ /* lh4 */
+ {decode_c_st1, decode_p_st1, decode_start_st1},
+ /* lh5 */
+ {decode_c_st1, decode_p_st1, decode_start_st1},
+ /* lh6 */
+ {decode_c_st1, decode_p_st1, decode_start_st1},
+ /* lh7 */
+ {decode_c_st1, decode_p_st1, decode_start_st1},
+ /* lzs */
+ {decode_c_lzs, decode_p_lzs, decode_start_lzs},
+ /* lz5 */
+ {decode_c_lz5, decode_p_lz5, decode_start_lz5}
};
static struct encode_option encode_set;
static struct decode_option decode_set;
-#if 0
-static node pos, matchpos, avail, *position, *parent, *prev;
-static int remainder, matchlen;
-static unsigned char *level, *childcount;
-static unsigned long dicsiz; /* t.okamoto */
-static unsigned short max_hash_val;
-static unsigned short hash1, hash2;
-#endif
-
-#ifdef SUPPORT_LH7
-#define DICSIZ (1L << 16)
-#define TXTSIZ (DICSIZ * 2L + MAXMATCH)
-#else
-#define DICSIZ (((unsigned long)1) << 15)
-#define TXTSIZ (DICSIZ * 2 + MAXMATCH)
-#endif
-
+#define TXTSIZ (MAX_DICSIZ * 2L + MAXMATCH)
#define HSHSIZ (((unsigned long)1) <<15)
#define NIL 0
-#define LIMIT 0x100 /* chain ŤΠlimit */
+#define LIMIT 0x100 /* limit of hash chain */
static unsigned int txtsiz;
-
static unsigned long dicsiz;
-
-static unsigned int hval;
-static int matchlen;
-static unsigned int matchpos;
-static unsigned int pos;
static unsigned int remainder;
+struct matchdata {
+ int len;
+ unsigned int off;
+};
-/* ------------------------------------------------------------------------ */
int
encode_alloc(method)
- int method;
+ int method;
{
- if (method == LZHUFF1_METHOD_NUM) { /* Changed N.Watazaki */
- encode_set = encode_define[0];
- maxmatch = 60;
- dicbit = 12; /* 12 Changed N.Watazaki */
- } else { /* method LH4(12),LH5(13),LH6(15) */
- encode_set = encode_define[1];
- maxmatch = MAXMATCH;
- if (method == LZHUFF7_METHOD_NUM)
- dicbit = LZHUFF7_DICBIT; /* 16 bits */
- else if (method == LZHUFF6_METHOD_NUM)
- dicbit = LZHUFF6_DICBIT; /* 15 bits */
- else /* LH5 LH4 is not used */
- dicbit = LZHUFF5_DICBIT; /* 13 bits */
- }
-
- dicsiz = (((unsigned long)1) << dicbit);
- txtsiz = dicsiz*2+maxmatch;
-
- if (hash) return method;
-
- alloc_buf();
-
- hash = (unsigned int*)xmalloc(HSHSIZ * sizeof(unsigned int));
- prev = (unsigned int*)xmalloc(DICSIZ * sizeof(unsigned int));
- text = (unsigned char*)xmalloc(TXTSIZ);
- too_flag = (unsigned char*)xmalloc(HSHSIZ);
-
- return method;
+ switch (method) {
+ case LZHUFF1_METHOD_NUM:
+ encode_set = encode_define[0];
+ maxmatch = 60;
+ dicbit = LZHUFF1_DICBIT; /* 12 bits Changed N.Watazaki */
+ break;
+ case LZHUFF5_METHOD_NUM:
+ encode_set = encode_define[1];
+ maxmatch = MAXMATCH;
+ dicbit = LZHUFF5_DICBIT; /* 13 bits */
+ break;
+ case LZHUFF6_METHOD_NUM:
+ encode_set = encode_define[1];
+ maxmatch = MAXMATCH;
+ dicbit = LZHUFF6_DICBIT; /* 15 bits */
+ break;
+ case LZHUFF7_METHOD_NUM:
+ encode_set = encode_define[1];
+ maxmatch = MAXMATCH;
+ dicbit = LZHUFF7_DICBIT; /* 16 bits */
+ break;
+ default:
+ error("unknown method %d", method);
+ exit(1);
+ }
+
+ dicsiz = (((unsigned long)1) << dicbit);
+ txtsiz = dicsiz*2+maxmatch;
+
+ if (hash) return method;
+
+ alloc_buf();
+
+ hash = (struct hash*)xmalloc(HSHSIZ * sizeof(struct hash));
+ prev = (unsigned int*)xmalloc(MAX_DICSIZ * sizeof(unsigned int));
+ text = (unsigned char*)xmalloc(TXTSIZ);
+
+ return method;
}
-/* ------------------------------------------------------------------------ */
-/* ¥Ý¥¤¥ó¥¿¤Î½é´ü²½ */
-
-static void init_slide()
+static void
+init_slide()
{
- unsigned int i;
-
- for (i = 0; i < HSHSIZ; i++) {
- hash[i] = NIL;
- too_flag[i] = 0;
- }
- /*
- for (i = 0; i < DICSIZ; i++) {
- prev[i] = NIL;
- }
- */
-}
+ unsigned int i;
-/* ¼½ñ¤ò DICSIZ ʬ Á°¤Ë¤º¤é¤¹ */
+ for (i = 0; i < HSHSIZ; i++) {
+ hash[i].pos = NIL;
+ hash[i].too_flag = 0;
+ }
+}
-static unsigned int
-update(crc)
- unsigned int crc;
+/* update dictionary */
+static void
+update_dict(pos, crc)
+ unsigned int *pos;
+ unsigned int *crc;
{
- unsigned int i, j;
- long n;
+ unsigned int i, j;
+ long n;
-#if 0
- memmove(&text[0], &text[dicsiz], (unsigned)(txtsiz - dicsiz));
-#else
- {
- int m;
- i = 0; j = dicsiz; m = txtsiz-dicsiz;
- while (m-- > 0) {
- text[i++] = text[j++];
- }
- }
-#endif
- n = fread_crc(&crc, &text[(unsigned)(txtsiz - dicsiz)],
- (unsigned)dicsiz, infile);
-
- remainder += n;
- encoded_origsize += n;
-
- pos -= dicsiz;
- for (i = 0; i < HSHSIZ; i++) {
- j = hash[i];
- hash[i] = (j > dicsiz) ? j - dicsiz : NIL;
- too_flag[i] = 0;
- }
- for (i = 0; i < dicsiz; i++) {
- j = prev[i];
- prev[i] = (j > dicsiz) ? j - dicsiz : NIL;
- }
+ memmove(&text[0], &text[dicsiz], txtsiz - dicsiz);
- return crc;
-}
+ n = fread_crc(crc, &text[txtsiz - dicsiz], dicsiz, infile);
+ remainder += n;
-/* ¸½ºß¤Îʸ»úÎó¤ò¥Á¥§¡¼¥ó¤ËÄɲ乤ë */
+ *pos -= dicsiz;
+ for (i = 0; i < HSHSIZ; i++) {
+ j = hash[i].pos;
+ hash[i].pos = (j > dicsiz) ? j - dicsiz : NIL;
+ hash[i].too_flag = 0;
+ }
+ for (i = 0; i < dicsiz; i++) {
+ j = prev[i];
+ prev[i] = (j > dicsiz) ? j - dicsiz : NIL;
+ }
+}
-static void insert()
+/* associate position with token */
+static void
+insert_hash(token, pos)
+ unsigned int token;
+ unsigned int pos;
{
- prev[pos & (dicsiz - 1)] = hash[hval];
- hash[hval] = pos;
+ prev[pos & (dicsiz - 1)] = hash[token].pos; /* chain the previous pos. */
+ hash[token].pos = pos;
}
-
-/* ¸½ºß¤Îʸ»úÎó¤ÈºÇĹ°ìÃפ¹¤ëʸ»úÎó¤ò¸¡º÷¤·¡¢¥Á¥§¡¼¥ó¤ËÄɲ乤ë */
-
-static void match_insert()
+static void
+search_dict_1(token, pos, off, max, m)
+ unsigned int token;
+ unsigned int pos;
+ unsigned int off;
+ unsigned int max; /* max. length of matching string */
+ struct matchdata *m;
{
- unsigned int scan_pos, scan_end, len;
- unsigned char *a, *b;
- unsigned int chain, off, h, max;
-
- max = maxmatch; /* MAXMATCH; */
- if (matchlen < THRESHOLD - 1) matchlen = THRESHOLD - 1;
- matchpos = pos;
-
- off = 0;
- for (h = hval; too_flag[h] && off < maxmatch - THRESHOLD; ) {
- h = ((h << 5) ^ text[pos + (++off) + 2]) & (unsigned)(HSHSIZ - 1);
- }
- if (off == maxmatch - THRESHOLD) off = 0;
- for (;;) {
- chain = 0;
- scan_pos = hash[h];
- scan_end = (pos > dicsiz) ? pos + off - dicsiz : off;
- while (scan_pos > scan_end) {
- chain++;
-
- if (text[scan_pos + matchlen - off] == text[pos + matchlen]) {
- {
- a = text + scan_pos - off; b = text + pos;
- for (len = 0; len < max && *a++ == *b++; len++);
- }
-
- if (len > matchlen) {
- matchpos = scan_pos - off;
- if ((matchlen = len) == max) {
- break;
- }
+ unsigned int chain = 0;
+ unsigned int scan_pos = hash[token].pos;
+ int scan_beg = scan_pos - off;
+ int scan_end = pos - dicsiz;
+ unsigned int len;
+
+ while (scan_beg > scan_end) {
+ chain++;
+
+ if (text[scan_beg + m->len] == text[pos + m->len]) {
+ {
+ /* collate token */
+ unsigned char *a = &text[scan_beg];
+ unsigned char *b = &text[pos];
+
+ for (len = 0; len < max && *a++ == *b++; len++);
+ }
+
+ if (len > m->len) {
+ m->off = pos - scan_beg;
+ m->len = len;
+ if (m->len == max)
+ break;
+
#ifdef DEBUG
- if (noslide) {
- if (matchpos < dicsiz) {
- printf("matchpos=%u scan_pos=%u dicsiz=%u\n"
- ,matchpos, scan_pos, dicsiz);
- }
- }
+ if (noslide) {
+ if (pos - m->off < dicsiz) {
+ printf("matchpos=%u scan_pos=%u dicsiz=%u\n",
+ pos - m->off, scan_pos, dicsiz);
+ }
+ }
#endif
- }
- }
- scan_pos = prev[scan_pos & (dicsiz - 1)];
- }
-
- if (chain >= LIMIT)
- too_flag[h] = 1;
-
- if (matchlen > off + 2 || off == 0)
- break;
- max = off + 2;
- off = 0;
- h = hval;
- }
- prev[pos & (dicsiz - 1)] = hash[hval];
- hash[hval] = pos;
+ }
+ }
+ scan_pos = prev[scan_pos & (dicsiz - 1)];
+ scan_beg = scan_pos - off;
+ }
+
+ if (chain >= LIMIT)
+ hash[token].too_flag = 1;
}
+/* search the longest token matching to current token */
+static void
+search_dict(token, pos, min, m)
+ unsigned int token; /* search token */
+ unsigned int pos; /* position of token */
+ int min; /* min. length of matching string */
+ struct matchdata *m;
+{
+ unsigned int off, tok, max;
-/* ¥Ý¥¤¥ó¥¿¤ò¿Ê¤á¡¢¼½ñ¤ò¹¹¿·¤·¡¢¥Ï¥Ã¥·¥åÃͤò¹¹¿·¤¹¤ë */
+ if (min < THRESHOLD - 1) min = THRESHOLD - 1;
-static unsigned int
-get_next(crc)
- unsigned int crc;
+ max = maxmatch;
+ m->off = 0;
+ m->len = min;
+
+ off = 0;
+ for (tok = token; hash[tok].too_flag && off < maxmatch - THRESHOLD; ) {
+ /* If matching position is too many, The search key is
+ changed into following token from `off' (for speed). */
+ ++off;
+ tok = NEXT_HASH(tok, pos+off);
+ }
+ if (off == maxmatch - THRESHOLD) {
+ off = 0;
+ tok = token;
+ }
+
+ search_dict_1(tok, pos, off, max, m);
+
+ if (off > 0 && m->len < off + 3)
+ /* re-search */
+ search_dict_1(token, pos, 0, off+2, m);
+
+ if (m->len > remainder) m->len = remainder;
+}
+
+/* slide dictionary */
+static void
+next_token(token, pos, crc)
+ unsigned int *token;
+ unsigned int *pos;
+ unsigned int *crc;
{
- remainder--;
- if (++pos >= txtsiz - maxmatch) {
- crc = update(crc);
+ remainder--;
+ if (++*pos >= txtsiz - maxmatch) {
+ update_dict(pos, crc);
#ifdef DEBUG
- noslide = 0;
+ noslide = 0;
#endif
- }
- hval = ((hval << 5) ^ text[pos + 2]) & (unsigned)(HSHSIZ - 1);
-
- return crc;
+ }
+ *token = NEXT_HASH(*token, *pos);
}
unsigned int
encode(interface)
struct interfacing *interface;
{
- int lastmatchlen;
- unsigned int lastmatchoffset;
- unsigned int crc;
+ unsigned int token, pos, crc;
+ size_t count;
+ struct matchdata match, last;
#ifdef DEBUG
- unsigned int addr;
-
- addr = 0;
-
- fout = fopen("en", "wt");
- if (fout == NULL) exit(1);
+ if (!fout)
+ fout = xfopen("en", "wt");
+ fprintf(fout, "[filename: %s]\n", reading_filename);
#endif
- infile = interface->infile;
- outfile = interface->outfile;
- origsize = interface->original;
- compsize = count = 0L;
- unpackable = 0;
+ infile = interface->infile;
+ outfile = interface->outfile;
+ origsize = interface->original;
+ compsize = count = 0L;
+ unpackable = 0;
INITIALIZE_CRC(crc);
- /* encode_alloc(); */ /* allocate_memory(); */
- init_slide();
+ init_slide();
- encode_set.encode_start();
- memset(&text[0], ' ', (long)TXTSIZ);
+ encode_set.encode_start();
+ memset(text, 0, TXTSIZ);
- remainder = fread_crc(&crc, &text[dicsiz], txtsiz-dicsiz, infile);
- encoded_origsize = remainder;
- matchlen = THRESHOLD - 1;
+ remainder = fread_crc(&crc, &text[dicsiz], txtsiz-dicsiz, infile);
- pos = dicsiz;
+ match.len = THRESHOLD - 1;
+ match.off = 0;
+ if (match.len > remainder) match.len = remainder;
- if (matchlen > remainder) matchlen = remainder;
- hval = ((((text[dicsiz] << 5) ^ text[dicsiz + 1]) << 5)
- ^ text[dicsiz + 2]) & (unsigned)(HSHSIZ - 1);
+ pos = dicsiz;
+ token = INIT_HASH(pos);
+ insert_hash(token, pos); /* associate token and pos */
- insert();
- while (remainder > 0 && ! unpackable) {
- lastmatchlen = matchlen; lastmatchoffset = pos - matchpos - 1;
- --matchlen;
- crc = get_next(crc); match_insert();
- if (matchlen > remainder) matchlen = remainder;
- if (matchlen > lastmatchlen || lastmatchlen < THRESHOLD) {
- encode_set.output(text[pos - 1], 0);
+ while (remainder > 0 && ! unpackable) {
+ last = match;
+
+ next_token(&token, &pos, &crc);
+ search_dict(token, pos, last.len-1, &match);
+ insert_hash(token, pos);
+
+ if (match.len > last.len || last.len < THRESHOLD) {
+ /* output a letter */
+ encode_set.output(text[pos - 1], 0);
#ifdef DEBUG
- fprintf(fout, "%u C %02X\n", addr, text[pos-1]);
- addr++;
+ fprintf(fout, "%u C %02X\n", count, text[pos-1]);
#endif
- count++;
- } else {
- encode_set.output(lastmatchlen + (UCHAR_MAX + 1 - THRESHOLD),
- (lastmatchoffset) & (dicsiz-1) );
- --lastmatchlen;
+ count++;
+ } else {
+ /* output length and offset */
+ encode_set.output(last.len + (256 - THRESHOLD),
+ (last.off-1) & (dicsiz-1) );
#ifdef DEBUG
- fprintf(fout, "%u M %u %u ", addr,
- lastmatchoffset & (dicsiz-1), lastmatchlen+1);
- addr += lastmatchlen +1 ;
-
- {
- int t,cc;
- for (t=0; t<lastmatchlen+1; t++) {
- cc = text[pos - lastmatchoffset - 2 + t];
- fprintf(fout, "%02X ", cc);
- }
+ {
+ int i;
+ unsigned char *ptr;
+ unsigned int offset = (last.off & (dicsiz-1));
+
+ fprintf(fout, "%u M <%u %u> ",
+ count, last.len, count - offset);
+
+ ptr = &text[pos-1 - offset];
+ for (i=0; i < last.len; i++)
+ fprintf(fout, "%02X ", ptr[i]);
fprintf(fout, "\n");
- }
+ }
#endif
- while (--lastmatchlen > 0) {
- crc = get_next(crc); insert();
- count++;
- }
- crc = get_next(crc);
- matchlen = THRESHOLD - 1;
- match_insert();
- if (matchlen > remainder) matchlen = remainder;
- }
- }
- encode_set.encode_end();
-
- interface->packed = compsize;
- interface->original = encoded_origsize;
+ count += last.len;
+
+ --last.len;
+ while (--last.len > 0) {
+ next_token(&token, &pos, &crc);
+ insert_hash(token, pos);
+ }
+ next_token(&token, &pos, &crc);
+ search_dict(token, pos, THRESHOLD - 1, &match);
+ insert_hash(token, pos);
+ }
+ }
+ encode_set.encode_end();
+
+ interface->packed = compsize;
+ interface->original = count;
return crc;
}
-/* ------------------------------------------------------------------------ */
unsigned int
decode(interface)
- struct interfacing *interface;
+ struct interfacing *interface;
{
- unsigned int i, j, k, c;
- unsigned int dicsiz1, offset;
- unsigned char *dtext;
- unsigned int crc;
+ unsigned int i, c;
+ unsigned int dicsiz1, adjust;
+ unsigned char *dtext;
+ unsigned int crc;
#ifdef DEBUG
- fout = fopen("de", "wt");
- if (fout == NULL) exit(1);
+ if (!fout)
+ fout = xfopen("de", "wt");
+ fprintf(fout, "[filename: %s]\n", writing_filename);
#endif
- infile = interface->infile;
- outfile = interface->outfile;
- dicbit = interface->dicbit;
- origsize = interface->original;
- compsize = interface->packed;
- decode_set = decode_define[interface->method - 1];
-
- INITIALIZE_CRC(crc);
- prev_char = -1;
- dicsiz = 1L << dicbit;
- dtext = (unsigned char *)xmalloc(dicsiz);
- for (i=0; i<dicsiz; i++) dtext[i] = 0x20;
- decode_set.decode_start();
- dicsiz1 = dicsiz - 1;
- offset = (interface->method == LARC_METHOD_NUM) ? 0x100 - 2 : 0x100 - 3;
- count = 0;
- loc = 0;
- while (count < origsize) {
- c = decode_set.decode_c();
- if (c <= UCHAR_MAX) {
+ infile = interface->infile;
+ outfile = interface->outfile;
+ dicbit = interface->dicbit;
+ origsize = interface->original;
+ compsize = interface->packed;
+ decode_set = decode_define[interface->method - 1];
+
+ INITIALIZE_CRC(crc);
+ dicsiz = 1L << dicbit;
+ dtext = (unsigned char *)xmalloc(dicsiz);
+ memset(dtext, 0, dicsiz);
+ decode_set.decode_start();
+ dicsiz1 = dicsiz - 1;
+ adjust = 256 - THRESHOLD;
+ if (interface->method == LARC_METHOD_NUM)
+ adjust = 256 - 2;
+
+ decode_count = 0;
+ loc = 0;
+ while (decode_count < origsize) {
+ c = decode_set.decode_c();
+ if (c < 256) {
#ifdef DEBUG
- fprintf(fout, "%u C %02X\n", count, c);
+ fprintf(fout, "%u C %02X\n", decode_count, c);
#endif
- dtext[loc++] = c;
- if (loc == dicsiz) {
- fwrite_crc(&crc, dtext, dicsiz, outfile);
- loc = 0;
- }
- count++;
- }
- else {
- j = c - offset;
- i = (loc - decode_set.decode_p() - 1) & dicsiz1;
+ dtext[loc++] = c;
+ if (loc == dicsiz) {
+ fwrite_crc(&crc, dtext, dicsiz, outfile);
+ loc = 0;
+ }
+ decode_count++;
+ }
+ else {
+ struct matchdata match;
+ unsigned int matchpos;
+
+ match.len = c - adjust;
+ match.off = decode_set.decode_p() + 1;
+ matchpos = (loc - match.off) & dicsiz1;
#ifdef DEBUG
- fprintf(fout, "%u M %u %u ", count, (loc-1-i) & dicsiz1, j);
+ fprintf(fout, "%u M <%u %u> ",
+ decode_count, match.len, decode_count-match.off);
#endif
- count += j;
- for (k = 0; k < j; k++) {
- c = dtext[(i + k) & dicsiz1];
-
+ decode_count += match.len;
+ for (i = 0; i < match.len; i++) {
+ c = dtext[(matchpos + i) & dicsiz1];
#ifdef DEBUG
- fprintf(fout, "%02X ", c & 0xff);
+ fprintf(fout, "%02X ", c & 0xff);
#endif
- dtext[loc++] = c;
- if (loc == dicsiz) {
- fwrite_crc(&crc, dtext, dicsiz, outfile);
- loc = 0;
- }
- }
+ dtext[loc++] = c;
+ if (loc == dicsiz) {
+ fwrite_crc(&crc, dtext, dicsiz, outfile);
+ loc = 0;
+ }
+ }
#ifdef DEBUG
- fprintf(fout, "\n");
+ fprintf(fout, "\n");
#endif
- }
- }
- if (loc != 0) {
- fwrite_crc(&crc, dtext, loc, outfile);
- }
+ }
+ }
+ if (loc != 0) {
+ fwrite_crc(&crc, dtext, loc, outfile);
+ }
+
+ free(dtext);
+
+ /* usually read size is interface->packed */
+ interface->read_size = interface->packed - compsize;
- free(dtext);
return crc;
}
-
-/* Local Variables: */
-/* mode:c */
-/* tab-width:4 */
-/* End: */
-/* vi: set tabstop=4: */