Annotation of embedaddon/php/ext/mbstring/libmbfl/mbfl/mbfl_convert.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:
                     22:  *
                     23:  */
                     24: /*
                     25:  * The source code included in this files was separated from mbfilter.c
                     26:  * by Moriyoshi Koizumi <moriyoshi@php.net> on 20 Dec 2002. The file
                     27:  * mbfilter.c is included in this package .
                     28:  *
                     29:  */
                     30: 
                     31: #ifdef HAVE_CONFIG_H
                     32: #include "config.h"
                     33: #endif
                     34: 
                     35: #ifdef HAVE_STDDEF_H
                     36: #include <stddef.h>
                     37: #endif
                     38: 
                     39: #include "mbfl_encoding.h"
                     40: #include "mbfl_allocators.h"
                     41: #include "mbfl_filter_output.h"
                     42: #include "mbfilter_pass.h"
                     43: #include "mbfilter_8bit.h"
                     44: #include "mbfilter_wchar.h"
                     45: 
                     46: #include "filters/mbfilter_euc_cn.h"
                     47: #include "filters/mbfilter_hz.h"
                     48: #include "filters/mbfilter_euc_tw.h"
                     49: #include "filters/mbfilter_big5.h"
                     50: #include "filters/mbfilter_uhc.h"
                     51: #include "filters/mbfilter_euc_kr.h"
                     52: #include "filters/mbfilter_iso2022_kr.h"
                     53: #include "filters/mbfilter_sjis.h"
                     54: #include "filters/mbfilter_sjis_open.h"
1.1.1.2 ! misho      55: #include "filters/mbfilter_sjis_2004.h"
        !            56: #include "filters/mbfilter_sjis_mobile.h"
        !            57: #include "filters/mbfilter_sjis_mac.h"
1.1       misho      58: #include "filters/mbfilter_cp51932.h"
                     59: #include "filters/mbfilter_jis.h"
                     60: #include "filters/mbfilter_iso2022_jp_ms.h"
1.1.1.2 ! misho      61: #include "filters/mbfilter_iso2022jp_2004.h"
        !            62: #include "filters/mbfilter_iso2022jp_mobile.h"
1.1       misho      63: #include "filters/mbfilter_euc_jp.h"
1.1.1.2 ! misho      64: #include "filters/mbfilter_euc_jp_2004.h"
1.1       misho      65: #include "filters/mbfilter_euc_jp_win.h"
1.1.1.2 ! misho      66: #include "filters/mbfilter_gb18030.h"
1.1       misho      67: #include "filters/mbfilter_ascii.h"
                     68: #include "filters/mbfilter_koi8r.h"
                     69: #include "filters/mbfilter_koi8u.h"
                     70: #include "filters/mbfilter_cp866.h"
                     71: #include "filters/mbfilter_cp932.h"
                     72: #include "filters/mbfilter_cp936.h"
                     73: #include "filters/mbfilter_cp1251.h"
                     74: #include "filters/mbfilter_cp1252.h"
                     75: #include "filters/mbfilter_cp1254.h"
                     76: #include "filters/mbfilter_cp5022x.h"
                     77: #include "filters/mbfilter_iso8859_1.h"
                     78: #include "filters/mbfilter_iso8859_2.h"
                     79: #include "filters/mbfilter_iso8859_3.h"
                     80: #include "filters/mbfilter_iso8859_4.h"
                     81: #include "filters/mbfilter_iso8859_5.h"
                     82: #include "filters/mbfilter_iso8859_6.h"
                     83: #include "filters/mbfilter_iso8859_7.h"
                     84: #include "filters/mbfilter_iso8859_8.h"
                     85: #include "filters/mbfilter_iso8859_9.h"
                     86: #include "filters/mbfilter_iso8859_10.h"
                     87: #include "filters/mbfilter_iso8859_13.h"
                     88: #include "filters/mbfilter_iso8859_14.h"
                     89: #include "filters/mbfilter_iso8859_15.h"
                     90: #include "filters/mbfilter_base64.h"
                     91: #include "filters/mbfilter_qprint.h"
                     92: #include "filters/mbfilter_uuencode.h"
                     93: #include "filters/mbfilter_7bit.h"
                     94: #include "filters/mbfilter_utf7.h"
                     95: #include "filters/mbfilter_utf7imap.h"
                     96: #include "filters/mbfilter_utf8.h"
1.1.1.2 ! misho      97: #include "filters/mbfilter_utf8_mobile.h"
1.1       misho      98: #include "filters/mbfilter_utf16.h"
                     99: #include "filters/mbfilter_utf32.h"
                    100: #include "filters/mbfilter_byte2.h"
                    101: #include "filters/mbfilter_byte4.h"
                    102: #include "filters/mbfilter_ucs4.h"
                    103: #include "filters/mbfilter_ucs2.h"
                    104: #include "filters/mbfilter_htmlent.h"
                    105: #include "filters/mbfilter_armscii8.h"
                    106: #include "filters/mbfilter_cp850.h"
                    107: 
                    108: /* hex character table "0123456789ABCDEF" */
                    109: static char mbfl_hexchar_table[] = {
                    110:        0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46
                    111: };
                    112: 
                    113: const struct mbfl_convert_vtbl *mbfl_convert_filter_list[] = {
                    114:        &vtbl_utf8_wchar,
                    115:        &vtbl_wchar_utf8,
                    116:        &vtbl_eucjp_wchar,
                    117:        &vtbl_wchar_eucjp,
                    118:        &vtbl_sjis_wchar,
                    119:        &vtbl_wchar_sjis,
                    120:        &vtbl_sjis_open_wchar,
                    121:        &vtbl_wchar_sjis_open,
1.1.1.2 ! misho     122:        &vtbl_sjis2004_wchar,
        !           123:        &vtbl_wchar_sjis2004,
1.1       misho     124:        &vtbl_cp51932_wchar,
                    125:        &vtbl_wchar_cp51932,
                    126:        &vtbl_jis_wchar,
                    127:        &vtbl_wchar_jis,
                    128:        &vtbl_jis_ms_wchar,
                    129:        &vtbl_wchar_jis_ms,
                    130:        &vtbl_2022jp_wchar,
                    131:        &vtbl_wchar_2022jp,
                    132:        &vtbl_2022jpms_wchar,
                    133:        &vtbl_wchar_2022jpms,
1.1.1.2 ! misho     134:        &vtbl_2022jp_2004_wchar,
        !           135:        &vtbl_wchar_2022jp_2004,
        !           136:        &vtbl_2022jp_kddi_wchar,
        !           137:        &vtbl_wchar_2022jp_kddi,
1.1       misho     138:        &vtbl_eucjpwin_wchar,
                    139:        &vtbl_wchar_eucjpwin,
1.1.1.2 ! misho     140:        &vtbl_eucjp2004_wchar,
        !           141:        &vtbl_wchar_eucjp2004,
1.1       misho     142:        &vtbl_cp932_wchar,
                    143:        &vtbl_wchar_cp932,
1.1.1.2 ! misho     144:        &vtbl_sjis_docomo_wchar,
        !           145:        &vtbl_wchar_sjis_docomo,
        !           146:        &vtbl_sjis_kddi_wchar,
        !           147:        &vtbl_wchar_sjis_kddi,
        !           148:        &vtbl_sjis_sb_wchar,
        !           149:        &vtbl_wchar_sjis_sb,
        !           150:        &vtbl_sjis_mac_wchar,
        !           151:        &vtbl_wchar_sjis_mac,
        !           152:        &vtbl_utf8_docomo_wchar,
        !           153:        &vtbl_wchar_utf8_docomo,
        !           154:        &vtbl_utf8_kddi_a_wchar,
        !           155:        &vtbl_wchar_utf8_kddi_a,
        !           156:        &vtbl_utf8_kddi_b_wchar,
        !           157:        &vtbl_wchar_utf8_kddi_b,
        !           158:        &vtbl_utf8_sb_wchar,
        !           159:        &vtbl_wchar_utf8_sb,
1.1       misho     160:        &vtbl_euccn_wchar,
                    161:        &vtbl_wchar_euccn,
                    162:        &vtbl_cp936_wchar,
                    163:        &vtbl_wchar_cp936,
1.1.1.2 ! misho     164:        &vtbl_gb18030_wchar,
        !           165:        &vtbl_wchar_gb18030,
1.1       misho     166:        &vtbl_hz_wchar,
                    167:        &vtbl_wchar_hz,
                    168:        &vtbl_euctw_wchar,
                    169:        &vtbl_wchar_euctw,
                    170:        &vtbl_big5_wchar,
                    171:        &vtbl_wchar_big5,
1.1.1.2 ! misho     172:        &vtbl_cp950_wchar,
        !           173:        &vtbl_wchar_cp950,
1.1       misho     174:        &vtbl_euckr_wchar,
                    175:        &vtbl_wchar_euckr,
                    176:        &vtbl_uhc_wchar,
                    177:        &vtbl_wchar_uhc,
                    178:        &vtbl_2022kr_wchar,
                    179:        &vtbl_wchar_2022kr,
                    180:        &vtbl_cp1251_wchar,
                    181:        &vtbl_wchar_cp1251,
                    182:        &vtbl_cp866_wchar,
                    183:        &vtbl_wchar_cp866,
                    184:        &vtbl_koi8r_wchar,
                    185:        &vtbl_wchar_koi8r,
                    186:        &vtbl_koi8u_wchar,
                    187:        &vtbl_wchar_koi8u,
                    188:        &vtbl_cp1252_wchar,
                    189:        &vtbl_wchar_cp1252,
                    190:        &vtbl_cp1254_wchar,
                    191:        &vtbl_wchar_cp1254,
                    192:        &vtbl_cp50220_wchar,
                    193:        &vtbl_wchar_cp50220,
                    194:        &vtbl_cp50220raw_wchar,
                    195:        &vtbl_wchar_cp50220raw,
                    196:        &vtbl_cp50221_wchar,
                    197:        &vtbl_wchar_cp50221,
                    198:        &vtbl_cp50222_wchar,
                    199:        &vtbl_wchar_cp50222,
                    200:        &vtbl_ascii_wchar,
                    201:        &vtbl_wchar_ascii,
                    202:        &vtbl_8859_1_wchar,
                    203:        &vtbl_wchar_8859_1,
                    204:        &vtbl_8859_2_wchar,
                    205:        &vtbl_wchar_8859_2,
                    206:        &vtbl_8859_3_wchar,
                    207:        &vtbl_wchar_8859_3,
                    208:        &vtbl_8859_4_wchar,
                    209:        &vtbl_wchar_8859_4,
                    210:        &vtbl_8859_5_wchar,
                    211:        &vtbl_wchar_8859_5,
                    212:        &vtbl_8859_6_wchar,
                    213:        &vtbl_wchar_8859_6,
                    214:        &vtbl_8859_7_wchar,
                    215:        &vtbl_wchar_8859_7,
                    216:        &vtbl_8859_8_wchar,
                    217:        &vtbl_wchar_8859_8,
                    218:        &vtbl_8859_9_wchar,
                    219:        &vtbl_wchar_8859_9,
                    220:        &vtbl_8859_10_wchar,
                    221:        &vtbl_wchar_8859_10,
                    222:        &vtbl_8859_13_wchar,
                    223:        &vtbl_wchar_8859_13,
                    224:        &vtbl_8859_14_wchar,
                    225:        &vtbl_wchar_8859_14,
                    226:        &vtbl_8859_15_wchar,
                    227:        &vtbl_wchar_8859_15,
                    228:        &vtbl_8bit_b64,
                    229:        &vtbl_b64_8bit,
                    230:        &vtbl_uuencode_8bit,
                    231:        &vtbl_wchar_html,
                    232:        &vtbl_html_wchar,
                    233:        &vtbl_8bit_qprint,
                    234:        &vtbl_qprint_8bit,
                    235:        &vtbl_8bit_7bit,
                    236:        &vtbl_7bit_8bit,
                    237:        &vtbl_utf7_wchar,
                    238:        &vtbl_wchar_utf7,
                    239:        &vtbl_utf7imap_wchar,
                    240:        &vtbl_wchar_utf7imap,
                    241:        &vtbl_utf16_wchar,
                    242:        &vtbl_wchar_utf16,
                    243:        &vtbl_utf16be_wchar,
                    244:        &vtbl_wchar_utf16be,
                    245:        &vtbl_utf16le_wchar,
                    246:        &vtbl_wchar_utf16le,
                    247:        &vtbl_utf32_wchar,
                    248:        &vtbl_wchar_utf32,
                    249:        &vtbl_utf32be_wchar,
                    250:        &vtbl_wchar_utf32be,
                    251:        &vtbl_utf32le_wchar,
                    252:        &vtbl_wchar_utf32le,
                    253:        &vtbl_ucs4_wchar,
                    254:        &vtbl_wchar_ucs4,
                    255:        &vtbl_ucs4be_wchar,
                    256:        &vtbl_wchar_ucs4be,
                    257:        &vtbl_ucs4le_wchar,
                    258:        &vtbl_wchar_ucs4le,
                    259:        &vtbl_ucs2_wchar,
                    260:        &vtbl_wchar_ucs2,
                    261:        &vtbl_ucs2be_wchar,
                    262:        &vtbl_wchar_ucs2be,
                    263:        &vtbl_ucs2le_wchar,
                    264:        &vtbl_wchar_ucs2le,
                    265:        &vtbl_byte4be_wchar,
                    266:        &vtbl_wchar_byte4be,
                    267:        &vtbl_byte4le_wchar,
                    268:        &vtbl_wchar_byte4le,
                    269:        &vtbl_byte2be_wchar,
                    270:        &vtbl_wchar_byte2be,
                    271:        &vtbl_byte2le_wchar,
                    272:        &vtbl_wchar_byte2le,
                    273:        &vtbl_armscii8_wchar,
                    274:        &vtbl_wchar_armscii8,
                    275:        &vtbl_cp850_wchar,
                    276:        &vtbl_wchar_cp850,
                    277:        &vtbl_pass,
                    278:        NULL
                    279: };
                    280: 
                    281: static int
                    282: mbfl_convert_filter_common_init(
                    283:        mbfl_convert_filter *filter,
                    284:        enum mbfl_no_encoding from,
                    285:        enum mbfl_no_encoding to,
                    286:        const struct mbfl_convert_vtbl *vtbl,
                    287:     int (*output_function)(int, void* ),
                    288:     int (*flush_function)(void*),
                    289:     void* data)
                    290: {
                    291:        /* encoding structure */
                    292:        if ((filter->from = mbfl_no2encoding(from)) == NULL) {
                    293:                return 1;
                    294:        }
                    295: 
                    296:        if ((filter->to = mbfl_no2encoding(to)) == NULL) {
                    297:                return 1;
                    298:        }
                    299: 
                    300:        if (output_function != NULL) {
                    301:                filter->output_function = output_function;
                    302:        } else {
                    303:                filter->output_function = mbfl_filter_output_null;
                    304:        }
                    305: 
                    306:        filter->flush_function = flush_function;
                    307:        filter->data = data;
                    308:        filter->illegal_mode = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
                    309:        filter->illegal_substchar = 0x3f;               /* '?' */
                    310:        filter->num_illegalchar = 0;
                    311:        filter->filter_ctor = vtbl->filter_ctor;
                    312:        filter->filter_dtor = vtbl->filter_dtor;
                    313:        filter->filter_function = vtbl->filter_function;
                    314:        filter->filter_flush = vtbl->filter_flush;
                    315:        filter->filter_copy = vtbl->filter_copy;
                    316: 
                    317:        (*filter->filter_ctor)(filter);
                    318: 
                    319:        return 0;
                    320: }
                    321: 
                    322: 
                    323: mbfl_convert_filter *
                    324: mbfl_convert_filter_new(
                    325:     enum mbfl_no_encoding from,
                    326:     enum mbfl_no_encoding to,
                    327:     int (*output_function)(int, void* ),
                    328:     int (*flush_function)(void*),
                    329:     void* data)
                    330: {
                    331:        mbfl_convert_filter * filter;
                    332:        const struct mbfl_convert_vtbl *vtbl;
                    333: 
                    334:        vtbl = mbfl_convert_filter_get_vtbl(from, to);
                    335: 
                    336:        if (vtbl == NULL) {
                    337:                vtbl = &vtbl_pass;
                    338:        }
                    339: 
                    340:        /* allocate */
                    341:        filter = (mbfl_convert_filter *)mbfl_malloc(sizeof(mbfl_convert_filter));
                    342:        if (filter == NULL) {
                    343:                return NULL;
                    344:        }
                    345: 
                    346:        if (mbfl_convert_filter_common_init(filter, from, to, vtbl,
                    347:                        output_function, flush_function, data)) {
                    348:                mbfl_free(filter);
                    349:                return NULL;
                    350:        }
                    351: 
                    352:        return filter;
                    353: }
                    354: 
                    355: mbfl_convert_filter *
                    356: mbfl_convert_filter_new2(
                    357:        const struct mbfl_convert_vtbl *vtbl,
                    358:     int (*output_function)(int, void* ),
                    359:     int (*flush_function)(void*),
                    360:     void* data)
                    361: {
                    362:        mbfl_convert_filter * filter;
                    363: 
                    364:        if (vtbl == NULL) {
                    365:                vtbl = &vtbl_pass;
                    366:        }
                    367: 
                    368:        /* allocate */
                    369:        filter = (mbfl_convert_filter *)mbfl_malloc(sizeof(mbfl_convert_filter));
                    370:        if (filter == NULL) {
                    371:                return NULL;
                    372:        }
                    373: 
                    374:        if (mbfl_convert_filter_common_init(filter, vtbl->from, vtbl->to, vtbl,
                    375:                        output_function, flush_function, data)) {
                    376:                mbfl_free(filter);
                    377:                return NULL;
                    378:        }
                    379: 
                    380:        return filter;
                    381: }
                    382: 
                    383: void
                    384: mbfl_convert_filter_delete(mbfl_convert_filter *filter)
                    385: {
                    386:        if (filter) {
                    387:                (*filter->filter_dtor)(filter);
                    388:                mbfl_free((void*)filter);
                    389:        }
                    390: }
                    391: 
                    392: int
                    393: mbfl_convert_filter_feed(int c, mbfl_convert_filter *filter)
                    394: {
                    395:        return (*filter->filter_function)(c, filter);
                    396: }
                    397: 
                    398: int
                    399: mbfl_convert_filter_flush(mbfl_convert_filter *filter)
                    400: {
                    401:        (*filter->filter_flush)(filter);
                    402:        return (filter->flush_function ? (*filter->flush_function)(filter->data) : 0);
                    403: }
                    404: 
                    405: void mbfl_convert_filter_reset(mbfl_convert_filter *filter,
                    406:            enum mbfl_no_encoding from, enum mbfl_no_encoding to)
                    407: {
                    408:        const struct mbfl_convert_vtbl *vtbl;
                    409: 
                    410:        /* destruct old filter */
                    411:        (*filter->filter_dtor)(filter);
                    412: 
                    413:        vtbl = mbfl_convert_filter_get_vtbl(from, to);
                    414: 
                    415:        if (vtbl == NULL) {
                    416:                vtbl = &vtbl_pass;
                    417:        }
                    418: 
                    419:        mbfl_convert_filter_common_init(filter, from, to, vtbl,
                    420:                        filter->output_function, filter->flush_function, filter->data);
                    421: }
                    422: 
                    423: void
                    424: mbfl_convert_filter_copy(
                    425:     mbfl_convert_filter *src,
                    426:     mbfl_convert_filter *dest)
                    427: {
                    428:        if (src->filter_copy != NULL) {
                    429:                src->filter_copy(src, dest);
                    430:                return;
                    431:        }
                    432: 
                    433:        *dest = *src;
                    434: }
                    435: 
                    436: int mbfl_convert_filter_devcat(mbfl_convert_filter *filter, mbfl_memory_device *src) 
                    437: {
                    438:        int n;
                    439:        unsigned char *p;
                    440: 
                    441:        p = src->buffer;
                    442:        n = src->pos;
                    443:        while (n > 0) {
                    444:                if ((*filter->filter_function)(*p++, filter) < 0) {
                    445:                        return -1;
                    446:                }
                    447:                n--;
                    448:        }
                    449: 
                    450:        return n;
                    451: }
                    452: 
                    453: int mbfl_convert_filter_strcat(mbfl_convert_filter *filter, const unsigned char *p)
                    454: {
                    455:        int c;
                    456: 
                    457:        while ((c = *p++) != '\0') {
                    458:                if ((*filter->filter_function)(c, filter) < 0) {
                    459:                        return -1;
                    460:                }
                    461:        }
                    462: 
                    463:        return 0;
                    464: }
                    465: 
                    466: /* illegal character output function for conv-filter */
                    467: int
                    468: mbfl_filt_conv_illegal_output(int c, mbfl_convert_filter *filter)
                    469: {
                    470:        int mode_backup, ret, n, m, r;
                    471: 
                    472:        ret = 0;
                    473:        mode_backup = filter->illegal_mode;
                    474:        filter->illegal_mode = MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE;
                    475:        switch (mode_backup) {
                    476:        case MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR:
                    477:                ret = (*filter->filter_function)(filter->illegal_substchar, filter);
                    478:                break;
                    479:        case MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG:
                    480:                if (c >= 0) {
                    481:                        if (c < MBFL_WCSGROUP_UCS4MAX) {        /* unicode */
                    482:                                ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"U+");
                    483:                        } else {
                    484:                                if (c < MBFL_WCSGROUP_WCHARMAX) {
                    485:                                        m = c & ~MBFL_WCSPLANE_MASK;
                    486:                                        switch (m) {
                    487:                                        case MBFL_WCSPLANE_JIS0208:
                    488:                                                ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"JIS+");
                    489:                                                break;
                    490:                                        case MBFL_WCSPLANE_JIS0212:
                    491:                                                ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"JIS2+");
                    492:                                                break;
1.1.1.2 ! misho     493:                                        case MBFL_WCSPLANE_JIS0213:
        !           494:                                                ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"JIS3+");
        !           495:                                                break;
1.1       misho     496:                                        case MBFL_WCSPLANE_WINCP932:
                    497:                                                ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"W932+");
                    498:                                                break;
1.1.1.2 ! misho     499:                                        case MBFL_WCSPLANE_GB18030:
        !           500:                                                ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"GB+");
        !           501:                                                break;
1.1       misho     502:                                        case MBFL_WCSPLANE_8859_1:
                    503:                                                ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"I8859_1+");
                    504:                                                break;
                    505:                                        default:
                    506:                                                ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"?+");
                    507:                                                break;
                    508:                                        }
                    509:                                        c &= MBFL_WCSPLANE_MASK;
                    510:                                } else {
                    511:                                        ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"BAD+");
                    512:                                        c &= MBFL_WCSGROUP_MASK;
                    513:                                }
                    514:                        }
                    515:                        if (ret >= 0) {
                    516:                                m = 0;
                    517:                                r = 28;
                    518:                                while (r >= 0) {
                    519:                                        n = (c >> r) & 0xf;
                    520:                                        if (n || m) {
                    521:                                                m = 1;
                    522:                                                ret = (*filter->filter_function)(mbfl_hexchar_table[n], filter);
                    523:                                                if (ret < 0) {
                    524:                                                        break;
                    525:                                                }
                    526:                                        }
                    527:                                        r -= 4;
                    528:                                }
                    529:                                if (m == 0 && ret >= 0) {
                    530:                                        ret = (*filter->filter_function)(mbfl_hexchar_table[0], filter);
                    531:                                }
                    532:                        }
                    533:                }
                    534:                break;
                    535:        case MBFL_OUTPUTFILTER_ILLEGAL_MODE_ENTITY:
                    536:                if (c >= 0) {
                    537:                        if (c < MBFL_WCSGROUP_UCS4MAX) {        /* unicode */
                    538:                                ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"&#x");
                    539:                                if (ret < 0)
                    540:                                        break;
                    541: 
                    542:                                m = 0;
                    543:                                r = 28;
                    544:                                while (r >= 0) {
                    545:                                        n = (c >> r) & 0xf;
                    546:                                        if (n || m) {
                    547:                                                m = 1;
                    548:                                                ret = (*filter->filter_function)(mbfl_hexchar_table[n], filter);
                    549:                                                if (ret < 0) {
                    550:                                                        break;
                    551:                                                }
                    552:                                        }
                    553:                                        r -= 4;
                    554:                                }
                    555:                                if (ret < 0) {
                    556:                                        break;
                    557:                                }
                    558:                                if (m == 0) {
                    559:                                        ret = (*filter->filter_function)(mbfl_hexchar_table[0], filter);
                    560:                                }
                    561:                                ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)";");
                    562:                        } else {
                    563:                                ret = (*filter->filter_function)(filter->illegal_substchar, filter);
                    564:                        }
                    565:                }
                    566:                break;
                    567:        default:
                    568:                break;
                    569:        }
                    570:        filter->illegal_mode = mode_backup;
                    571:        filter->num_illegalchar++;
                    572: 
                    573:        return ret;
                    574: }
                    575: 
                    576: const struct mbfl_convert_vtbl * mbfl_convert_filter_get_vtbl(enum mbfl_no_encoding from, enum mbfl_no_encoding to)
                    577: {
                    578:        const struct mbfl_convert_vtbl *vtbl;
                    579:        int i;
                    580: 
                    581:        if (to == mbfl_no_encoding_base64 ||
                    582:            to == mbfl_no_encoding_qprint ||
                    583:            to == mbfl_no_encoding_7bit) {
                    584:                from = mbfl_no_encoding_8bit;
                    585:        } else if (from == mbfl_no_encoding_base64 ||
                    586:                           from == mbfl_no_encoding_qprint ||
                    587:                           from == mbfl_no_encoding_uuencode) {
                    588:                to = mbfl_no_encoding_8bit;
                    589:        }
                    590: 
                    591:        i = 0;
                    592:        while ((vtbl = mbfl_convert_filter_list[i++]) != NULL){
                    593:                if (vtbl->from == from && vtbl->to == to) {
                    594:                        return vtbl;
                    595:                }
                    596:        }
                    597: 
                    598:        return NULL;
                    599: }
                    600: 
                    601: /*
                    602:  * commonly used constructor and destructor
                    603:  */
                    604: void mbfl_filt_conv_common_ctor(mbfl_convert_filter *filter)
                    605: {
                    606:        filter->status = 0;
                    607:        filter->cache = 0;
                    608: }
                    609: 
                    610: int mbfl_filt_conv_common_flush(mbfl_convert_filter *filter)
                    611: {
                    612:        filter->status = 0;
                    613:        filter->cache = 0;
                    614: 
                    615:        if (filter->flush_function != NULL) {
                    616:                (*filter->flush_function)(filter->data);
                    617:        }
                    618:        return 0;
                    619: }
                    620: 
                    621: void mbfl_filt_conv_common_dtor(mbfl_convert_filter *filter)
                    622: {
                    623:        filter->status = 0;
                    624:        filter->cache = 0;
                    625: }
                    626: 
                    627: 

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