Annotation of embedaddon/php/ext/mbstring/libmbfl/filters/mbfilter_sjis.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.h"
! 36:
! 37: #include "unicode_table_cp932_ext.h"
! 38: #include "unicode_table_jis.h"
! 39:
! 40: static int mbfl_filt_ident_sjis(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_aliases[] = {"x-sjis", "SHIFT-JIS", NULL};
! 62:
! 63: const mbfl_encoding mbfl_encoding_sjis = {
! 64: mbfl_no_encoding_sjis,
! 65: "SJIS",
! 66: "Shift_JIS",
! 67: (const char *(*)[])&mbfl_encoding_sjis_aliases,
! 68: mblen_table_sjis,
! 69: MBFL_ENCTYPE_MBCS
! 70: };
! 71:
! 72: const struct mbfl_identify_vtbl vtbl_identify_sjis = {
! 73: mbfl_no_encoding_sjis,
! 74: mbfl_filt_ident_common_ctor,
! 75: mbfl_filt_ident_common_dtor,
! 76: mbfl_filt_ident_sjis
! 77: };
! 78:
! 79: const struct mbfl_convert_vtbl vtbl_sjis_wchar = {
! 80: mbfl_no_encoding_sjis,
! 81: mbfl_no_encoding_wchar,
! 82: mbfl_filt_conv_common_ctor,
! 83: mbfl_filt_conv_common_dtor,
! 84: mbfl_filt_conv_sjis_wchar,
! 85: mbfl_filt_conv_common_flush
! 86: };
! 87:
! 88: const struct mbfl_convert_vtbl vtbl_wchar_sjis = {
! 89: mbfl_no_encoding_wchar,
! 90: mbfl_no_encoding_sjis,
! 91: mbfl_filt_conv_common_ctor,
! 92: mbfl_filt_conv_common_dtor,
! 93: mbfl_filt_conv_wchar_sjis,
! 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 => wchar
! 145: */
! 146: int
! 147: mbfl_filt_conv_sjis_wchar(int c, mbfl_convert_filter *filter)
! 148: {
! 149: int c1, 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: SJIS_DECODE(c1, c, s1, s2);
! 172: w = (s1 - 0x21)*94 + s2 - 0x21;
! 173: if (w >= 0 && w < jisx0208_ucs_table_size) {
! 174: w = jisx0208_ucs_table[w];
! 175: } else {
! 176: w = 0;
! 177: }
! 178: if (w <= 0) {
! 179: if (s1 < 0x7f && s2 < 0x7f) {
! 180: w = (s1 << 8) | s2;
! 181: w &= MBFL_WCSPLANE_MASK;
! 182: w |= MBFL_WCSPLANE_JIS0208;
! 183: } else {
! 184: w = (c1 << 8) | c;
! 185: w &= MBFL_WCSGROUP_MASK;
! 186: w |= MBFL_WCSGROUP_THROUGH;
! 187: }
! 188: }
! 189: CK((*filter->output_function)(w, filter->data));
! 190: } else if ((c >= 0 && c < 0x21) || c == 0x7f) { /* CTLs */
! 191: CK((*filter->output_function)(c, filter->data));
! 192: } else {
! 193: w = (c1 << 8) | c;
! 194: w &= MBFL_WCSGROUP_MASK;
! 195: w |= MBFL_WCSGROUP_THROUGH;
! 196: CK((*filter->output_function)(w, filter->data));
! 197: }
! 198: break;
! 199:
! 200: default:
! 201: filter->status = 0;
! 202: break;
! 203: }
! 204:
! 205: return c;
! 206: }
! 207:
! 208: /*
! 209: * wchar => SJIS
! 210: */
! 211: int
! 212: mbfl_filt_conv_wchar_sjis(int c, mbfl_convert_filter *filter)
! 213: {
! 214: int c1, c2, s1, s2;
! 215:
! 216: s1 = 0;
! 217: if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) {
! 218: s1 = ucs_a1_jis_table[c - ucs_a1_jis_table_min];
! 219: } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) {
! 220: s1 = ucs_a2_jis_table[c - ucs_a2_jis_table_min];
! 221: } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) {
! 222: s1 = ucs_i_jis_table[c - ucs_i_jis_table_min];
! 223: } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) {
! 224: s1 = ucs_r_jis_table[c - ucs_r_jis_table_min];
! 225: }
! 226: if (s1 <= 0) {
! 227: c1 = c & ~MBFL_WCSPLANE_MASK;
! 228: if (c1 == MBFL_WCSPLANE_JIS0208) {
! 229: s1 = c & MBFL_WCSPLANE_MASK;
! 230: } else if (c == 0xa5) { /* YEN SIGN */
! 231: s1 = 0x216f; /* FULLWIDTH YEN SIGN */
! 232: } else if (c == 0x203e) { /* OVER LINE */
! 233: s1 = 0x2131; /* FULLWIDTH MACRON */
! 234: } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */
! 235: s1 = 0x2140;
! 236: } else if (c == 0xff5e) { /* FULLWIDTH TILDE */
! 237: s1 = 0x2141;
! 238: } else if (c == 0x2225) { /* PARALLEL TO */
! 239: s1 = 0x2142;
! 240: } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */
! 241: s1 = 0x215d;
! 242: } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */
! 243: s1 = 0x2171;
! 244: } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */
! 245: s1 = 0x2172;
! 246: } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */
! 247: s1 = 0x224c;
! 248: }
! 249: if (c == 0) {
! 250: s1 = 0;
! 251: } else if (s1 <= 0) {
! 252: s1 = -1;
! 253: }
! 254: } else if (s1 >= 0x8080) {
! 255: s1 = -1;
! 256: }
! 257: if (s1 >= 0) {
! 258: if (s1 < 0x100) { /* latin or kana */
! 259: CK((*filter->output_function)(s1, filter->data));
! 260: } else { /* kanji */
! 261: c1 = (s1 >> 8) & 0xff;
! 262: c2 = s1 & 0xff;
! 263: SJIS_ENCODE(c1, c2, s1, s2);
! 264: CK((*filter->output_function)(s1, filter->data));
! 265: CK((*filter->output_function)(s2, filter->data));
! 266: }
! 267: } else {
! 268: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
! 269: CK(mbfl_filt_conv_illegal_output(c, filter));
! 270: }
! 271: }
! 272:
! 273: return c;
! 274: }
! 275:
! 276: static int mbfl_filt_ident_sjis(int c, mbfl_identify_filter *filter)
! 277: {
! 278: if (filter->status) { /* kanji second char */
! 279: if (c < 0x40 || c > 0xfc || c == 0x7f) { /* bad */
! 280: filter->flag = 1;
! 281: }
! 282: filter->status = 0;
! 283: } else if (c >= 0 && c < 0x80) { /* latin ok */
! 284: ;
! 285: } else if (c > 0xa0 && c < 0xe0) { /* kana ok */
! 286: ;
! 287: } else if (c > 0x80 && c < 0xf0 && c != 0xa0) { /* kanji first char */
! 288: filter->status = 1;
! 289: } else { /* bad */
! 290: filter->flag = 1;
! 291: }
! 292:
! 293: return c;
! 294: }
! 295:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>