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

#define ENCODING_UCS2NATIVE   ENCODING_UCS2BE

Definition at line 118 of file SDL_iconv.c.

#define ENCODING_UCS4NATIVE   ENCODING_UCS4BE

Definition at line 119 of file SDL_iconv.c.

#define ENCODING_UTF16NATIVE   ENCODING_UTF16BE

Definition at line 116 of file SDL_iconv.c.

Referenced by SDL_iconv().

#define ENCODING_UTF32NATIVE   ENCODING_UTF32BE

Definition at line 117 of file SDL_iconv.c.

Referenced by SDL_iconv().

#define UNICODE_BOM   0xFEFF

Definition at line 93 of file SDL_iconv.c.

Referenced by SDL_iconv().

#define UNKNOWN_ASCII   '?'

Definition at line 95 of file SDL_iconv.c.

Referenced by SDL_iconv().

#define UNKNOWN_UNICODE   0xFFFD

Definition at line 96 of file SDL_iconv.c.

Referenced by SDL_iconv().

Enumeration Type Documentation

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 98 of file SDL_iconv.c.

Function Documentation

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

Definition at line 171 of file SDL_iconv.c.

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

Referenced by SDL_iconv_open().

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

Definition at line 246 of file SDL_iconv.c.

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().

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

Definition at line 850 of file SDL_iconv.c.

References SDL_free().

Referenced by SDL_iconv_string().

851 {
852  if (cd != (SDL_iconv_t)-1) {
853  SDL_free(cd);
854  }
855  return 0;
856 }
void SDL_free(void *mem)
SDL_iconv_t SDL_iconv_open ( const char *  tocode,
const char *  fromcode 
)

Definition at line 206 of file SDL_iconv.c.

References SDL_iconv_t::dst_fmt, ENCODING_UNKNOWN, encodings, getlocale(), i, SDL_arraysize, SDL_malloc, SDL_strcasecmp, and SDL_iconv_t::src_fmt.

Referenced by SDL_iconv_string().

207 {
208  int src_fmt = ENCODING_UNKNOWN;
209  int dst_fmt = ENCODING_UNKNOWN;
210  int i;
211  char fromcode_buffer[64];
212  char tocode_buffer[64];
213 
214  if (!fromcode || !*fromcode) {
215  fromcode = getlocale(fromcode_buffer, sizeof(fromcode_buffer));
216  }
217  if (!tocode || !*tocode) {
218  tocode = getlocale(tocode_buffer, sizeof(tocode_buffer));
219  }
220  for (i = 0; i < SDL_arraysize(encodings); ++i) {
221  if (SDL_strcasecmp(fromcode, encodings[i].name) == 0) {
222  src_fmt = encodings[i].format;
223  if (dst_fmt != ENCODING_UNKNOWN) {
224  break;
225  }
226  }
227  if (SDL_strcasecmp(tocode, encodings[i].name) == 0) {
228  dst_fmt = encodings[i].format;
229  if (src_fmt != ENCODING_UNKNOWN) {
230  break;
231  }
232  }
233  }
234  if (src_fmt != ENCODING_UNKNOWN && dst_fmt != ENCODING_UNKNOWN) {
235  SDL_iconv_t cd = (SDL_iconv_t) SDL_malloc(sizeof(*cd));
236  if (cd) {
237  cd->src_fmt = src_fmt;
238  cd->dst_fmt = dst_fmt;
239  return cd;
240  }
241  }
242  return (SDL_iconv_t) - 1;
243 }
GLuint const GLchar * name
#define SDL_strcasecmp
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:42
static struct @24 encodings[]
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
#define SDL_malloc
static const char * getlocale(char *buffer, size_t bufsize)
Definition: SDL_iconv.c:171
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 861 of file SDL_iconv.c.

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.

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

Variable Documentation

struct { ... } encodings[]

Referenced by SDL_iconv_open().

int format

Definition at line 136 of file SDL_iconv.c.

const char* name

Definition at line 135 of file SDL_iconv.c.