Return to mbfilter_cp5022x.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / mbstring / libmbfl / filters |
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: