Annotation of embedaddon/php/ext/mbstring/libmbfl/mbfl/mbfl_convert.c, revision 1.1
1.1 ! misho 1: /*
! 2: * "streamable kanji code filter and converter"
! 3: * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
! 4: *
! 5: * LICENSE NOTICES
! 6: *
! 7: * This file is part of "streamable kanji code filter and converter",
! 8: * which is distributed under the terms of GNU Lesser General Public
! 9: * License (version 2) as published by the Free Software Foundation.
! 10: *
! 11: * This software is distributed in the hope that it will be useful,
! 12: * but WITHOUT ANY WARRANTY; without even the implied warranty of
! 13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 14: * GNU Lesser General Public License for more details.
! 15: *
! 16: * You should have received a copy of the GNU Lesser General Public
! 17: * License along with "streamable kanji code filter and converter";
! 18: * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
! 19: * Suite 330, Boston, MA 02111-1307 USA
! 20: *
! 21: * The author of this file:
! 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"
! 55: #include "filters/mbfilter_cp51932.h"
! 56: #include "filters/mbfilter_jis.h"
! 57: #include "filters/mbfilter_iso2022_jp_ms.h"
! 58: #include "filters/mbfilter_euc_jp.h"
! 59: #include "filters/mbfilter_euc_jp_win.h"
! 60: #include "filters/mbfilter_ascii.h"
! 61: #include "filters/mbfilter_koi8r.h"
! 62: #include "filters/mbfilter_koi8u.h"
! 63: #include "filters/mbfilter_cp866.h"
! 64: #include "filters/mbfilter_cp932.h"
! 65: #include "filters/mbfilter_cp936.h"
! 66: #include "filters/mbfilter_cp1251.h"
! 67: #include "filters/mbfilter_cp1252.h"
! 68: #include "filters/mbfilter_cp1254.h"
! 69: #include "filters/mbfilter_cp5022x.h"
! 70: #include "filters/mbfilter_iso8859_1.h"
! 71: #include "filters/mbfilter_iso8859_2.h"
! 72: #include "filters/mbfilter_iso8859_3.h"
! 73: #include "filters/mbfilter_iso8859_4.h"
! 74: #include "filters/mbfilter_iso8859_5.h"
! 75: #include "filters/mbfilter_iso8859_6.h"
! 76: #include "filters/mbfilter_iso8859_7.h"
! 77: #include "filters/mbfilter_iso8859_8.h"
! 78: #include "filters/mbfilter_iso8859_9.h"
! 79: #include "filters/mbfilter_iso8859_10.h"
! 80: #include "filters/mbfilter_iso8859_13.h"
! 81: #include "filters/mbfilter_iso8859_14.h"
! 82: #include "filters/mbfilter_iso8859_15.h"
! 83: #include "filters/mbfilter_base64.h"
! 84: #include "filters/mbfilter_qprint.h"
! 85: #include "filters/mbfilter_uuencode.h"
! 86: #include "filters/mbfilter_7bit.h"
! 87: #include "filters/mbfilter_utf7.h"
! 88: #include "filters/mbfilter_utf7imap.h"
! 89: #include "filters/mbfilter_utf8.h"
! 90: #include "filters/mbfilter_utf16.h"
! 91: #include "filters/mbfilter_utf32.h"
! 92: #include "filters/mbfilter_byte2.h"
! 93: #include "filters/mbfilter_byte4.h"
! 94: #include "filters/mbfilter_ucs4.h"
! 95: #include "filters/mbfilter_ucs2.h"
! 96: #include "filters/mbfilter_htmlent.h"
! 97: #include "filters/mbfilter_armscii8.h"
! 98: #include "filters/mbfilter_cp850.h"
! 99:
! 100: /* hex character table "0123456789ABCDEF" */
! 101: static char mbfl_hexchar_table[] = {
! 102: 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46
! 103: };
! 104:
! 105: const struct mbfl_convert_vtbl *mbfl_convert_filter_list[] = {
! 106: &vtbl_utf8_wchar,
! 107: &vtbl_wchar_utf8,
! 108: &vtbl_eucjp_wchar,
! 109: &vtbl_wchar_eucjp,
! 110: &vtbl_sjis_wchar,
! 111: &vtbl_wchar_sjis,
! 112: &vtbl_sjis_open_wchar,
! 113: &vtbl_wchar_sjis_open,
! 114: &vtbl_cp51932_wchar,
! 115: &vtbl_wchar_cp51932,
! 116: &vtbl_jis_wchar,
! 117: &vtbl_wchar_jis,
! 118: &vtbl_jis_ms_wchar,
! 119: &vtbl_wchar_jis_ms,
! 120: &vtbl_2022jp_wchar,
! 121: &vtbl_wchar_2022jp,
! 122: &vtbl_2022jpms_wchar,
! 123: &vtbl_wchar_2022jpms,
! 124: &vtbl_eucjpwin_wchar,
! 125: &vtbl_wchar_eucjpwin,
! 126: &vtbl_cp932_wchar,
! 127: &vtbl_wchar_cp932,
! 128: &vtbl_euccn_wchar,
! 129: &vtbl_wchar_euccn,
! 130: &vtbl_cp936_wchar,
! 131: &vtbl_wchar_cp936,
! 132: &vtbl_hz_wchar,
! 133: &vtbl_wchar_hz,
! 134: &vtbl_euctw_wchar,
! 135: &vtbl_wchar_euctw,
! 136: &vtbl_big5_wchar,
! 137: &vtbl_wchar_big5,
! 138: &vtbl_euckr_wchar,
! 139: &vtbl_wchar_euckr,
! 140: &vtbl_uhc_wchar,
! 141: &vtbl_wchar_uhc,
! 142: &vtbl_2022kr_wchar,
! 143: &vtbl_wchar_2022kr,
! 144: &vtbl_cp1251_wchar,
! 145: &vtbl_wchar_cp1251,
! 146: &vtbl_cp866_wchar,
! 147: &vtbl_wchar_cp866,
! 148: &vtbl_koi8r_wchar,
! 149: &vtbl_wchar_koi8r,
! 150: &vtbl_koi8u_wchar,
! 151: &vtbl_wchar_koi8u,
! 152: &vtbl_cp1252_wchar,
! 153: &vtbl_wchar_cp1252,
! 154: &vtbl_cp1254_wchar,
! 155: &vtbl_wchar_cp1254,
! 156: &vtbl_cp50220_wchar,
! 157: &vtbl_wchar_cp50220,
! 158: &vtbl_cp50220raw_wchar,
! 159: &vtbl_wchar_cp50220raw,
! 160: &vtbl_cp50221_wchar,
! 161: &vtbl_wchar_cp50221,
! 162: &vtbl_cp50222_wchar,
! 163: &vtbl_wchar_cp50222,
! 164: &vtbl_ascii_wchar,
! 165: &vtbl_wchar_ascii,
! 166: &vtbl_8859_1_wchar,
! 167: &vtbl_wchar_8859_1,
! 168: &vtbl_8859_2_wchar,
! 169: &vtbl_wchar_8859_2,
! 170: &vtbl_8859_3_wchar,
! 171: &vtbl_wchar_8859_3,
! 172: &vtbl_8859_4_wchar,
! 173: &vtbl_wchar_8859_4,
! 174: &vtbl_8859_5_wchar,
! 175: &vtbl_wchar_8859_5,
! 176: &vtbl_8859_6_wchar,
! 177: &vtbl_wchar_8859_6,
! 178: &vtbl_8859_7_wchar,
! 179: &vtbl_wchar_8859_7,
! 180: &vtbl_8859_8_wchar,
! 181: &vtbl_wchar_8859_8,
! 182: &vtbl_8859_9_wchar,
! 183: &vtbl_wchar_8859_9,
! 184: &vtbl_8859_10_wchar,
! 185: &vtbl_wchar_8859_10,
! 186: &vtbl_8859_13_wchar,
! 187: &vtbl_wchar_8859_13,
! 188: &vtbl_8859_14_wchar,
! 189: &vtbl_wchar_8859_14,
! 190: &vtbl_8859_15_wchar,
! 191: &vtbl_wchar_8859_15,
! 192: &vtbl_8bit_b64,
! 193: &vtbl_b64_8bit,
! 194: &vtbl_uuencode_8bit,
! 195: &vtbl_wchar_html,
! 196: &vtbl_html_wchar,
! 197: &vtbl_8bit_qprint,
! 198: &vtbl_qprint_8bit,
! 199: &vtbl_8bit_7bit,
! 200: &vtbl_7bit_8bit,
! 201: &vtbl_utf7_wchar,
! 202: &vtbl_wchar_utf7,
! 203: &vtbl_utf7imap_wchar,
! 204: &vtbl_wchar_utf7imap,
! 205: &vtbl_utf16_wchar,
! 206: &vtbl_wchar_utf16,
! 207: &vtbl_utf16be_wchar,
! 208: &vtbl_wchar_utf16be,
! 209: &vtbl_utf16le_wchar,
! 210: &vtbl_wchar_utf16le,
! 211: &vtbl_utf32_wchar,
! 212: &vtbl_wchar_utf32,
! 213: &vtbl_utf32be_wchar,
! 214: &vtbl_wchar_utf32be,
! 215: &vtbl_utf32le_wchar,
! 216: &vtbl_wchar_utf32le,
! 217: &vtbl_ucs4_wchar,
! 218: &vtbl_wchar_ucs4,
! 219: &vtbl_ucs4be_wchar,
! 220: &vtbl_wchar_ucs4be,
! 221: &vtbl_ucs4le_wchar,
! 222: &vtbl_wchar_ucs4le,
! 223: &vtbl_ucs2_wchar,
! 224: &vtbl_wchar_ucs2,
! 225: &vtbl_ucs2be_wchar,
! 226: &vtbl_wchar_ucs2be,
! 227: &vtbl_ucs2le_wchar,
! 228: &vtbl_wchar_ucs2le,
! 229: &vtbl_byte4be_wchar,
! 230: &vtbl_wchar_byte4be,
! 231: &vtbl_byte4le_wchar,
! 232: &vtbl_wchar_byte4le,
! 233: &vtbl_byte2be_wchar,
! 234: &vtbl_wchar_byte2be,
! 235: &vtbl_byte2le_wchar,
! 236: &vtbl_wchar_byte2le,
! 237: &vtbl_armscii8_wchar,
! 238: &vtbl_wchar_armscii8,
! 239: &vtbl_cp850_wchar,
! 240: &vtbl_wchar_cp850,
! 241: &vtbl_pass,
! 242: NULL
! 243: };
! 244:
! 245: static int
! 246: mbfl_convert_filter_common_init(
! 247: mbfl_convert_filter *filter,
! 248: enum mbfl_no_encoding from,
! 249: enum mbfl_no_encoding to,
! 250: const struct mbfl_convert_vtbl *vtbl,
! 251: int (*output_function)(int, void* ),
! 252: int (*flush_function)(void*),
! 253: void* data)
! 254: {
! 255: /* encoding structure */
! 256: if ((filter->from = mbfl_no2encoding(from)) == NULL) {
! 257: return 1;
! 258: }
! 259:
! 260: if ((filter->to = mbfl_no2encoding(to)) == NULL) {
! 261: return 1;
! 262: }
! 263:
! 264: if (output_function != NULL) {
! 265: filter->output_function = output_function;
! 266: } else {
! 267: filter->output_function = mbfl_filter_output_null;
! 268: }
! 269:
! 270: filter->flush_function = flush_function;
! 271: filter->data = data;
! 272: filter->illegal_mode = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
! 273: filter->illegal_substchar = 0x3f; /* '?' */
! 274: filter->num_illegalchar = 0;
! 275: filter->filter_ctor = vtbl->filter_ctor;
! 276: filter->filter_dtor = vtbl->filter_dtor;
! 277: filter->filter_function = vtbl->filter_function;
! 278: filter->filter_flush = vtbl->filter_flush;
! 279: filter->filter_copy = vtbl->filter_copy;
! 280:
! 281: (*filter->filter_ctor)(filter);
! 282:
! 283: return 0;
! 284: }
! 285:
! 286:
! 287: mbfl_convert_filter *
! 288: mbfl_convert_filter_new(
! 289: enum mbfl_no_encoding from,
! 290: enum mbfl_no_encoding to,
! 291: int (*output_function)(int, void* ),
! 292: int (*flush_function)(void*),
! 293: void* data)
! 294: {
! 295: mbfl_convert_filter * filter;
! 296: const struct mbfl_convert_vtbl *vtbl;
! 297:
! 298: vtbl = mbfl_convert_filter_get_vtbl(from, to);
! 299:
! 300: if (vtbl == NULL) {
! 301: vtbl = &vtbl_pass;
! 302: }
! 303:
! 304: /* allocate */
! 305: filter = (mbfl_convert_filter *)mbfl_malloc(sizeof(mbfl_convert_filter));
! 306: if (filter == NULL) {
! 307: return NULL;
! 308: }
! 309:
! 310: if (mbfl_convert_filter_common_init(filter, from, to, vtbl,
! 311: output_function, flush_function, data)) {
! 312: mbfl_free(filter);
! 313: return NULL;
! 314: }
! 315:
! 316: return filter;
! 317: }
! 318:
! 319: mbfl_convert_filter *
! 320: mbfl_convert_filter_new2(
! 321: const struct mbfl_convert_vtbl *vtbl,
! 322: int (*output_function)(int, void* ),
! 323: int (*flush_function)(void*),
! 324: void* data)
! 325: {
! 326: mbfl_convert_filter * filter;
! 327:
! 328: if (vtbl == NULL) {
! 329: vtbl = &vtbl_pass;
! 330: }
! 331:
! 332: /* allocate */
! 333: filter = (mbfl_convert_filter *)mbfl_malloc(sizeof(mbfl_convert_filter));
! 334: if (filter == NULL) {
! 335: return NULL;
! 336: }
! 337:
! 338: if (mbfl_convert_filter_common_init(filter, vtbl->from, vtbl->to, vtbl,
! 339: output_function, flush_function, data)) {
! 340: mbfl_free(filter);
! 341: return NULL;
! 342: }
! 343:
! 344: return filter;
! 345: }
! 346:
! 347: void
! 348: mbfl_convert_filter_delete(mbfl_convert_filter *filter)
! 349: {
! 350: if (filter) {
! 351: (*filter->filter_dtor)(filter);
! 352: mbfl_free((void*)filter);
! 353: }
! 354: }
! 355:
! 356: int
! 357: mbfl_convert_filter_feed(int c, mbfl_convert_filter *filter)
! 358: {
! 359: return (*filter->filter_function)(c, filter);
! 360: }
! 361:
! 362: int
! 363: mbfl_convert_filter_flush(mbfl_convert_filter *filter)
! 364: {
! 365: (*filter->filter_flush)(filter);
! 366: return (filter->flush_function ? (*filter->flush_function)(filter->data) : 0);
! 367: }
! 368:
! 369: void mbfl_convert_filter_reset(mbfl_convert_filter *filter,
! 370: enum mbfl_no_encoding from, enum mbfl_no_encoding to)
! 371: {
! 372: const struct mbfl_convert_vtbl *vtbl;
! 373:
! 374: /* destruct old filter */
! 375: (*filter->filter_dtor)(filter);
! 376:
! 377: vtbl = mbfl_convert_filter_get_vtbl(from, to);
! 378:
! 379: if (vtbl == NULL) {
! 380: vtbl = &vtbl_pass;
! 381: }
! 382:
! 383: mbfl_convert_filter_common_init(filter, from, to, vtbl,
! 384: filter->output_function, filter->flush_function, filter->data);
! 385: }
! 386:
! 387: void
! 388: mbfl_convert_filter_copy(
! 389: mbfl_convert_filter *src,
! 390: mbfl_convert_filter *dest)
! 391: {
! 392: if (src->filter_copy != NULL) {
! 393: src->filter_copy(src, dest);
! 394: return;
! 395: }
! 396:
! 397: *dest = *src;
! 398: }
! 399:
! 400: int mbfl_convert_filter_devcat(mbfl_convert_filter *filter, mbfl_memory_device *src)
! 401: {
! 402: int n;
! 403: unsigned char *p;
! 404:
! 405: p = src->buffer;
! 406: n = src->pos;
! 407: while (n > 0) {
! 408: if ((*filter->filter_function)(*p++, filter) < 0) {
! 409: return -1;
! 410: }
! 411: n--;
! 412: }
! 413:
! 414: return n;
! 415: }
! 416:
! 417: int mbfl_convert_filter_strcat(mbfl_convert_filter *filter, const unsigned char *p)
! 418: {
! 419: int c;
! 420:
! 421: while ((c = *p++) != '\0') {
! 422: if ((*filter->filter_function)(c, filter) < 0) {
! 423: return -1;
! 424: }
! 425: }
! 426:
! 427: return 0;
! 428: }
! 429:
! 430: /* illegal character output function for conv-filter */
! 431: int
! 432: mbfl_filt_conv_illegal_output(int c, mbfl_convert_filter *filter)
! 433: {
! 434: int mode_backup, ret, n, m, r;
! 435:
! 436: ret = 0;
! 437: mode_backup = filter->illegal_mode;
! 438: filter->illegal_mode = MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE;
! 439: switch (mode_backup) {
! 440: case MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR:
! 441: ret = (*filter->filter_function)(filter->illegal_substchar, filter);
! 442: break;
! 443: case MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG:
! 444: if (c >= 0) {
! 445: if (c < MBFL_WCSGROUP_UCS4MAX) { /* unicode */
! 446: ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"U+");
! 447: } else {
! 448: if (c < MBFL_WCSGROUP_WCHARMAX) {
! 449: m = c & ~MBFL_WCSPLANE_MASK;
! 450: switch (m) {
! 451: case MBFL_WCSPLANE_JIS0208:
! 452: ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"JIS+");
! 453: break;
! 454: case MBFL_WCSPLANE_JIS0212:
! 455: ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"JIS2+");
! 456: break;
! 457: case MBFL_WCSPLANE_WINCP932:
! 458: ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"W932+");
! 459: break;
! 460: case MBFL_WCSPLANE_8859_1:
! 461: ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"I8859_1+");
! 462: break;
! 463: default:
! 464: ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"?+");
! 465: break;
! 466: }
! 467: c &= MBFL_WCSPLANE_MASK;
! 468: } else {
! 469: ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"BAD+");
! 470: c &= MBFL_WCSGROUP_MASK;
! 471: }
! 472: }
! 473: if (ret >= 0) {
! 474: m = 0;
! 475: r = 28;
! 476: while (r >= 0) {
! 477: n = (c >> r) & 0xf;
! 478: if (n || m) {
! 479: m = 1;
! 480: ret = (*filter->filter_function)(mbfl_hexchar_table[n], filter);
! 481: if (ret < 0) {
! 482: break;
! 483: }
! 484: }
! 485: r -= 4;
! 486: }
! 487: if (m == 0 && ret >= 0) {
! 488: ret = (*filter->filter_function)(mbfl_hexchar_table[0], filter);
! 489: }
! 490: }
! 491: }
! 492: break;
! 493: case MBFL_OUTPUTFILTER_ILLEGAL_MODE_ENTITY:
! 494: if (c >= 0) {
! 495: if (c < MBFL_WCSGROUP_UCS4MAX) { /* unicode */
! 496: ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)"&#x");
! 497: if (ret < 0)
! 498: break;
! 499:
! 500: m = 0;
! 501: r = 28;
! 502: while (r >= 0) {
! 503: n = (c >> r) & 0xf;
! 504: if (n || m) {
! 505: m = 1;
! 506: ret = (*filter->filter_function)(mbfl_hexchar_table[n], filter);
! 507: if (ret < 0) {
! 508: break;
! 509: }
! 510: }
! 511: r -= 4;
! 512: }
! 513: if (ret < 0) {
! 514: break;
! 515: }
! 516: if (m == 0) {
! 517: ret = (*filter->filter_function)(mbfl_hexchar_table[0], filter);
! 518: }
! 519: ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)";");
! 520: } else {
! 521: ret = (*filter->filter_function)(filter->illegal_substchar, filter);
! 522: }
! 523: }
! 524: break;
! 525: default:
! 526: break;
! 527: }
! 528: filter->illegal_mode = mode_backup;
! 529: filter->num_illegalchar++;
! 530:
! 531: return ret;
! 532: }
! 533:
! 534: const struct mbfl_convert_vtbl * mbfl_convert_filter_get_vtbl(enum mbfl_no_encoding from, enum mbfl_no_encoding to)
! 535: {
! 536: const struct mbfl_convert_vtbl *vtbl;
! 537: int i;
! 538:
! 539: if (to == mbfl_no_encoding_base64 ||
! 540: to == mbfl_no_encoding_qprint ||
! 541: to == mbfl_no_encoding_7bit) {
! 542: from = mbfl_no_encoding_8bit;
! 543: } else if (from == mbfl_no_encoding_base64 ||
! 544: from == mbfl_no_encoding_qprint ||
! 545: from == mbfl_no_encoding_uuencode) {
! 546: to = mbfl_no_encoding_8bit;
! 547: }
! 548:
! 549: i = 0;
! 550: while ((vtbl = mbfl_convert_filter_list[i++]) != NULL){
! 551: if (vtbl->from == from && vtbl->to == to) {
! 552: return vtbl;
! 553: }
! 554: }
! 555:
! 556: return NULL;
! 557: }
! 558:
! 559: /*
! 560: * commonly used constructor and destructor
! 561: */
! 562: void mbfl_filt_conv_common_ctor(mbfl_convert_filter *filter)
! 563: {
! 564: filter->status = 0;
! 565: filter->cache = 0;
! 566: }
! 567:
! 568: int mbfl_filt_conv_common_flush(mbfl_convert_filter *filter)
! 569: {
! 570: filter->status = 0;
! 571: filter->cache = 0;
! 572:
! 573: if (filter->flush_function != NULL) {
! 574: (*filter->flush_function)(filter->data);
! 575: }
! 576: return 0;
! 577: }
! 578:
! 579: void mbfl_filt_conv_common_dtor(mbfl_convert_filter *filter)
! 580: {
! 581: filter->status = 0;
! 582: filter->cache = 0;
! 583: }
! 584:
! 585:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>