OSDN Git Service

extract.c and decode.c was refined.
[lha/olha.git] / decode.c
1 /***********************************************************
2         decode.c
3 ***********************************************************/
4 #include "ar.h"
5
6 extern struct lha_opts opts;
7
8 void
9 decode(struct lzh_istream *rp, FILE *outfile, unsigned long remainder, unsigned int *crc)
10 {
11     char buf[MAXDICSIZ];
12     struct huf_t huf;
13     unsigned int r, n;
14
15     huf_decode_start(rp, opts.method);
16
17     r = 0;
18     n = (uint)MIN(remainder, MAXDICSIZ);
19
20     for (;;) {
21         uint c = decode_c(&huf, rp);
22         if (c <= UCHAR_MAX) {
23             buf[r] = c;
24             if (++r == n) {
25                 fwrite_crc(buf, n, outfile, crc);
26                 if (outfile != stdout && opts.quiet < 1) {
27                     putc('.', stdout);
28                 }
29
30                 remainder -= n;
31                 if (remainder <= 0) return;
32
33                 r = 0;
34                 n = (uint)MIN(remainder, MAXDICSIZ);
35             }
36         }
37         else {
38             unsigned int slide_off = 0;
39             int slide_len = 0;
40
41             slide_len = c - (UCHAR_MAX + 1 - THRESHOLD);
42             slide_off = (r - decode_p(&huf, rp) - 1) & (MAXDICSIZ - 1);
43             while (--slide_len >= 0) {
44                 buf[r] = buf[slide_off];
45                 slide_off = (slide_off+1) & (MAXDICSIZ - 1);
46                 if (++r == n) {
47                     fwrite_crc(buf, n, outfile, crc);
48                     if (outfile != stdout && opts.quiet < 1) {
49                         putc('.', stdout);
50                     }
51
52                     remainder -= n;
53                     if (remainder <= 0) return;
54
55                     r = 0;
56                     n = (uint)MIN(remainder, MAXDICSIZ);
57                 }
58             }
59         }
60     }
61 }