Annotation of embedaddon/php/ext/mbstring/libmbfl/filters/mbfilter_sjis_open.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_ja.c
! 26: * by moriyoshi koizumi <moriyoshi@php.net> on 4 dec 2002.
! 27: *
! 28: */
! 29:
! 30: #ifdef HAVE_CONFIG_H
! 31: #include "config.h"
! 32: #endif
! 33:
! 34: #include "mbfilter.h"
! 35: #include "mbfilter_sjis_open.h"
! 36:
! 37: #include "unicode_table_cp932_ext.h"
! 38: #include "unicode_table_jis.h"
! 39:
! 40: static int mbfl_filt_ident_sjis_open(int c, mbfl_identify_filter *filter);
! 41:
! 42: static const unsigned char mblen_table_sjis[] = { /* 0x80-0x9f,0xE0-0xFF */
! 43: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
! 44: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
! 45: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
! 46: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
! 47: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
! 48: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
! 49: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
! 50: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
! 51: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
! 52: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
! 53: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
! 54: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
! 55: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
! 56: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
! 57: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
! 58: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
! 59: };
! 60:
! 61: static const char *mbfl_encoding_sjis_open_aliases[] = {"SJIS-open", "SJIS-ms", NULL};
! 62:
! 63: const mbfl_encoding mbfl_encoding_sjis_open = {
! 64: mbfl_no_encoding_sjis_open,
! 65: "SJIS-win",
! 66: "Shift_JIS",
! 67: (const char *(*)[])&mbfl_encoding_sjis_open_aliases,
! 68: mblen_table_sjis,
! 69: MBFL_ENCTYPE_MBCS
! 70: };
! 71:
! 72: const struct mbfl_identify_vtbl vtbl_identify_sjis_open = {
! 73: mbfl_no_encoding_sjis_open,
! 74: mbfl_filt_ident_common_ctor,
! 75: mbfl_filt_ident_common_dtor,
! 76: mbfl_filt_ident_sjis_open
! 77: };
! 78:
! 79: const struct mbfl_convert_vtbl vtbl_sjis_open_wchar = {
! 80: mbfl_no_encoding_sjis_open,
! 81: mbfl_no_encoding_wchar,
! 82: mbfl_filt_conv_common_ctor,
! 83: mbfl_filt_conv_common_dtor,
! 84: mbfl_filt_conv_sjis_open_wchar,
! 85: mbfl_filt_conv_common_flush
! 86: };
! 87:
! 88: const struct mbfl_convert_vtbl vtbl_wchar_sjis_open = {
! 89: mbfl_no_encoding_wchar,
! 90: mbfl_no_encoding_sjis_open,
! 91: mbfl_filt_conv_common_ctor,
! 92: mbfl_filt_conv_common_dtor,
! 93: mbfl_filt_conv_wchar_sjis_open,
! 94: mbfl_filt_conv_common_flush
! 95: };
! 96:
! 97: #define CK(statement) do { if ((statement) < 0) return (-1); } while (0)
! 98:
! 99: #define SJIS_ENCODE(c1,c2,s1,s2) \
! 100: do { \
! 101: s1 = c1; \
! 102: s1--; \
! 103: s1 >>= 1; \
! 104: if ((c1) < 0x5f) { \
! 105: s1 += 0x71; \
! 106: } else { \
! 107: s1 += 0xb1; \
! 108: } \
! 109: s2 = c2; \
! 110: if ((c1) & 1) { \
! 111: if ((c2) < 0x60) { \
! 112: s2--; \
! 113: } \
! 114: s2 += 0x20; \
! 115: } else { \
! 116: s2 += 0x7e; \
! 117: } \
! 118: } while (0)
! 119:
! 120: #define SJIS_DECODE(c1,c2,s1,s2) \
! 121: do { \
! 122: s1 = c1; \
! 123: if (s1 < 0xa0) { \
! 124: s1 -= 0x81; \
! 125: } else { \
! 126: s1 -= 0xc1; \
! 127: } \
! 128: s1 <<= 1; \
! 129: s1 += 0x21; \
! 130: s2 = c2; \
! 131: if (s2 < 0x9f) { \
! 132: if (s2 < 0x7f) { \
! 133: s2++; \
! 134: } \
! 135: s2 -= 0x20; \
! 136: } else { \
! 137: s1++; \
! 138: s2 -= 0x7e; \
! 139: } \
! 140: } while (0)
! 141:
! 142:
! 143: /*
! 144: * SJIS-win => wchar
! 145: */
! 146: int
! 147: mbfl_filt_conv_sjis_open_wchar(int c, mbfl_convert_filter *filter)
! 148: {
! 149: int c1, s, s1, s2, w;
! 150:
! 151: switch (filter->status) {
! 152: case 0:
! 153: if (c >= 0 && c < 0x80) { /* latin */
! 154: CK((*filter->output_function)(c, filter->data));
! 155: } else if (c > 0xa0 && c < 0xe0) { /* kana */
! 156: CK((*filter->output_function)(0xfec0 + c, filter->data));
! 157: } else if (c > 0x80 && c < 0xfd && c != 0xa0) { /* kanji first char */
! 158: filter->status = 1;
! 159: filter->cache = c;
! 160: } else {
! 161: w = c & MBFL_WCSGROUP_MASK;
! 162: w |= MBFL_WCSGROUP_THROUGH;
! 163: CK((*filter->output_function)(w, filter->data));
! 164: }
! 165: break;
! 166:
! 167: case 1: /* kanji second char */
! 168: filter->status = 0;
! 169: c1 = filter->cache;
! 170: if (c >= 0x40 && c <= 0xfc && c != 0x7f) {
! 171: w = 0;
! 172: SJIS_DECODE(c1, c, s1, s2);
! 173: s = (s1 - 0x21)*94 + s2 - 0x21;
! 174: if (s <= 137) {
! 175: if (s == 31) {
! 176: w = 0xff3c; /* FULLWIDTH REVERSE SOLIDUS */
! 177: } else if (s == 32) {
! 178: w = 0xff5e; /* FULLWIDTH TILDE */
! 179: } else if (s == 33) {
! 180: w = 0x2225; /* PARALLEL TO */
! 181: } else if (s == 60) {
! 182: w = 0xff0d; /* FULLWIDTH HYPHEN-MINUS */
! 183: } else if (s == 80) {
! 184: w = 0xffe0; /* FULLWIDTH CENT SIGN */
! 185: } else if (s == 81) {
! 186: w = 0xffe1; /* FULLWIDTH POUND SIGN */
! 187: } else if (s == 137) {
! 188: w = 0xffe2; /* FULLWIDTH NOT SIGN */
! 189: }
! 190: }
! 191: if (w == 0) {
! 192: if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) { /* vendor ext1 (13ku) */
! 193: w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min];
! 194: } else if (s >= 0 && s < jisx0208_ucs_table_size) { /* X 0208 */
! 195: w = jisx0208_ucs_table[s];
! 196: } else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) { /* vendor ext2 (89ku - 92ku) */
! 197: w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min];
! 198: } else if (s >= cp932ext3_ucs_table_min && s < cp932ext3_ucs_table_max) { /* vendor ext3 (115ku - 119ku) */
! 199: w = cp932ext3_ucs_table[s - cp932ext3_ucs_table_min];
! 200: } else if (s >= (94*94) && s < (114*94)) { /* user (95ku - 114ku) */
! 201: w = s - (94*94) + 0xe000;
! 202: }
! 203: }
! 204: if (w <= 0) {
! 205: w = (s1 << 8) | s2;
! 206: w &= MBFL_WCSPLANE_MASK;
! 207: w |= MBFL_WCSPLANE_WINCP932;
! 208: }
! 209: CK((*filter->output_function)(w, filter->data));
! 210: } else if ((c >= 0 && c < 0x21) || c == 0x7f) { /* CTLs */
! 211: CK((*filter->output_function)(c, filter->data));
! 212: } else {
! 213: w = (c1 << 8) | c;
! 214: w &= MBFL_WCSGROUP_MASK;
! 215: w |= MBFL_WCSGROUP_THROUGH;
! 216: CK((*filter->output_function)(w, filter->data));
! 217: }
! 218: break;
! 219:
! 220: default:
! 221: filter->status = 0;
! 222: break;
! 223: }
! 224:
! 225: return c;
! 226: }
! 227:
! 228: /*
! 229: * wchar => SJIS-win
! 230: */
! 231: int
! 232: mbfl_filt_conv_wchar_sjis_open(int c, mbfl_convert_filter *filter)
! 233: {
! 234: int c1, c2, s1, s2;
! 235:
! 236: s1 = 0;
! 237: s2 = 0;
! 238: if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) {
! 239: s1 = ucs_a1_jis_table[c - ucs_a1_jis_table_min];
! 240: } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) {
! 241: s1 = ucs_a2_jis_table[c - ucs_a2_jis_table_min];
! 242: } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) {
! 243: s1 = ucs_i_jis_table[c - ucs_i_jis_table_min];
! 244: } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) {
! 245: s1 = ucs_r_jis_table[c - ucs_r_jis_table_min];
! 246: } else if (c >= 0xe000 && c < (0xe000 + 20*94)) { /* user (95ku - 114ku) */
! 247: s1 = c - 0xe000;
! 248: c1 = s1/94 + 0x7f;
! 249: c2 = s1%94 + 0x21;
! 250: s1 = (c1 << 8) | c2;
! 251: s2 = 1;
! 252: }
! 253: if (s1 <= 0) {
! 254: c1 = c & ~MBFL_WCSPLANE_MASK;
! 255: if (c1 == MBFL_WCSPLANE_WINCP932) {
! 256: s1 = c & MBFL_WCSPLANE_MASK;
! 257: s2 = 1;
! 258: } else if (c1 == MBFL_WCSPLANE_JIS0208) {
! 259: s1 = c & MBFL_WCSPLANE_MASK;
! 260: } else if (c1 == MBFL_WCSPLANE_JIS0212) {
! 261: s1 = c & MBFL_WCSPLANE_MASK;
! 262: s1 |= 0x8080;
! 263: } else if (c == 0xa5) { /* YEN SIGN */
! 264: s1 = 0x216f; /* FULLWIDTH YEN SIGN */
! 265: } else if (c == 0x203e) { /* OVER LINE */
! 266: s1 = 0x2131; /* FULLWIDTH MACRON */
! 267: } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */
! 268: s1 = 0x2140;
! 269: } else if (c == 0xff5e) { /* FULLWIDTH TILDE */
! 270: s1 = 0x2141;
! 271: } else if (c == 0x2225) { /* PARALLEL TO */
! 272: s1 = 0x2142;
! 273: } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */
! 274: s1 = 0x215d;
! 275: } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */
! 276: s1 = 0x2171;
! 277: } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */
! 278: s1 = 0x2172;
! 279: } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */
! 280: s1 = 0x224c;
! 281: }
! 282: }
! 283: if ((s1 <= 0) || (s1 >= 0x8080 && s2 == 0)) { /* not found or X 0212 */
! 284: s1 = -1;
! 285: c1 = 0;
! 286: c2 = cp932ext1_ucs_table_max - cp932ext1_ucs_table_min;
! 287: while (c1 < c2) { /* CP932 vendor ext1 (13ku) */
! 288: if (c == cp932ext1_ucs_table[c1]) {
! 289: s1 = ((c1/94 + 0x2d) << 8) + (c1%94 + 0x21);
! 290: break;
! 291: }
! 292: c1++;
! 293: }
! 294: if (s1 <= 0) {
! 295: c1 = 0;
! 296: c2 = cp932ext3_ucs_table_max - cp932ext3_ucs_table_min;
! 297: while (c1 < c2) { /* CP932 vendor ext3 (115ku - 119ku) */
! 298: if (c == cp932ext3_ucs_table[c1]) {
! 299: s1 = ((c1/94 + 0x93) << 8) + (c1%94 + 0x21);
! 300: break;
! 301: }
! 302: c1++;
! 303: }
! 304: }
! 305: if (c == 0) {
! 306: s1 = 0;
! 307: } else if (s1 <= 0) {
! 308: s1 = -1;
! 309: }
! 310: }
! 311: if (s1 >= 0) {
! 312: if (s1 < 0x100) { /* latin or kana */
! 313: CK((*filter->output_function)(s1, filter->data));
! 314: } else { /* kanji */
! 315: c1 = (s1 >> 8) & 0xff;
! 316: c2 = s1 & 0xff;
! 317: SJIS_ENCODE(c1, c2, s1, s2);
! 318: CK((*filter->output_function)(s1, filter->data));
! 319: CK((*filter->output_function)(s2, filter->data));
! 320: }
! 321: } else {
! 322: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
! 323: CK(mbfl_filt_conv_illegal_output(c, filter));
! 324: }
! 325: }
! 326:
! 327: return c;
! 328: }
! 329:
! 330: static int mbfl_filt_ident_sjis_open(int c, mbfl_identify_filter *filter)
! 331: {
! 332: if (filter->status) { /* kanji second char */
! 333: if (c < 0x40 || c > 0xfc || c == 0x7f) { /* bad */
! 334: filter->flag = 1;
! 335: }
! 336: filter->status = 0;
! 337: } else if (c >= 0 && c < 0x80) { /* latin ok */
! 338: ;
! 339: } else if (c > 0xa0 && c < 0xe0) { /* kana ok */
! 340: ;
! 341: } else if (c > 0x80 && c < 0xfd && c != 0xa0) { /* kanji first char */
! 342: filter->status = 1;
! 343: } else { /* bad */
! 344: filter->flag = 1;
! 345: }
! 346:
! 347: return c;
! 348: }
! 349:
! 350:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>