comparison src/stdlib/SDL_iconv.c @ 1662:782fd950bd46 SDL-1.3

Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API. WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid. The code is now run through a consistent indent format: indent -i4 -nut -nsc -br -ce The headers are being converted to automatically generate doxygen documentation.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 28 May 2006 13:04:16 +0000
parents c99e7a9c9bc9
children 4da1ee79c9af
comparison
equal deleted inserted replaced
1661:281d3f4870e5 1662:782fd950bd46
28 28
29 #ifdef HAVE_ICONV 29 #ifdef HAVE_ICONV
30 30
31 #include <errno.h> 31 #include <errno.h>
32 32
33 size_t SDL_iconv(SDL_iconv_t cd, 33 size_t
34 char **inbuf, size_t *inbytesleft, 34 SDL_iconv (SDL_iconv_t cd,
35 char **outbuf, size_t *outbytesleft) 35 char **inbuf, size_t * inbytesleft,
36 char **outbuf, size_t * outbytesleft)
36 { 37 {
37 size_t retCode = iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft); 38 size_t retCode = iconv (cd, inbuf, inbytesleft, outbuf, outbytesleft);
38 if ( retCode == (size_t)-1 ) { 39 if (retCode == (size_t) - 1) {
39 switch(errno) { 40 switch (errno) {
40 case E2BIG: 41 case E2BIG:
41 return SDL_ICONV_E2BIG; 42 return SDL_ICONV_E2BIG;
42 case EILSEQ: 43 case EILSEQ:
43 return SDL_ICONV_EILSEQ; 44 return SDL_ICONV_EILSEQ;
44 case EINVAL: 45 case EINVAL:
45 return SDL_ICONV_EINVAL; 46 return SDL_ICONV_EINVAL;
46 default: 47 default:
47 return SDL_ICONV_ERROR; 48 return SDL_ICONV_ERROR;
48 } 49 }
49 } 50 }
50 return retCode; 51 return retCode;
51 } 52 }
52 53
53 #else 54 #else
54 55
55 /* Lots of useful information on Unicode at: 56 /* Lots of useful information on Unicode at:
59 #define UNICODE_BOM 0xFEFF 60 #define UNICODE_BOM 0xFEFF
60 61
61 #define UNKNOWN_ASCII '?' 62 #define UNKNOWN_ASCII '?'
62 #define UNKNOWN_UNICODE 0xFFFD 63 #define UNKNOWN_UNICODE 0xFFFD
63 64
64 enum { 65 enum
65 ENCODING_UNKNOWN, 66 {
66 ENCODING_ASCII, 67 ENCODING_UNKNOWN,
67 ENCODING_LATIN1, 68 ENCODING_ASCII,
68 ENCODING_UTF8, 69 ENCODING_LATIN1,
69 ENCODING_UTF16, /* Needs byte order marker */ 70 ENCODING_UTF8,
70 ENCODING_UTF16BE, 71 ENCODING_UTF16, /* Needs byte order marker */
71 ENCODING_UTF16LE, 72 ENCODING_UTF16BE,
72 ENCODING_UTF32, /* Needs byte order marker */ 73 ENCODING_UTF16LE,
73 ENCODING_UTF32BE, 74 ENCODING_UTF32, /* Needs byte order marker */
74 ENCODING_UTF32LE, 75 ENCODING_UTF32BE,
75 ENCODING_UCS2, /* Native byte order assumed */ 76 ENCODING_UTF32LE,
76 ENCODING_UCS4, /* Native byte order assumed */ 77 ENCODING_UCS2, /* Native byte order assumed */
78 ENCODING_UCS4, /* Native byte order assumed */
77 }; 79 };
78 #if SDL_BYTEORDER == SDL_BIG_ENDIAN 80 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
79 #define ENCODING_UTF16NATIVE ENCODING_UTF16BE 81 #define ENCODING_UTF16NATIVE ENCODING_UTF16BE
80 #define ENCODING_UTF32NATIVE ENCODING_UTF32BE 82 #define ENCODING_UTF32NATIVE ENCODING_UTF32BE
81 #else 83 #else
83 #define ENCODING_UTF32NATIVE ENCODING_UTF32LE 85 #define ENCODING_UTF32NATIVE ENCODING_UTF32LE
84 #endif 86 #endif
85 87
86 struct _SDL_iconv_t 88 struct _SDL_iconv_t
87 { 89 {
88 int src_fmt; 90 int src_fmt;
89 int dst_fmt; 91 int dst_fmt;
90 }; 92 };
91 93
92 static struct { 94 static struct
93 const char *name; 95 {
94 int format; 96 const char *name;
97 int format;
95 } encodings[] = { 98 } encodings[] = {
96 { "ASCII", ENCODING_ASCII }, 99 {
97 { "US-ASCII", ENCODING_ASCII }, 100 "ASCII", ENCODING_ASCII}, {
98 { "LATIN1", ENCODING_LATIN1 }, 101 "US-ASCII", ENCODING_ASCII}, {
99 { "ISO-8859-1", ENCODING_LATIN1 }, 102 "LATIN1", ENCODING_LATIN1}, {
100 { "UTF8", ENCODING_UTF8 }, 103 "ISO-8859-1", ENCODING_LATIN1}, {
101 { "UTF-8", ENCODING_UTF8 }, 104 "UTF8", ENCODING_UTF8}, {
102 { "UTF16", ENCODING_UTF16 }, 105 "UTF-8", ENCODING_UTF8}, {
103 { "UTF-16", ENCODING_UTF16 }, 106 "UTF16", ENCODING_UTF16}, {
104 { "UTF16BE", ENCODING_UTF16BE }, 107 "UTF-16", ENCODING_UTF16}, {
105 { "UTF-16BE", ENCODING_UTF16BE }, 108 "UTF16BE", ENCODING_UTF16BE}, {
106 { "UTF16LE", ENCODING_UTF16LE }, 109 "UTF-16BE", ENCODING_UTF16BE}, {
107 { "UTF-16LE", ENCODING_UTF16LE }, 110 "UTF16LE", ENCODING_UTF16LE}, {
108 { "UTF32", ENCODING_UTF32 }, 111 "UTF-16LE", ENCODING_UTF16LE}, {
109 { "UTF-32", ENCODING_UTF32 }, 112 "UTF32", ENCODING_UTF32}, {
110 { "UTF32BE", ENCODING_UTF32BE }, 113 "UTF-32", ENCODING_UTF32}, {
111 { "UTF-32BE", ENCODING_UTF32BE }, 114 "UTF32BE", ENCODING_UTF32BE}, {
112 { "UTF32LE", ENCODING_UTF32LE }, 115 "UTF-32BE", ENCODING_UTF32BE}, {
113 { "UTF-32LE", ENCODING_UTF32LE }, 116 "UTF32LE", ENCODING_UTF32LE}, {
114 { "UCS2", ENCODING_UCS2 }, 117 "UTF-32LE", ENCODING_UTF32LE}, {
115 { "UCS-2", ENCODING_UCS2 }, 118 "UCS2", ENCODING_UCS2}, {
116 { "UCS4", ENCODING_UCS4 }, 119 "UCS-2", ENCODING_UCS2}, {
117 { "UCS-4", ENCODING_UCS4 }, 120 "UCS4", ENCODING_UCS4}, {
118 }; 121 "UCS-4", ENCODING_UCS4},};
119 122
120 SDL_iconv_t SDL_iconv_open(const char *tocode, const char *fromcode) 123 SDL_iconv_t
124 SDL_iconv_open (const char *tocode, const char *fromcode)
121 { 125 {
122 int src_fmt = ENCODING_UNKNOWN; 126 int src_fmt = ENCODING_UNKNOWN;
123 int dst_fmt = ENCODING_UNKNOWN; 127 int dst_fmt = ENCODING_UNKNOWN;
124 int i; 128 int i;
125 129
126 for ( i = 0; i < SDL_arraysize(encodings); ++i ) { 130 for (i = 0; i < SDL_arraysize (encodings); ++i) {
127 if ( SDL_strcasecmp(fromcode, encodings[i].name) == 0 ) { 131 if (SDL_strcasecmp (fromcode, encodings[i].name) == 0) {
128 src_fmt = encodings[i].format; 132 src_fmt = encodings[i].format;
129 if ( dst_fmt != ENCODING_UNKNOWN ) { 133 if (dst_fmt != ENCODING_UNKNOWN) {
130 break; 134 break;
131 } 135 }
132 } 136 }
133 if ( SDL_strcasecmp(tocode, encodings[i].name) == 0 ) { 137 if (SDL_strcasecmp (tocode, encodings[i].name) == 0) {
134 dst_fmt = encodings[i].format; 138 dst_fmt = encodings[i].format;
135 if ( src_fmt != ENCODING_UNKNOWN ) { 139 if (src_fmt != ENCODING_UNKNOWN) {
136 break; 140 break;
137 } 141 }
138 } 142 }
139 } 143 }
140 if ( src_fmt != ENCODING_UNKNOWN && dst_fmt != ENCODING_UNKNOWN ) { 144 if (src_fmt != ENCODING_UNKNOWN && dst_fmt != ENCODING_UNKNOWN) {
141 SDL_iconv_t cd = (SDL_iconv_t)SDL_malloc(sizeof(*cd)); 145 SDL_iconv_t cd = (SDL_iconv_t) SDL_malloc (sizeof (*cd));
142 if ( cd ) { 146 if (cd) {
143 cd->src_fmt = src_fmt; 147 cd->src_fmt = src_fmt;
144 cd->dst_fmt = dst_fmt; 148 cd->dst_fmt = dst_fmt;
145 return cd; 149 return cd;
146 } 150 }
147 } 151 }
148 return (SDL_iconv_t)-1; 152 return (SDL_iconv_t) - 1;
149 } 153 }
150 154
151 size_t SDL_iconv(SDL_iconv_t cd, 155 size_t
152 char **inbuf, size_t *inbytesleft, 156 SDL_iconv (SDL_iconv_t cd,
153 char **outbuf, size_t *outbytesleft) 157 char **inbuf, size_t * inbytesleft,
158 char **outbuf, size_t * outbytesleft)
154 { 159 {
155 /* For simplicity, we'll convert everything to and from UCS-4 */ 160 /* For simplicity, we'll convert everything to and from UCS-4 */
156 char *src, *dst; 161 char *src, *dst;
157 size_t srclen, dstlen; 162 size_t srclen, dstlen;
158 Uint32 ch; 163 Uint32 ch;
159 size_t total; 164 size_t total;
160 165
161 if ( !inbuf || !*inbuf ) { 166 if (!inbuf || !*inbuf) {
162 /* Reset the context */ 167 /* Reset the context */
163 return 0; 168 return 0;
164 } 169 }
165 if ( !outbuf || !*outbuf || !outbytesleft || !*outbytesleft ) { 170 if (!outbuf || !*outbuf || !outbytesleft || !*outbytesleft) {
166 return SDL_ICONV_E2BIG; 171 return SDL_ICONV_E2BIG;
167 } 172 }
168 src = *inbuf; 173 src = *inbuf;
169 srclen = (inbytesleft ? *inbytesleft : 0); 174 srclen = (inbytesleft ? *inbytesleft : 0);
170 dst = *outbuf; 175 dst = *outbuf;
171 dstlen = *outbytesleft; 176 dstlen = *outbytesleft;
172 177
173 switch ( cd->src_fmt ) { 178 switch (cd->src_fmt) {
174 case ENCODING_UTF16: 179 case ENCODING_UTF16:
175 /* Scan for a byte order marker */ 180 /* Scan for a byte order marker */
176 { 181 {
177 Uint8 *p = (Uint8 *)src; 182 Uint8 *p = (Uint8 *) src;
178 size_t n = srclen / 2; 183 size_t n = srclen / 2;
179 while ( n ) { 184 while (n) {
180 if ( p[0] == 0xFF && p[1] == 0xFE ) { 185 if (p[0] == 0xFF && p[1] == 0xFE) {
181 cd->src_fmt = ENCODING_UTF16BE; 186 cd->src_fmt = ENCODING_UTF16BE;
182 break; 187 break;
183 } else if ( p[0] == 0xFE && p[1] == 0xFF ) { 188 } else if (p[0] == 0xFE && p[1] == 0xFF) {
184 cd->src_fmt = ENCODING_UTF16LE; 189 cd->src_fmt = ENCODING_UTF16LE;
185 break; 190 break;
186 } 191 }
187 p += 2; 192 p += 2;
188 --n; 193 --n;
189 } 194 }
190 if ( n == 0 ) { 195 if (n == 0) {
191 /* We can't tell, default to host order */ 196 /* We can't tell, default to host order */
192 cd->src_fmt = ENCODING_UTF16NATIVE; 197 cd->src_fmt = ENCODING_UTF16NATIVE;
193 } 198 }
194 } 199 }
195 break; 200 break;
196 case ENCODING_UTF32: 201 case ENCODING_UTF32:
197 /* Scan for a byte order marker */ 202 /* Scan for a byte order marker */
198 { 203 {
199 Uint8 *p = (Uint8 *)src; 204 Uint8 *p = (Uint8 *) src;
200 size_t n = srclen / 4; 205 size_t n = srclen / 4;
201 while ( n ) { 206 while (n) {
202 if ( p[0] == 0xFF && p[1] == 0xFE && 207 if (p[0] == 0xFF && p[1] == 0xFE &&
203 p[2] == 0x00 && p[3] == 0x00 ) { 208 p[2] == 0x00 && p[3] == 0x00) {
204 cd->src_fmt = ENCODING_UTF32BE; 209 cd->src_fmt = ENCODING_UTF32BE;
205 break; 210 break;
206 } else if ( p[0] == 0x00 && p[1] == 0x00 && 211 } else if (p[0] == 0x00 && p[1] == 0x00 &&
207 p[2] == 0xFE && p[3] == 0xFF ) { 212 p[2] == 0xFE && p[3] == 0xFF) {
208 cd->src_fmt = ENCODING_UTF32LE; 213 cd->src_fmt = ENCODING_UTF32LE;
209 break; 214 break;
210 } 215 }
211 p += 4; 216 p += 4;
212 --n; 217 --n;
213 } 218 }
214 if ( n == 0 ) { 219 if (n == 0) {
215 /* We can't tell, default to host order */ 220 /* We can't tell, default to host order */
216 cd->src_fmt = ENCODING_UTF32NATIVE; 221 cd->src_fmt = ENCODING_UTF32NATIVE;
217 } 222 }
218 } 223 }
219 break; 224 break;
220 } 225 }
221 226
222 switch ( cd->dst_fmt ) { 227 switch (cd->dst_fmt) {
223 case ENCODING_UTF16: 228 case ENCODING_UTF16:
224 /* Default to host order, need to add byte order marker */ 229 /* Default to host order, need to add byte order marker */
225 if ( dstlen < 2 ) { 230 if (dstlen < 2) {
226 return SDL_ICONV_E2BIG; 231 return SDL_ICONV_E2BIG;
227 } 232 }
228 *(Uint16 *)dst = UNICODE_BOM; 233 *(Uint16 *) dst = UNICODE_BOM;
229 dst += 2; 234 dst += 2;
230 dstlen -= 2; 235 dstlen -= 2;
231 cd->dst_fmt = ENCODING_UTF16NATIVE; 236 cd->dst_fmt = ENCODING_UTF16NATIVE;
232 break; 237 break;
233 case ENCODING_UTF32: 238 case ENCODING_UTF32:
234 /* Default to host order, need to add byte order marker */ 239 /* Default to host order, need to add byte order marker */
235 if ( dstlen < 4 ) { 240 if (dstlen < 4) {
236 return SDL_ICONV_E2BIG; 241 return SDL_ICONV_E2BIG;
237 } 242 }
238 *(Uint32 *)dst = UNICODE_BOM; 243 *(Uint32 *) dst = UNICODE_BOM;
239 dst += 4; 244 dst += 4;
240 dstlen -= 4; 245 dstlen -= 4;
241 cd->dst_fmt = ENCODING_UTF32NATIVE; 246 cd->dst_fmt = ENCODING_UTF32NATIVE;
242 break; 247 break;
243 } 248 }
244 249
245 total = 0; 250 total = 0;
246 while ( srclen > 0 ) { 251 while (srclen > 0) {
247 /* Decode a character */ 252 /* Decode a character */
248 switch ( cd->src_fmt ) { 253 switch (cd->src_fmt) {
249 case ENCODING_ASCII: 254 case ENCODING_ASCII:
250 { 255 {
251 Uint8 *p = (Uint8 *)src; 256 Uint8 *p = (Uint8 *) src;
252 ch = (Uint32)(p[0] & 0x7F); 257 ch = (Uint32) (p[0] & 0x7F);
253 ++src; 258 ++src;
254 --srclen; 259 --srclen;
255 } 260 }
256 break; 261 break;
257 case ENCODING_LATIN1: 262 case ENCODING_LATIN1:
258 { 263 {
259 Uint8 *p = (Uint8 *)src; 264 Uint8 *p = (Uint8 *) src;
260 ch = (Uint32)p[0]; 265 ch = (Uint32) p[0];
261 ++src; 266 ++src;
262 --srclen; 267 --srclen;
263 } 268 }
264 break; 269 break;
265 case ENCODING_UTF8: /* RFC 3629 */ 270 case ENCODING_UTF8: /* RFC 3629 */
266 { 271 {
267 Uint8 *p = (Uint8 *)src; 272 Uint8 *p = (Uint8 *) src;
268 size_t left = 0; 273 size_t left = 0;
269 SDL_bool overlong = SDL_FALSE; 274 SDL_bool overlong = SDL_FALSE;
270 if ( p[0] >= 0xFC ) { 275 if (p[0] >= 0xFC) {
271 if ( (p[0] & 0xFE) != 0xFC ) { 276 if ((p[0] & 0xFE) != 0xFC) {
272 /* Skip illegal sequences 277 /* Skip illegal sequences
273 return SDL_ICONV_EILSEQ; 278 return SDL_ICONV_EILSEQ;
274 */ 279 */
275 ch = UNKNOWN_UNICODE; 280 ch = UNKNOWN_UNICODE;
276 } else { 281 } else {
277 if ( p[0] == 0xFC ) { 282 if (p[0] == 0xFC) {
278 overlong = SDL_TRUE; 283 overlong = SDL_TRUE;
279 } 284 }
280 ch = (Uint32)(p[0] & 0x01); 285 ch = (Uint32) (p[0] & 0x01);
281 left = 5; 286 left = 5;
282 } 287 }
283 } else if ( p[0] >= 0xF8 ) { 288 } else if (p[0] >= 0xF8) {
284 if ( (p[0] & 0xFC) != 0xF8 ) { 289 if ((p[0] & 0xFC) != 0xF8) {
285 /* Skip illegal sequences 290 /* Skip illegal sequences
286 return SDL_ICONV_EILSEQ; 291 return SDL_ICONV_EILSEQ;
287 */ 292 */
288 ch = UNKNOWN_UNICODE; 293 ch = UNKNOWN_UNICODE;
289 } else { 294 } else {
290 if ( p[0] == 0xF8 ) { 295 if (p[0] == 0xF8) {
291 overlong = SDL_TRUE; 296 overlong = SDL_TRUE;
292 } 297 }
293 ch = (Uint32)(p[0] & 0x03); 298 ch = (Uint32) (p[0] & 0x03);
294 left = 4; 299 left = 4;
295 } 300 }
296 } else if ( p[0] >= 0xF0 ) { 301 } else if (p[0] >= 0xF0) {
297 if ( (p[0] & 0xF8) != 0xF0 ) { 302 if ((p[0] & 0xF8) != 0xF0) {
298 /* Skip illegal sequences 303 /* Skip illegal sequences
299 return SDL_ICONV_EILSEQ; 304 return SDL_ICONV_EILSEQ;
300 */ 305 */
301 ch = UNKNOWN_UNICODE; 306 ch = UNKNOWN_UNICODE;
302 } else { 307 } else {
303 if ( p[0] == 0xF0 ) { 308 if (p[0] == 0xF0) {
304 overlong = SDL_TRUE; 309 overlong = SDL_TRUE;
305 } 310 }
306 ch = (Uint32)(p[0] & 0x07); 311 ch = (Uint32) (p[0] & 0x07);
307 left = 3; 312 left = 3;
308 } 313 }
309 } else if ( p[0] >= 0xE0 ) { 314 } else if (p[0] >= 0xE0) {
310 if ( (p[0] & 0xF0) != 0xE0 ) { 315 if ((p[0] & 0xF0) != 0xE0) {
311 /* Skip illegal sequences 316 /* Skip illegal sequences
312 return SDL_ICONV_EILSEQ; 317 return SDL_ICONV_EILSEQ;
313 */ 318 */
314 ch = UNKNOWN_UNICODE; 319 ch = UNKNOWN_UNICODE;
315 } else { 320 } else {
316 if ( p[0] == 0xE0 ) { 321 if (p[0] == 0xE0) {
317 overlong = SDL_TRUE; 322 overlong = SDL_TRUE;
318 } 323 }
319 ch = (Uint32)(p[0] & 0x0F); 324 ch = (Uint32) (p[0] & 0x0F);
320 left = 2; 325 left = 2;
321 } 326 }
322 } else if ( p[0] >= 0xC0 ) { 327 } else if (p[0] >= 0xC0) {
323 if ( (p[0] & 0xE0) != 0xC0 ) { 328 if ((p[0] & 0xE0) != 0xC0) {
324 /* Skip illegal sequences 329 /* Skip illegal sequences
325 return SDL_ICONV_EILSEQ; 330 return SDL_ICONV_EILSEQ;
326 */ 331 */
327 ch = UNKNOWN_UNICODE; 332 ch = UNKNOWN_UNICODE;
328 } else { 333 } else {
329 if ( (p[0] & 0xCE) == 0xC0 ) { 334 if ((p[0] & 0xCE) == 0xC0) {
330 overlong = SDL_TRUE; 335 overlong = SDL_TRUE;
331 } 336 }
332 ch = (Uint32)(p[0] & 0x1F); 337 ch = (Uint32) (p[0] & 0x1F);
333 left = 1; 338 left = 1;
334 } 339 }
335 } else { 340 } else {
336 if ( (p[0] & 0x80) != 0x00 ) { 341 if ((p[0] & 0x80) != 0x00) {
337 /* Skip illegal sequences 342 /* Skip illegal sequences
338 return SDL_ICONV_EILSEQ; 343 return SDL_ICONV_EILSEQ;
339 */ 344 */
340 ch = UNKNOWN_UNICODE; 345 ch = UNKNOWN_UNICODE;
341 } else { 346 } else {
342 ch = (Uint32)p[0]; 347 ch = (Uint32) p[0];
343 } 348 }
344 } 349 }
345 ++src; 350 ++src;
346 --srclen; 351 --srclen;
347 if ( srclen < left ) { 352 if (srclen < left) {
348 return SDL_ICONV_EINVAL; 353 return SDL_ICONV_EINVAL;
349 } 354 }
350 while ( left-- ) { 355 while (left--) {
351 ++p; 356 ++p;
352 if ( (p[0] & 0xC0) != 0x80 ) { 357 if ((p[0] & 0xC0) != 0x80) {
353 /* Skip illegal sequences 358 /* Skip illegal sequences
354 return SDL_ICONV_EILSEQ; 359 return SDL_ICONV_EILSEQ;
355 */ 360 */
356 ch = UNKNOWN_UNICODE; 361 ch = UNKNOWN_UNICODE;
357 break; 362 break;
358 } 363 }
359 ch <<= 6; 364 ch <<= 6;
360 ch |= (p[0] & 0x3F); 365 ch |= (p[0] & 0x3F);
361 ++src; 366 ++src;
362 --srclen; 367 --srclen;
363 } 368 }
364 if ( overlong ) { 369 if (overlong) {
365 /* Potential security risk 370 /* Potential security risk
366 return SDL_ICONV_EILSEQ; 371 return SDL_ICONV_EILSEQ;
367 */ 372 */
368 ch = UNKNOWN_UNICODE; 373 ch = UNKNOWN_UNICODE;
369 } 374 }
370 if ( (ch >= 0xD800 && ch <= 0xDFFF) || 375 if ((ch >= 0xD800 && ch <= 0xDFFF) ||
371 (ch == 0xFFFE || ch == 0xFFFF) || 376 (ch == 0xFFFE || ch == 0xFFFF) || ch > 0x10FFFF) {
372 ch > 0x10FFFF ) { 377 /* Skip illegal sequences
373 /* Skip illegal sequences 378 return SDL_ICONV_EILSEQ;
374 return SDL_ICONV_EILSEQ; 379 */
375 */ 380 ch = UNKNOWN_UNICODE;
376 ch = UNKNOWN_UNICODE; 381 }
377 } 382 }
378 } 383 break;
379 break; 384 case ENCODING_UTF16BE: /* RFC 2781 */
380 case ENCODING_UTF16BE: /* RFC 2781 */ 385 {
381 { 386 Uint8 *p = (Uint8 *) src;
382 Uint8 *p = (Uint8 *)src; 387 Uint16 W1, W2;
383 Uint16 W1, W2; 388 if (srclen < 2) {
384 if ( srclen < 2 ) { 389 return SDL_ICONV_EINVAL;
385 return SDL_ICONV_EINVAL; 390 }
386 } 391 W1 = ((Uint16) p[0] << 8) | (Uint16) p[1];
387 W1 = ((Uint16)p[0] << 8) | 392 src += 2;
388 (Uint16)p[1]; 393 srclen -= 2;
389 src += 2; 394 if (W1 < 0xD800 || W1 > 0xDFFF) {
390 srclen -= 2; 395 ch = (Uint32) W1;
391 if ( W1 < 0xD800 || W1 > 0xDFFF ) { 396 break;
392 ch = (Uint32)W1; 397 }
393 break; 398 if (W1 > 0xDBFF) {
394 } 399 /* Skip illegal sequences
395 if ( W1 > 0xDBFF ) { 400 return SDL_ICONV_EILSEQ;
396 /* Skip illegal sequences 401 */
397 return SDL_ICONV_EILSEQ; 402 ch = UNKNOWN_UNICODE;
398 */ 403 break;
399 ch = UNKNOWN_UNICODE; 404 }
400 break; 405 if (srclen < 2) {
401 } 406 return SDL_ICONV_EINVAL;
402 if ( srclen < 2 ) { 407 }
403 return SDL_ICONV_EINVAL; 408 p = (Uint8 *) src;
404 } 409 W2 = ((Uint16) p[0] << 8) | (Uint16) p[1];
405 p = (Uint8 *)src; 410 src += 2;
406 W2 = ((Uint16)p[0] << 8) | 411 srclen -= 2;
407 (Uint16)p[1]; 412 if (W2 < 0xDC00 || W2 > 0xDFFF) {
408 src += 2; 413 /* Skip illegal sequences
409 srclen -= 2; 414 return SDL_ICONV_EILSEQ;
410 if ( W2 < 0xDC00 || W2 > 0xDFFF ) { 415 */
411 /* Skip illegal sequences 416 ch = UNKNOWN_UNICODE;
412 return SDL_ICONV_EILSEQ; 417 break;
413 */ 418 }
414 ch = UNKNOWN_UNICODE; 419 ch = (((Uint32) (W1 & 0x3FF) << 10) |
415 break; 420 (Uint32) (W2 & 0x3FF)) + 0x10000;
416 } 421 }
417 ch = (((Uint32)(W1 & 0x3FF) << 10) | 422 break;
418 (Uint32)(W2 & 0x3FF)) + 0x10000; 423 case ENCODING_UTF16LE: /* RFC 2781 */
419 } 424 {
420 break; 425 Uint8 *p = (Uint8 *) src;
421 case ENCODING_UTF16LE: /* RFC 2781 */ 426 Uint16 W1, W2;
422 { 427 if (srclen < 2) {
423 Uint8 *p = (Uint8 *)src; 428 return SDL_ICONV_EINVAL;
424 Uint16 W1, W2; 429 }
425 if ( srclen < 2 ) { 430 W1 = ((Uint16) p[1] << 8) | (Uint16) p[0];
426 return SDL_ICONV_EINVAL; 431 src += 2;
427 } 432 srclen -= 2;
428 W1 = ((Uint16)p[1] << 8) | 433 if (W1 < 0xD800 || W1 > 0xDFFF) {
429 (Uint16)p[0]; 434 ch = (Uint32) W1;
430 src += 2; 435 break;
431 srclen -= 2; 436 }
432 if ( W1 < 0xD800 || W1 > 0xDFFF ) { 437 if (W1 > 0xDBFF) {
433 ch = (Uint32)W1; 438 /* Skip illegal sequences
434 break; 439 return SDL_ICONV_EILSEQ;
435 } 440 */
436 if ( W1 > 0xDBFF ) { 441 ch = UNKNOWN_UNICODE;
437 /* Skip illegal sequences 442 break;
438 return SDL_ICONV_EILSEQ; 443 }
439 */ 444 if (srclen < 2) {
440 ch = UNKNOWN_UNICODE; 445 return SDL_ICONV_EINVAL;
441 break; 446 }
442 } 447 p = (Uint8 *) src;
443 if ( srclen < 2 ) { 448 W2 = ((Uint16) p[1] << 8) | (Uint16) p[0];
444 return SDL_ICONV_EINVAL; 449 src += 2;
445 } 450 srclen -= 2;
446 p = (Uint8 *)src; 451 if (W2 < 0xDC00 || W2 > 0xDFFF) {
447 W2 = ((Uint16)p[1] << 8) | 452 /* Skip illegal sequences
448 (Uint16)p[0]; 453 return SDL_ICONV_EILSEQ;
449 src += 2; 454 */
450 srclen -= 2; 455 ch = UNKNOWN_UNICODE;
451 if ( W2 < 0xDC00 || W2 > 0xDFFF ) { 456 break;
452 /* Skip illegal sequences 457 }
453 return SDL_ICONV_EILSEQ; 458 ch = (((Uint32) (W1 & 0x3FF) << 10) |
454 */ 459 (Uint32) (W2 & 0x3FF)) + 0x10000;
455 ch = UNKNOWN_UNICODE; 460 }
456 break; 461 break;
457 } 462 case ENCODING_UTF32BE:
458 ch = (((Uint32)(W1 & 0x3FF) << 10) | 463 {
459 (Uint32)(W2 & 0x3FF)) + 0x10000; 464 Uint8 *p = (Uint8 *) src;
460 } 465 if (srclen < 4) {
461 break; 466 return SDL_ICONV_EINVAL;
462 case ENCODING_UTF32BE: 467 }
463 { 468 ch = ((Uint32) p[0] << 24) |
464 Uint8 *p = (Uint8 *)src; 469 ((Uint32) p[1] << 16) |
465 if ( srclen < 4 ) { 470 ((Uint32) p[2] << 8) | (Uint32) p[3];
466 return SDL_ICONV_EINVAL; 471 src += 4;
467 } 472 srclen -= 4;
468 ch = ((Uint32)p[0] << 24) | 473 }
469 ((Uint32)p[1] << 16) | 474 break;
470 ((Uint32)p[2] << 8) | 475 case ENCODING_UTF32LE:
471 (Uint32)p[3]; 476 {
472 src += 4; 477 Uint8 *p = (Uint8 *) src;
473 srclen -= 4; 478 if (srclen < 4) {
474 } 479 return SDL_ICONV_EINVAL;
475 break; 480 }
476 case ENCODING_UTF32LE: 481 ch = ((Uint32) p[3] << 24) |
477 { 482 ((Uint32) p[2] << 16) |
478 Uint8 *p = (Uint8 *)src; 483 ((Uint32) p[1] << 8) | (Uint32) p[0];
479 if ( srclen < 4 ) { 484 src += 4;
480 return SDL_ICONV_EINVAL; 485 srclen -= 4;
481 } 486 }
482 ch = ((Uint32)p[3] << 24) | 487 break;
483 ((Uint32)p[2] << 16) | 488 case ENCODING_UCS2:
484 ((Uint32)p[1] << 8) | 489 {
485 (Uint32)p[0]; 490 Uint16 *p = (Uint16 *) src;
486 src += 4; 491 if (srclen < 2) {
487 srclen -= 4; 492 return SDL_ICONV_EINVAL;
488 } 493 }
489 break; 494 ch = *p;
490 case ENCODING_UCS2: 495 src += 2;
491 { 496 srclen -= 2;
492 Uint16 *p = (Uint16 *)src; 497 }
493 if ( srclen < 2 ) { 498 break;
494 return SDL_ICONV_EINVAL; 499 case ENCODING_UCS4:
495 } 500 {
496 ch = *p; 501 Uint32 *p = (Uint32 *) src;
497 src += 2; 502 if (srclen < 4) {
498 srclen -= 2; 503 return SDL_ICONV_EINVAL;
499 } 504 }
500 break; 505 ch = *p;
501 case ENCODING_UCS4: 506 src += 4;
502 { 507 srclen -= 4;
503 Uint32 *p = (Uint32 *)src; 508 }
504 if ( srclen < 4 ) { 509 break;
505 return SDL_ICONV_EINVAL; 510 }
506 } 511
507 ch = *p; 512 /* Encode a character */
508 src += 4; 513 switch (cd->dst_fmt) {
509 srclen -= 4; 514 case ENCODING_ASCII:
510 } 515 {
511 break; 516 Uint8 *p = (Uint8 *) dst;
512 } 517 if (dstlen < 1) {
513 518 return SDL_ICONV_E2BIG;
514 /* Encode a character */ 519 }
515 switch ( cd->dst_fmt ) { 520 if (ch > 0x7F) {
516 case ENCODING_ASCII: 521 *p = UNKNOWN_ASCII;
517 { 522 } else {
518 Uint8 *p = (Uint8 *)dst; 523 *p = (Uint8) ch;
519 if ( dstlen < 1 ) { 524 }
520 return SDL_ICONV_E2BIG; 525 ++dst;
521 } 526 --dstlen;
522 if ( ch > 0x7F ) { 527 }
523 *p = UNKNOWN_ASCII; 528 break;
524 } else { 529 case ENCODING_LATIN1:
525 *p = (Uint8)ch; 530 {
526 } 531 Uint8 *p = (Uint8 *) dst;
527 ++dst; 532 if (dstlen < 1) {
528 --dstlen; 533 return SDL_ICONV_E2BIG;
529 } 534 }
530 break; 535 if (ch > 0xFF) {
531 case ENCODING_LATIN1: 536 *p = UNKNOWN_ASCII;
532 { 537 } else {
533 Uint8 *p = (Uint8 *)dst; 538 *p = (Uint8) ch;
534 if ( dstlen < 1 ) { 539 }
535 return SDL_ICONV_E2BIG; 540 ++dst;
536 } 541 --dstlen;
537 if ( ch > 0xFF ) { 542 }
538 *p = UNKNOWN_ASCII; 543 break;
539 } else { 544 case ENCODING_UTF8: /* RFC 3629 */
540 *p = (Uint8)ch; 545 {
541 } 546 Uint8 *p = (Uint8 *) dst;
542 ++dst; 547 if (ch > 0x10FFFF) {
543 --dstlen; 548 ch = UNKNOWN_UNICODE;
544 } 549 }
545 break; 550 if (ch <= 0x7F) {
546 case ENCODING_UTF8: /* RFC 3629 */ 551 if (dstlen < 1) {
547 { 552 return SDL_ICONV_E2BIG;
548 Uint8 *p = (Uint8 *)dst; 553 }
549 if ( ch > 0x10FFFF ) { 554 *p = (Uint8) ch;
550 ch = UNKNOWN_UNICODE; 555 ++dst;
551 } 556 --dstlen;
552 if ( ch <= 0x7F ) { 557 } else if (ch <= 0x7FF) {
553 if ( dstlen < 1 ) { 558 if (dstlen < 2) {
554 return SDL_ICONV_E2BIG; 559 return SDL_ICONV_E2BIG;
555 } 560 }
556 *p = (Uint8)ch; 561 p[0] = 0xC0 | (Uint8) ((ch >> 6) & 0x1F);
557 ++dst; 562 p[1] = 0x80 | (Uint8) (ch & 0x3F);
558 --dstlen; 563 dst += 2;
559 } else if ( ch <= 0x7FF ) { 564 dstlen -= 2;
560 if ( dstlen < 2 ) { 565 } else if (ch <= 0xFFFF) {
561 return SDL_ICONV_E2BIG; 566 if (dstlen < 3) {
562 } 567 return SDL_ICONV_E2BIG;
563 p[0] = 0xC0 | (Uint8)((ch >> 6) & 0x1F); 568 }
564 p[1] = 0x80 | (Uint8)(ch & 0x3F); 569 p[0] = 0xE0 | (Uint8) ((ch >> 12) & 0x0F);
565 dst += 2; 570 p[1] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
566 dstlen -= 2; 571 p[2] = 0x80 | (Uint8) (ch & 0x3F);
567 } else if ( ch <= 0xFFFF ) { 572 dst += 3;
568 if ( dstlen < 3 ) { 573 dstlen -= 3;
569 return SDL_ICONV_E2BIG; 574 } else if (ch <= 0x1FFFFF) {
570 } 575 if (dstlen < 4) {
571 p[0] = 0xE0 | (Uint8)((ch >> 12) & 0x0F); 576 return SDL_ICONV_E2BIG;
572 p[1] = 0x80 | (Uint8)((ch >> 6) & 0x3F); 577 }
573 p[2] = 0x80 | (Uint8)(ch & 0x3F); 578 p[0] = 0xF0 | (Uint8) ((ch >> 18) & 0x07);
574 dst += 3; 579 p[1] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
575 dstlen -= 3; 580 p[2] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
576 } else if ( ch <= 0x1FFFFF ) { 581 p[3] = 0x80 | (Uint8) (ch & 0x3F);
577 if ( dstlen < 4 ) { 582 dst += 4;
578 return SDL_ICONV_E2BIG; 583 dstlen -= 4;
579 } 584 } else if (ch <= 0x3FFFFFF) {
580 p[0] = 0xF0 | (Uint8)((ch >> 18) & 0x07); 585 if (dstlen < 5) {
581 p[1] = 0x80 | (Uint8)((ch >> 12) & 0x3F); 586 return SDL_ICONV_E2BIG;
582 p[2] = 0x80 | (Uint8)((ch >> 6) & 0x3F); 587 }
583 p[3] = 0x80 | (Uint8)(ch & 0x3F); 588 p[0] = 0xF8 | (Uint8) ((ch >> 24) & 0x03);
584 dst += 4; 589 p[1] = 0x80 | (Uint8) ((ch >> 18) & 0x3F);
585 dstlen -= 4; 590 p[2] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
586 } else if ( ch <= 0x3FFFFFF ) { 591 p[3] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
587 if ( dstlen < 5 ) { 592 p[4] = 0x80 | (Uint8) (ch & 0x3F);
588 return SDL_ICONV_E2BIG; 593 dst += 5;
589 } 594 dstlen -= 5;
590 p[0] = 0xF8 | (Uint8)((ch >> 24) & 0x03); 595 } else {
591 p[1] = 0x80 | (Uint8)((ch >> 18) & 0x3F); 596 if (dstlen < 6) {
592 p[2] = 0x80 | (Uint8)((ch >> 12) & 0x3F); 597 return SDL_ICONV_E2BIG;
593 p[3] = 0x80 | (Uint8)((ch >> 6) & 0x3F); 598 }
594 p[4] = 0x80 | (Uint8)(ch & 0x3F); 599 p[0] = 0xFC | (Uint8) ((ch >> 30) & 0x01);
595 dst += 5; 600 p[1] = 0x80 | (Uint8) ((ch >> 24) & 0x3F);
596 dstlen -= 5; 601 p[2] = 0x80 | (Uint8) ((ch >> 18) & 0x3F);
597 } else { 602 p[3] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
598 if ( dstlen < 6 ) { 603 p[4] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
599 return SDL_ICONV_E2BIG; 604 p[5] = 0x80 | (Uint8) (ch & 0x3F);
600 } 605 dst += 6;
601 p[0] = 0xFC | (Uint8)((ch >> 30) & 0x01); 606 dstlen -= 6;
602 p[1] = 0x80 | (Uint8)((ch >> 24) & 0x3F); 607 }
603 p[2] = 0x80 | (Uint8)((ch >> 18) & 0x3F); 608 }
604 p[3] = 0x80 | (Uint8)((ch >> 12) & 0x3F); 609 break;
605 p[4] = 0x80 | (Uint8)((ch >> 6) & 0x3F); 610 case ENCODING_UTF16BE: /* RFC 2781 */
606 p[5] = 0x80 | (Uint8)(ch & 0x3F); 611 {
607 dst += 6; 612 Uint8 *p = (Uint8 *) dst;
608 dstlen -= 6; 613 if (ch > 0x10FFFF) {
609 } 614 ch = UNKNOWN_UNICODE;
610 } 615 }
611 break; 616 if (ch < 0x10000) {
612 case ENCODING_UTF16BE: /* RFC 2781 */ 617 if (dstlen < 2) {
613 { 618 return SDL_ICONV_E2BIG;
614 Uint8 *p = (Uint8 *)dst; 619 }
615 if ( ch > 0x10FFFF ) { 620 p[0] = (Uint8) (ch >> 8);
616 ch = UNKNOWN_UNICODE; 621 p[1] = (Uint8) ch;
617 } 622 dst += 2;
618 if ( ch < 0x10000 ) { 623 dstlen -= 2;
619 if ( dstlen < 2 ) { 624 } else {
620 return SDL_ICONV_E2BIG; 625 Uint16 W1, W2;
621 } 626 if (dstlen < 4) {
622 p[0] = (Uint8)(ch >> 8); 627 return SDL_ICONV_E2BIG;
623 p[1] = (Uint8)ch; 628 }
624 dst += 2; 629 ch = ch - 0x10000;
625 dstlen -= 2; 630 W1 = 0xD800 | (Uint16) ((ch >> 10) & 0x3FF);
626 } else { 631 W2 = 0xDC00 | (Uint16) (ch & 0x3FF);
627 Uint16 W1, W2; 632 p[0] = (Uint8) (W1 >> 8);
628 if ( dstlen < 4 ) { 633 p[1] = (Uint8) W1;
629 return SDL_ICONV_E2BIG; 634 p[2] = (Uint8) (W2 >> 8);
630 } 635 p[3] = (Uint8) W2;
631 ch = ch - 0x10000; 636 dst += 4;
632 W1 = 0xD800 | (Uint16)((ch >> 10) & 0x3FF); 637 dstlen -= 4;
633 W2 = 0xDC00 | (Uint16)(ch & 0x3FF); 638 }
634 p[0] = (Uint8)(W1 >> 8); 639 }
635 p[1] = (Uint8)W1; 640 break;
636 p[2] = (Uint8)(W2 >> 8); 641 case ENCODING_UTF16LE: /* RFC 2781 */
637 p[3] = (Uint8)W2; 642 {
638 dst += 4; 643 Uint8 *p = (Uint8 *) dst;
639 dstlen -= 4; 644 if (ch > 0x10FFFF) {
640 } 645 ch = UNKNOWN_UNICODE;
641 } 646 }
642 break; 647 if (ch < 0x10000) {
643 case ENCODING_UTF16LE: /* RFC 2781 */ 648 if (dstlen < 2) {
644 { 649 return SDL_ICONV_E2BIG;
645 Uint8 *p = (Uint8 *)dst; 650 }
646 if ( ch > 0x10FFFF ) { 651 p[1] = (Uint8) (ch >> 8);
647 ch = UNKNOWN_UNICODE; 652 p[0] = (Uint8) ch;
648 } 653 dst += 2;
649 if ( ch < 0x10000 ) { 654 dstlen -= 2;
650 if ( dstlen < 2 ) { 655 } else {
651 return SDL_ICONV_E2BIG; 656 Uint16 W1, W2;
652 } 657 if (dstlen < 4) {
653 p[1] = (Uint8)(ch >> 8); 658 return SDL_ICONV_E2BIG;
654 p[0] = (Uint8)ch; 659 }
655 dst += 2; 660 ch = ch - 0x10000;
656 dstlen -= 2; 661 W1 = 0xD800 | (Uint16) ((ch >> 10) & 0x3FF);
657 } else { 662 W2 = 0xDC00 | (Uint16) (ch & 0x3FF);
658 Uint16 W1, W2; 663 p[1] = (Uint8) (W1 >> 8);
659 if ( dstlen < 4 ) { 664 p[0] = (Uint8) W1;
660 return SDL_ICONV_E2BIG; 665 p[3] = (Uint8) (W2 >> 8);
661 } 666 p[2] = (Uint8) W2;
662 ch = ch - 0x10000; 667 dst += 4;
663 W1 = 0xD800 | (Uint16)((ch >> 10) & 0x3FF); 668 dstlen -= 4;
664 W2 = 0xDC00 | (Uint16)(ch & 0x3FF); 669 }
665 p[1] = (Uint8)(W1 >> 8); 670 }
666 p[0] = (Uint8)W1; 671 break;
667 p[3] = (Uint8)(W2 >> 8); 672 case ENCODING_UTF32BE:
668 p[2] = (Uint8)W2; 673 {
669 dst += 4; 674 Uint8 *p = (Uint8 *) dst;
670 dstlen -= 4; 675 if (ch > 0x10FFFF) {
671 } 676 ch = UNKNOWN_UNICODE;
672 } 677 }
673 break; 678 if (dstlen < 4) {
674 case ENCODING_UTF32BE: 679 return SDL_ICONV_E2BIG;
675 { 680 }
676 Uint8 *p = (Uint8 *)dst; 681 p[0] = (Uint8) (ch >> 24);
677 if ( ch > 0x10FFFF ) { 682 p[1] = (Uint8) (ch >> 16);
678 ch = UNKNOWN_UNICODE; 683 p[2] = (Uint8) (ch >> 8);
679 } 684 p[3] = (Uint8) ch;
680 if ( dstlen < 4 ) { 685 dst += 4;
681 return SDL_ICONV_E2BIG; 686 dstlen -= 4;
682 } 687 }
683 p[0] = (Uint8)(ch >> 24); 688 break;
684 p[1] = (Uint8)(ch >> 16); 689 case ENCODING_UTF32LE:
685 p[2] = (Uint8)(ch >> 8); 690 {
686 p[3] = (Uint8)ch; 691 Uint8 *p = (Uint8 *) dst;
687 dst += 4; 692 if (ch > 0x10FFFF) {
688 dstlen -= 4; 693 ch = UNKNOWN_UNICODE;
689 } 694 }
690 break; 695 if (dstlen < 4) {
691 case ENCODING_UTF32LE: 696 return SDL_ICONV_E2BIG;
692 { 697 }
693 Uint8 *p = (Uint8 *)dst; 698 p[3] = (Uint8) (ch >> 24);
694 if ( ch > 0x10FFFF ) { 699 p[2] = (Uint8) (ch >> 16);
695 ch = UNKNOWN_UNICODE; 700 p[1] = (Uint8) (ch >> 8);
696 } 701 p[0] = (Uint8) ch;
697 if ( dstlen < 4 ) { 702 dst += 4;
698 return SDL_ICONV_E2BIG; 703 dstlen -= 4;
699 } 704 }
700 p[3] = (Uint8)(ch >> 24); 705 break;
701 p[2] = (Uint8)(ch >> 16); 706 case ENCODING_UCS2:
702 p[1] = (Uint8)(ch >> 8); 707 {
703 p[0] = (Uint8)ch; 708 Uint16 *p = (Uint16 *) dst;
704 dst += 4; 709 if (ch > 0xFFFF) {
705 dstlen -= 4; 710 ch = UNKNOWN_UNICODE;
706 } 711 }
707 break; 712 if (dstlen < 2) {
708 case ENCODING_UCS2: 713 return SDL_ICONV_E2BIG;
709 { 714 }
710 Uint16 *p = (Uint16 *)dst; 715 *p = (Uint16) ch;
711 if ( ch > 0xFFFF ) { 716 dst += 2;
712 ch = UNKNOWN_UNICODE; 717 dstlen -= 2;
713 } 718 }
714 if ( dstlen < 2 ) { 719 break;
715 return SDL_ICONV_E2BIG; 720 case ENCODING_UCS4:
716 } 721 {
717 *p = (Uint16)ch; 722 Uint32 *p = (Uint32 *) dst;
718 dst += 2; 723 if (ch > 0x7FFFFFFF) {
719 dstlen -= 2; 724 ch = UNKNOWN_UNICODE;
720 } 725 }
721 break; 726 if (dstlen < 4) {
722 case ENCODING_UCS4: 727 return SDL_ICONV_E2BIG;
723 { 728 }
724 Uint32 *p = (Uint32 *)dst; 729 *p = ch;
725 if ( ch > 0x7FFFFFFF ) { 730 dst += 4;
726 ch = UNKNOWN_UNICODE; 731 dstlen -= 4;
727 } 732 }
728 if ( dstlen < 4 ) { 733 break;
729 return SDL_ICONV_E2BIG; 734 }
730 } 735
731 *p = ch; 736 /* Update state */
732 dst += 4; 737 *inbuf = src;
733 dstlen -= 4; 738 *inbytesleft = srclen;
734 } 739 *outbuf = dst;
735 break; 740 *outbytesleft = dstlen;
736 } 741 ++total;
737 742 }
738 /* Update state */ 743 return total;
739 *inbuf = src;
740 *inbytesleft = srclen;
741 *outbuf = dst;
742 *outbytesleft = dstlen;
743 ++total;
744 }
745 return total;
746 } 744 }
747 745
748 int SDL_iconv_close(SDL_iconv_t cd) 746 int
747 SDL_iconv_close (SDL_iconv_t cd)
749 { 748 {
750 if ( cd && cd != (SDL_iconv_t)-1 ) { 749 if (cd && cd != (SDL_iconv_t) - 1) {
751 SDL_free(cd); 750 SDL_free (cd);
752 } 751 }
753 return 0; 752 return 0;
754 } 753 }
755 754
756 #endif /* !HAVE_ICONV */ 755 #endif /* !HAVE_ICONV */
757 756
758 char *SDL_iconv_string(const char *tocode, const char *fromcode, char *inbuf, size_t inbytesleft) 757 char *
758 SDL_iconv_string (const char *tocode, const char *fromcode, char *inbuf,
759 size_t inbytesleft)
759 { 760 {
760 SDL_iconv_t cd; 761 SDL_iconv_t cd;
761 char *string; 762 char *string;
762 size_t stringsize; 763 size_t stringsize;
763 char *outbuf; 764 char *outbuf;
764 size_t outbytesleft; 765 size_t outbytesleft;
765 size_t retCode = 0; 766 size_t retCode = 0;
766 767
767 cd = SDL_iconv_open(tocode, fromcode); 768 cd = SDL_iconv_open (tocode, fromcode);
768 if ( cd == (SDL_iconv_t)-1 ) { 769 if (cd == (SDL_iconv_t) - 1) {
769 return NULL; 770 return NULL;
770 } 771 }
771 772
772 stringsize = inbytesleft > 4 ? inbytesleft : 4; 773 stringsize = inbytesleft > 4 ? inbytesleft : 4;
773 string = SDL_malloc(stringsize); 774 string = SDL_malloc (stringsize);
774 if ( !string ) { 775 if (!string) {
775 SDL_iconv_close(cd); 776 SDL_iconv_close (cd);
776 return NULL; 777 return NULL;
777 } 778 }
778 outbuf = string; 779 outbuf = string;
779 outbytesleft = stringsize; 780 outbytesleft = stringsize;
780 SDL_memset(outbuf, 0, 4); 781 SDL_memset (outbuf, 0, 4);
781 782
782 while ( inbytesleft > 0 ) { 783 while (inbytesleft > 0) {
783 retCode = SDL_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); 784 retCode =
784 switch (retCode) { 785 SDL_iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
785 case SDL_ICONV_E2BIG: 786 switch (retCode) {
786 { 787 case SDL_ICONV_E2BIG:
787 char *oldstring = string; 788 {
788 stringsize *= 2; 789 char *oldstring = string;
789 string = SDL_realloc(string, stringsize); 790 stringsize *= 2;
790 if ( !string ) { 791 string = SDL_realloc (string, stringsize);
791 SDL_iconv_close(cd); 792 if (!string) {
792 return NULL; 793 SDL_iconv_close (cd);
793 } 794 return NULL;
794 outbuf = string + (outbuf - oldstring); 795 }
795 outbytesleft = stringsize - (outbuf - string); 796 outbuf = string + (outbuf - oldstring);
796 SDL_memset(outbuf, 0, 4); 797 outbytesleft = stringsize - (outbuf - string);
797 } 798 SDL_memset (outbuf, 0, 4);
798 break; 799 }
799 case SDL_ICONV_EILSEQ: 800 break;
800 /* Try skipping some input data - not perfect, but... */ 801 case SDL_ICONV_EILSEQ:
801 ++inbuf; 802 /* Try skipping some input data - not perfect, but... */
802 --inbytesleft; 803 ++inbuf;
803 break; 804 --inbytesleft;
804 case SDL_ICONV_EINVAL: 805 break;
805 case SDL_ICONV_ERROR: 806 case SDL_ICONV_EINVAL:
806 /* We can't continue... */ 807 case SDL_ICONV_ERROR:
807 inbytesleft = 0; 808 /* We can't continue... */
808 break; 809 inbytesleft = 0;
809 } 810 break;
810 } 811 }
811 SDL_iconv_close(cd); 812 }
812 813 SDL_iconv_close (cd);
813 return string; 814
815 return string;
814 } 816 }
817
818 /* vi: set ts=4 sw=4 expandtab: */