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, 1.1.1.2 ! misho 57: MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE 1.1 misho 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, 1.1.1.2 ! misho 66: MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE 1.1 misho 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, 1.1.1.2 ! misho 75: MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE 1.1 misho 76: }; 77: 78: const mbfl_encoding mbfl_encoding_cp50221 = { 79: mbfl_no_encoding_cp50221, 80: "CP50221", 81: "ISO-2022-JP", 82: NULL, 83: NULL, 1.1.1.2 ! misho 84: MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE 1.1 misho 85: }; 86: 87: const mbfl_encoding mbfl_encoding_cp50222 = { 88: mbfl_no_encoding_cp50222, 89: "CP50222", 90: "ISO-2022-JP", 91: NULL, 92: NULL, 1.1.1.2 ! misho 93: MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE 1.1 misho 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)); 1.1.1.2 ! misho 253: } else if ((filter->status == 0x80 || filter->status == 0x90) && c > 0x20 && c < 0x93) { /* kanji first char */ 1.1 misho 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) */ 1.1.1.2 ! misho 285: w = s - 94*94 + 0xe000; 1.1 misho 286: } else { 287: w = 0; 288: } 289: if (w <= 0) { 290: w = (c1 << 8) | c; 291: w &= MBFL_WCSPLANE_MASK; 292: w |= MBFL_WCSPLANE_JIS0208; 293: } 294: } else { 295: if (s >= 0 && s < jisx0212_ucs_table_size) { 296: w = jisx0212_ucs_table[s]; 297: } else { 298: w = 0; 299: } 300: if (w <= 0) { 301: w = (c1 << 8) | c; 302: w &= MBFL_WCSPLANE_MASK; 303: w |= MBFL_WCSPLANE_JIS0212; 304: } 305: } 306: CK((*filter->output_function)(w, filter->data)); 307: } else if (c == 0x1b) { 308: filter->status += 2; 309: } else if ((c >= 0 && c < 0x21) || c == 0x7f) { /* CTLs */ 310: CK((*filter->output_function)(c, filter->data)); 311: } else { 312: w = (c1 << 8) | c; 313: w &= MBFL_WCSGROUP_MASK; 314: w |= MBFL_WCSGROUP_THROUGH; 315: CK((*filter->output_function)(w, filter->data)); 316: } 317: break; 318: 319: /* ESC */ 320: /* case 0x02: */ 321: /* case 0x12: */ 322: /* case 0x22: */ 323: /* case 0x82: */ 324: /* case 0x92: */ 325: case 2: 326: if (c == 0x24) { /* '$' */ 327: filter->status++; 328: } else if (c == 0x28) { /* '(' */ 329: filter->status += 3; 330: } else { 331: filter->status &= ~0xf; 332: CK((*filter->output_function)(0x1b, filter->data)); 333: goto retry; 334: } 335: break; 336: 337: /* ESC $ */ 338: /* case 0x03: */ 339: /* case 0x13: */ 340: /* case 0x23: */ 341: /* case 0x83: */ 342: /* case 0x93: */ 343: case 3: 344: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */ 345: filter->status = 0x80; 346: } else if (c == 0x28) { /* '(' */ 347: filter->status++; 348: } else { 349: filter->status &= ~0xf; 350: CK((*filter->output_function)(0x1b, filter->data)); 351: CK((*filter->output_function)(0x24, filter->data)); 352: goto retry; 353: } 354: break; 355: 356: /* ESC $ ( */ 357: /* case 0x04: */ 358: /* case 0x14: */ 359: /* case 0x24: */ 360: /* case 0x84: */ 361: /* case 0x94: */ 362: case 4: 363: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */ 364: filter->status = 0x80; 365: } else if (c == 0x44) { /* 'D' */ 366: filter->status = 0x90; 367: } else { 368: filter->status &= ~0xf; 369: CK((*filter->output_function)(0x1b, filter->data)); 370: CK((*filter->output_function)(0x24, filter->data)); 371: CK((*filter->output_function)(0x28, filter->data)); 372: goto retry; 373: } 374: break; 375: 376: /* ESC ( */ 377: /* case 0x05: */ 378: /* case 0x15: */ 379: /* case 0x25: */ 380: /* case 0x85: */ 381: /* case 0x95: */ 382: case 5: 383: if (c == 0x42 || c == 0x48) { /* 'B' or 'H' */ 384: filter->status = 0; 385: } else if (c == 0x4a) { /* 'J' */ 386: filter->status = 0x10; 387: } else if (c == 0x49) { /* 'I' */ 388: filter->status = 0x20; 389: } else { 390: filter->status &= ~0xf; 391: CK((*filter->output_function)(0x1b, filter->data)); 392: CK((*filter->output_function)(0x28, filter->data)); 393: goto retry; 394: } 395: break; 396: 397: default: 398: filter->status = 0; 399: break; 400: } 401: 402: return c; 403: } 404: 405: /* 406: * wchar => JIS 407: */ 408: int 409: mbfl_filt_conv_wchar_jis_ms(int c, mbfl_convert_filter *filter) 410: { 411: int c1, s; 412: 413: s = 0; 414: if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) { 415: s = ucs_a1_jis_table[c - ucs_a1_jis_table_min]; 416: } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) { 417: s = ucs_a2_jis_table[c - ucs_a2_jis_table_min]; 418: } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) { 419: s = ucs_i_jis_table[c - ucs_i_jis_table_min]; 420: } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) { 421: s = ucs_r_jis_table[c - ucs_r_jis_table_min]; 422: } else if (c >= 0xe000 && c < (0xe000 + 10 * 94)) { 423: /* PUE => Microsoft extended (pseudo 95ku - 114ku) */ 424: /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */ 425: s = c - 0xe000; 426: s = (s / 94 + 0x75) << 8 | (s % 94 + 0x21); 427: } else if (c >= (0xe000 + 10 * 94) && c <= (0xe000 + 20 * 94)) { 428: /* PUE => JISX0212 user-defined (G3 85ku - 94ku) */ 429: /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */ 430: s = c - (0xe000 + 10 * 94); 431: s = (s / 94 + 0xf5) << 8 | (s % 94 + 0xa1); 432: } 433: 434: /* do some transliteration */ 435: if (s <= 0) { 436: c1 = c & ~MBFL_WCSPLANE_MASK; 437: if (c1 == MBFL_WCSPLANE_JIS0208) { 438: s = c & MBFL_WCSPLANE_MASK; 439: } else if (c1 == MBFL_WCSPLANE_JIS0212) { 440: s = c & MBFL_WCSPLANE_MASK; 441: s |= 0x8080; 442: } else if (c == 0xa5) { /* YEN SIGN */ 443: s = 0x1005c; 444: } else if (c == 0x203e) { /* OVER LINE */ 445: s = 0x1007e; 446: } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */ 447: s = 0x2140; 448: } else if (c == 0xff5e) { /* FULLWIDTH TILDE */ 449: s = 0x2141; 450: } else if (c == 0x2225) { /* PARALLEL TO */ 451: s = 0x2142; 452: } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */ 453: s = 0x215d; 454: } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */ 455: s = 0x2171; 456: } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */ 457: s = 0x2172; 458: } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */ 459: s = 0x224c; 460: } 461: } 1.1.1.2 ! misho 462: if (s <= 0 || (s >= 0x8080 && s < 0x10000)) { 1.1 misho 463: int i; 464: s = -1; 465: 466: for (i = 0; 467: i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) { 468: const int oh = cp932ext1_ucs_table_min / 94; 469: 470: if (c == cp932ext1_ucs_table[i]) { 471: s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21); 472: break; 473: } 474: } 475: 476: if (s < 0) { 477: const int oh = cp932ext2_ucs_table_min / 94; 478: const int cp932ext2_ucs_table_size = 479: cp932ext2_ucs_table_max - cp932ext2_ucs_table_min; 480: for (i = 0; i < cp932ext2_ucs_table_size; i++) { 481: if (c == cp932ext2_ucs_table[i]) { 482: s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21); 483: break; 484: } 485: } 486: } 487: 488: if (s < 0) { 489: const int cp932ext3_ucs_table_size = 490: cp932ext3_ucs_table_max - cp932ext3_ucs_table_min; 491: const int limit = cp932ext3_ucs_table_size > 492: cp932ext3_eucjp_table_size ? 493: cp932ext3_eucjp_table_size: 494: cp932ext3_ucs_table_size; 495: for (i = 0; i < limit; i++) { 496: if (c == cp932ext3_ucs_table[i]) { 497: s = cp932ext3_eucjp_table[i]; 498: break; 499: } 500: } 501: } 502: 503: if (c == 0) { 504: s = 0; 505: } else if (s <= 0) { 506: s = -1; 507: } 508: } 509: 510: if (s >= 0) { 511: if (s < 0x80) { /* ASCII */ 512: if ((filter->status & 0xff00) != 0) { 513: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 514: CK((*filter->output_function)(0x28, filter->data)); /* '(' */ 515: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */ 516: } 517: filter->status = 0; 518: CK((*filter->output_function)(s, filter->data)); 519: } else if (s < 0x100) { /* kana */ 520: if ((filter->status & 0xff00) != 0x100) { 521: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 522: CK((*filter->output_function)(0x28, filter->data)); /* '(' */ 523: CK((*filter->output_function)(0x49, filter->data)); /* 'I' */ 524: } 525: filter->status = 0x100; 526: CK((*filter->output_function)(s & 0x7f, filter->data)); 527: } else if (s < 0x8080) { /* X 0208 */ 528: if ((filter->status & 0xff00) != 0x200) { 529: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 530: CK((*filter->output_function)(0x24, filter->data)); /* '$' */ 531: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */ 532: } 533: filter->status = 0x200; 534: CK((*filter->output_function)((s >> 8) & 0x7f, filter->data)); 535: CK((*filter->output_function)(s & 0x7f, filter->data)); 536: } else if (s < 0x10000) { /* X 0212 */ 537: if ((filter->status & 0xff00) != 0x300) { 538: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 539: CK((*filter->output_function)(0x24, filter->data)); /* '$' */ 540: CK((*filter->output_function)(0x28, filter->data)); /* '(' */ 541: CK((*filter->output_function)(0x44, filter->data)); /* 'D' */ 542: } 543: filter->status = 0x300; 544: CK((*filter->output_function)((s >> 8) & 0x7f, filter->data)); 545: CK((*filter->output_function)(s & 0x7f, filter->data)); 546: } else { /* X 0201 latin */ 547: if ((filter->status & 0xff00) != 0x400) { 548: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 549: CK((*filter->output_function)(0x28, filter->data)); /* '(' */ 550: CK((*filter->output_function)(0x4a, filter->data)); /* 'J' */ 551: } 552: filter->status = 0x400; 553: CK((*filter->output_function)(s & 0x7f, filter->data)); 554: } 555: } else { 556: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) { 557: CK(mbfl_filt_conv_illegal_output(c, filter)); 558: } 559: } 560: 561: return c; 562: } 563: 564: /* 565: * wchar => CP50220 566: */ 567: static void 568: mbfl_filt_conv_wchar_cp50220_ctor(mbfl_convert_filter *filt) 569: { 570: mbfl_filt_conv_wchar_cp50220_ctx *ctx; 571: 572: mbfl_filt_conv_common_ctor(filt); 573: 574: ctx = mbfl_malloc(sizeof(mbfl_filt_conv_wchar_cp50220_ctx)); 575: if (ctx == NULL) { 576: mbfl_filt_conv_common_dtor(filt); 577: return; 578: } 579: 580: ctx->tl_param.mode = MBFL_FILT_TL_HAN2ZEN_KATAKANA | MBFL_FILT_TL_HAN2ZEN_GLUE; 581: 582: ctx->last = *filt; 583: ctx->last.opaque = ctx; 584: ctx->last.data = filt->data; 585: filt->filter_function = vtbl_tl_jisx0201_jisx0208.filter_function; 586: filt->filter_flush = vtbl_tl_jisx0201_jisx0208.filter_flush; 587: filt->output_function = (int(*)(int, void *))ctx->last.filter_function; 588: filt->flush_function = (int(*)(void *))ctx->last.filter_flush; 589: filt->data = &ctx->last; 590: filt->opaque = ctx; 591: vtbl_tl_jisx0201_jisx0208.filter_ctor(filt); 592: } 593: 594: static void 595: mbfl_filt_conv_wchar_cp50220_copy(mbfl_convert_filter *src, mbfl_convert_filter *dest) 596: { 597: mbfl_filt_conv_wchar_cp50220_ctx *ctx; 598: 599: *dest = *src; 600: ctx = mbfl_malloc(sizeof(mbfl_filt_conv_wchar_cp50220_ctx)); 601: if (ctx != NULL) { 602: *ctx = *(mbfl_filt_conv_wchar_cp50220_ctx*)src->opaque; 603: } 604: 605: dest->opaque = ctx; 606: dest->data = &ctx->last; 607: } 608: 609: static void 610: mbfl_filt_conv_wchar_cp50220_dtor(mbfl_convert_filter *filt) 611: { 612: vtbl_tl_jisx0201_jisx0208.filter_dtor(filt); 613: 614: if (filt->opaque != NULL) { 615: mbfl_free(filt->opaque); 616: } 617: 618: mbfl_filt_conv_common_dtor(filt); 619: } 620: 621: /* 622: * wchar => cp50220raw 623: */ 624: int 625: mbfl_filt_conv_wchar_cp50220raw(int c, mbfl_convert_filter *filter) 626: { 627: if (c & MBFL_WCSPLANE_JIS0208) { 628: const int s = c & MBFL_WCSPLANE_MASK; 629: 630: if ((filter->status & 0xff00) != 0x200) { 631: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 632: CK((*filter->output_function)(0x24, filter->data)); /* '$' */ 633: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */ 634: filter->status = 0x200; 635: } 636: CK((*filter->output_function)((s >> 8) & 0x7f, filter->data)); 637: CK((*filter->output_function)(s & 0x7f, filter->data)); 638: return c; 639: } else { 640: return mbfl_filt_conv_wchar_cp50221(c, filter); 641: } 642: } 643: 644: /* 645: * wchar => CP50221 646: */ 647: int 648: mbfl_filt_conv_wchar_cp50221(int c, mbfl_convert_filter *filter) 649: { 650: int s = 0; 651: 652: if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) { 653: s = ucs_a1_jis_table[c - ucs_a1_jis_table_min]; 654: } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) { 655: s = ucs_a2_jis_table[c - ucs_a2_jis_table_min]; 656: } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) { 657: s = ucs_i_jis_table[c - ucs_i_jis_table_min]; 658: } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) { 659: s = ucs_r_jis_table[c - ucs_r_jis_table_min]; 660: } else if (c >= 0xe000 && c < (0xe000 + 10 * 94)) { 661: /* PUE => Microsoft extended */ 662: /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */ 663: s = c - 0xe000; 664: s = (s / 94 + 0x75) << 8 | (s % 94 + 0x21); 665: } else if (c >= (0xe000 + 10 * 94) && c <= (0xe000 + 20 * 94)) { 666: /* PUE => JISX0212 user-defined (G3 85ku - 94ku) */ 667: /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */ 668: s = c - (0xe000 + 10 * 94); 669: s = (s / 94 + 0xf5) << 8 | (s % 94 + 0xa1); 670: } 671: 672: if (s <= 0) { 673: if (c == 0xa5) { /* YEN SIGN */ 674: s = 0x1005c; 675: } else if (c == 0x203e) { /* OVER LINE */ 676: s = 0x1007e; 677: } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */ 678: s = 0x2140; 679: } else if (c == 0xff5e) { /* FULLWIDTH TILDE */ 680: s = 0x2141; 681: } else if (c == 0x2225) { /* PARALLEL TO */ 682: s = 0x2142; 683: } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */ 684: s = 0x215d; 685: } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */ 686: s = 0x2171; 687: } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */ 688: s = 0x2172; 689: } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */ 690: s = 0x224c; 691: } 692: } 1.1.1.2 ! misho 693: if (s <= 0 || (s >= 0x8080 && s < 0x10000)) { 1.1 misho 694: int i; 695: s = -1; 696: 697: for (i = 0; 698: i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; 699: i++) { 700: const int oh = cp932ext1_ucs_table_min / 94; 701: 702: if (c == cp932ext1_ucs_table[i]) { 703: s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21); 704: break; 705: } 706: } 707: 708: if (s < 0) { 709: const int oh = cp932ext2_ucs_table_min / 94; 710: const int cp932ext2_ucs_table_size = 711: cp932ext2_ucs_table_max - cp932ext2_ucs_table_min; 712: for (i = 0; i < cp932ext2_ucs_table_size; i++) { 713: if (c == cp932ext2_ucs_table[i]) { 714: s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21); 715: break; 716: } 717: } 718: } 719: 720: if (s < 0) { 721: const int cp932ext3_ucs_table_size = 722: cp932ext3_ucs_table_max - cp932ext3_ucs_table_min; 723: const int limit = cp932ext3_ucs_table_size > 724: cp932ext3_eucjp_table_size ? 725: cp932ext3_eucjp_table_size: 726: cp932ext3_ucs_table_size; 727: for (i = 0; i < limit; i++) { 728: if (c == cp932ext3_ucs_table[i]) { 729: s = cp932ext3_eucjp_table[i]; 730: break; 731: } 732: } 733: } 734: 735: if (c == 0) { 736: s = 0; 737: } else if (s <= 0) { 738: s = -1; 739: } 740: } 741: 742: if (s >= 0) { 743: if (s < 0x80) { /* ASCII */ 744: if ((filter->status & 0xff00) != 0) { 745: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 746: CK((*filter->output_function)(0x28, filter->data)); /* '(' */ 747: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */ 748: filter->status = 0; 749: } 750: CK((*filter->output_function)(s, filter->data)); 751: } else if (s >= 0xa0 && s < 0xe0) { /* X 0201 kana */ 752: if ((filter->status & 0xff00) != 0x500) { 753: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 754: CK((*filter->output_function)(0x28, filter->data)); /* '(' */ 755: CK((*filter->output_function)(0x49, filter->data)); /* 'I' */ 756: filter->status = 0x500; 757: } 758: CK((*filter->output_function)(s - 0x80, filter->data)); 759: } else if (s < 0x8080) { /* X 0208 */ 760: if ((filter->status & 0xff00) != 0x200) { 761: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 762: CK((*filter->output_function)(0x24, filter->data)); /* '$' */ 763: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */ 764: filter->status = 0x200; 765: } 766: CK((*filter->output_function)((s >> 8) & 0x7f, filter->data)); 767: CK((*filter->output_function)(s & 0x7f, filter->data)); 768: } else if (s < 0x10000) { /* X0212 */ 769: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) { 770: CK(mbfl_filt_conv_illegal_output(c, filter)); 771: } 772: } else { /* X 0201 latin */ 773: if ((filter->status & 0xff00) != 0x400) { 774: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 775: CK((*filter->output_function)(0x28, filter->data)); /* '(' */ 776: CK((*filter->output_function)(0x4a, filter->data)); /* 'J' */ 777: } 778: filter->status = 0x400; 779: CK((*filter->output_function)(s & 0x7f, filter->data)); 780: } 781: } else { 782: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) { 783: CK(mbfl_filt_conv_illegal_output(c, filter)); 784: } 785: } 786: 787: return c; 788: } 789: 790: /* 791: * wchar => CP50222 792: */ 793: int 794: mbfl_filt_conv_wchar_cp50222(int c, mbfl_convert_filter *filter) 795: { 796: int s; 797: 798: s = 0; 799: 800: if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) { 801: s = ucs_a1_jis_table[c - ucs_a1_jis_table_min]; 802: } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) { 803: s = ucs_a2_jis_table[c - ucs_a2_jis_table_min]; 804: } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) { 805: s = ucs_i_jis_table[c - ucs_i_jis_table_min]; 806: } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) { 807: s = ucs_r_jis_table[c - ucs_r_jis_table_min]; 808: } else if (c >= 0xe000 && c < (0xe000 + 10 * 94)) { 809: /* PUE => Microsoft extended */ 810: /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */ 811: s = c - 0xe000; 812: s = (s / 94 + 0x75) << 8 | (s % 94 + 0x21); 813: } else if (c >= (0xe000 + 10 * 94) && c <= (0xe000 + 20 * 94)) { 814: /* PUE => JISX0212 user-defined (G3 85ku - 94ku) */ 815: /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */ 816: s = c - (0xe000 + 10 * 94); 817: s = (s / 94 + 0xf5) << 8 | (s % 94 + 0xa1); 818: } 819: 820: if (s <= 0) { 821: if (c == 0xa5) { /* YEN SIGN */ 822: s = 0x1005c; 823: } else if (c == 0x203e) { /* OVER LINE */ 824: s = 0x1007e; 825: } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */ 826: s = 0x2140; 827: } else if (c == 0xff5e) { /* FULLWIDTH TILDE */ 828: s = 0x2141; 829: } else if (c == 0x2225) { /* PARALLEL TO */ 830: s = 0x2142; 831: } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */ 832: s = 0x215d; 833: } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */ 834: s = 0x2171; 835: } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */ 836: s = 0x2172; 837: } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */ 838: s = 0x224c; 839: } 840: } 1.1.1.2 ! misho 841: if (s <= 0 || (s >= 0x8080 && s < 0x10000)) { 1.1 misho 842: int i; 843: s = -1; 844: 845: for (i = 0; 846: i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) { 847: const int oh = cp932ext1_ucs_table_min / 94; 848: 849: if (c == cp932ext1_ucs_table[i]) { 850: s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21); 851: break; 852: } 853: } 854: 855: if (s <= 0) { 856: const int oh = cp932ext2_ucs_table_min / 94; 857: const int cp932ext2_ucs_table_size = 858: cp932ext2_ucs_table_max - cp932ext2_ucs_table_min; 859: for (i = 0; i < cp932ext2_ucs_table_size; i++) { 860: if (c == cp932ext2_ucs_table[i]) { 861: s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21); 862: break; 863: } 864: } 865: } 866: 867: if (s <= 0) { 868: const int cp932ext3_ucs_table_size = 869: cp932ext3_ucs_table_max - cp932ext3_ucs_table_min; 870: const int limit = cp932ext3_ucs_table_size > 871: cp932ext3_eucjp_table_size ? 872: cp932ext3_eucjp_table_size: 873: cp932ext3_ucs_table_size; 874: for (i = 0; i < limit; i++) { 875: if (c == cp932ext3_ucs_table[i]) { 876: s = cp932ext3_eucjp_table[i]; 877: break; 878: } 879: } 880: } 881: 882: if (c == 0) { 883: s = 0; 884: } else if (s <= 0) { 885: s = -1; 886: } 887: } 888: 889: if (s >= 0) { 890: if (s < 0x80) { /* ASCII */ 891: if ((filter->status & 0xff00) == 0x500) { 892: CK((*filter->output_function)(0x0f, filter->data)); /* SO */ 893: filter->status = 0; 894: } else if ((filter->status & 0xff00) != 0) { 895: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 896: CK((*filter->output_function)(0x28, filter->data)); /* '(' */ 897: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */ 898: filter->status = 0; 899: } 900: CK((*filter->output_function)(s, filter->data)); 901: } else if (s >= 0xa0 && s < 0xe0) { /* X 0201 kana */ 902: if ((filter->status & 0xff00) != 0x500) { 903: CK((*filter->output_function)(0x0e, filter->data)); /* SI */ 904: filter->status = 0x500; 905: } 906: CK((*filter->output_function)(s - 0x80, filter->data)); 907: } else if (s < 0x8080) { /* X 0208 */ 908: if ((filter->status & 0xff00) == 0x500) { 909: CK((*filter->output_function)(0x0f, filter->data)); /* SO */ 910: filter->status = 0; 911: } 912: if ((filter->status & 0xff00) != 0x200) { 913: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 914: CK((*filter->output_function)(0x24, filter->data)); /* '$' */ 915: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */ 916: filter->status = 0x200; 917: } 918: CK((*filter->output_function)((s >> 8) & 0x7f, filter->data)); 919: CK((*filter->output_function)(s & 0x7f, filter->data)); 920: } else if (s < 0x10000) { /* X0212 */ 921: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) { 922: CK(mbfl_filt_conv_illegal_output(c, filter)); 923: } 924: } else { /* X 0201 latin */ 925: if ((filter->status & 0xff00) == 0x500) { 926: CK((*filter->output_function)(0x0f, filter->data)); /* SO */ 927: filter->status = 0; 928: } 929: if ((filter->status & 0xff00) != 0x400) { 930: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 931: CK((*filter->output_function)(0x28, filter->data)); /* '(' */ 932: CK((*filter->output_function)(0x4a, filter->data)); /* 'J' */ 933: } 934: filter->status = 0x400; 935: CK((*filter->output_function)(s & 0x7f, filter->data)); 936: } 937: } else { 938: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) { 939: CK(mbfl_filt_conv_illegal_output(c, filter)); 940: } 941: } 942: 943: return c; 944: } 945: 946: int 947: mbfl_filt_conv_wchar_cp50222_flush(mbfl_convert_filter *filter) 948: { 949: /* back to latin */ 950: if ((filter->status & 0xff00) == 0x500) { 951: CK((*filter->output_function)(0x0f, filter->data)); /* SO */ 952: } else if ((filter->status & 0xff00) != 0) { 953: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */ 954: CK((*filter->output_function)(0x28, filter->data)); /* '(' */ 955: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */ 956: } 957: filter->status &= 0xff; 958: 959: if (filter->flush_function != NULL) { 960: return (*filter->flush_function)(filter->data); 961: } 962: 963: return 0; 964: } 965: 966: 967: static int mbfl_filt_ident_jis_ms(int c, mbfl_identify_filter *filter) 968: { 969: retry: 970: switch (filter->status & 0xf) { 971: /* case 0x00: ASCII */ 972: /* case 0x10: X 0201 latin */ 973: /* case 0x20: X 0201 kana */ 974: /* case 0x80: X 0208 */ 975: /* case 0x90: X 0212 */ 976: case 0: 977: if (c == 0x1b) { 978: filter->status += 2; 979: } else if (c == 0x0e) { /* "kana in" */ 980: filter->status = 0x20; 981: } else if (c == 0x0f) { /* "kana out" */ 982: filter->status = 0; 983: } else if ((filter->status == 0x80 || filter->status == 0x90) && c > 0x20 && c < 0x7f) { /* kanji first char */ 984: filter->status += 1; 985: } else if (c >= 0 && c < 0x80) { /* latin, CTLs */ 986: ; 987: } else { 988: filter->flag = 1; /* bad */ 989: } 990: break; 991: 992: /* case 0x81: X 0208 second char */ 993: /* case 0x91: X 0212 second char */ 994: case 1: 995: filter->status &= ~0xf; 996: if (c == 0x1b) { 997: goto retry; 998: } else if (c < 0x21 || c > 0x7e) { /* bad */ 999: filter->flag = 1; 1000: } 1001: break; 1002: 1003: /* ESC */ 1004: case 2: 1005: if (c == 0x24) { /* '$' */ 1006: filter->status++; 1007: } else if (c == 0x28) { /* '(' */ 1008: filter->status += 3; 1009: } else { 1010: filter->flag = 1; /* bad */ 1011: filter->status &= ~0xf; 1012: goto retry; 1013: } 1014: break; 1015: 1016: /* ESC $ */ 1017: case 3: 1018: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */ 1019: filter->status = 0x80; 1020: } else if (c == 0x28) { /* '(' */ 1021: filter->status++; 1022: } else { 1023: filter->flag = 1; /* bad */ 1024: filter->status &= ~0xf; 1025: goto retry; 1026: } 1027: break; 1028: 1029: /* ESC $ ( */ 1030: case 4: 1031: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */ 1032: filter->status = 0x80; 1033: } else if (c == 0x44) { /* 'D' */ 1034: filter->status = 0x90; 1035: } else { 1036: filter->flag = 1; /* bad */ 1037: filter->status &= ~0xf; 1038: goto retry; 1039: } 1040: break; 1041: 1042: /* ESC ( */ 1043: case 5: 1044: if (c == 0x42 || c == 0x48) { /* 'B' or 'H' */ 1045: filter->status = 0; 1046: } else if (c == 0x4a) { /* 'J' */ 1047: filter->status = 0x10; 1048: } else if (c == 0x49) { /* 'I' */ 1049: filter->status = 0x20; 1050: } else { 1051: filter->flag = 1; /* bad */ 1052: filter->status &= ~0xf; 1053: goto retry; 1054: } 1055: break; 1056: 1057: default: 1058: filter->status = 0; 1059: break; 1060: } 1061: 1062: return c; 1063: } 1064: 1065: static int mbfl_filt_ident_cp50220(int c, mbfl_identify_filter *filter) 1066: { 1067: retry: 1068: switch (filter->status & 0xf) { 1069: /* case 0x00: ASCII */ 1070: /* case 0x10: X 0201 latin */ 1071: /* case 0x80: X 0208 */ 1072: case 0: 1073: if (c == 0x1b) { 1074: filter->status += 2; 1075: } else if (filter->status == 0x80 && c > 0x20 && c < 0x7f) { /* kanji first char */ 1076: filter->status += 1; 1077: } else if (c >= 0 && c < 0x80) { /* latin, CTLs */ 1078: ; 1079: } else { 1080: filter->flag = 1; /* bad */ 1081: } 1082: break; 1083: 1084: /* case 0x81: X 0208 second char */ 1085: case 1: 1086: if (c == 0x1b) { 1087: filter->status++; 1088: } else { 1089: filter->status &= ~0xf; 1090: if (c < 0x21 || c > 0x7e) { /* bad */ 1091: filter->flag = 1; 1092: } 1093: } 1094: break; 1095: 1096: /* ESC */ 1097: case 2: 1098: if (c == 0x24) { /* '$' */ 1099: filter->status++; 1100: } else if (c == 0x28) { /* '(' */ 1101: filter->status += 3; 1102: } else { 1103: filter->flag = 1; /* bad */ 1104: filter->status &= ~0xf; 1105: goto retry; 1106: } 1107: break; 1108: 1109: /* ESC $ */ 1110: case 3: 1111: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */ 1112: filter->status = 0x80; 1113: } else { 1114: filter->flag = 1; /* bad */ 1115: filter->status &= ~0xf; 1116: goto retry; 1117: } 1118: break; 1119: 1120: /* ESC ( */ 1121: case 5: 1122: if (c == 0x42) { /* 'B' */ 1123: filter->status = 0; 1124: } else if (c == 0x4a) { /* 'J' */ 1125: filter->status = 0x10; 1126: } else { 1127: filter->flag = 1; /* bad */ 1128: filter->status &= ~0xf; 1129: goto retry; 1130: } 1131: break; 1132: 1133: default: 1134: filter->status = 0; 1135: break; 1136: } 1137: 1138: return c; 1139: } 1140: 1141: static int mbfl_filt_ident_cp50221(int c, mbfl_identify_filter *filter) 1142: { 1143: retry: 1144: switch (filter->status & 0xf) { 1145: /* case 0x00: ASCII */ 1146: /* case 0x10: X 0201 latin */ 1147: /* case 0x80: X 0208 */ 1148: case 0: 1149: if (c == 0x1b) { 1150: filter->status += 2; 1151: } else if (filter->status == 0x80 && c > 0x20 && c < 0x7f) { /* kanji first char */ 1152: filter->status += 1; 1153: } else if (c >= 0 && c < 0x80) { /* latin, CTLs */ 1154: ; 1155: } else { 1156: filter->flag = 1; /* bad */ 1157: } 1158: break; 1159: 1160: /* case 0x81: X 0208 second char */ 1161: case 1: 1162: if (c == 0x1b) { 1163: filter->status++; 1164: } else { 1165: filter->status &= ~0xf; 1166: if (c < 0x21 || c > 0x7e) { /* bad */ 1167: filter->flag = 1; 1168: } 1169: } 1170: break; 1171: 1172: /* ESC */ 1173: case 2: 1174: if (c == 0x24) { /* '$' */ 1175: filter->status++; 1176: } else if (c == 0x28) { /* '(' */ 1177: filter->status += 3; 1178: } else { 1179: filter->flag = 1; /* bad */ 1180: filter->status &= ~0xf; 1181: goto retry; 1182: } 1183: break; 1184: 1185: /* ESC $ */ 1186: case 3: 1187: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */ 1188: filter->status = 0x80; 1189: } else { 1190: filter->flag = 1; /* bad */ 1191: filter->status &= ~0xf; 1192: goto retry; 1193: } 1194: break; 1195: 1196: /* ESC ( */ 1197: case 5: 1198: if (c == 0x42) { /* 'B' */ 1199: filter->status = 0; 1200: } else if (c == 0x4a) { /* 'J' */ 1201: filter->status = 0x10; 1202: } else if (c == 0x49) { /* 'I' */ 1203: filter->status = 0x20; 1204: } else { 1205: filter->flag = 1; /* bad */ 1206: filter->status &= ~0xf; 1207: goto retry; 1208: } 1209: break; 1210: 1211: default: 1212: filter->status = 0; 1213: break; 1214: } 1215: 1216: return c; 1217: } 1218: 1219: static int mbfl_filt_ident_cp50222(int c, mbfl_identify_filter *filter) 1220: { 1221: retry: 1222: switch (filter->status & 0xf) { 1223: /* case 0x00: ASCII */ 1224: /* case 0x10: X 0201 latin */ 1225: /* case 0x80: X 0208 */ 1226: case 0: 1227: if (c == 0x1b) { 1228: filter->status += 2; 1229: } else if (filter->status == 0x80 && c > 0x20 && c < 0x7f) { /* kanji first char */ 1230: filter->status += 1; 1231: } else if (c >= 0 && c < 0x80) { /* latin, CTLs */ 1232: ; 1233: } else { 1234: filter->flag = 1; /* bad */ 1235: } 1236: break; 1237: 1238: /* case 0x81: X 0208 second char */ 1239: case 1: 1240: if (c == 0x1b) { 1241: filter->status++; 1242: } else { 1243: filter->status &= ~0xf; 1244: if (c < 0x21 || c > 0x7e) { /* bad */ 1245: filter->flag = 1; 1246: } 1247: } 1248: break; 1249: 1250: /* ESC */ 1251: case 2: 1252: if (c == 0x24) { /* '$' */ 1253: filter->status++; 1254: } else if (c == 0x28) { /* '(' */ 1255: filter->status += 3; 1256: } else { 1257: filter->flag = 1; /* bad */ 1258: filter->status &= ~0xf; 1259: goto retry; 1260: } 1261: break; 1262: 1263: /* ESC $ */ 1264: case 3: 1265: if (c == 0x40 || c == 0x42) { /* '@' or 'B' */ 1266: filter->status = 0x80; 1267: } else { 1268: filter->flag = 1; /* bad */ 1269: filter->status &= ~0xf; 1270: goto retry; 1271: } 1272: break; 1273: 1274: /* ESC ( */ 1275: case 5: 1276: if (c == 0x42) { /* 'B' */ 1277: filter->status = 0; 1278: } else if (c == 0x4a) { /* 'J' */ 1279: filter->status = 0x10; 1280: } else { 1281: filter->flag = 1; /* bad */ 1282: filter->status &= ~0xf; 1283: goto retry; 1284: } 1285: break; 1286: 1287: default: 1288: filter->status = 0; 1289: break; 1290: } 1291: 1292: return c; 1293: } 1294: 1295: 1296: