"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "lha-114i/src/crcio.c" of archive lha-114i.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /* ------------------------------------------------------------------------ */
2 /* LHa for UNIX */
3 /* crcio.c -- crc input / output */
4 /* */
5 /* Modified Nobutaka Watazaki */
6 /* */
7 /* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
8 /* ------------------------------------------------------------------------ */
9 #include "lha.h"
10
11 /* ------------------------------------------------------------------------ */
12 static unsigned short crctable[UCHAR_MAX + 1];
13 static unsigned char subbitbuf, bitcount;
14 #ifdef EUC
15 static int putc_euc_cache;
16 #endif
17 static int getc_euc_cache;
18
19 /* ------------------------------------------------------------------------ */
20 void
21 make_crctable( /* void */ )
22 {
23 unsigned int i, j, r;
24
25 for (i = 0; i <= UCHAR_MAX; i++) {
26 r = i;
27 for (j = 0; j < CHAR_BIT; j++)
28 if (r & 1)
29 r = (r >> 1) ^ CRCPOLY;
30 else
31 r >>= 1;
32 crctable[i] = r;
33 }
34 }
35
36 /* ------------------------------------------------------------------------ */
37 #ifdef NEED_INCREMENTAL_INDICATOR
38 static void
39 put_indicator(count)
40 long int count;
41 {
42 if (!quiet && indicator_threshold) {
43 while (count > indicator_count) {
44 putchar('o');
45 fflush(stdout);
46 indicator_count += indicator_threshold;
47 }
48 }
49 }
50 #endif
51
52 /* ------------------------------------------------------------------------ */
53 unsigned short
54 calccrc(p, n)
55 unsigned char *p;
56 unsigned int n;
57 {
58 reading_size += n;
59 #ifdef NEED_INCREMENTAL_INDICATOR
60 put_indicator(reading_size);
61 #endif
62 while (n-- > 0)
63 UPDATE_CRC(*p++);
64 return crc;
65 }
66
67 /* ------------------------------------------------------------------------ */
68 void
69 fillbuf(n) /* Shift bitbuf n bits left, read n bits */
70 unsigned char n;
71 {
72 while (n > bitcount) {
73 n -= bitcount;
74 bitbuf = (bitbuf << bitcount) + (subbitbuf >> (CHAR_BIT - bitcount));
75 if (compsize != 0) {
76 compsize--;
77 subbitbuf = (unsigned char) getc(infile);
78 }
79 else
80 subbitbuf = 0;
81 bitcount = CHAR_BIT;
82 }
83 bitcount -= n;
84 bitbuf = (bitbuf << n) + (subbitbuf >> (CHAR_BIT - n));
85 subbitbuf <<= n;
86 }
87
88 /* ------------------------------------------------------------------------ */
89 unsigned short
90 getbits(n)
91 unsigned char n;
92 {
93 unsigned short x;
94
95 x = bitbuf >> (2 * CHAR_BIT - n);
96 fillbuf(n);
97 return x;
98 }
99
100 /* ------------------------------------------------------------------------ */
101 void
102 putcode(n, x) /* Write rightmost n bits of x */
103 unsigned char n;
104 unsigned short x;
105 {
106 while (n >= bitcount) {
107 n -= bitcount;
108 subbitbuf += x >> (USHRT_BIT - bitcount);
109 x <<= bitcount;
110 if (compsize < origsize) {
111 if (fwrite(&subbitbuf, 1, 1, outfile) == 0) {
112 /* fileerror(WTERR, outfile); */
113 fatal_error("Write error in crcio.c(putcode)\n");
114 /* exit(errno); */
115 }
116 compsize++;
117 }
118 else
119 unpackable = 1;
120 subbitbuf = 0;
121 bitcount = CHAR_BIT;
122 }
123 subbitbuf += x >> (USHRT_BIT - bitcount);
124 bitcount -= n;
125 }
126
127 /* ------------------------------------------------------------------------ */
128 void
129 putbits(n, x) /* Write rightmost n bits of x */
130 unsigned char n;
131 unsigned short x;
132 {
133 x <<= USHRT_BIT - n;
134 while (n >= bitcount) {
135 n -= bitcount;
136 subbitbuf += x >> (USHRT_BIT - bitcount);
137 x <<= bitcount;
138 if (compsize < origsize) {
139 if (fwrite(&subbitbuf, 1, 1, outfile) == 0) {
140 /* fileerror(WTERR, outfile); */
141 fatal_error("Write error in crcio.c(putbits)\n");
142 /* exit(errno); */
143 }
144 compsize++;
145 }
146 else
147 unpackable = 1;
148 subbitbuf = 0;
149 bitcount = CHAR_BIT;
150 }
151 subbitbuf += x >> (USHRT_BIT - bitcount);
152 bitcount -= n;
153 }
154
155 /* ------------------------------------------------------------------------ */
156 int
157 fread_crc(p, n, fp)
158 unsigned char *p;
159 int n;
160 FILE *fp;
161 {
162 if (text_mode)
163 n = fread_txt(p, n, fp);
164 else
165 n = fread(p, 1, n, fp);
166
167 calccrc(p, n);
168 return n;
169 }
170
171 /* ------------------------------------------------------------------------ */
172 void
173 fwrite_crc(p, n, fp)
174 unsigned char *p;
175 int n;
176 FILE *fp;
177 {
178 calccrc(p, n);
179 if (verify_mode)
180 return;
181
182 if (fp) {
183 if (text_mode) {
184 if (fwrite_txt(p, n, fp))
185 fatal_error("File write error\n");
186 }
187 else {
188 if (fwrite(p, 1, n, fp) < n)
189 fatal_error("File write error\n");
190 }
191 }
192 }
193
194 /* ------------------------------------------------------------------------ */
195 void
196 init_code_cache( /* void */ )
197 { /* called from copyfile() in util.c */
198 #ifdef EUC
199 putc_euc_cache = EOF;
200 #endif
201 getc_euc_cache = EOF;
202 }
203
204 void
205 init_getbits( /* void */ )
206 {
207 bitbuf = 0;
208 subbitbuf = 0;
209 bitcount = 0;
210 fillbuf(2 * CHAR_BIT);
211 #ifdef EUC
212 putc_euc_cache = EOF;
213 #endif
214 }
215
216 /* ------------------------------------------------------------------------ */
217 void
218 init_putbits( /* void */ )
219 {
220 bitcount = CHAR_BIT;
221 subbitbuf = 0;
222 getc_euc_cache = EOF;
223 }
224
225 /* ------------------------------------------------------------------------ */
226 #ifdef EUC
227 void
228 putc_euc(c, fd)
229 int c;
230 FILE *fd;
231 {
232 int d;
233
234 if (putc_euc_cache == EOF) {
235 if (!euc_mode || c < 0x81 || c > 0xFC) {
236 putc(c, fd);
237 return;
238 }
239 if (c >= 0xA0 && c < 0xE0) {
240 putc(0x8E, fd); /* single shift */
241 putc(c, fd);
242 return;
243 }
244 putc_euc_cache = c; /* save first byte */
245 return;
246 }
247 d = putc_euc_cache;
248 putc_euc_cache = EOF;
249 if (d >= 0xA0)
250 d -= 0xE0 - 0xA0;
251 if (c > 0x9E) {
252 c = c - 0x9F + 0x21;
253 d = (d - 0x81) * 2 + 0x22;
254 }
255 else {
256 if (c > 0x7E)
257 c--;
258 c -= 0x1F;
259 d = (d - 0x81) * 2 + 0x21;
260 }
261 putc(0x80 | d, fd);
262 putc(0x80 | c, fd);
263 }
264 #endif
265
266 /* ------------------------------------------------------------------------ */
267 int
268 fwrite_txt(p, n, fp)
269 unsigned char *p;
270 int n;
271 FILE *fp;
272 {
273 while (--n >= 0) {
274 if (*p != '\015' && *p != '\032') {
275 #ifdef EUC
276 putc_euc(*p, fp);
277 #else
278 putc(*p, fp);
279 #endif
280 }
281
282 prev_char = *p++;
283 }
284 return (ferror(fp));
285 }
286
287 /* ------------------------------------------------------------------------ */
288 int
289 fread_txt(p, n, fp)
290 unsigned char *p;
291 int n;
292 FILE *fp;
293 {
294 int c;
295 int cnt = 0;
296
297 while (cnt < n) {
298 if (getc_euc_cache != EOF) {
299 c = getc_euc_cache;
300 getc_euc_cache = EOF;
301 }
302 else {
303 if ((c = fgetc(fp)) == EOF)
304 break;
305 if (c == '\n') {
306 getc_euc_cache = c;
307 ++origsize;
308 c = '\r';
309 }
310 #ifdef EUC
311 else if (euc_mode && (c == 0x8E || 0xA0 < c && c < 0xFF)) {
312 int d = fgetc(fp);
313 if (d == EOF) {
314 *p++ = c;
315 cnt++;
316 break;
317 }
318 if (c == 0x8E) { /* single shift (KANA) */
319 if ((0x20 < d && d < 0x7F) || (0xA0 < d && d < 0xFF))
320 c = d | 0x80;
321 else
322 getc_euc_cache = d;
323 }
324 else {
325 if (0xA0 < d && d < 0xFF) { /* if GR */
326 c &= 0x7F; /* convert to MS-kanji */
327 d &= 0x7F;
328 if (!(c & 1)) {
329 c--;
330 d += 0x7F - 0x21;
331 }
332 if ((d += 0x40 - 0x21) > 0x7E)
333 d++;
334 if ((c = (c >> 1) + 0x71) >= 0xA0)
335 c += 0xE0 - 0xA0;
336 }
337 getc_euc_cache = d;
338 }
339 }
340 #endif
341 }
342 *p++ = c;
343 cnt++;
344 }
345 return cnt;
346 }
347
348 /* ------------------------------------------------------------------------ */
349 unsigned short
350 calc_header_crc(p, n) /* Thanks T.Okamoto */
351 unsigned char *p;
352 unsigned int n;
353 {
354 crc = 0;
355 while (n-- > 0)
356 UPDATE_CRC(*p++);
357 return crc;
358 }