Annotation of embedaddon/php/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c, revision 1.1.1.1
1.1 misho 1: /*
2: * "streamable kanji code filter and converter"
3: * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
4: *
5: * LICENSE NOTICES
6: *
7: * This file is part of "streamable kanji code filter and converter",
8: * which is distributed under the terms of GNU Lesser General Public
9: * License (version 2) as published by the Free Software Foundation.
10: *
11: * This software is distributed in the hope that it will be useful,
12: * but WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: * GNU Lesser General Public License for more details.
15: *
16: * You should have received a copy of the GNU Lesser General Public
17: * License along with "streamable kanji code filter and converter";
18: * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
19: * Suite 330, Boston, MA 02111-1307 USA
20: *
21: * The author of this file: Moriyoshi Koizumi <koizumi@gree.co.jp>
22: *
23: */
24:
25: #ifdef HAVE_CONFIG_H
26: #include "config.h"
27: #endif
28:
29: #include "mbfilter.h"
30: #include "mbfilter_cp5022x.h"
31: #include "mbfilter_jis.h"
32: #include "mbfilter_tl_jisx0201_jisx0208.h"
33:
34: #include "unicode_table_cp932_ext.h"
35: #include "unicode_table_jis.h"
36: #include "cp932_table.h"
37:
38: typedef struct _mbfl_filt_conv_wchar_cp50220_ctx {
39: mbfl_filt_tl_jisx0201_jisx0208_param tl_param;
40: mbfl_convert_filter last;
41: } mbfl_filt_conv_wchar_cp50220_ctx;
42:
43: static int mbfl_filt_ident_jis_ms(int c, mbfl_identify_filter *filter);
44: static int mbfl_filt_ident_cp50220(int c, mbfl_identify_filter *filter);
45: static int mbfl_filt_ident_cp50221(int c, mbfl_identify_filter *filter);
46: static int mbfl_filt_ident_cp50222(int c, mbfl_identify_filter *filter);
47: static void mbfl_filt_conv_wchar_cp50220_ctor(mbfl_convert_filter *filt);
48: static void mbfl_filt_conv_wchar_cp50220_dtor(mbfl_convert_filter *filt);
49: static void mbfl_filt_conv_wchar_cp50220_copy(mbfl_convert_filter *src, mbfl_convert_filter *dest);
50:
51: const mbfl_encoding mbfl_encoding_jis_ms = {
52: mbfl_no_encoding_jis_ms,
53: "JIS-ms",
54: "ISO-2022-JP",
55: NULL,
56: NULL,
57: MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE
58: };
59:
60: const mbfl_encoding mbfl_encoding_cp50220 = {
61: mbfl_no_encoding_cp50220,
62: "CP50220",
63: "ISO-2022-JP",
64: (const char *(*)[])NULL,
65: NULL,
66: MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE
67: };
68:
69: const mbfl_encoding mbfl_encoding_cp50220raw = {
70: mbfl_no_encoding_cp50220raw,
71: "CP50220raw",
72: "ISO-2022-JP",
73: (const char *(*)[])NULL,
74: NULL,
75: MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE
76: };
77:
78: const mbfl_encoding mbfl_encoding_cp50221 = {
79: mbfl_no_encoding_cp50221,
80: "CP50221",
81: "ISO-2022-JP",
82: NULL,
83: NULL,
84: MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE
85: };
86:
87: const mbfl_encoding mbfl_encoding_cp50222 = {
88: mbfl_no_encoding_cp50222,
89: "CP50222",
90: "ISO-2022-JP",
91: NULL,
92: NULL,
93: MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE
94: };
95:
96: const struct mbfl_identify_vtbl vtbl_identify_jis_ms = {
97: mbfl_no_encoding_jis_ms,
98: mbfl_filt_ident_common_ctor,
99: mbfl_filt_ident_common_dtor,
100: mbfl_filt_ident_jis_ms
101: };
102:
103: const struct mbfl_identify_vtbl vtbl_identify_cp50220 = {
104: mbfl_no_encoding_cp50220,
105: mbfl_filt_ident_common_ctor,
106: mbfl_filt_ident_common_dtor,
107: mbfl_filt_ident_cp50220
108: };
109:
110: const struct mbfl_identify_vtbl vtbl_identify_cp50220raw = {
111: mbfl_no_encoding_cp50220raw,
112: mbfl_filt_ident_common_ctor,
113: mbfl_filt_ident_common_dtor,
114: mbfl_filt_ident_cp50220
115: };
116:
117: const struct mbfl_identify_vtbl vtbl_identify_cp50221 = {
118: mbfl_no_encoding_cp50221,
119: mbfl_filt_ident_common_ctor,
120: mbfl_filt_ident_common_dtor,
121: mbfl_filt_ident_cp50221
122: };
123:
124: const struct mbfl_identify_vtbl vtbl_identify_cp50222 = {
125: mbfl_no_encoding_cp50222,
126: mbfl_filt_ident_common_ctor,
127: mbfl_filt_ident_common_dtor,
128: mbfl_filt_ident_cp50222
129: };
130:
131: const struct mbfl_convert_vtbl vtbl_jis_ms_wchar = {
132: mbfl_no_encoding_jis_ms,
133: mbfl_no_encoding_wchar,
134: mbfl_filt_conv_common_ctor,
135: mbfl_filt_conv_common_dtor,
136: mbfl_filt_conv_jis_ms_wchar,
137: mbfl_filt_conv_common_flush,
138: };
139:
140: const struct mbfl_convert_vtbl vtbl_wchar_jis_ms = {
141: mbfl_no_encoding_wchar,
142: mbfl_no_encoding_jis_ms,
143: mbfl_filt_conv_common_ctor,
144: mbfl_filt_conv_common_dtor,
145: mbfl_filt_conv_wchar_jis_ms,
146: mbfl_filt_conv_any_jis_flush
147: };
148:
149: const struct mbfl_convert_vtbl vtbl_cp50220_wchar = {
150: mbfl_no_encoding_cp50220,
151: mbfl_no_encoding_wchar,
152: mbfl_filt_conv_common_ctor,
153: mbfl_filt_conv_common_dtor,
154: mbfl_filt_conv_jis_ms_wchar,
155: mbfl_filt_conv_common_flush
156: };
157:
158: const struct mbfl_convert_vtbl vtbl_wchar_cp50220 = {
159: mbfl_no_encoding_wchar,
160: mbfl_no_encoding_cp50220,
161: mbfl_filt_conv_wchar_cp50220_ctor,
162: mbfl_filt_conv_wchar_cp50220_dtor,
163: mbfl_filt_conv_wchar_cp50221,
164: mbfl_filt_conv_any_jis_flush,
165: mbfl_filt_conv_wchar_cp50220_copy
166: };
167:
168: const struct mbfl_convert_vtbl vtbl_cp50220raw_wchar = {
169: mbfl_no_encoding_cp50220raw,
170: mbfl_no_encoding_wchar,
171: mbfl_filt_conv_common_ctor,
172: mbfl_filt_conv_common_dtor,
173: mbfl_filt_conv_jis_ms_wchar,
174: mbfl_filt_conv_common_flush
175: };
176:
177: const struct mbfl_convert_vtbl vtbl_wchar_cp50220raw = {
178: mbfl_no_encoding_wchar,
179: mbfl_no_encoding_cp50220raw,
180: mbfl_filt_conv_wchar_cp50220_ctor,
181: mbfl_filt_conv_wchar_cp50220_dtor,
182: mbfl_filt_conv_wchar_cp50220raw,
183: mbfl_filt_conv_any_jis_flush,
184: mbfl_filt_conv_wchar_cp50220_copy
185: };
186:
187: const struct mbfl_convert_vtbl vtbl_cp50221_wchar = {
188: mbfl_no_encoding_cp50221,
189: mbfl_no_encoding_wchar,
190: mbfl_filt_conv_common_ctor,
191: mbfl_filt_conv_common_dtor,
192: mbfl_filt_conv_jis_ms_wchar,
193: mbfl_filt_conv_common_flush
194: };
195:
196: const struct mbfl_convert_vtbl vtbl_wchar_cp50221 = {
197: mbfl_no_encoding_wchar,
198: mbfl_no_encoding_cp50221,
199: mbfl_filt_conv_common_ctor,
200: mbfl_filt_conv_common_dtor,
201: mbfl_filt_conv_wchar_cp50221,
202: mbfl_filt_conv_any_jis_flush
203: };
204:
205: const struct mbfl_convert_vtbl vtbl_cp50222_wchar = {
206: mbfl_no_encoding_cp50222,
207: mbfl_no_encoding_wchar,
208: mbfl_filt_conv_common_ctor,
209: mbfl_filt_conv_common_dtor,
210: mbfl_filt_conv_jis_ms_wchar,
211: mbfl_filt_conv_common_flush
212: };
213:
214: const struct mbfl_convert_vtbl vtbl_wchar_cp50222 = {
215: mbfl_no_encoding_wchar,
216: mbfl_no_encoding_cp50222,
217: mbfl_filt_conv_common_ctor,
218: mbfl_filt_conv_common_dtor,
219: mbfl_filt_conv_wchar_cp50222,
220: mbfl_filt_conv_wchar_cp50222_flush
221: };
222:
223: #define CK(statement) do { if ((statement) < 0) return (-1); } while (0)
224:
225: /*
226: * JIS-ms => wchar
227: */
228: int
229: mbfl_filt_conv_jis_ms_wchar(int c, mbfl_convert_filter *filter)
230: {
231: int c1, s, w;
232:
233: retry:
234: switch (filter->status & 0xf) {
235: /* case 0x00: ASCII */
236: /* case 0x10: X 0201 latin */
237: /* case 0x20: X 0201 kana */
238: /* case 0x80: X 0208 */
239: /* case 0x90: X 0212 */
240: case 0:
241: if (c == 0x1b) {
242: filter->status += 2;
243: } else if (c == 0x0e) { /* "kana in" */
244: filter->status = 0x20;
245: } else if (c == 0x0f) { /* "kana out" */
246: filter->status = 0;
247: } else if (filter->status == 0x10 && c == 0x5c) { /* YEN SIGN */
248: CK((*filter->output_function)(0xa5, filter->data));
249: } else if (filter->status == 0x10 && c == 0x7e) { /* OVER LINE */
250: CK((*filter->output_function)(0x203e, filter->data));
251: } else if (filter->status == 0x20 && c > 0x20 && c < 0x60) { /* kana */
252: CK((*filter->output_function)(0xff40 + c, filter->data));
253: } else if ((filter->status == 0x80 || filter->status == 0x90) && c > 0x20 && c < 0x7f) { /* kanji first char */
254: filter->cache = c;
255: filter->status += 1;
256: } else if (c >= 0 && c < 0x80) { /* latin, CTLs */
257: CK((*filter->output_function)(c, filter->data));
258: } else if (c > 0xa0 && c < 0xe0) { /* GR kana */
259: CK((*filter->output_function)(0xfec0 + c, filter->data));
260: } else {
261: w = c & MBFL_WCSGROUP_MASK;
262: w |= MBFL_WCSGROUP_THROUGH;
263: CK((*filter->output_function)(w, filter->data));
264: }
265: break;
266:
267: /* case 0x81: X 0208 second char */
268: /* case 0x91: X 0212 second char */
269: case 1:
270: filter->status &= ~0xf;
271: c1 = filter->cache;
272: if (c > 0x20 && c < 0x7f) {
273: s = (c1 - 0x21)*94 + c - 0x21;
274: if (filter->status == 0x80) {
275: if (s >= 0 && s < jisx0208_ucs_table_size) {
276: w = jisx0208_ucs_table[s];
277: } else if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) {
278: w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min];
279: } else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) {
280: w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min];
281: } else if (s >= cp932ext3_ucs_table_min && s < cp932ext2_ucs_table_max) {
282: w = cp932ext3_ucs_table[s - cp932ext3_ucs_table_min];
283: } else if (s >= 94 * 94 && s < 114 * 94) {
284: /* user-defined => PUA (Microsoft extended) */
285: w = (s & 0xff) + ((s >> 8) - 94) * 94 + 0xe000;
286: } else if (s >= 212 * 94 && s < 222 * 94) {
287: /* user-defined => PUA (G3 85 - 94 Ku) */
288: w = (s & 0xff) + ((s >> 8) - 212) * 94 + 0xe000 + 10 * 94;
289: } else {
290: w = 0;
291: }
292: if (w <= 0) {
293: w = (c1 << 8) | c;
294: w &= MBFL_WCSPLANE_MASK;
295: w |= MBFL_WCSPLANE_JIS0208;
296: }
297: } else {
298: if (s >= 0 && s < jisx0212_ucs_table_size) {
299: w = jisx0212_ucs_table[s];
300: } else {
301: w = 0;
302: }
303: if (w <= 0) {
304: w = (c1 << 8) | c;
305: w &= MBFL_WCSPLANE_MASK;
306: w |= MBFL_WCSPLANE_JIS0212;
307: }
308: }
309: CK((*filter->output_function)(w, filter->data));
310: } else if (c == 0x1b) {
311: filter->status += 2;
312: } else if ((c >= 0 && c < 0x21) || c == 0x7f) { /* CTLs */
313: CK((*filter->output_function)(c, filter->data));
314: } else {
315: w = (c1 << 8) | c;
316: w &= MBFL_WCSGROUP_MASK;
317: w |= MBFL_WCSGROUP_THROUGH;
318: CK((*filter->output_function)(w, filter->data));
319: }
320: break;
321:
322: /* ESC */
323: /* case 0x02: */
324: /* case 0x12: */
325: /* case 0x22: */
326: /* case 0x82: */
327: /* case 0x92: */
328: case 2:
329: if (c == 0x24) { /* '$' */
330: filter->status++;
331: } else if (c == 0x28) { /* '(' */
332: filter->status += 3;
333: } else {
334: filter->status &= ~0xf;
335: CK((*filter->output_function)(0x1b, filter->data));
336: goto retry;
337: }
338: break;
339:
340: /* ESC $ */
341: /* case 0x03: */
342: /* case 0x13: */
343: /* case 0x23: */
344: /* case 0x83: */
345: /* case 0x93: */
346: case 3:
347: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */
348: filter->status = 0x80;
349: } else if (c == 0x28) { /* '(' */
350: filter->status++;
351: } else {
352: filter->status &= ~0xf;
353: CK((*filter->output_function)(0x1b, filter->data));
354: CK((*filter->output_function)(0x24, filter->data));
355: goto retry;
356: }
357: break;
358:
359: /* ESC $ ( */
360: /* case 0x04: */
361: /* case 0x14: */
362: /* case 0x24: */
363: /* case 0x84: */
364: /* case 0x94: */
365: case 4:
366: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */
367: filter->status = 0x80;
368: } else if (c == 0x44) { /* 'D' */
369: filter->status = 0x90;
370: } else {
371: filter->status &= ~0xf;
372: CK((*filter->output_function)(0x1b, filter->data));
373: CK((*filter->output_function)(0x24, filter->data));
374: CK((*filter->output_function)(0x28, filter->data));
375: goto retry;
376: }
377: break;
378:
379: /* ESC ( */
380: /* case 0x05: */
381: /* case 0x15: */
382: /* case 0x25: */
383: /* case 0x85: */
384: /* case 0x95: */
385: case 5:
386: if (c == 0x42 || c == 0x48) { /* 'B' or 'H' */
387: filter->status = 0;
388: } else if (c == 0x4a) { /* 'J' */
389: filter->status = 0x10;
390: } else if (c == 0x49) { /* 'I' */
391: filter->status = 0x20;
392: } else {
393: filter->status &= ~0xf;
394: CK((*filter->output_function)(0x1b, filter->data));
395: CK((*filter->output_function)(0x28, filter->data));
396: goto retry;
397: }
398: break;
399:
400: default:
401: filter->status = 0;
402: break;
403: }
404:
405: return c;
406: }
407:
408: /*
409: * wchar => JIS
410: */
411: int
412: mbfl_filt_conv_wchar_jis_ms(int c, mbfl_convert_filter *filter)
413: {
414: int c1, s;
415:
416: s = 0;
417: if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) {
418: s = ucs_a1_jis_table[c - ucs_a1_jis_table_min];
419: } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) {
420: s = ucs_a2_jis_table[c - ucs_a2_jis_table_min];
421: } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) {
422: s = ucs_i_jis_table[c - ucs_i_jis_table_min];
423: } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) {
424: s = ucs_r_jis_table[c - ucs_r_jis_table_min];
425: } else if (c >= 0xe000 && c < (0xe000 + 10 * 94)) {
426: /* PUE => Microsoft extended (pseudo 95ku - 114ku) */
427: /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */
428: s = c - 0xe000;
429: s = (s / 94 + 0x75) << 8 | (s % 94 + 0x21);
430: } else if (c >= (0xe000 + 10 * 94) && c <= (0xe000 + 20 * 94)) {
431: /* PUE => JISX0212 user-defined (G3 85ku - 94ku) */
432: /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */
433: s = c - (0xe000 + 10 * 94);
434: s = (s / 94 + 0xf5) << 8 | (s % 94 + 0xa1);
435: }
436:
437: /* do some transliteration */
438: if (s <= 0) {
439: c1 = c & ~MBFL_WCSPLANE_MASK;
440: if (c1 == MBFL_WCSPLANE_JIS0208) {
441: s = c & MBFL_WCSPLANE_MASK;
442: } else if (c1 == MBFL_WCSPLANE_JIS0212) {
443: s = c & MBFL_WCSPLANE_MASK;
444: s |= 0x8080;
445: } else if (c == 0xa5) { /* YEN SIGN */
446: s = 0x1005c;
447: } else if (c == 0x203e) { /* OVER LINE */
448: s = 0x1007e;
449: } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */
450: s = 0x2140;
451: } else if (c == 0xff5e) { /* FULLWIDTH TILDE */
452: s = 0x2141;
453: } else if (c == 0x2225) { /* PARALLEL TO */
454: s = 0x2142;
455: } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */
456: s = 0x215d;
457: } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */
458: s = 0x2171;
459: } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */
460: s = 0x2172;
461: } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */
462: s = 0x224c;
463: }
464: }
465: if (s <= 0 || s >= 0x8080 && s < 0x10000) {
466: int i;
467: s = -1;
468:
469: for (i = 0;
470: i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) {
471: const int oh = cp932ext1_ucs_table_min / 94;
472:
473: if (c == cp932ext1_ucs_table[i]) {
474: s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21);
475: break;
476: }
477: }
478:
479: if (s < 0) {
480: const int oh = cp932ext2_ucs_table_min / 94;
481: const int cp932ext2_ucs_table_size =
482: cp932ext2_ucs_table_max - cp932ext2_ucs_table_min;
483: for (i = 0; i < cp932ext2_ucs_table_size; i++) {
484: if (c == cp932ext2_ucs_table[i]) {
485: s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21);
486: break;
487: }
488: }
489: }
490:
491: if (s < 0) {
492: const int cp932ext3_ucs_table_size =
493: cp932ext3_ucs_table_max - cp932ext3_ucs_table_min;
494: const int limit = cp932ext3_ucs_table_size >
495: cp932ext3_eucjp_table_size ?
496: cp932ext3_eucjp_table_size:
497: cp932ext3_ucs_table_size;
498: for (i = 0; i < limit; i++) {
499: if (c == cp932ext3_ucs_table[i]) {
500: s = cp932ext3_eucjp_table[i];
501: break;
502: }
503: }
504: }
505:
506: if (c == 0) {
507: s = 0;
508: } else if (s <= 0) {
509: s = -1;
510: }
511: }
512:
513: if (s >= 0) {
514: if (s < 0x80) { /* ASCII */
515: if ((filter->status & 0xff00) != 0) {
516: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
517: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
518: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
519: }
520: filter->status = 0;
521: CK((*filter->output_function)(s, filter->data));
522: } else if (s < 0x100) { /* kana */
523: if ((filter->status & 0xff00) != 0x100) {
524: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
525: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
526: CK((*filter->output_function)(0x49, filter->data)); /* 'I' */
527: }
528: filter->status = 0x100;
529: CK((*filter->output_function)(s & 0x7f, filter->data));
530: } else if (s < 0x8080) { /* X 0208 */
531: if ((filter->status & 0xff00) != 0x200) {
532: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
533: CK((*filter->output_function)(0x24, filter->data)); /* '$' */
534: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
535: }
536: filter->status = 0x200;
537: CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
538: CK((*filter->output_function)(s & 0x7f, filter->data));
539: } else if (s < 0x10000) { /* X 0212 */
540: if ((filter->status & 0xff00) != 0x300) {
541: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
542: CK((*filter->output_function)(0x24, filter->data)); /* '$' */
543: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
544: CK((*filter->output_function)(0x44, filter->data)); /* 'D' */
545: }
546: filter->status = 0x300;
547: CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
548: CK((*filter->output_function)(s & 0x7f, filter->data));
549: } else { /* X 0201 latin */
550: if ((filter->status & 0xff00) != 0x400) {
551: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
552: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
553: CK((*filter->output_function)(0x4a, filter->data)); /* 'J' */
554: }
555: filter->status = 0x400;
556: CK((*filter->output_function)(s & 0x7f, filter->data));
557: }
558: } else {
559: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
560: CK(mbfl_filt_conv_illegal_output(c, filter));
561: }
562: }
563:
564: return c;
565: }
566:
567: /*
568: * wchar => CP50220
569: */
570: static void
571: mbfl_filt_conv_wchar_cp50220_ctor(mbfl_convert_filter *filt)
572: {
573: mbfl_filt_conv_wchar_cp50220_ctx *ctx;
574:
575: mbfl_filt_conv_common_ctor(filt);
576:
577: ctx = mbfl_malloc(sizeof(mbfl_filt_conv_wchar_cp50220_ctx));
578: if (ctx == NULL) {
579: mbfl_filt_conv_common_dtor(filt);
580: return;
581: }
582:
583: ctx->tl_param.mode = MBFL_FILT_TL_HAN2ZEN_KATAKANA | MBFL_FILT_TL_HAN2ZEN_GLUE;
584:
585: ctx->last = *filt;
586: ctx->last.opaque = ctx;
587: ctx->last.data = filt->data;
588: filt->filter_function = vtbl_tl_jisx0201_jisx0208.filter_function;
589: filt->filter_flush = vtbl_tl_jisx0201_jisx0208.filter_flush;
590: filt->output_function = (int(*)(int, void *))ctx->last.filter_function;
591: filt->flush_function = (int(*)(void *))ctx->last.filter_flush;
592: filt->data = &ctx->last;
593: filt->opaque = ctx;
594: vtbl_tl_jisx0201_jisx0208.filter_ctor(filt);
595: }
596:
597: static void
598: mbfl_filt_conv_wchar_cp50220_copy(mbfl_convert_filter *src, mbfl_convert_filter *dest)
599: {
600: mbfl_filt_conv_wchar_cp50220_ctx *ctx;
601:
602: *dest = *src;
603: ctx = mbfl_malloc(sizeof(mbfl_filt_conv_wchar_cp50220_ctx));
604: if (ctx != NULL) {
605: *ctx = *(mbfl_filt_conv_wchar_cp50220_ctx*)src->opaque;
606: }
607:
608: dest->opaque = ctx;
609: dest->data = &ctx->last;
610: }
611:
612: static void
613: mbfl_filt_conv_wchar_cp50220_dtor(mbfl_convert_filter *filt)
614: {
615: vtbl_tl_jisx0201_jisx0208.filter_dtor(filt);
616:
617: if (filt->opaque != NULL) {
618: mbfl_free(filt->opaque);
619: }
620:
621: mbfl_filt_conv_common_dtor(filt);
622: }
623:
624: /*
625: * wchar => cp50220raw
626: */
627: int
628: mbfl_filt_conv_wchar_cp50220raw(int c, mbfl_convert_filter *filter)
629: {
630: if (c & MBFL_WCSPLANE_JIS0208) {
631: const int s = c & MBFL_WCSPLANE_MASK;
632:
633: if ((filter->status & 0xff00) != 0x200) {
634: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
635: CK((*filter->output_function)(0x24, filter->data)); /* '$' */
636: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
637: filter->status = 0x200;
638: }
639: CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
640: CK((*filter->output_function)(s & 0x7f, filter->data));
641: return c;
642: } else {
643: return mbfl_filt_conv_wchar_cp50221(c, filter);
644: }
645: }
646:
647: /*
648: * wchar => CP50221
649: */
650: int
651: mbfl_filt_conv_wchar_cp50221(int c, mbfl_convert_filter *filter)
652: {
653: int s = 0;
654:
655: if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) {
656: s = ucs_a1_jis_table[c - ucs_a1_jis_table_min];
657: } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) {
658: s = ucs_a2_jis_table[c - ucs_a2_jis_table_min];
659: } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) {
660: s = ucs_i_jis_table[c - ucs_i_jis_table_min];
661: } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) {
662: s = ucs_r_jis_table[c - ucs_r_jis_table_min];
663: } else if (c >= 0xe000 && c < (0xe000 + 10 * 94)) {
664: /* PUE => Microsoft extended */
665: /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */
666: s = c - 0xe000;
667: s = (s / 94 + 0x75) << 8 | (s % 94 + 0x21);
668: } else if (c >= (0xe000 + 10 * 94) && c <= (0xe000 + 20 * 94)) {
669: /* PUE => JISX0212 user-defined (G3 85ku - 94ku) */
670: /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */
671: s = c - (0xe000 + 10 * 94);
672: s = (s / 94 + 0xf5) << 8 | (s % 94 + 0xa1);
673: }
674:
675: if (s <= 0) {
676: if (c == 0xa5) { /* YEN SIGN */
677: s = 0x1005c;
678: } else if (c == 0x203e) { /* OVER LINE */
679: s = 0x1007e;
680: } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */
681: s = 0x2140;
682: } else if (c == 0xff5e) { /* FULLWIDTH TILDE */
683: s = 0x2141;
684: } else if (c == 0x2225) { /* PARALLEL TO */
685: s = 0x2142;
686: } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */
687: s = 0x215d;
688: } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */
689: s = 0x2171;
690: } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */
691: s = 0x2172;
692: } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */
693: s = 0x224c;
694: }
695: }
696: if (s <= 0 || s >= 0x8080 && s < 0x10000) {
697: int i;
698: s = -1;
699:
700: for (i = 0;
701: i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min;
702: i++) {
703: const int oh = cp932ext1_ucs_table_min / 94;
704:
705: if (c == cp932ext1_ucs_table[i]) {
706: s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21);
707: break;
708: }
709: }
710:
711: if (s < 0) {
712: const int oh = cp932ext2_ucs_table_min / 94;
713: const int cp932ext2_ucs_table_size =
714: cp932ext2_ucs_table_max - cp932ext2_ucs_table_min;
715: for (i = 0; i < cp932ext2_ucs_table_size; i++) {
716: if (c == cp932ext2_ucs_table[i]) {
717: s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21);
718: break;
719: }
720: }
721: }
722:
723: if (s < 0) {
724: const int cp932ext3_ucs_table_size =
725: cp932ext3_ucs_table_max - cp932ext3_ucs_table_min;
726: const int limit = cp932ext3_ucs_table_size >
727: cp932ext3_eucjp_table_size ?
728: cp932ext3_eucjp_table_size:
729: cp932ext3_ucs_table_size;
730: for (i = 0; i < limit; i++) {
731: if (c == cp932ext3_ucs_table[i]) {
732: s = cp932ext3_eucjp_table[i];
733: break;
734: }
735: }
736: }
737:
738: if (c == 0) {
739: s = 0;
740: } else if (s <= 0) {
741: s = -1;
742: }
743: }
744:
745: if (s >= 0) {
746: if (s < 0x80) { /* ASCII */
747: if ((filter->status & 0xff00) != 0) {
748: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
749: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
750: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
751: filter->status = 0;
752: }
753: CK((*filter->output_function)(s, filter->data));
754: } else if (s >= 0xa0 && s < 0xe0) { /* X 0201 kana */
755: if ((filter->status & 0xff00) != 0x500) {
756: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
757: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
758: CK((*filter->output_function)(0x49, filter->data)); /* 'I' */
759: filter->status = 0x500;
760: }
761: CK((*filter->output_function)(s - 0x80, filter->data));
762: } else if (s < 0x8080) { /* X 0208 */
763: if ((filter->status & 0xff00) != 0x200) {
764: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
765: CK((*filter->output_function)(0x24, filter->data)); /* '$' */
766: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
767: filter->status = 0x200;
768: }
769: CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
770: CK((*filter->output_function)(s & 0x7f, filter->data));
771: } else if (s < 0x10000) { /* X0212 */
772: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
773: CK(mbfl_filt_conv_illegal_output(c, filter));
774: }
775: } else { /* X 0201 latin */
776: if ((filter->status & 0xff00) != 0x400) {
777: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
778: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
779: CK((*filter->output_function)(0x4a, filter->data)); /* 'J' */
780: }
781: filter->status = 0x400;
782: CK((*filter->output_function)(s & 0x7f, filter->data));
783: }
784: } else {
785: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
786: CK(mbfl_filt_conv_illegal_output(c, filter));
787: }
788: }
789:
790: return c;
791: }
792:
793: /*
794: * wchar => CP50222
795: */
796: int
797: mbfl_filt_conv_wchar_cp50222(int c, mbfl_convert_filter *filter)
798: {
799: int s;
800:
801: s = 0;
802:
803: if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) {
804: s = ucs_a1_jis_table[c - ucs_a1_jis_table_min];
805: } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) {
806: s = ucs_a2_jis_table[c - ucs_a2_jis_table_min];
807: } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) {
808: s = ucs_i_jis_table[c - ucs_i_jis_table_min];
809: } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) {
810: s = ucs_r_jis_table[c - ucs_r_jis_table_min];
811: } else if (c >= 0xe000 && c < (0xe000 + 10 * 94)) {
812: /* PUE => Microsoft extended */
813: /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */
814: s = c - 0xe000;
815: s = (s / 94 + 0x75) << 8 | (s % 94 + 0x21);
816: } else if (c >= (0xe000 + 10 * 94) && c <= (0xe000 + 20 * 94)) {
817: /* PUE => JISX0212 user-defined (G3 85ku - 94ku) */
818: /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */
819: s = c - (0xe000 + 10 * 94);
820: s = (s / 94 + 0xf5) << 8 | (s % 94 + 0xa1);
821: }
822:
823: if (s <= 0) {
824: if (c == 0xa5) { /* YEN SIGN */
825: s = 0x1005c;
826: } else if (c == 0x203e) { /* OVER LINE */
827: s = 0x1007e;
828: } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */
829: s = 0x2140;
830: } else if (c == 0xff5e) { /* FULLWIDTH TILDE */
831: s = 0x2141;
832: } else if (c == 0x2225) { /* PARALLEL TO */
833: s = 0x2142;
834: } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */
835: s = 0x215d;
836: } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */
837: s = 0x2171;
838: } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */
839: s = 0x2172;
840: } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */
841: s = 0x224c;
842: }
843: }
844: if (s <= 0 || s >= 0x8080 && s < 0x10000) {
845: int i;
846: s = -1;
847:
848: for (i = 0;
849: i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) {
850: const int oh = cp932ext1_ucs_table_min / 94;
851:
852: if (c == cp932ext1_ucs_table[i]) {
853: s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21);
854: break;
855: }
856: }
857:
858: if (s <= 0) {
859: const int oh = cp932ext2_ucs_table_min / 94;
860: const int cp932ext2_ucs_table_size =
861: cp932ext2_ucs_table_max - cp932ext2_ucs_table_min;
862: for (i = 0; i < cp932ext2_ucs_table_size; i++) {
863: if (c == cp932ext2_ucs_table[i]) {
864: s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21);
865: break;
866: }
867: }
868: }
869:
870: if (s <= 0) {
871: const int cp932ext3_ucs_table_size =
872: cp932ext3_ucs_table_max - cp932ext3_ucs_table_min;
873: const int limit = cp932ext3_ucs_table_size >
874: cp932ext3_eucjp_table_size ?
875: cp932ext3_eucjp_table_size:
876: cp932ext3_ucs_table_size;
877: for (i = 0; i < limit; i++) {
878: if (c == cp932ext3_ucs_table[i]) {
879: s = cp932ext3_eucjp_table[i];
880: break;
881: }
882: }
883: }
884:
885: if (c == 0) {
886: s = 0;
887: } else if (s <= 0) {
888: s = -1;
889: }
890: }
891:
892: if (s >= 0) {
893: if (s < 0x80) { /* ASCII */
894: if ((filter->status & 0xff00) == 0x500) {
895: CK((*filter->output_function)(0x0f, filter->data)); /* SO */
896: filter->status = 0;
897: } else if ((filter->status & 0xff00) != 0) {
898: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
899: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
900: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
901: filter->status = 0;
902: }
903: CK((*filter->output_function)(s, filter->data));
904: } else if (s >= 0xa0 && s < 0xe0) { /* X 0201 kana */
905: if ((filter->status & 0xff00) != 0x500) {
906: CK((*filter->output_function)(0x0e, filter->data)); /* SI */
907: filter->status = 0x500;
908: }
909: CK((*filter->output_function)(s - 0x80, filter->data));
910: } else if (s < 0x8080) { /* X 0208 */
911: if ((filter->status & 0xff00) == 0x500) {
912: CK((*filter->output_function)(0x0f, filter->data)); /* SO */
913: filter->status = 0;
914: }
915: if ((filter->status & 0xff00) != 0x200) {
916: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
917: CK((*filter->output_function)(0x24, filter->data)); /* '$' */
918: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
919: filter->status = 0x200;
920: }
921: CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
922: CK((*filter->output_function)(s & 0x7f, filter->data));
923: } else if (s < 0x10000) { /* X0212 */
924: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
925: CK(mbfl_filt_conv_illegal_output(c, filter));
926: }
927: } else { /* X 0201 latin */
928: if ((filter->status & 0xff00) == 0x500) {
929: CK((*filter->output_function)(0x0f, filter->data)); /* SO */
930: filter->status = 0;
931: }
932: if ((filter->status & 0xff00) != 0x400) {
933: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
934: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
935: CK((*filter->output_function)(0x4a, filter->data)); /* 'J' */
936: }
937: filter->status = 0x400;
938: CK((*filter->output_function)(s & 0x7f, filter->data));
939: }
940: } else {
941: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
942: CK(mbfl_filt_conv_illegal_output(c, filter));
943: }
944: }
945:
946: return c;
947: }
948:
949: int
950: mbfl_filt_conv_wchar_cp50222_flush(mbfl_convert_filter *filter)
951: {
952: /* back to latin */
953: if ((filter->status & 0xff00) == 0x500) {
954: CK((*filter->output_function)(0x0f, filter->data)); /* SO */
955: } else if ((filter->status & 0xff00) != 0) {
956: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
957: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
958: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
959: }
960: filter->status &= 0xff;
961:
962: if (filter->flush_function != NULL) {
963: return (*filter->flush_function)(filter->data);
964: }
965:
966: return 0;
967: }
968:
969:
970: static int mbfl_filt_ident_jis_ms(int c, mbfl_identify_filter *filter)
971: {
972: retry:
973: switch (filter->status & 0xf) {
974: /* case 0x00: ASCII */
975: /* case 0x10: X 0201 latin */
976: /* case 0x20: X 0201 kana */
977: /* case 0x80: X 0208 */
978: /* case 0x90: X 0212 */
979: case 0:
980: if (c == 0x1b) {
981: filter->status += 2;
982: } else if (c == 0x0e) { /* "kana in" */
983: filter->status = 0x20;
984: } else if (c == 0x0f) { /* "kana out" */
985: filter->status = 0;
986: } else if ((filter->status == 0x80 || filter->status == 0x90) && c > 0x20 && c < 0x7f) { /* kanji first char */
987: filter->status += 1;
988: } else if (c >= 0 && c < 0x80) { /* latin, CTLs */
989: ;
990: } else {
991: filter->flag = 1; /* bad */
992: }
993: break;
994:
995: /* case 0x81: X 0208 second char */
996: /* case 0x91: X 0212 second char */
997: case 1:
998: filter->status &= ~0xf;
999: if (c == 0x1b) {
1000: goto retry;
1001: } else if (c < 0x21 || c > 0x7e) { /* bad */
1002: filter->flag = 1;
1003: }
1004: break;
1005:
1006: /* ESC */
1007: case 2:
1008: if (c == 0x24) { /* '$' */
1009: filter->status++;
1010: } else if (c == 0x28) { /* '(' */
1011: filter->status += 3;
1012: } else {
1013: filter->flag = 1; /* bad */
1014: filter->status &= ~0xf;
1015: goto retry;
1016: }
1017: break;
1018:
1019: /* ESC $ */
1020: case 3:
1021: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */
1022: filter->status = 0x80;
1023: } else if (c == 0x28) { /* '(' */
1024: filter->status++;
1025: } else {
1026: filter->flag = 1; /* bad */
1027: filter->status &= ~0xf;
1028: goto retry;
1029: }
1030: break;
1031:
1032: /* ESC $ ( */
1033: case 4:
1034: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */
1035: filter->status = 0x80;
1036: } else if (c == 0x44) { /* 'D' */
1037: filter->status = 0x90;
1038: } else {
1039: filter->flag = 1; /* bad */
1040: filter->status &= ~0xf;
1041: goto retry;
1042: }
1043: break;
1044:
1045: /* ESC ( */
1046: case 5:
1047: if (c == 0x42 || c == 0x48) { /* 'B' or 'H' */
1048: filter->status = 0;
1049: } else if (c == 0x4a) { /* 'J' */
1050: filter->status = 0x10;
1051: } else if (c == 0x49) { /* 'I' */
1052: filter->status = 0x20;
1053: } else {
1054: filter->flag = 1; /* bad */
1055: filter->status &= ~0xf;
1056: goto retry;
1057: }
1058: break;
1059:
1060: default:
1061: filter->status = 0;
1062: break;
1063: }
1064:
1065: return c;
1066: }
1067:
1068: static int mbfl_filt_ident_cp50220(int c, mbfl_identify_filter *filter)
1069: {
1070: retry:
1071: switch (filter->status & 0xf) {
1072: /* case 0x00: ASCII */
1073: /* case 0x10: X 0201 latin */
1074: /* case 0x80: X 0208 */
1075: case 0:
1076: if (c == 0x1b) {
1077: filter->status += 2;
1078: } else if (filter->status == 0x80 && c > 0x20 && c < 0x7f) { /* kanji first char */
1079: filter->status += 1;
1080: } else if (c >= 0 && c < 0x80) { /* latin, CTLs */
1081: ;
1082: } else {
1083: filter->flag = 1; /* bad */
1084: }
1085: break;
1086:
1087: /* case 0x81: X 0208 second char */
1088: case 1:
1089: if (c == 0x1b) {
1090: filter->status++;
1091: } else {
1092: filter->status &= ~0xf;
1093: if (c < 0x21 || c > 0x7e) { /* bad */
1094: filter->flag = 1;
1095: }
1096: }
1097: break;
1098:
1099: /* ESC */
1100: case 2:
1101: if (c == 0x24) { /* '$' */
1102: filter->status++;
1103: } else if (c == 0x28) { /* '(' */
1104: filter->status += 3;
1105: } else {
1106: filter->flag = 1; /* bad */
1107: filter->status &= ~0xf;
1108: goto retry;
1109: }
1110: break;
1111:
1112: /* ESC $ */
1113: case 3:
1114: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */
1115: filter->status = 0x80;
1116: } else {
1117: filter->flag = 1; /* bad */
1118: filter->status &= ~0xf;
1119: goto retry;
1120: }
1121: break;
1122:
1123: /* ESC ( */
1124: case 5:
1125: if (c == 0x42) { /* 'B' */
1126: filter->status = 0;
1127: } else if (c == 0x4a) { /* 'J' */
1128: filter->status = 0x10;
1129: } else {
1130: filter->flag = 1; /* bad */
1131: filter->status &= ~0xf;
1132: goto retry;
1133: }
1134: break;
1135:
1136: default:
1137: filter->status = 0;
1138: break;
1139: }
1140:
1141: return c;
1142: }
1143:
1144: static int mbfl_filt_ident_cp50221(int c, mbfl_identify_filter *filter)
1145: {
1146: retry:
1147: switch (filter->status & 0xf) {
1148: /* case 0x00: ASCII */
1149: /* case 0x10: X 0201 latin */
1150: /* case 0x80: X 0208 */
1151: case 0:
1152: if (c == 0x1b) {
1153: filter->status += 2;
1154: } else if (filter->status == 0x80 && c > 0x20 && c < 0x7f) { /* kanji first char */
1155: filter->status += 1;
1156: } else if (c >= 0 && c < 0x80) { /* latin, CTLs */
1157: ;
1158: } else {
1159: filter->flag = 1; /* bad */
1160: }
1161: break;
1162:
1163: /* case 0x81: X 0208 second char */
1164: case 1:
1165: if (c == 0x1b) {
1166: filter->status++;
1167: } else {
1168: filter->status &= ~0xf;
1169: if (c < 0x21 || c > 0x7e) { /* bad */
1170: filter->flag = 1;
1171: }
1172: }
1173: break;
1174:
1175: /* ESC */
1176: case 2:
1177: if (c == 0x24) { /* '$' */
1178: filter->status++;
1179: } else if (c == 0x28) { /* '(' */
1180: filter->status += 3;
1181: } else {
1182: filter->flag = 1; /* bad */
1183: filter->status &= ~0xf;
1184: goto retry;
1185: }
1186: break;
1187:
1188: /* ESC $ */
1189: case 3:
1190: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */
1191: filter->status = 0x80;
1192: } else {
1193: filter->flag = 1; /* bad */
1194: filter->status &= ~0xf;
1195: goto retry;
1196: }
1197: break;
1198:
1199: /* ESC ( */
1200: case 5:
1201: if (c == 0x42) { /* 'B' */
1202: filter->status = 0;
1203: } else if (c == 0x4a) { /* 'J' */
1204: filter->status = 0x10;
1205: } else if (c == 0x49) { /* 'I' */
1206: filter->status = 0x20;
1207: } else {
1208: filter->flag = 1; /* bad */
1209: filter->status &= ~0xf;
1210: goto retry;
1211: }
1212: break;
1213:
1214: default:
1215: filter->status = 0;
1216: break;
1217: }
1218:
1219: return c;
1220: }
1221:
1222: static int mbfl_filt_ident_cp50222(int c, mbfl_identify_filter *filter)
1223: {
1224: retry:
1225: switch (filter->status & 0xf) {
1226: /* case 0x00: ASCII */
1227: /* case 0x10: X 0201 latin */
1228: /* case 0x80: X 0208 */
1229: case 0:
1230: if (c == 0x1b) {
1231: filter->status += 2;
1232: } else if (filter->status == 0x80 && c > 0x20 && c < 0x7f) { /* kanji first char */
1233: filter->status += 1;
1234: } else if (c >= 0 && c < 0x80) { /* latin, CTLs */
1235: ;
1236: } else {
1237: filter->flag = 1; /* bad */
1238: }
1239: break;
1240:
1241: /* case 0x81: X 0208 second char */
1242: case 1:
1243: if (c == 0x1b) {
1244: filter->status++;
1245: } else {
1246: filter->status &= ~0xf;
1247: if (c < 0x21 || c > 0x7e) { /* bad */
1248: filter->flag = 1;
1249: }
1250: }
1251: break;
1252:
1253: /* ESC */
1254: case 2:
1255: if (c == 0x24) { /* '$' */
1256: filter->status++;
1257: } else if (c == 0x28) { /* '(' */
1258: filter->status += 3;
1259: } else {
1260: filter->flag = 1; /* bad */
1261: filter->status &= ~0xf;
1262: goto retry;
1263: }
1264: break;
1265:
1266: /* ESC $ */
1267: case 3:
1268: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */
1269: filter->status = 0x80;
1270: } else {
1271: filter->flag = 1; /* bad */
1272: filter->status &= ~0xf;
1273: goto retry;
1274: }
1275: break;
1276:
1277: /* ESC ( */
1278: case 5:
1279: if (c == 0x42) { /* 'B' */
1280: filter->status = 0;
1281: } else if (c == 0x4a) { /* 'J' */
1282: filter->status = 0x10;
1283: } else {
1284: filter->flag = 1; /* bad */
1285: filter->status &= ~0xf;
1286: goto retry;
1287: }
1288: break;
1289:
1290: default:
1291: filter->status = 0;
1292: break;
1293: }
1294:
1295: return c;
1296: }
1297:
1298:
1299:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>