Annotation of embedaddon/php/ext/mbstring/libmbfl/filters/mbfilter_utf32.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.
27: *
28: */
29:
30: #ifdef HAVE_CONFIG_H
31: #include "config.h"
32: #endif
33:
34: #include "mbfilter.h"
35: #include "mbfilter_utf32.h"
36:
37: static const char *mbfl_encoding_utf32_aliases[] = {"utf32", NULL};
38:
39: const mbfl_encoding mbfl_encoding_utf32 = {
40: mbfl_no_encoding_utf32,
41: "UTF-32",
42: "UTF-32",
43: (const char *(*)[])&mbfl_encoding_utf32_aliases,
44: NULL,
45: MBFL_ENCTYPE_WCS4BE
46: };
47:
48: const mbfl_encoding mbfl_encoding_utf32be = {
49: mbfl_no_encoding_utf32be,
50: "UTF-32BE",
51: "UTF-32BE",
52: NULL,
53: NULL,
54: MBFL_ENCTYPE_WCS4BE
55: };
56:
57: const mbfl_encoding mbfl_encoding_utf32le = {
58: mbfl_no_encoding_utf32le,
59: "UTF-32LE",
60: "UTF-32LE",
61: NULL,
62: NULL,
63: MBFL_ENCTYPE_WCS4LE
64: };
65:
66: const struct mbfl_convert_vtbl vtbl_utf32_wchar = {
67: mbfl_no_encoding_utf32,
68: mbfl_no_encoding_wchar,
69: mbfl_filt_conv_common_ctor,
70: mbfl_filt_conv_common_dtor,
71: mbfl_filt_conv_utf32_wchar,
72: mbfl_filt_conv_common_flush
73: };
74:
75: const struct mbfl_convert_vtbl vtbl_wchar_utf32 = {
76: mbfl_no_encoding_wchar,
77: mbfl_no_encoding_utf32,
78: mbfl_filt_conv_common_ctor,
79: mbfl_filt_conv_common_dtor,
80: mbfl_filt_conv_wchar_utf32be,
81: mbfl_filt_conv_common_flush
82: };
83:
84: const struct mbfl_convert_vtbl vtbl_utf32be_wchar = {
85: mbfl_no_encoding_utf32be,
86: mbfl_no_encoding_wchar,
87: mbfl_filt_conv_common_ctor,
88: mbfl_filt_conv_common_dtor,
89: mbfl_filt_conv_utf32be_wchar,
90: mbfl_filt_conv_common_flush
91: };
92:
93: const struct mbfl_convert_vtbl vtbl_wchar_utf32be = {
94: mbfl_no_encoding_wchar,
95: mbfl_no_encoding_utf32be,
96: mbfl_filt_conv_common_ctor,
97: mbfl_filt_conv_common_dtor,
98: mbfl_filt_conv_wchar_utf32be,
99: mbfl_filt_conv_common_flush
100: };
101:
102: const struct mbfl_convert_vtbl vtbl_utf32le_wchar = {
103: mbfl_no_encoding_utf32le,
104: mbfl_no_encoding_wchar,
105: mbfl_filt_conv_common_ctor,
106: mbfl_filt_conv_common_dtor,
107: mbfl_filt_conv_utf32le_wchar,
108: mbfl_filt_conv_common_flush
109: };
110:
111: const struct mbfl_convert_vtbl vtbl_wchar_utf32le = {
112: mbfl_no_encoding_wchar,
113: mbfl_no_encoding_utf32le,
114: mbfl_filt_conv_common_ctor,
115: mbfl_filt_conv_common_dtor,
116: mbfl_filt_conv_wchar_utf32le,
117: mbfl_filt_conv_common_flush
118: };
119:
120: #define CK(statement) do { if ((statement) < 0) return (-1); } while (0)
121:
122: /*
123: * UTF-32 => wchar
124: */
125: int mbfl_filt_conv_utf32_wchar(int c, mbfl_convert_filter *filter)
126: {
127: int n, endian;
128:
129: endian = filter->status & 0xff00;
130: switch (filter->status & 0xff) {
131: case 0:
132: if (endian) {
133: n = c & 0xff;
134: } else {
135: n = (c & 0xff) << 24;
136: }
137: filter->cache = n;
138: filter->status++;
139: break;
140: case 1:
141: if (endian) {
142: n = (c & 0xff) << 8;
143: } else {
144: n = (c & 0xff) << 16;
145: }
146: filter->cache |= n;
147: filter->status++;
148: break;
149: case 2:
150: if (endian) {
151: n = (c & 0xff) << 16;
152: } else {
153: n = (c & 0xff) << 8;
154: }
155: filter->cache |= n;
156: filter->status++;
157: break;
158: default:
159: if (endian) {
160: n = (c & 0xff) << 24;
161: } else {
162: n = c & 0xff;
163: }
164: n |= filter->cache;
165: if ((n & 0xffff) == 0 && ((n >> 16) & 0xffff) == 0xfffe) {
166: if (endian) {
167: filter->status = 0; /* big-endian */
168: } else {
169: filter->status = 0x100; /* little-endian */
170: }
171: CK((*filter->output_function)(0xfeff, filter->data));
172: } else {
173: filter->status &= ~0xff;
174: if (n < MBFL_WCSPLANE_UTF32MAX && (n < 0xd800 || n > 0xdfff)) {
175: CK((*filter->output_function)(n, filter->data));
1.1.1.2 ! misho 176: } else {
! 177: n = (n & MBFL_WCSGROUP_MASK) | MBFL_WCSGROUP_THROUGH;
! 178: CK((*filter->output_function)(n, filter->data));
1.1 misho 179: }
180: }
181: break;
182: }
183:
184: return c;
185: }
186:
187: /*
188: * UTF-32BE => wchar
189: */
190: int mbfl_filt_conv_utf32be_wchar(int c, mbfl_convert_filter *filter)
191: {
192: int n;
193:
194: if (filter->status == 0) {
195: filter->status = 1;
196: n = (c & 0xff) << 24;
197: filter->cache = n;
198: } else if (filter->status == 1) {
199: filter->status = 2;
200: n = (c & 0xff) << 16;
201: filter->cache |= n;
202: } else if (filter->status == 2) {
203: filter->status = 3;
204: n = (c & 0xff) << 8;
205: filter->cache |= n;
206: } else {
207: filter->status = 0;
208: n = (c & 0xff) | filter->cache;
209: if (n < MBFL_WCSPLANE_UTF32MAX && (n < 0xd800 || n > 0xdfff)) {
210: CK((*filter->output_function)(n, filter->data));
1.1.1.2 ! misho 211: } else {
! 212: n = (n & MBFL_WCSGROUP_MASK) | MBFL_WCSGROUP_THROUGH;
! 213: CK((*filter->output_function)(n, filter->data));
1.1 misho 214: }
215: }
216: return c;
217: }
218:
219: /*
220: * wchar => UTF-32BE
221: */
222: int mbfl_filt_conv_wchar_utf32be(int c, mbfl_convert_filter *filter)
223: {
224: if (c >= 0 && c < MBFL_WCSPLANE_UTF32MAX) {
225: CK((*filter->output_function)((c >> 24) & 0xff, filter->data));
226: CK((*filter->output_function)((c >> 16) & 0xff, filter->data));
227: CK((*filter->output_function)((c >> 8) & 0xff, filter->data));
228: CK((*filter->output_function)(c & 0xff, filter->data));
229: } else {
230: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
231: CK(mbfl_filt_conv_illegal_output(c, filter));
232: }
233: }
234:
235: return c;
236: }
237:
238: /*
239: * UTF-32LE => wchar
240: */
241: int mbfl_filt_conv_utf32le_wchar(int c, mbfl_convert_filter *filter)
242: {
243: int n;
244:
245: if (filter->status == 0) {
246: filter->status = 1;
247: n = (c & 0xff);
248: filter->cache = n;
249: } else if (filter->status == 1) {
250: filter->status = 2;
251: n = (c & 0xff) << 8;
252: filter->cache |= n;
253: } else if (filter->status == 2) {
254: filter->status = 3;
255: n = (c & 0xff) << 16;
256: filter->cache |= n;
257: } else {
258: filter->status = 0;
259: n = ((c & 0xff) << 24) | filter->cache;
260: if (n < MBFL_WCSPLANE_UTF32MAX && (n < 0xd800 || n > 0xdfff)) {
261: CK((*filter->output_function)(n, filter->data));
1.1.1.2 ! misho 262: } else {
! 263: n = (n & MBFL_WCSGROUP_MASK) | MBFL_WCSGROUP_THROUGH;
! 264: CK((*filter->output_function)(n, filter->data));
! 265: }
1.1 misho 266: }
267: return c;
268: }
269:
270: /*
271: * wchar => UTF-32LE
272: */
273: int mbfl_filt_conv_wchar_utf32le(int c, mbfl_convert_filter *filter)
274: {
275: if (c >= 0 && c < MBFL_WCSPLANE_UTF32MAX) {
276: CK((*filter->output_function)(c & 0xff, filter->data));
277: CK((*filter->output_function)((c >> 8) & 0xff, filter->data));
278: CK((*filter->output_function)((c >> 16) & 0xff, filter->data));
279: CK((*filter->output_function)((c >> 24) & 0xff, filter->data));
280: } else {
281: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
282: CK(mbfl_filt_conv_illegal_output(c, filter));
283: }
284: }
285:
286: return c;
287: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>