Mercurial > sdl-ios-xcode
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: */ |