Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
iconv.cpp
Go to the documentation of this file.
1
29#ifdef _WIN32
30
31#include <errno.h>
32#include <windows.h>
33
34
35typedef int iconv_t;
36
37iconv_t iconv_open (const char*, const char*);
38size_t iconv (iconv_t, char**, size_t*, char**, size_t*);
39int iconv_close (iconv_t);
40
41
42iconv_t iconv_open (const char *from_code, const char *to_code)
43{
44 static const struct {
45 int code;
46 const char *name;
47 } pages[] = {
48 { 37, "EBCDIC-US" },
49 { 437, "OEM - United States" },
50 { 500, "IBM EBCDIC - International" },
51 { 708, "Arabic - ASMO 708" },
52 { 709, "Arabic - ASMO 449+, BCON V4" },
53 { 710, "Arabic - Transparent Arabic" },
54 { 720, "Arabic - Transparent ASMO" },
55 { 737, "OEM - Greek (formerly 437G)" },
56 { 775, "OEM - Baltic" },
57 { 850, "OEM - Multilingual Latin I" },
58 { 852, "OEM - Latin II" },
59 { 855, "OEM - Cyrillic (primarily Russian)" },
60 { 857, "OEM - Turkish" },
61 { 858, "OEM - Multlingual Latin I + Euro symbol" },
62 { 860, "OEM - Portuguese" },
63 { 861, "OEM - Icelandic" },
64 { 862, "OEM - Hebrew" },
65 { 863, "OEM - Canadian-French" },
66 { 864, "OEM - Arabic" },
67 { 865, "OEM - Nordic" },
68 { 866, "OEM - Russian" },
69 { 869, "OEM - Modern Greek" },
70 { 870, "IBM EBCDIC - Multilingual/ROECE (Latin-2)" },
71 { 874, "ANSI/OEM - Thai (same as 28605, ISO 8859-15)" },
72 { 875, "IBM EBCDIC - Modern Greek" },
73 { 932, "Shift_JIS" },
74 { 936, "ANSI/OEM - Simplified Chinese (PRC, Singapore)" },
75 { 949, "ANSI/OEM - Korean (Unified Hangeul Code)" },
76 { 950, "ANSI/OEM - Traditional Chinese" },
77 { 1026, "IBM EBCDIC - Turkish (Latin-5)" },
78 { 1047, "IBM EBCDIC - Latin 1/Open System" },
79 { 1140, "EBCDIC-CA-FR@EURO" },
80 { 1141, "EBCDIC-AT-DE@EURO" },
81 { 1142, "EBCDIC-DK-NO@EURO" },
82 { 1143, "EBCDIC-FI-SE@EURO" },
83 { 1144, "EBCDIC-IT@EURO" },
84 { 1145, "EBCDIC-ES-A@EURO" },
85 { 1146, "EBCDIC-UK@EURO" },
86 { 1147, "EBCDIC-FR@EURO" },
87 { 1148, "IBM EBCDIC - International (500 + Euro symbol)" },
88 { 1149, "EBCDIC-IS-FRISS@EURO" },
89 { 1200, "UCS-2-LE" },
90 { 1201, "UCS-2-BE" },
91 { 1251, "ANSI - Cyrillic" },
92 { 1252, "ANSI - Latin I" },
93 { 1253, "ANSI - Greek" },
94 { 1254, "ANSI - Turkish" },
95 { 1255, "ANSI - Hebrew" },
96 { 1256, "ANSI - Arabic" },
97 { 1257, "ANSI - Baltic" },
98 { 1258, "ANSI/OEM - Vietnamese" },
99 { 1361, "Korean (Johab)" },
100 { 10000, "MAC - Roman" },
101 { 10001, "MAC-JP" },
102 { 10002, "MAC - Traditional Chinese (Big5)" },
103 { 10003, "MAC-KR" },
104 { 10004, "MAC-AR" },
105 { 10005, "MAC - Hebrew" },
106 { 10006, "MAC - Greek I" },
107 { 10007, "MAC-CYRILLIC" },
108 { 10008, "MAC - Simplified Chinese (GB 2312)" },
109 { 10010, "MAC - Romania" },
110 { 10017, "MAC - Ukraine" },
111 { 10021, "MAC - Thai" },
112 { 10029, "MAC - Latin II" },
113 { 10079, "MAC - Icelandic" },
114 { 10081, "MAC - Turkish" },
115 { 10082, "MAC - Croatia" },
116 { 12000, "UCS-4-LE" },
117 { 12001, "UCS-4-BE" },
118 { 20000, "CNS - Taiwan" },
119 { 20001, "TCA - Taiwan" },
120 { 20002, "Eten - Taiwan" },
121 { 20003, "IBM5550 - Taiwan" },
122 { 20004, "TeleText - Taiwan" },
123 { 20005, "Wang - Taiwan" },
124 { 20105, "IA5 IRV International Alphabet No. 5 (7-bit)" },
125 { 20106, "IA5 German (7-bit)" },
126 { 20107, "IA5 Swedish (7-bit)" },
127 { 20108, "IA5 Norwegian (7-bit)" },
128 { 20127, "ANSI_X3.4-1968" },
129 { 20261, "T.61" },
130 { 20269, "ISO 6937 Non-Spacing Accent" },
131 { 20273, "EBCDIC-DE" },
132 { 20277, "EBCDIC-DK-NO" },
133 { 20278, "EBCDIC-FI-SE" },
134 { 20280, "EBCDIC-IT" },
135 { 20284, "EBCDIC-ES-A" },
136 { 20285, "EBCDIC-UK" },
137 { 20290, "EBCDIC-JP" },
138 { 20297, "EBCDIC-FR" },
139 { 20420, "EBCDIC-AR" },
140 { 20423, "IBM EBCDIC - Greek" },
141 { 20424, "IBM EBCDIC - Hebrew" },
142 { 20833, "EBCDIC-KR" },
143 { 20838, "IBM EBCDIC - Thai" },
144 { 20866, "Russian - KOI8-R" },
145 { 20871, "IBM EBCDIC - Icelandic" },
146 { 20880, "IBM EBCDIC - Cyrillic (Russian)" },
147 { 20905, "IBM EBCDIC - Turkish" },
148 { 20924, "IBM EBCDIC - Latin-1/Open System (1047 + Euro symbol)" },
149 { 20932, "JIS X 0208-1990 & 0121-1990" },
150 { 20936, "GB2312" },
151 { 21025, "IBM EBCDIC - Cyrillic (Serbian, Bulgarian)" },
152 { 21027, "Extended Alpha Lowercase" },
153 { 21866, "Ukrainian (KOI8-U)" },
154 { 28591, "ISO-8859-1" },
155 { 28592, "ISO-8859-2" },
156 { 28593, "ISO-8859-3" },
157 { 28594, "ISO-8859-4" },
158 { 28595, "ISO-8859-5" },
159 { 28596, "ISO-8859-6" },
160 { 28597, "ISO-8859-7" },
161 { 28598, "ISO-8859-8" },
162 { 28599, "ISO-8859-95" },
163 { 28605, "ISO-8859-15" },
164 { 29001, "Europa 3" },
165 { 38598, "ISO-8859-8 Hebrew" },
166 { 50220, "ISO-2022 Japanese with no halfwidth Katakana" },
167 { 50221, "ISO-2022-JP" },
168 { 50222, "ISO-2022 Japanese JIS X 0201-1989" },
169 { 50225, "ISO-2022-KR" },
170 { 50227, "ISO-2022 Simplified Chinese" },
171 { 50229, "ISO-2022 Traditional Chinese" },
172 { 50930, "Japanese (Katakana) Extended" },
173 { 50931, "US/Canada and Japanese" },
174 { 50933, "Korean Extended and Korean" },
175 { 50935, "Simplified Chinese Extended and Simplified Chinese" },
176 { 50936, "Simplified Chinese" },
177 { 50937, "US/Canada and Traditional Chinese" },
178 { 50939, "Japanese (Latin) Extended and Japanese" },
179 { 51932, "EUC-JP" },
180 { 51936, "EUC - Simplified Chinese" },
181 { 51949, "EUC-KR" },
182 { 51950, "EUC - Traditional Chinese" },
183 { 52936, "HZ-GB2312 Simplified Chinese" },
184 { 54936, "Windows XP: GB18030 Simplified Chinese (4 Byte)" },
185 { 57002, "ISCII Devanagari 57003 ISCII Bengali" },
186 { 57004, "ISCII Tamil" },
187 { 57005, "ISCII Telugu" },
188 { 57006, "ISCII Assamese" },
189 { 57007, "ISCII Oriya" },
190 { 57008, "ISCII Kannada" },
191 { 57009, "ISCII Malayalam" },
192 { 57010, "ISCII Gujarati" },
193 { 57011, "ISCII Punjabi" },
194 { 65000, "UTF-7" },
195 { 65001, "UTF-8" }
196 };
197
198 iconv_t cd = 0;
199
200 for (size_t i = 0; ; ++i) {
201
202 if (i == sizeof pages / sizeof *pages) {
203 cd = -1;
204 break;
205 }
206
207 if (!strcmp (from_code, pages [i].name)) {
208 cd |= pages [i].code << 16;
209
210 if (cd & 0x0000ffff)
211 break;
212 }
213
214 if (!strcmp (to_code, pages [i].name)) {
215 cd |= pages [i].code & 0xffff;
216
217 if (cd & 0xffff0000)
218 break;
219 }
220 }
221
222 // validate code pages
223 if ( -1 == cd
224 || !MultiByteToWideChar (cd & 0x0000ffff, 0, "", 1, 0, 0)
225 || !MultiByteToWideChar ((cd >> 16) & 0x0000ffff, 0, "", 1, 0, 0)) {
226 // [EINVAL]
227 // The conversion specified by fromcode and tocode
228 // is not supported by the implementation.
229 errno = EINVAL;
230 cd = -1;
231 }
232
233 return cd;
234}
235
236
237size_t iconv (iconv_t cd,
238 char **inbuf, size_t *inbytesleft,
239 char **outbuf, size_t *outbytesleft)
240{
241 const int fromcode = (cd >> 16) & 0x0000ffff;
242 const int tocode = cd & 0x0000ffff;
243
244 if (0x0000ffff == fromcode || 0x0000ffff == tocode) {
245 errno = EBADF;
246 return size_t (-1);
247 }
248
249 wchar_t wbuf [256];
250
251 // allocate a sufficient amount of storage to conver the input
252 // buffer to wide character assuming, pessimistically, that
253 // each byte converts to one wide character
254 wchar_t *pwc = *inbytesleft < sizeof wbuf / sizeof *wbuf ?
255 wbuf : new wchar_t [*inbytesleft];
256
257 // convert the contents of the narrow input buffer to wide characters
258 // `nwout' -- number of wide chars successfully produced by the call
259 const int nwout =
260 MultiByteToWideChar (fromcode, MB_ERR_INVALID_CHARS,
261 *inbuf, int (*inbytesleft),
262 pwc, int (*inbytesleft));
263
264 if (!nwout) {
265 if (pwc != wbuf)
266 delete[] pwc;
267
268 const int error = GetLastError ();
269 errno = ERROR_INSUFFICIENT_BUFFER == error || !error ? E2BIG : EILSEQ;
270 return size_t (-1);
271 }
272
273 // convert the contents of wide character buffer into the narrow
274 // character buffer
275 // `nnout' -- number of narrow chars successfully produced by the
276 // call
277 const int nnout =
278 WideCharToMultiByte (tocode, 0,
279 pwc, nwout,
280 *outbuf, int (*outbytesleft),
281 0, 0);
282 if (!nnout || !*outbytesleft) {
283 if (pwc != wbuf)
284 delete[] pwc;
285
286 const int error = GetLastError ();
287 errno = ERROR_INSUFFICIENT_BUFFER == error || !error ? E2BIG : EILSEQ;
288 return size_t (-1);
289 }
290
291 // compute the number of wide characters consumed by second
292 // conversion
293 // `nwin' -- number of wide chars consumed by the call above
294 const int nwin =
295 MultiByteToWideChar (tocode, 0, *outbuf, nnout, 0, 0);
296
297 if (!nwin) {
298 if (pwc != wbuf)
299 delete[] pwc;
300
301 const int error = GetLastError ();
302 errno = ERROR_INSUFFICIENT_BUFFER == error || !error ? E2BIG : EILSEQ;
303 return size_t (-1);
304 }
305
306 // finally, compute the number of narrow characters in the source
307 // encoding corresponding to the number of narrow characters in
308 // the destrination encoding
309 // `nnin' -- number of narrow chars consumed by the first call
310 const int nnin =
311 WideCharToMultiByte (fromcode, 0, pwc, nwin, 0, 0, 0, 0);
312 if (pwc != wbuf)
313 delete[] pwc;
314
315 if (!nnin) {
316 const int error = GetLastError ();
317 errno = ERROR_INSUFFICIENT_BUFFER == error || !error ? E2BIG : EILSEQ;
318 return size_t (-1);
319 }
320
321 // advance buffers to the first character to convert
322 *inbuf += nnin;
323 *outbuf += nnout;
324
325 // decrement the size of each buffer
326 *inbytesleft -= nnin;
327 *outbytesleft -= nnout;
328
329 if (*inbytesleft) {
330 errno = E2BIG;
331 return size_t (-1);
332 }
333
334 return 0;
335}
336
337
338int iconv_close (iconv_t cd)
339{
340 const int fromcode = (cd >> 16) & 0x0000ffff;
341 const int tocode = cd & 0x0000ffff;
342
343 if (0x0000ffff == fromcode || 0x0000ffff == tocode) {
344 errno = EBADF;
345 return -1;
346 }
347
348 return 0;
349}
350
351#endif // _WIN32
#define i
Definition 17.names.cpp:126
#define EILSEQ
const char * name
Definition codecvt1.cpp:72
@ error
throw a parse_error exception in case of a tag
#define E2BIG
Definition process.cpp:50
#define EINVAL
Definition cmdopt.cpp:40