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>