OSDN Git Service

various improvement
[lha/olha.git] / io.c
1 /***********************************************************
2         io.c -- input/output
3 ***********************************************************/
4 #include "ar.h"
5 #include <stdlib.h>
6 #include <stdarg.h>
7
8 #define CRCPOLY  0xA001         /* ANSI CRC-16 */
9                          /* CCITT: 0x8408 */
10
11 FILE *arcfile, *infile, *outfile;
12 uint crc;
13 ushort bitbuf;
14
15 ushort crctable[UCHAR_MAX + 1];
16 static uint subbitbuf;
17 static int bitcount;
18
19 void
20 error(char *fmt, ...)
21 {
22     va_list args;
23
24     va_start(args, fmt);
25     putc('\n', stderr);
26     vfprintf(stderr, fmt, args);
27     putc('\n', stderr);
28     va_end(args);
29     exit(EXIT_FAILURE);
30 }
31
32 void
33 make_crctable(void)
34 {
35     uint i, j, r;
36
37     for (i = 0; i <= UCHAR_MAX; i++) {
38         r = i;
39         for (j = 0; j < CHAR_BIT; j++)
40             if (r & 1)
41                 r = (r >> 1) ^ CRCPOLY;
42             else
43                 r >>= 1;
44         crctable[i] = r;
45     }
46 }
47
48 void
49 fillbuf(int n)
50 {                               /* Shift bitbuf n bits left, read n bits */
51     bitbuf <<= n;
52     while (n > bitcount) {
53         bitbuf |= subbitbuf << (n -= bitcount);
54         if (compsize != 0) {
55             compsize--;
56             subbitbuf = (uchar) getc(arcfile);
57         }
58         else
59             subbitbuf = 0;
60         bitcount = CHAR_BIT;
61     }
62     bitbuf |= subbitbuf >> (bitcount -= n);
63 }
64
65 uint
66 getbits(int n)
67 {
68     uint x;
69
70     x = bitbuf >> (BITBUFSIZ - n);
71     fillbuf(n);
72     return x;
73 }
74
75 void
76 putbits(int n, uint x)
77 {                               /* Write rightmost n bits of x */
78     if (n < bitcount) {
79         subbitbuf |= x << (bitcount -= n);
80     }
81     else {
82         if (compsize < origsize) {
83             putc(subbitbuf | (x >> (n -= bitcount)), outfile);
84             compsize++;
85         }
86         else
87             unpackable = 1;
88         if (n < CHAR_BIT) {
89             subbitbuf = x << (bitcount = CHAR_BIT - n);
90         }
91         else {
92             if (compsize < origsize) {
93                 putc(x >> (n - CHAR_BIT), outfile);
94                 compsize++;
95             }
96             else
97                 unpackable = 1;
98             subbitbuf = x << (bitcount = 2 * CHAR_BIT - n);
99         }
100     }
101 }
102
103 int
104 fread_crc(uchar * p, int n, FILE * f)
105 {
106     int i;
107
108     i = n = fread(p, 1, n, f);
109     origsize += n;
110     while (--i >= 0)
111         UPDATE_CRC(*p++);
112     return n;
113 }
114
115 void
116 fwrite_crc(uchar * p, int n, FILE * f)
117 {
118     if (fwrite(p, 1, n, f) < n)
119         error("Unable to write");
120     while (--n >= 0)
121         UPDATE_CRC(*p++);
122 }
123
124 void
125 init_getbits(void)
126 {
127     bitbuf = 0;
128     subbitbuf = 0;
129     bitcount = 0;
130     fillbuf(BITBUFSIZ);
131 }
132
133 void
134 init_putbits(void)
135 {
136     bitcount = CHAR_BIT;
137     subbitbuf = 0;
138 }