Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
3.5 KiB

  1. /*
  2. * UNI2UTF -- Unicode to/from UTF conversions
  3. *
  4. * Copyright (C) 1996, Microsoft Corporation. All rights reserved.
  5. *
  6. * History:
  7. *
  8. * 10-14-96 msliger Created.
  9. */
  10. #include <stdio.h>
  11. #include "uni2utf.h" /* prototype verification */
  12. /*
  13. * Unicode2UTF()
  14. *
  15. * This function converts any 0-terminated Unicode string to the corresponding
  16. * nul-terminated UTF string, and returns a pointer to the resulting string.
  17. * The pointer references a single, static internal buffer, so the result will
  18. * be destroyed on the next call.
  19. *
  20. * If the generated UTF string would be too long, NULL is returned.
  21. */
  22. char *Unicode2UTF(const wchar_t *unicode)
  23. {
  24. static char utfbuffer[MAX_UTF_LENGTH + 4];
  25. int utfindex = 0;
  26. while (*unicode != 0)
  27. {
  28. if (utfindex >= MAX_UTF_LENGTH)
  29. {
  30. return(NULL);
  31. }
  32. if (*unicode < 0x0080)
  33. {
  34. utfbuffer[utfindex++] = (char) *unicode;
  35. }
  36. else if (*unicode < 0x0800)
  37. {
  38. utfbuffer[utfindex++] = (char) (0xC0 + (*unicode >> 6));
  39. utfbuffer[utfindex++] = (char) (0x80 + (*unicode & 0x3F));
  40. }
  41. else
  42. {
  43. utfbuffer[utfindex++] = (char) (0xE0 + (*unicode >> 12));
  44. utfbuffer[utfindex++] = (char) (0x80 + ((*unicode >> 6) & 0x3F));
  45. utfbuffer[utfindex++] = (char) (0x80 + (*unicode & 0x3F));
  46. }
  47. unicode++;
  48. }
  49. utfbuffer[utfindex] = '\0';
  50. return(utfbuffer);
  51. }
  52. /*
  53. * UTF2Unicode()
  54. *
  55. * This function converts a valid UTF string into the corresponding unicode string,
  56. * and returns a pointer to the resulting unicode. The pointer references a single,
  57. * internal static buffer, which will be destroyed on the next call.
  58. *
  59. * If the generated unicode string would be too long, or if the UTF string contains
  60. * any illegal UTF values, NULL is returned.
  61. */
  62. wchar_t *UTF2Unicode(const char *utfString)
  63. {
  64. static wchar_t unicodebuffer[MAX_UNICODE_LENGTH + 1];
  65. int unicodeindex = 0;
  66. int c;
  67. while (*utfString != 0)
  68. {
  69. if (unicodeindex >= MAX_UNICODE_LENGTH)
  70. {
  71. return(NULL);
  72. }
  73. c = (*utfString++ & 0x00FF);
  74. if (c < 0x0080)
  75. {
  76. unicodebuffer[unicodeindex] = (unsigned short) c;
  77. }
  78. else if (c < 0x00C0)
  79. {
  80. return(NULL); /* 0x0080..0x00BF illegal */
  81. }
  82. else if (c < 0x00E0)
  83. {
  84. unicodebuffer[unicodeindex] = (unsigned short) ((c & 0x001F) << 6);
  85. c = (*utfString++ & 0x00FF);
  86. if ((c < 0x0080) || (c > 0x00BF))
  87. {
  88. return(NULL); /* trail must be 0x0080..0x00BF */
  89. }
  90. unicodebuffer[unicodeindex] |= (c & 0x003F);
  91. }
  92. else if (c < 0x00F0)
  93. {
  94. unicodebuffer[unicodeindex] = (unsigned short) ((c & 0x000F) << 12);
  95. c = (*utfString++ & 0x00FF);
  96. if ((c < 0x0080) || (c > 0x00BF))
  97. {
  98. return(NULL); /* trails must be 0x0080..0x00BF */
  99. }
  100. unicodebuffer[unicodeindex] |= ((c & 0x003F) << 6);
  101. c = (*utfString++ & 0x00FF);
  102. if ((c < 0x0080) || (c > 0x00BF))
  103. {
  104. return(NULL); /* trails must be 0x0080..0x00BF */
  105. }
  106. unicodebuffer[unicodeindex] |= (c & 0x003F);
  107. }
  108. else
  109. {
  110. return(NULL); /* lead can't be > 0x00EF */
  111. }
  112. unicodeindex++;
  113. }
  114. unicodebuffer[unicodeindex] = 0;
  115. return(unicodebuffer);
  116. }