OSDN Git Service

* src/lha.h (prev_char): discard unused variable `prev_char'.
[lha/lha.git] / src / crcio.c
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 #ifdef EUC
13 static int      putc_euc_cache;
14 #endif
15 static int      getc_euc_cache;
16
17 /* ------------------------------------------------------------------------ */
18 void
19 make_crctable( /* void */ )
20 {
21     unsigned int    i, j, r;
22
23     for (i = 0; i <= UCHAR_MAX; i++) {
24         r = i;
25         for (j = 0; j < CHAR_BIT; j++)
26             if (r & 1)
27                 r = (r >> 1) ^ CRCPOLY;
28             else
29                 r >>= 1;
30         crctable[i] = r;
31     }
32 }
33
34 /* ------------------------------------------------------------------------ */
35 unsigned int
36 calccrc(crc, p, n)
37     unsigned int crc;
38     unsigned char  *p;
39     unsigned int    n;
40 {
41     while (n-- > 0)
42         crc = UPDATE_CRC(crc, *p++);
43     return crc;
44 }
45
46 /* ------------------------------------------------------------------------ */
47 int
48 fread_crc(crcp, p, n, fp)
49     unsigned int *crcp;
50     unsigned char  *p;
51     int             n;
52     FILE           *fp;
53 {
54     if (text_mode)
55         n = fread_txt(p, n, fp);
56     else
57         n = fread(p, 1, n, fp);
58
59     *crcp = calccrc(*crcp, p, n);
60 #ifdef NEED_INCREMENTAL_INDICATOR
61     put_indicator(n);
62 #endif
63     return n;
64 }
65
66 /* ------------------------------------------------------------------------ */
67 void
68 fwrite_crc(crcp, p, n, fp)
69     unsigned int *crcp;
70     unsigned char  *p;
71     int             n;
72     FILE           *fp;
73 {
74     *crcp = calccrc(*crcp, p, n);
75 #ifdef NEED_INCREMENTAL_INDICATOR
76     put_indicator(n);
77 #endif
78     if (verify_mode)
79         return;
80
81     if (fp) {
82         if (text_mode) {
83             if (fwrite_txt(p, n, fp))
84                 fatal_error("File write error");
85         }
86         else {
87             if (fwrite(p, 1, n, fp) < n)
88                 fatal_error("File write error");
89         }
90     }
91 }
92
93 /* ------------------------------------------------------------------------ */
94 void
95 init_code_cache( /* void */ )
96 {               /* called from copyfile() in util.c */
97 #ifdef EUC
98     putc_euc_cache = EOF;
99 #endif
100     getc_euc_cache = EOF;
101 }
102
103 /* ------------------------------------------------------------------------ */
104 #ifdef EUC
105 int
106 putc_euc(c, fd)
107     int             c;
108     FILE           *fd;
109 {
110     int             d;
111
112     if (putc_euc_cache == EOF) {
113         if (!euc_mode || c < 0x81 || c > 0xFC) {
114             return putc(c, fd);
115         }
116         if (c >= 0xA0 && c < 0xE0) {
117             if (putc(0x8E, fd) == EOF) return EOF;  /* single shift */
118             return putc(c, fd);
119         }
120         putc_euc_cache = c; /* save first byte */
121         return c;
122     }
123     d = putc_euc_cache;
124     putc_euc_cache = EOF;
125     if (d >= 0xA0)
126         d -= 0xE0 - 0xA0;
127     if (c > 0x9E) {
128         c = c - 0x9F + 0x21;
129         d = (d - 0x81) * 2 + 0x22;
130     }
131     else {
132         if (c > 0x7E)
133             c--;
134         c -= 0x1F;
135         d = (d - 0x81) * 2 + 0x21;
136     }
137     if (putc(0x80 | d, fd) == EOF) return EOF;
138     return putc(0x80 | c, fd);
139 }
140 #endif
141
142 /* ------------------------------------------------------------------------ */
143 int
144 fwrite_txt(p, n, fp)
145     unsigned char  *p;
146     int             n;
147     FILE           *fp;
148 {
149     while (--n >= 0) {
150         if (*p != '\015' && *p != '\032') {
151 #ifdef EUC
152             if (putc_euc(*p, fp) == EOF)
153                 break;
154 #else
155             if (putc(*p, fp) == EOF)
156                 break;
157 #endif
158         }
159         p++;
160     }
161     return (ferror(fp));
162 }
163
164 /* ------------------------------------------------------------------------ */
165 int
166 fread_txt(p, n, fp)
167     unsigned char  *p;
168     int             n;
169     FILE           *fp;
170 {
171     int             c;
172     int             cnt = 0;
173
174     while (cnt < n) {
175         if (getc_euc_cache != EOF) {
176             c = getc_euc_cache;
177             getc_euc_cache = EOF;
178         }
179         else {
180             if ((c = fgetc(fp)) == EOF)
181                 break;
182             if (c == '\n') {
183                 getc_euc_cache = c;
184                 ++origsize;
185                 c = '\r';
186             }
187 #ifdef EUC
188             else if (euc_mode && (c == 0x8E || (0xA0 < c && c < 0xFF))) {
189                 int             d = fgetc(fp);
190                 if (d == EOF) {
191                     *p++ = c;
192                     cnt++;
193                     break;
194                 }
195                 if (c == 0x8E) {    /* single shift (KANA) */
196                     if ((0x20 < d && d < 0x7F) || (0xA0 < d && d < 0xFF))
197                         c = d | 0x80;
198                     else
199                         getc_euc_cache = d;
200                 }
201                 else {
202                     if (0xA0 < d && d < 0xFF) { /* if GR */
203                         c &= 0x7F;  /* convert to MS-kanji */
204                         d &= 0x7F;
205                         if (!(c & 1)) {
206                             c--;
207                             d += 0x7F - 0x21;
208                         }
209                         if ((d += 0x40 - 0x21) > 0x7E)
210                             d++;
211                         if ((c = (c >> 1) + 0x71) >= 0xA0)
212                             c += 0xE0 - 0xA0;
213                     }
214                     getc_euc_cache = d;
215                 }
216             }
217 #endif
218         }
219         *p++ = c;
220         cnt++;
221     }
222     return cnt;
223 }