Annotation of embedaddon/php/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c, revision 1.1.1.2

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: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>