conv.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. #include <errno.h>
  2. #include <string.h>
  3. #include <iconv.h>
  4. #include "conv.h"
  5. #ifndef __BYTE_ORDER__
  6. #error __BYTE_ORDER__ not defined!
  7. #endif // __BYTE_ORDER__
  8. #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  9. #define _UTF_16 "UTF-16LE//"
  10. #define _UTF_32 "UTF-32LE//"
  11. #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  12. #define _UTF_16 "UTF-16BE//"
  13. #define _UTF_32 "UTF-32BE//"
  14. #else // __BYTE_ORDER__
  15. #error Invalid Byte Order!
  16. #endif // __BYTE_ORDER__
  17. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  18. static size_t _Conv(iconv_t cd, char **pszIn, size_t nCbIn, char **pszOut, size_t nCbOut, size_t *pnTruncated)
  19. {
  20. size_t nRet = nCbOut;
  21. iconv(cd, pszIn, &nCbIn, pszOut, &nCbOut);
  22. if(pnTruncated)
  23. *pnTruncated = nCbIn;
  24. return nRet - nCbOut;
  25. }
  26. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  27. size_t wcs16len(const char16_t *psz)
  28. {
  29. const char16_t *p = psz;
  30. while(*p)
  31. p++;
  32. return (size_t)(p - psz);
  33. }
  34. size_t wcs32len(const char32_t *psz)
  35. {
  36. const char32_t *p = psz;
  37. while(*p)
  38. p++;
  39. return (size_t)(p - psz);
  40. }
  41. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  42. size_t EncToUtf8(const char *pszEncIn, const void *pszIn, size_t nCbIn, char *pszOut, size_t nCbOut)
  43. {
  44. if(pszEncIn && pszIn && pszOut && nCbOut && nCbIn != (size_t)-1)
  45. {
  46. iconv_t desc = iconv_open("UTF-8//", pszEncIn);
  47. if(desc != (iconv_t)-1)
  48. {
  49. size_t nRet;
  50. size_t nTrunc;
  51. char *pIn = (char*)pszIn;
  52. memset(pszOut, 0, nCbOut);
  53. nRet = _Conv(desc, &pIn, nCbIn, &pszOut, nCbOut - 1, &nTrunc);
  54. iconv_close(desc);
  55. return nRet;
  56. }
  57. }
  58. return 0;
  59. }
  60. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  61. size_t Utf8ToLatin1(const char *pszIn, size_t nCbIn, char *pszOut, size_t nCbOut)
  62. {
  63. if(pszIn && pszOut && nCbOut)
  64. {
  65. iconv_t desc = iconv_open("LATIN1//", "UTF-8//");
  66. if(desc != (iconv_t)-1)
  67. {
  68. size_t nRet;
  69. size_t nTrunc;
  70. char *pIn = (char*)pszIn;
  71. if(nCbIn == (size_t)-1)
  72. nCbIn = strlen(pszIn);
  73. memset(pszOut, 0, nCbOut);
  74. nRet = _Conv(desc, &pIn, nCbIn, &pszOut, nCbOut - 1, &nTrunc);
  75. iconv_close(desc);
  76. return nRet;
  77. }
  78. }
  79. return 0;
  80. }
  81. size_t Latin1ToUtf8(const char *pszIn, size_t nCbIn, char *pszOut, size_t nCbOut)
  82. {
  83. if(pszIn && pszOut && nCbOut)
  84. {
  85. iconv_t desc = iconv_open("UTF-8//", "LATIN1//");
  86. if(desc != (iconv_t)-1)
  87. {
  88. size_t nRet;
  89. size_t nTrunc;
  90. char *pIn = (char*)pszIn;
  91. if(nCbIn == (size_t)-1)
  92. nCbIn = strlen(pszIn);
  93. memset(pszOut, 0, nCbOut);
  94. nRet = _Conv(desc, &pIn, nCbIn, &pszOut, nCbOut - 1, &nTrunc);
  95. iconv_close(desc);
  96. return nRet;
  97. }
  98. }
  99. return 0;
  100. }
  101. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  102. size_t Utf8ToUtf16(const char *pszIn, size_t nCbIn, char16_t *pszOut, size_t nCChOut)
  103. {
  104. if(pszIn && pszOut && nCChOut)
  105. {
  106. iconv_t desc = iconv_open(_UTF_16, "UTF-8//");
  107. if(desc != (iconv_t)-1)
  108. {
  109. size_t nRet;
  110. size_t nTrunc;
  111. char *pIn = (char*)pszIn;
  112. if(nCbIn == (size_t)-1)
  113. nCbIn = strlen(pszIn);
  114. memset(pszOut, 0, nCChOut * sizeof(char16_t));
  115. nRet = _Conv(desc, &pIn, nCbIn, (char**)&pszOut, (nCChOut - 1) * sizeof(char16_t), &nTrunc);
  116. iconv_close(desc);
  117. return nRet;
  118. }
  119. }
  120. return 0;
  121. }
  122. size_t Utf16ToUtf8(const char16_t *pszIn, size_t nCChIn, char *pszOut, size_t nCbOut)
  123. {
  124. if(pszIn && pszOut && nCbOut)
  125. {
  126. iconv_t desc = iconv_open("UTF-8//", _UTF_16);
  127. if(desc != (iconv_t)-1)
  128. {
  129. size_t nRet;
  130. size_t nTrunc;
  131. char *pIn = (char*)pszIn;
  132. if(nCChIn == (size_t)-1)
  133. nCChIn = wcs16len(pszIn);
  134. memset(pszOut, 0, nCbOut);
  135. nRet = _Conv(desc, &pIn, nCChIn * sizeof(char16_t), &pszOut, nCbOut - 1, &nTrunc);
  136. iconv_close(desc);
  137. return nRet;
  138. }
  139. }
  140. return 0;
  141. }
  142. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  143. size_t Utf8ToUtf32(const char *pszIn, size_t nCbIn, char32_t *pszOut, size_t nCChOut)
  144. {
  145. if(pszIn && pszOut && nCChOut)
  146. {
  147. iconv_t desc = iconv_open(_UTF_32, "UTF-8//");
  148. if(desc != (iconv_t)-1)
  149. {
  150. size_t nRet;
  151. size_t nTrunc;
  152. char *pIn = (char*)pszIn;
  153. if(nCbIn == (size_t)-1)
  154. nCbIn = strlen(pszIn);
  155. memset(pszOut, 0, nCChOut * sizeof(char32_t));
  156. nRet = _Conv(desc, &pIn, nCbIn, (char**)&pszOut, (nCChOut - 1) * sizeof(char32_t), &nTrunc);
  157. iconv_close(desc);
  158. return nRet;
  159. }
  160. }
  161. return 0;
  162. }
  163. size_t Utf32ToUtf8(const char32_t *pszIn, size_t nCChIn, char *pszOut, size_t nCbOut)
  164. {
  165. if(pszIn && pszOut && nCbOut)
  166. {
  167. iconv_t desc = iconv_open("UTF-8//", _UTF_32);
  168. if(desc != (iconv_t)-1)
  169. {
  170. size_t nRet;
  171. size_t nTrunc;
  172. char *pIn = (char*)pszIn;
  173. if(nCChIn == (size_t)-1)
  174. nCChIn = wcs32len(pszIn);
  175. memset(pszOut, 0, nCbOut);
  176. nRet = _Conv(desc, &pIn, nCChIn * sizeof(char32_t), &pszOut, nCbOut - 1, &nTrunc);
  177. iconv_close(desc);
  178. return nRet;
  179. }
  180. }
  181. return 0;
  182. }
  183. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  184. size_t Utf8ToWcs(const char *pszIn, size_t nCbIn, wchar_t *pszOut, size_t nCChOut)
  185. {
  186. if(pszIn && pszOut && nCChOut)
  187. {
  188. iconv_t desc = iconv_open("WCHAR_T//", "UTF-8//");
  189. if(desc != (iconv_t)-1)
  190. {
  191. size_t nRet;
  192. size_t nTrunc;
  193. char *pIn = (char*)pszIn;
  194. if(nCbIn == (size_t)-1)
  195. nCbIn = strlen(pszIn);
  196. memset(pszOut, 0, nCChOut * sizeof(wchar_t));
  197. nRet = _Conv(desc, &pIn, nCbIn, (char**)&pszOut, (nCChOut - 1) * sizeof(wchar_t), &nTrunc);
  198. iconv_close(desc);
  199. return nRet;
  200. }
  201. }
  202. return 0;
  203. }
  204. size_t WcsToUtf8(const wchar_t *pszIn, size_t nCChIn, char *pszOut, size_t nCbOut)
  205. {
  206. if(pszIn && pszOut && nCbOut)
  207. {
  208. iconv_t desc = iconv_open("UTF-8//", "WCHAR_T//");
  209. if(desc != (iconv_t)-1)
  210. {
  211. size_t nRet;
  212. size_t nTrunc;
  213. char *pIn = (char*)pszIn;
  214. if(nCChIn == (size_t)-1)
  215. nCChIn = wcslen(pszIn);
  216. memset(pszOut, 0, nCbOut);
  217. nRet = _Conv(desc, &pIn, nCChIn * sizeof(wchar_t), &pszOut, nCbOut - 1, &nTrunc);
  218. iconv_close(desc);
  219. return nRet;
  220. }
  221. }
  222. return 0;
  223. }