SDL 2.0
SDL_iconv.c File Reference
#include "../SDL_internal.h"
#include "SDL_stdinc.h"
#include "SDL_endian.h"
+ Include dependency graph for SDL_iconv.c:

Go to the source code of this file.

Data Structures

struct  SDL_iconv_t
 

Macros

#define UNICODE_BOM   0xFEFF
 
#define UNKNOWN_ASCII   '?'
 
#define UNKNOWN_UNICODE   0xFFFD
 
#define ENCODING_UTF16NATIVE   ENCODING_UTF16BE
 
#define ENCODING_UTF32NATIVE   ENCODING_UTF32BE
 
#define ENCODING_UCS2NATIVE   ENCODING_UCS2BE
 
#define ENCODING_UCS4NATIVE   ENCODING_UCS4BE
 

Enumerations

enum  {
  ENCODING_UNKNOWN ,
  ENCODING_ASCII ,
  ENCODING_LATIN1 ,
  ENCODING_UTF8 ,
  ENCODING_UTF16 ,
  ENCODING_UTF16BE ,
  ENCODING_UTF16LE ,
  ENCODING_UTF32 ,
  ENCODING_UTF32BE ,
  ENCODING_UTF32LE ,
  ENCODING_UCS2BE ,
  ENCODING_UCS2LE ,
  ENCODING_UCS4BE ,
  ENCODING_UCS4LE
}
 

Functions

static const char * getlocale (char *buffer, size_t bufsize)
 
SDL_iconv_t SDL_iconv_open (const char *tocode, const char *fromcode)
 
size_t SDL_iconv (SDL_iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
 
int SDL_iconv_close (SDL_iconv_t cd)
 
char * SDL_iconv_string (const char *tocode, const char *fromcode, const char *inbuf, size_t inbytesleft)
 

Variables

struct {
   const char *   name
 
   int   format
 
encodings []
 

Macro Definition Documentation

◆ ENCODING_UCS2NATIVE

#define ENCODING_UCS2NATIVE   ENCODING_UCS2BE

Definition at line 120 of file SDL_iconv.c.

◆ ENCODING_UCS4NATIVE

#define ENCODING_UCS4NATIVE   ENCODING_UCS4BE

Definition at line 121 of file SDL_iconv.c.

◆ ENCODING_UTF16NATIVE

#define ENCODING_UTF16NATIVE   ENCODING_UTF16BE

Definition at line 118 of file SDL_iconv.c.

◆ ENCODING_UTF32NATIVE

#define ENCODING_UTF32NATIVE   ENCODING_UTF32BE

Definition at line 119 of file SDL_iconv.c.

◆ UNICODE_BOM

#define UNICODE_BOM   0xFEFF

Definition at line 95 of file SDL_iconv.c.

◆ UNKNOWN_ASCII

#define UNKNOWN_ASCII   '?'

Definition at line 97 of file SDL_iconv.c.

◆ UNKNOWN_UNICODE

#define UNKNOWN_UNICODE   0xFFFD

Definition at line 98 of file SDL_iconv.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
ENCODING_UNKNOWN 
ENCODING_ASCII 
ENCODING_LATIN1 
ENCODING_UTF8 
ENCODING_UTF16 
ENCODING_UTF16BE 
ENCODING_UTF16LE 
ENCODING_UTF32 
ENCODING_UTF32BE 
ENCODING_UTF32LE 
ENCODING_UCS2BE 
ENCODING_UCS2LE 
ENCODING_UCS4BE 
ENCODING_UCS4LE 

Definition at line 100 of file SDL_iconv.c.

101{
106 ENCODING_UTF16, /* Needs byte order marker */
109 ENCODING_UTF32, /* Needs byte order marker */
116};
@ ENCODING_UNKNOWN
Definition: SDL_iconv.c:102
@ ENCODING_UTF16
Definition: SDL_iconv.c:106
@ ENCODING_LATIN1
Definition: SDL_iconv.c:104
@ ENCODING_UCS2BE
Definition: SDL_iconv.c:112
@ ENCODING_UCS4LE
Definition: SDL_iconv.c:115
@ ENCODING_UCS2LE
Definition: SDL_iconv.c:113
@ ENCODING_ASCII
Definition: SDL_iconv.c:103
@ ENCODING_UCS4BE
Definition: SDL_iconv.c:114
@ ENCODING_UTF16BE
Definition: SDL_iconv.c:107
@ ENCODING_UTF32
Definition: SDL_iconv.c:109
@ ENCODING_UTF32LE
Definition: SDL_iconv.c:111
@ ENCODING_UTF8
Definition: SDL_iconv.c:105
@ ENCODING_UTF16LE
Definition: SDL_iconv.c:108
@ ENCODING_UTF32BE
Definition: SDL_iconv.c:110

Function Documentation

◆ getlocale()

static const char * getlocale ( char *  buffer,
size_t  bufsize 
)
static

Definition at line 173 of file SDL_iconv.c.

174{
175 const char *lang;
176 char *ptr;
177
178 lang = SDL_getenv("LC_ALL");
179 if (!lang) {
180 lang = SDL_getenv("LC_CTYPE");
181 }
182 if (!lang) {
183 lang = SDL_getenv("LC_MESSAGES");
184 }
185 if (!lang) {
186 lang = SDL_getenv("LANG");
187 }
188 if (!lang || !*lang || SDL_strcmp(lang, "C") == 0) {
189 lang = "ASCII";
190 }
191
192 /* We need to trim down strings like "en_US.UTF-8@blah" to "UTF-8" */
193 ptr = SDL_strchr(lang, '.');
194 if (ptr != NULL) {
195 lang = ptr + 1;
196 }
197
198 SDL_strlcpy(buffer, lang, bufsize);
199 ptr = SDL_strchr(buffer, '@');
200 if (ptr != NULL) {
201 *ptr = '\0'; /* chop end of string. */
202 }
203
204 return buffer;
205}
#define SDL_strchr
#define SDL_getenv
#define SDL_strlcpy
#define SDL_strcmp
GLuint buffer
GLenum GLuint GLsizei bufsize
#define NULL
Definition: begin_code.h:167

References NULL, SDL_getenv, SDL_strchr, SDL_strcmp, and SDL_strlcpy.

Referenced by SDL_iconv_open().

◆ SDL_iconv()

size_t SDL_iconv ( SDL_iconv_t  cd,
const char **  inbuf,
size_t inbytesleft,
char **  outbuf,
size_t outbytesleft 
)

Definition at line 248 of file SDL_iconv.c.

251{
252 /* For simplicity, we'll convert everything to and from UCS-4 */
253 const char *src;
254 char *dst;
255 size_t srclen, dstlen;
256 Uint32 ch = 0;
257 size_t total;
258
259 if (!inbuf || !*inbuf) {
260 /* Reset the context */
261 return 0;
262 }
263 if (!outbuf || !*outbuf || !outbytesleft || !*outbytesleft) {
264 return SDL_ICONV_E2BIG;
265 }
266 src = *inbuf;
267 srclen = (inbytesleft ? *inbytesleft : 0);
268 dst = *outbuf;
269 dstlen = *outbytesleft;
270
271 switch (cd->src_fmt) {
272 case ENCODING_UTF16:
273 /* Scan for a byte order marker */
274 {
275 Uint8 *p = (Uint8 *) src;
276 size_t n = srclen / 2;
277 while (n) {
278 if (p[0] == 0xFF && p[1] == 0xFE) {
279 cd->src_fmt = ENCODING_UTF16BE;
280 break;
281 } else if (p[0] == 0xFE && p[1] == 0xFF) {
282 cd->src_fmt = ENCODING_UTF16LE;
283 break;
284 }
285 p += 2;
286 --n;
287 }
288 if (n == 0) {
289 /* We can't tell, default to host order */
290 cd->src_fmt = ENCODING_UTF16NATIVE;
291 }
292 }
293 break;
294 case ENCODING_UTF32:
295 /* Scan for a byte order marker */
296 {
297 Uint8 *p = (Uint8 *) src;
298 size_t n = srclen / 4;
299 while (n) {
300 if (p[0] == 0xFF && p[1] == 0xFE &&
301 p[2] == 0x00 && p[3] == 0x00) {
302 cd->src_fmt = ENCODING_UTF32BE;
303 break;
304 } else if (p[0] == 0x00 && p[1] == 0x00 &&
305 p[2] == 0xFE && p[3] == 0xFF) {
306 cd->src_fmt = ENCODING_UTF32LE;
307 break;
308 }
309 p += 4;
310 --n;
311 }
312 if (n == 0) {
313 /* We can't tell, default to host order */
314 cd->src_fmt = ENCODING_UTF32NATIVE;
315 }
316 }
317 break;
318 }
319
320 switch (cd->dst_fmt) {
321 case ENCODING_UTF16:
322 /* Default to host order, need to add byte order marker */
323 if (dstlen < 2) {
324 return SDL_ICONV_E2BIG;
325 }
326 *(Uint16 *) dst = UNICODE_BOM;
327 dst += 2;
328 dstlen -= 2;
329 cd->dst_fmt = ENCODING_UTF16NATIVE;
330 break;
331 case ENCODING_UTF32:
332 /* Default to host order, need to add byte order marker */
333 if (dstlen < 4) {
334 return SDL_ICONV_E2BIG;
335 }
336 *(Uint32 *) dst = UNICODE_BOM;
337 dst += 4;
338 dstlen -= 4;
339 cd->dst_fmt = ENCODING_UTF32NATIVE;
340 break;
341 }
342
343 total = 0;
344 while (srclen > 0) {
345 /* Decode a character */
346 switch (cd->src_fmt) {
347 case ENCODING_ASCII:
348 {
349 Uint8 *p = (Uint8 *) src;
350 ch = (Uint32) (p[0] & 0x7F);
351 ++src;
352 --srclen;
353 }
354 break;
355 case ENCODING_LATIN1:
356 {
357 Uint8 *p = (Uint8 *) src;
358 ch = (Uint32) p[0];
359 ++src;
360 --srclen;
361 }
362 break;
363 case ENCODING_UTF8: /* RFC 3629 */
364 {
365 Uint8 *p = (Uint8 *) src;
366 size_t left = 0;
367 SDL_bool overlong = SDL_FALSE;
368 if (p[0] >= 0xFC) {
369 if ((p[0] & 0xFE) != 0xFC) {
370 /* Skip illegal sequences
371 return SDL_ICONV_EILSEQ;
372 */
373 ch = UNKNOWN_UNICODE;
374 } else {
375 if (p[0] == 0xFC && srclen > 1 && (p[1] & 0xFC) == 0x80) {
376 overlong = SDL_TRUE;
377 }
378 ch = (Uint32) (p[0] & 0x01);
379 left = 5;
380 }
381 } else if (p[0] >= 0xF8) {
382 if ((p[0] & 0xFC) != 0xF8) {
383 /* Skip illegal sequences
384 return SDL_ICONV_EILSEQ;
385 */
386 ch = UNKNOWN_UNICODE;
387 } else {
388 if (p[0] == 0xF8 && srclen > 1 && (p[1] & 0xF8) == 0x80) {
389 overlong = SDL_TRUE;
390 }
391 ch = (Uint32) (p[0] & 0x03);
392 left = 4;
393 }
394 } else if (p[0] >= 0xF0) {
395 if ((p[0] & 0xF8) != 0xF0) {
396 /* Skip illegal sequences
397 return SDL_ICONV_EILSEQ;
398 */
399 ch = UNKNOWN_UNICODE;
400 } else {
401 if (p[0] == 0xF0 && srclen > 1 && (p[1] & 0xF0) == 0x80) {
402 overlong = SDL_TRUE;
403 }
404 ch = (Uint32) (p[0] & 0x07);
405 left = 3;
406 }
407 } else if (p[0] >= 0xE0) {
408 if ((p[0] & 0xF0) != 0xE0) {
409 /* Skip illegal sequences
410 return SDL_ICONV_EILSEQ;
411 */
412 ch = UNKNOWN_UNICODE;
413 } else {
414 if (p[0] == 0xE0 && srclen > 1 && (p[1] & 0xE0) == 0x80) {
415 overlong = SDL_TRUE;
416 }
417 ch = (Uint32) (p[0] & 0x0F);
418 left = 2;
419 }
420 } else if (p[0] >= 0xC0) {
421 if ((p[0] & 0xE0) != 0xC0) {
422 /* Skip illegal sequences
423 return SDL_ICONV_EILSEQ;
424 */
425 ch = UNKNOWN_UNICODE;
426 } else {
427 if ((p[0] & 0xDE) == 0xC0) {
428 overlong = SDL_TRUE;
429 }
430 ch = (Uint32) (p[0] & 0x1F);
431 left = 1;
432 }
433 } else {
434 if ((p[0] & 0x80) != 0x00) {
435 /* Skip illegal sequences
436 return SDL_ICONV_EILSEQ;
437 */
438 ch = UNKNOWN_UNICODE;
439 } else {
440 ch = (Uint32) p[0];
441 }
442 }
443 ++src;
444 --srclen;
445 if (srclen < left) {
446 return SDL_ICONV_EINVAL;
447 }
448 while (left--) {
449 ++p;
450 if ((p[0] & 0xC0) != 0x80) {
451 /* Skip illegal sequences
452 return SDL_ICONV_EILSEQ;
453 */
454 ch = UNKNOWN_UNICODE;
455 break;
456 }
457 ch <<= 6;
458 ch |= (p[0] & 0x3F);
459 ++src;
460 --srclen;
461 }
462 if (overlong) {
463 /* Potential security risk
464 return SDL_ICONV_EILSEQ;
465 */
466 ch = UNKNOWN_UNICODE;
467 }
468 if ((ch >= 0xD800 && ch <= 0xDFFF) ||
469 (ch == 0xFFFE || ch == 0xFFFF) || ch > 0x10FFFF) {
470 /* Skip illegal sequences
471 return SDL_ICONV_EILSEQ;
472 */
473 ch = UNKNOWN_UNICODE;
474 }
475 }
476 break;
477 case ENCODING_UTF16BE: /* RFC 2781 */
478 {
479 Uint8 *p = (Uint8 *) src;
480 Uint16 W1, W2;
481 if (srclen < 2) {
482 return SDL_ICONV_EINVAL;
483 }
484 W1 = ((Uint16) p[0] << 8) | (Uint16) p[1];
485 src += 2;
486 srclen -= 2;
487 if (W1 < 0xD800 || W1 > 0xDFFF) {
488 ch = (Uint32) W1;
489 break;
490 }
491 if (W1 > 0xDBFF) {
492 /* Skip illegal sequences
493 return SDL_ICONV_EILSEQ;
494 */
495 ch = UNKNOWN_UNICODE;
496 break;
497 }
498 if (srclen < 2) {
499 return SDL_ICONV_EINVAL;
500 }
501 p = (Uint8 *) src;
502 W2 = ((Uint16) p[0] << 8) | (Uint16) p[1];
503 src += 2;
504 srclen -= 2;
505 if (W2 < 0xDC00 || W2 > 0xDFFF) {
506 /* Skip illegal sequences
507 return SDL_ICONV_EILSEQ;
508 */
509 ch = UNKNOWN_UNICODE;
510 break;
511 }
512 ch = (((Uint32) (W1 & 0x3FF) << 10) |
513 (Uint32) (W2 & 0x3FF)) + 0x10000;
514 }
515 break;
516 case ENCODING_UTF16LE: /* RFC 2781 */
517 {
518 Uint8 *p = (Uint8 *) src;
519 Uint16 W1, W2;
520 if (srclen < 2) {
521 return SDL_ICONV_EINVAL;
522 }
523 W1 = ((Uint16) p[1] << 8) | (Uint16) p[0];
524 src += 2;
525 srclen -= 2;
526 if (W1 < 0xD800 || W1 > 0xDFFF) {
527 ch = (Uint32) W1;
528 break;
529 }
530 if (W1 > 0xDBFF) {
531 /* Skip illegal sequences
532 return SDL_ICONV_EILSEQ;
533 */
534 ch = UNKNOWN_UNICODE;
535 break;
536 }
537 if (srclen < 2) {
538 return SDL_ICONV_EINVAL;
539 }
540 p = (Uint8 *) src;
541 W2 = ((Uint16) p[1] << 8) | (Uint16) p[0];
542 src += 2;
543 srclen -= 2;
544 if (W2 < 0xDC00 || W2 > 0xDFFF) {
545 /* Skip illegal sequences
546 return SDL_ICONV_EILSEQ;
547 */
548 ch = UNKNOWN_UNICODE;
549 break;
550 }
551 ch = (((Uint32) (W1 & 0x3FF) << 10) |
552 (Uint32) (W2 & 0x3FF)) + 0x10000;
553 }
554 break;
555 case ENCODING_UCS2LE:
556 {
557 Uint8 *p = (Uint8 *) src;
558 if (srclen < 2) {
559 return SDL_ICONV_EINVAL;
560 }
561 ch = ((Uint32) p[1] << 8) | (Uint32) p[0];
562 src += 2;
563 srclen -= 2;
564 }
565 break;
566 case ENCODING_UCS2BE:
567 {
568 Uint8 *p = (Uint8 *) src;
569 if (srclen < 2) {
570 return SDL_ICONV_EINVAL;
571 }
572 ch = ((Uint32) p[0] << 8) | (Uint32) p[1];
573 src += 2;
574 srclen -= 2;
575 }
576 break;
577 case ENCODING_UCS4BE:
578 case ENCODING_UTF32BE:
579 {
580 Uint8 *p = (Uint8 *) src;
581 if (srclen < 4) {
582 return SDL_ICONV_EINVAL;
583 }
584 ch = ((Uint32) p[0] << 24) |
585 ((Uint32) p[1] << 16) |
586 ((Uint32) p[2] << 8) | (Uint32) p[3];
587 src += 4;
588 srclen -= 4;
589 }
590 break;
591 case ENCODING_UCS4LE:
592 case ENCODING_UTF32LE:
593 {
594 Uint8 *p = (Uint8 *) src;
595 if (srclen < 4) {
596 return SDL_ICONV_EINVAL;
597 }
598 ch = ((Uint32) p[3] << 24) |
599 ((Uint32) p[2] << 16) |
600 ((Uint32) p[1] << 8) | (Uint32) p[0];
601 src += 4;
602 srclen -= 4;
603 }
604 break;
605 }
606
607 /* Encode a character */
608 switch (cd->dst_fmt) {
609 case ENCODING_ASCII:
610 {
611 Uint8 *p = (Uint8 *) dst;
612 if (dstlen < 1) {
613 return SDL_ICONV_E2BIG;
614 }
615 if (ch > 0x7F) {
616 *p = UNKNOWN_ASCII;
617 } else {
618 *p = (Uint8) ch;
619 }
620 ++dst;
621 --dstlen;
622 }
623 break;
624 case ENCODING_LATIN1:
625 {
626 Uint8 *p = (Uint8 *) dst;
627 if (dstlen < 1) {
628 return SDL_ICONV_E2BIG;
629 }
630 if (ch > 0xFF) {
631 *p = UNKNOWN_ASCII;
632 } else {
633 *p = (Uint8) ch;
634 }
635 ++dst;
636 --dstlen;
637 }
638 break;
639 case ENCODING_UTF8: /* RFC 3629 */
640 {
641 Uint8 *p = (Uint8 *) dst;
642 if (ch > 0x10FFFF) {
643 ch = UNKNOWN_UNICODE;
644 }
645 if (ch <= 0x7F) {
646 if (dstlen < 1) {
647 return SDL_ICONV_E2BIG;
648 }
649 *p = (Uint8) ch;
650 ++dst;
651 --dstlen;
652 } else if (ch <= 0x7FF) {
653 if (dstlen < 2) {
654 return SDL_ICONV_E2BIG;
655 }
656 p[0] = 0xC0 | (Uint8) ((ch >> 6) & 0x1F);
657 p[1] = 0x80 | (Uint8) (ch & 0x3F);
658 dst += 2;
659 dstlen -= 2;
660 } else if (ch <= 0xFFFF) {
661 if (dstlen < 3) {
662 return SDL_ICONV_E2BIG;
663 }
664 p[0] = 0xE0 | (Uint8) ((ch >> 12) & 0x0F);
665 p[1] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
666 p[2] = 0x80 | (Uint8) (ch & 0x3F);
667 dst += 3;
668 dstlen -= 3;
669 } else if (ch <= 0x1FFFFF) {
670 if (dstlen < 4) {
671 return SDL_ICONV_E2BIG;
672 }
673 p[0] = 0xF0 | (Uint8) ((ch >> 18) & 0x07);
674 p[1] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
675 p[2] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
676 p[3] = 0x80 | (Uint8) (ch & 0x3F);
677 dst += 4;
678 dstlen -= 4;
679 } else if (ch <= 0x3FFFFFF) {
680 if (dstlen < 5) {
681 return SDL_ICONV_E2BIG;
682 }
683 p[0] = 0xF8 | (Uint8) ((ch >> 24) & 0x03);
684 p[1] = 0x80 | (Uint8) ((ch >> 18) & 0x3F);
685 p[2] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
686 p[3] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
687 p[4] = 0x80 | (Uint8) (ch & 0x3F);
688 dst += 5;
689 dstlen -= 5;
690 } else {
691 if (dstlen < 6) {
692 return SDL_ICONV_E2BIG;
693 }
694 p[0] = 0xFC | (Uint8) ((ch >> 30) & 0x01);
695 p[1] = 0x80 | (Uint8) ((ch >> 24) & 0x3F);
696 p[2] = 0x80 | (Uint8) ((ch >> 18) & 0x3F);
697 p[3] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
698 p[4] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
699 p[5] = 0x80 | (Uint8) (ch & 0x3F);
700 dst += 6;
701 dstlen -= 6;
702 }
703 }
704 break;
705 case ENCODING_UTF16BE: /* RFC 2781 */
706 {
707 Uint8 *p = (Uint8 *) dst;
708 if (ch > 0x10FFFF) {
709 ch = UNKNOWN_UNICODE;
710 }
711 if (ch < 0x10000) {
712 if (dstlen < 2) {
713 return SDL_ICONV_E2BIG;
714 }
715 p[0] = (Uint8) (ch >> 8);
716 p[1] = (Uint8) ch;
717 dst += 2;
718 dstlen -= 2;
719 } else {
720 Uint16 W1, W2;
721 if (dstlen < 4) {
722 return SDL_ICONV_E2BIG;
723 }
724 ch = ch - 0x10000;
725 W1 = 0xD800 | (Uint16) ((ch >> 10) & 0x3FF);
726 W2 = 0xDC00 | (Uint16) (ch & 0x3FF);
727 p[0] = (Uint8) (W1 >> 8);
728 p[1] = (Uint8) W1;
729 p[2] = (Uint8) (W2 >> 8);
730 p[3] = (Uint8) W2;
731 dst += 4;
732 dstlen -= 4;
733 }
734 }
735 break;
736 case ENCODING_UTF16LE: /* RFC 2781 */
737 {
738 Uint8 *p = (Uint8 *) dst;
739 if (ch > 0x10FFFF) {
740 ch = UNKNOWN_UNICODE;
741 }
742 if (ch < 0x10000) {
743 if (dstlen < 2) {
744 return SDL_ICONV_E2BIG;
745 }
746 p[1] = (Uint8) (ch >> 8);
747 p[0] = (Uint8) ch;
748 dst += 2;
749 dstlen -= 2;
750 } else {
751 Uint16 W1, W2;
752 if (dstlen < 4) {
753 return SDL_ICONV_E2BIG;
754 }
755 ch = ch - 0x10000;
756 W1 = 0xD800 | (Uint16) ((ch >> 10) & 0x3FF);
757 W2 = 0xDC00 | (Uint16) (ch & 0x3FF);
758 p[1] = (Uint8) (W1 >> 8);
759 p[0] = (Uint8) W1;
760 p[3] = (Uint8) (W2 >> 8);
761 p[2] = (Uint8) W2;
762 dst += 4;
763 dstlen -= 4;
764 }
765 }
766 break;
767 case ENCODING_UCS2BE:
768 {
769 Uint8 *p = (Uint8 *) dst;
770 if (ch > 0xFFFF) {
771 ch = UNKNOWN_UNICODE;
772 }
773 if (dstlen < 2) {
774 return SDL_ICONV_E2BIG;
775 }
776 p[0] = (Uint8) (ch >> 8);
777 p[1] = (Uint8) ch;
778 dst += 2;
779 dstlen -= 2;
780 }
781 break;
782 case ENCODING_UCS2LE:
783 {
784 Uint8 *p = (Uint8 *) dst;
785 if (ch > 0xFFFF) {
786 ch = UNKNOWN_UNICODE;
787 }
788 if (dstlen < 2) {
789 return SDL_ICONV_E2BIG;
790 }
791 p[1] = (Uint8) (ch >> 8);
792 p[0] = (Uint8) ch;
793 dst += 2;
794 dstlen -= 2;
795 }
796 break;
797 case ENCODING_UTF32BE:
798 if (ch > 0x10FFFF) {
799 ch = UNKNOWN_UNICODE;
800 }
801 /* fallthrough */
802 case ENCODING_UCS4BE:
803 if (ch > 0x7FFFFFFF) {
804 ch = UNKNOWN_UNICODE;
805 }
806 {
807 Uint8 *p = (Uint8 *) dst;
808 if (dstlen < 4) {
809 return SDL_ICONV_E2BIG;
810 }
811 p[0] = (Uint8) (ch >> 24);
812 p[1] = (Uint8) (ch >> 16);
813 p[2] = (Uint8) (ch >> 8);
814 p[3] = (Uint8) ch;
815 dst += 4;
816 dstlen -= 4;
817 }
818 break;
819 case ENCODING_UTF32LE:
820 if (ch > 0x10FFFF) {
821 ch = UNKNOWN_UNICODE;
822 }
823 /* fallthrough */
824 case ENCODING_UCS4LE:
825 if (ch > 0x7FFFFFFF) {
826 ch = UNKNOWN_UNICODE;
827 }
828 {
829 Uint8 *p = (Uint8 *) dst;
830 if (dstlen < 4) {
831 return SDL_ICONV_E2BIG;
832 }
833 p[3] = (Uint8) (ch >> 24);
834 p[2] = (Uint8) (ch >> 16);
835 p[1] = (Uint8) (ch >> 8);
836 p[0] = (Uint8) ch;
837 dst += 4;
838 dstlen -= 4;
839 }
840 break;
841 }
842
843 /* Update state */
844 *inbuf = src;
845 *inbytesleft = srclen;
846 *outbuf = dst;
847 *outbytesleft = dstlen;
848 ++total;
849 }
850 return total;
851}
#define UNICODE_BOM
Definition: SDL_iconv.c:95
#define UNKNOWN_UNICODE
Definition: SDL_iconv.c:98
#define ENCODING_UTF16NATIVE
Definition: SDL_iconv.c:118
#define ENCODING_UTF32NATIVE
Definition: SDL_iconv.c:119
#define UNKNOWN_ASCII
Definition: SDL_iconv.c:97
GLenum src
GLint left
GLenum GLenum dst
GLfloat GLfloat p
GLdouble n
#define SDL_ICONV_EINVAL
Definition: SDL_stdinc.h:544
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
uint32_t Uint32
Definition: SDL_stdinc.h:203
#define SDL_ICONV_E2BIG
Definition: SDL_stdinc.h:542
uint16_t Uint16
Definition: SDL_stdinc.h:191
uint8_t Uint8
Definition: SDL_stdinc.h:179

References ENCODING_ASCII, ENCODING_LATIN1, ENCODING_UCS2BE, ENCODING_UCS2LE, ENCODING_UCS4BE, ENCODING_UCS4LE, ENCODING_UTF16, ENCODING_UTF16BE, ENCODING_UTF16LE, ENCODING_UTF16NATIVE, ENCODING_UTF32, ENCODING_UTF32BE, ENCODING_UTF32LE, ENCODING_UTF32NATIVE, ENCODING_UTF8, SDL_FALSE, SDL_ICONV_E2BIG, SDL_ICONV_EINVAL, SDL_TRUE, UNICODE_BOM, UNKNOWN_ASCII, and UNKNOWN_UNICODE.

Referenced by SDL_iconv_string().

◆ SDL_iconv_close()

int SDL_iconv_close ( SDL_iconv_t  cd)

Definition at line 854 of file SDL_iconv.c.

855{
856 if (cd != (SDL_iconv_t)-1) {
857 SDL_free(cd);
858 }
859 return 0;
860}
#define SDL_free

References SDL_free.

Referenced by SDL_iconv_string().

◆ SDL_iconv_open()

SDL_iconv_t SDL_iconv_open ( const char *  tocode,
const char *  fromcode 
)

Definition at line 208 of file SDL_iconv.c.

209{
210 int src_fmt = ENCODING_UNKNOWN;
211 int dst_fmt = ENCODING_UNKNOWN;
212 int i;
213 char fromcode_buffer[64];
214 char tocode_buffer[64];
215
216 if (!fromcode || !*fromcode) {
217 fromcode = getlocale(fromcode_buffer, sizeof(fromcode_buffer));
218 }
219 if (!tocode || !*tocode) {
220 tocode = getlocale(tocode_buffer, sizeof(tocode_buffer));
221 }
222 for (i = 0; i < SDL_arraysize(encodings); ++i) {
223 if (SDL_strcasecmp(fromcode, encodings[i].name) == 0) {
224 src_fmt = encodings[i].format;
225 if (dst_fmt != ENCODING_UNKNOWN) {
226 break;
227 }
228 }
229 if (SDL_strcasecmp(tocode, encodings[i].name) == 0) {
230 dst_fmt = encodings[i].format;
231 if (src_fmt != ENCODING_UNKNOWN) {
232 break;
233 }
234 }
235 }
236 if (src_fmt != ENCODING_UNKNOWN && dst_fmt != ENCODING_UNKNOWN) {
237 SDL_iconv_t cd = (SDL_iconv_t) SDL_malloc(sizeof(*cd));
238 if (cd) {
239 cd->src_fmt = src_fmt;
240 cd->dst_fmt = dst_fmt;
241 return cd;
242 }
243 }
244 return (SDL_iconv_t) - 1;
245}
#define SDL_malloc
#define SDL_strcasecmp
static const char * getlocale(char *buffer, size_t bufsize)
Definition: SDL_iconv.c:173
static struct @37 encodings[]
GLuint const GLchar * name
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50

References ENCODING_UNKNOWN, encodings, getlocale(), i, SDL_arraysize, SDL_malloc, and SDL_strcasecmp.

Referenced by SDL_iconv_string().

◆ SDL_iconv_string()

char * SDL_iconv_string ( const char *  tocode,
const char *  fromcode,
const char *  inbuf,
size_t  inbytesleft 
)

This function converts a string between encodings in one pass, returning a string that must be freed with SDL_free() or NULL on error.

Definition at line 865 of file SDL_iconv.c.

867{
868 SDL_iconv_t cd;
869 char *string;
870 size_t stringsize;
871 char *outbuf;
872 size_t outbytesleft;
873 size_t retCode = 0;
874
875 cd = SDL_iconv_open(tocode, fromcode);
876 if (cd == (SDL_iconv_t) - 1) {
877 /* See if we can recover here (fixes iconv on Solaris 11) */
878 if (!tocode || !*tocode) {
879 tocode = "UTF-8";
880 }
881 if (!fromcode || !*fromcode) {
882 fromcode = "UTF-8";
883 }
884 cd = SDL_iconv_open(tocode, fromcode);
885 }
886 if (cd == (SDL_iconv_t) - 1) {
887 return NULL;
888 }
889
890 stringsize = inbytesleft > 4 ? inbytesleft : 4;
891 string = SDL_malloc(stringsize);
892 if (!string) {
893 SDL_iconv_close(cd);
894 return NULL;
895 }
896 outbuf = string;
897 outbytesleft = stringsize;
898 SDL_memset(outbuf, 0, 4);
899
900 while (inbytesleft > 0) {
901 retCode = SDL_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
902 switch (retCode) {
903 case SDL_ICONV_E2BIG:
904 {
905 char *oldstring = string;
906 stringsize *= 2;
907 string = SDL_realloc(string, stringsize);
908 if (!string) {
909 SDL_iconv_close(cd);
910 return NULL;
911 }
912 outbuf = string + (outbuf - oldstring);
913 outbytesleft = stringsize - (outbuf - string);
914 SDL_memset(outbuf, 0, 4);
915 }
916 break;
917 case SDL_ICONV_EILSEQ:
918 /* Try skipping some input data - not perfect, but... */
919 ++inbuf;
920 --inbytesleft;
921 break;
922 case SDL_ICONV_EINVAL:
923 case SDL_ICONV_ERROR:
924 /* We can't continue... */
925 inbytesleft = 0;
926 break;
927 }
928 }
929 SDL_iconv_close(cd);
930
931 return string;
932}
#define SDL_memset
#define SDL_realloc
SDL_iconv_t SDL_iconv_open(const char *tocode, const char *fromcode)
Definition: SDL_iconv.c:208
size_t SDL_iconv(SDL_iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: SDL_iconv.c:248
int SDL_iconv_close(SDL_iconv_t cd)
Definition: SDL_iconv.c:854
GLsizei const GLchar *const * string
#define SDL_ICONV_ERROR
Definition: SDL_stdinc.h:541
#define SDL_ICONV_EILSEQ
Definition: SDL_stdinc.h:543

References NULL, SDL_iconv(), SDL_iconv_close(), SDL_ICONV_E2BIG, SDL_ICONV_EILSEQ, SDL_ICONV_EINVAL, SDL_ICONV_ERROR, SDL_iconv_open(), SDL_malloc, SDL_memset, and SDL_realloc.

Variable Documentation

◆ 

struct { ... } encodings[]

Referenced by SDL_iconv_open().

◆ format

int format

Definition at line 138 of file SDL_iconv.c.

◆ name

const char* name

Definition at line 137 of file SDL_iconv.c.