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
make_crctable()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
calccrc(crc,p,n)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
fread_crc(crcp,p,n,fp)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
fwrite_crc(crcp,p,n,fp)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
init_code_cache()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
putc_euc(c,fd)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
fwrite_txt(p,n,fp)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
fread_txt(p,n,fp)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 }
224