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 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_ucs2.h"
36 :
37 : static const char *mbfl_encoding_ucs2_aliases[] = {"ISO-10646-UCS-2", "UCS2" , "UNICODE", NULL};
38 :
39 : const mbfl_encoding mbfl_encoding_ucs2 = {
40 : mbfl_no_encoding_ucs2,
41 : "UCS-2",
42 : "UCS-2",
43 : (const char *(*)[])&mbfl_encoding_ucs2_aliases,
44 : NULL,
45 : MBFL_ENCTYPE_WCS2BE
46 : };
47 :
48 : const mbfl_encoding mbfl_encoding_ucs2be = {
49 : mbfl_no_encoding_ucs2be,
50 : "UCS-2BE",
51 : "UCS-2BE",
52 : NULL,
53 : NULL,
54 : MBFL_ENCTYPE_WCS2BE
55 : };
56 :
57 : const mbfl_encoding mbfl_encoding_ucs2le = {
58 : mbfl_no_encoding_ucs2le,
59 : "UCS-2LE",
60 : "UCS-2LE",
61 : NULL,
62 : NULL,
63 : MBFL_ENCTYPE_WCS2LE
64 : };
65 :
66 : const struct mbfl_convert_vtbl vtbl_ucs2_wchar = {
67 : mbfl_no_encoding_ucs2,
68 : mbfl_no_encoding_wchar,
69 : mbfl_filt_conv_common_ctor,
70 : mbfl_filt_conv_common_dtor,
71 : mbfl_filt_conv_ucs2_wchar,
72 : mbfl_filt_conv_common_flush
73 : };
74 :
75 : const struct mbfl_convert_vtbl vtbl_wchar_ucs2 = {
76 : mbfl_no_encoding_wchar,
77 : mbfl_no_encoding_ucs2,
78 : mbfl_filt_conv_common_ctor,
79 : mbfl_filt_conv_common_dtor,
80 : mbfl_filt_conv_wchar_ucs2be,
81 : mbfl_filt_conv_common_flush
82 : };
83 :
84 : const struct mbfl_convert_vtbl vtbl_ucs2be_wchar = {
85 : mbfl_no_encoding_ucs2be,
86 : mbfl_no_encoding_wchar,
87 : mbfl_filt_conv_common_ctor,
88 : mbfl_filt_conv_common_dtor,
89 : mbfl_filt_conv_ucs2be_wchar,
90 : mbfl_filt_conv_common_flush
91 : };
92 :
93 : const struct mbfl_convert_vtbl vtbl_wchar_ucs2be = {
94 : mbfl_no_encoding_wchar,
95 : mbfl_no_encoding_ucs2be,
96 : mbfl_filt_conv_common_ctor,
97 : mbfl_filt_conv_common_dtor,
98 : mbfl_filt_conv_wchar_ucs2be,
99 : mbfl_filt_conv_common_flush
100 : };
101 :
102 : const struct mbfl_convert_vtbl vtbl_ucs2le_wchar = {
103 : mbfl_no_encoding_ucs2le,
104 : mbfl_no_encoding_wchar,
105 : mbfl_filt_conv_common_ctor,
106 : mbfl_filt_conv_common_dtor,
107 : mbfl_filt_conv_ucs2le_wchar,
108 : mbfl_filt_conv_common_flush
109 : };
110 :
111 : const struct mbfl_convert_vtbl vtbl_wchar_ucs2le = {
112 : mbfl_no_encoding_wchar,
113 : mbfl_no_encoding_ucs2le,
114 : mbfl_filt_conv_common_ctor,
115 : mbfl_filt_conv_common_dtor,
116 : mbfl_filt_conv_wchar_ucs2le,
117 : mbfl_filt_conv_common_flush
118 : };
119 :
120 : #define CK(statement) do { if ((statement) < 0) return (-1); } while (0)
121 :
122 : /*
123 : * UCS-2 => wchar
124 : */
125 : int mbfl_filt_conv_ucs2_wchar(int c, mbfl_convert_filter *filter)
126 0 : {
127 : int n, endian;
128 :
129 0 : endian = filter->status & 0xff00;
130 0 : switch (filter->status & 0xff) {
131 : case 0:
132 0 : if (endian) {
133 0 : n = c & 0xff;
134 : } else {
135 0 : n = (c & 0xff) << 8;
136 : }
137 0 : filter->cache = n;
138 0 : filter->status++;
139 0 : break;
140 : default:
141 0 : if (endian) {
142 0 : n = (c & 0xff) << 8;
143 : } else {
144 0 : n = c & 0xff;
145 : }
146 0 : n |= filter->cache;
147 0 : if (n == 0xfffe) {
148 0 : if (endian) {
149 0 : filter->status = 0; /* big-endian */
150 : } else {
151 0 : filter->status = 0x100; /* little-endian */
152 : }
153 0 : CK((*filter->output_function)(0xfeff, filter->data));
154 : } else {
155 0 : filter->status &= ~0xff;
156 0 : CK((*filter->output_function)(n, filter->data));
157 : }
158 : break;
159 : }
160 :
161 0 : return c;
162 : }
163 :
164 : /*
165 : * UCS-2BE => wchar
166 : */
167 : int mbfl_filt_conv_ucs2be_wchar(int c, mbfl_convert_filter *filter)
168 16 : {
169 : int n;
170 :
171 16 : if (filter->status == 0) {
172 8 : filter->status = 1;
173 8 : n = (c & 0xff) << 8;
174 8 : filter->cache = n;
175 : } else {
176 8 : filter->status = 0;
177 8 : n = (c & 0xff) | filter->cache;
178 8 : CK((*filter->output_function)(n, filter->data));
179 : }
180 16 : return c;
181 : }
182 :
183 : /*
184 : * wchar => UCS-2BE
185 : */
186 : int mbfl_filt_conv_wchar_ucs2be(int c, mbfl_convert_filter *filter)
187 17 : {
188 34 : if (c >= 0 && c < MBFL_WCSPLANE_UCS2MAX) {
189 17 : CK((*filter->output_function)((c >> 8) & 0xff, filter->data));
190 17 : CK((*filter->output_function)(c & 0xff, filter->data));
191 : } else {
192 0 : if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
193 0 : CK(mbfl_filt_conv_illegal_output(c, filter));
194 : }
195 : }
196 :
197 17 : return c;
198 : }
199 :
200 : /*
201 : * UCS-2LE => wchar
202 : */
203 : int mbfl_filt_conv_ucs2le_wchar(int c, mbfl_convert_filter *filter)
204 144 : {
205 : int n;
206 :
207 144 : if (filter->status == 0) {
208 72 : filter->status = 1;
209 72 : n = c & 0xff;
210 72 : filter->cache = n;
211 : } else {
212 72 : filter->status = 0;
213 72 : n = ((c & 0xff) << 8) | filter->cache;
214 72 : CK((*filter->output_function)(n, filter->data));
215 : }
216 144 : return c;
217 : }
218 :
219 :
220 : /*
221 : * wchar => UCS-2LE
222 : */
223 : int mbfl_filt_conv_wchar_ucs2le(int c, mbfl_convert_filter *filter)
224 0 : {
225 0 : if (c >= 0 && c < MBFL_WCSPLANE_UCS2MAX) {
226 0 : CK((*filter->output_function)(c & 0xff, filter->data));
227 0 : CK((*filter->output_function)((c >> 8) & 0xff, filter->data));
228 : } else {
229 0 : if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
230 0 : CK(mbfl_filt_conv_illegal_output(c, filter));
231 : }
232 : }
233 :
234 0 : return c;
235 : }
236 :
237 :
238 :
|