OSDN Git Service

debugging code was removed.
[lha/olha.git] / io.c
1 /***********************************************************
2         io.c -- input/output
3 ***********************************************************/
4 #include "ar.h"
5 #include <assert.h>
6
7 #define CRCPOLY  0xA001         /* ANSI CRC-16 */
8                          /* CCITT: 0x8408 */
9
10 ushort crctable[UCHAR_MAX + 1];
11
12 void
13 make_crctable(void)
14 {
15     uint i, j, r;
16
17     for (i = 0; i <= UCHAR_MAX; i++) {
18         r = i;
19         for (j = 0; j < CHAR_BIT; j++)
20             if (r & 1)
21                 r = (r >> 1) ^ CRCPOLY;
22             else
23                 r >>= 1;
24         crctable[i] = r;
25     }
26 }
27
28 /*
29
30     shift bitbuf n bits left, read n bits
31
32                       <---- n bits shift |
33
34          7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
35          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 bitbuf   |                               |
37          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38                             <-----n----->
39
40
41
42                            read from file
43                           <------------->
44                           7 6 5 4 3 2 1 0
45                          +-+-+-+-+-+-+-+-+
46                 subbitbuf|          1 1 1|
47                          +-+-+-+-+-+-+-+-+
48                             <-----n----->
49                                     <--->
50                                      bitcount (size of subbitbuf data)
51
52 */
53
54 const char *
55 bitstring(unsigned int bitbuf, int n, char *ptr, size_t sz)
56 {
57     static char str[256];
58     size_t size = sz;
59
60     if (ptr == NULL) {
61       ptr = str;
62       size = sizeof(str);
63     }
64
65     if (n+1 > size)
66         return "bit size is too big";
67
68     str[n] = '\0';
69
70     while (n > 0) {
71       str[--n] = (bitbuf & 1) ? '1' : '0';
72       bitbuf >>= 1;
73     }
74     return str;
75 }
76
77 void
78 fillbuf(struct lzh_istream *rp, int n)
79 {
80     assert(n <= BITBUFSIZ);
81
82     /*
83       bitcount = 3
84       n = 7
85          7 6 5 4 3 2 1 0
86         +-+-+-+-+-+-+-+-+
87         |x x x x x 1 1 1|
88         +-+-+-+-+-+-+-+-+
89
90       n = 4
91          7 6 5 4 3 2 1 0
92         +-+-+-+-+-+-+-+-+
93         |x 1 1 1 x x x x|
94         +-+-+-+-+-+-+-+-+
95     */
96
97     rp->bitbuf <<= n;
98     while (n > rp->bitcount) {
99         /* set left (n - bitcount) bits from subbitbuf */
100         /* subbitbuf is extended unsigned int */
101         n -= rp->bitcount;
102         rp->bitbuf |= rp->subbitbuf << n;
103         if (rp->compsize != 0) {
104             rp->compsize--;
105             rp->subbitbuf = (uchar) getc(rp->fp);
106         }
107         else
108             rp->subbitbuf = 0;
109         rp->bitcount = CHAR_BIT;
110     }
111     /* set n bits from subbitbuf */
112     rp->bitcount -= n;
113     rp->bitbuf |= (rp->subbitbuf >> rp->bitcount) & ((1 << n)-1);
114 }
115
116 uint
117 getbits(struct lzh_istream *rp, int n)
118 {
119     uint x;
120
121     x = rp->bitbuf >> (BITBUFSIZ - n);
122     fillbuf(rp, n);
123     return x;
124 }
125
126 void
127 putbits(struct lzh_ostream *wp, int n, uint x)
128 {                               /* Write rightmost n bits of x */
129     if (n < wp->bitcount) {
130         wp->subbitbuf |= x << (wp->bitcount -= n);
131     }
132     else {
133         if (wp->compsize < wp->origsize) {
134             putc(wp->subbitbuf | (x >> (n -= wp->bitcount)), wp->fp);
135             wp->compsize++;
136         }
137         else
138             wp->unpackable = 1;
139         if (n < CHAR_BIT) {
140             wp->subbitbuf = x << (wp->bitcount = CHAR_BIT - n);
141         }
142         else {
143             if (wp->compsize < wp->origsize) {
144                 putc(x >> (n - CHAR_BIT), wp->fp);
145                 wp->compsize++;
146             }
147             else
148                 wp->unpackable = 1;
149             wp->subbitbuf = x << (wp->bitcount = 2 * CHAR_BIT - n);
150         }
151     }
152 }
153
154 int
155 fread_crc(void *p, int n, FILE * f, unsigned int *crc)
156 {
157     int i;
158
159     i = n = fread(p, 1, n, f);
160     if (crc) {
161         while (--i >= 0)
162             UPDATE_CRC(*crc, *(unsigned char*)p++);
163     }
164     return n;
165 }
166
167 void
168 fwrite_crc(void *p, int n, FILE * f, unsigned int *crc)
169 {
170     if (fwrite(p, 1, n, f) < n)
171         error("Unable to write");
172     if (crc) {
173         while (--n >= 0)
174             UPDATE_CRC(*crc, *(unsigned char*)p++);
175     }
176 }
177
178 void
179 init_getbits(struct lzh_istream *rp)
180 {
181     rp->bitbuf = 0;
182     rp->subbitbuf = 0;
183     rp->bitcount = 0;
184     fillbuf(rp, BITBUFSIZ);
185 }
186
187 void
188 init_putbits(struct lzh_ostream *wp)
189 {
190     wp->bitcount = CHAR_BIT;
191     wp->subbitbuf = 0;
192 }