Leaked source code of windows server 2003
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.

186 lines
5.4 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1997
  6. //
  7. // File: utf8.cpp
  8. //
  9. // Contents: WideChar to/from UTF8 APIs
  10. //
  11. // Functions: WideCharToUTF8
  12. // UTF8ToWideChar
  13. //
  14. // History: 19-Feb-97 philh created
  15. //--------------------------------------------------------------------------
  16. #ifdef SMIME_V3
  17. #include <windows.h>
  18. #include <dbgdef.h>
  19. #include "utf8.h"
  20. #include "badstrfunctions.h"
  21. #define wcslen my_wcslen
  22. int my_wcslen(LPCWSTR pwsz);
  23. //+-------------------------------------------------------------------------
  24. // Maps a wide-character (Unicode) string to a new UTF-8 encoded character
  25. // string.
  26. //
  27. // The wide characters are mapped as follows:
  28. //
  29. // Start End Bits UTF-8 Characters
  30. // ------ ------ ---- --------------------------------
  31. // 0x0000 0x007F 7 0x0xxxxxxx
  32. // 0x0080 0x07FF 11 0x110xxxxx 0x10xxxxxx
  33. // 0x0800 0xFFFF 16 0x1110xxxx 0x10xxxxxx 0x10xxxxxx
  34. //
  35. // The parameter and return value semantics are the same as for the
  36. // Win32 API, WideCharToMultiByte.
  37. //
  38. // Note, starting with NT 4.0, WideCharToMultiByte supports CP_UTF8. CP_UTF8
  39. // isn't supported on Win95.
  40. //--------------------------------------------------------------------------
  41. int
  42. WINAPI
  43. WideCharToUTF8(
  44. IN LPCWSTR lpWideCharStr,
  45. IN int cchWideChar,
  46. OUT LPSTR lpUTF8Str,
  47. IN int cchUTF8
  48. )
  49. {
  50. int cchRemainUTF8;
  51. if (cchUTF8 < 0)
  52. goto InvalidParameter;
  53. cchRemainUTF8 = cchUTF8;
  54. if (cchWideChar < 0)
  55. cchWideChar = wcslen(lpWideCharStr) + 1;
  56. while (cchWideChar--) {
  57. WCHAR wch = *lpWideCharStr++;
  58. if (wch <= 0x7F) {
  59. // 7 bits
  60. cchRemainUTF8 -= 1;
  61. if (cchRemainUTF8 >= 0)
  62. *lpUTF8Str++ = (char) wch;
  63. } else if (wch <= 0x7FF) {
  64. // 11 bits
  65. cchRemainUTF8 -= 2;
  66. if (cchRemainUTF8 >= 0) {
  67. *lpUTF8Str++ = (char) (0xC0 | ((wch >> 6) & 0x1F));
  68. *lpUTF8Str++ = (char) (0x80 | (wch & 0x3F));
  69. }
  70. } else {
  71. // 16 bits
  72. cchRemainUTF8 -= 3;
  73. if (cchRemainUTF8 >= 0) {
  74. *lpUTF8Str++ = (char) (0xE0 | ((wch >> 12) & 0x0F));
  75. *lpUTF8Str++ = (char) (0x80 | ((wch >> 6) & 0x3F));
  76. *lpUTF8Str++ = (char) (0x80 | (wch & 0x3F));
  77. }
  78. }
  79. }
  80. if (cchRemainUTF8 >= 0)
  81. cchUTF8 = cchUTF8 - cchRemainUTF8;
  82. else if (cchUTF8 == 0)
  83. cchUTF8 = -cchRemainUTF8;
  84. else {
  85. cchUTF8 = 0;
  86. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  87. }
  88. return cchUTF8;
  89. InvalidParameter:
  90. SetLastError(ERROR_INVALID_PARAMETER);
  91. return 0;
  92. }
  93. //+-------------------------------------------------------------------------
  94. // Maps a UTF-8 encoded character string to a new wide-character (Unicode)
  95. // string.
  96. //
  97. // See CertWideCharToUTF8 for how the UTF-8 characters are mapped to wide
  98. // characters.
  99. //
  100. // The parameter and return value semantics are the same as for the
  101. // Win32 API, MultiByteToWideChar.
  102. //
  103. // If the UTF-8 characters don't contain the expected high order bits,
  104. // ERROR_INVALID_PARAMETER is set and 0 is returned.
  105. //
  106. // Note, starting with NT 4.0, MultiByteToWideChar supports CP_UTF8. CP_UTF8
  107. // isn't supported on Win95.
  108. //--------------------------------------------------------------------------
  109. int
  110. WINAPI
  111. UTF8ToWideChar(
  112. IN LPCSTR lpUTF8Str,
  113. IN int cchUTF8,
  114. OUT LPWSTR lpWideCharStr,
  115. IN int cchWideChar
  116. )
  117. {
  118. int cchRemainWideChar;
  119. if (cchWideChar < 0)
  120. goto InvalidParameter;
  121. cchRemainWideChar = cchWideChar;
  122. if (cchUTF8 < 0)
  123. cchUTF8 = strlen(lpUTF8Str) + 1;
  124. while (cchUTF8--) {
  125. char ch = *lpUTF8Str++;
  126. WCHAR wch;
  127. if (0 == (ch & 0x80))
  128. // 7 bits, 1 byte
  129. wch = (WCHAR) ch;
  130. else if (0xC0 == (ch & 0xE0)) {
  131. // 11 bits, 2 bytes
  132. char ch2;
  133. if (--cchUTF8 < 0)
  134. goto InvalidParameter;
  135. ch2 = *lpUTF8Str++;
  136. if (0x80 != (ch2 & 0xC0))
  137. goto InvalidParameter;
  138. wch = (((WCHAR) ch & 0x1F) << 6) | ((WCHAR) ch2 & 0x3F);
  139. } else if (0xE0 == (ch & 0xF0)) {
  140. // 16 bits, 3 bytes
  141. char ch2;
  142. char ch3;
  143. cchUTF8 -= 2;
  144. if (cchUTF8 < 0)
  145. goto InvalidParameter;
  146. ch2 = *lpUTF8Str++;
  147. ch3 = *lpUTF8Str++;
  148. if (0x80 != (ch2 & 0xC0) || 0x80 != (ch3 & 0xC0))
  149. goto InvalidParameter;
  150. wch = (((WCHAR) ch & 0x0F) << 12) | (((WCHAR) ch2 & 0x3F) << 6) |
  151. ((WCHAR) ch3 & 0x3F);
  152. } else
  153. goto InvalidParameter;
  154. if (--cchRemainWideChar >= 0)
  155. *lpWideCharStr++ = wch;
  156. }
  157. if (cchRemainWideChar >= 0)
  158. cchWideChar = cchWideChar - cchRemainWideChar;
  159. else if (cchWideChar == 0)
  160. cchWideChar = -cchRemainWideChar;
  161. else {
  162. cchWideChar = 0;
  163. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  164. }
  165. return cchWideChar;
  166. InvalidParameter:
  167. SetLastError(ERROR_INVALID_PARAMETER);
  168. return 0;
  169. }
  170. #endif //SMIME_V3