|
@@ -0,0 +1,262 @@
|
|
|
|
+#include <errno.h>
|
|
|
|
+#include <string.h>
|
|
|
|
+#include <iconv.h>
|
|
|
|
+#include "suconv.h"
|
|
|
|
+
|
|
|
|
+#ifndef __BYTE_ORDER__
|
|
|
|
+#error __BYTE_ORDER__ not defined!
|
|
|
|
+#endif // __BYTE_ORDER__
|
|
|
|
+
|
|
|
|
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
|
|
+#define _UTF_16 "UTF-16LE//"
|
|
|
|
+#define _UTF_32 "UTF-32LE//"
|
|
|
|
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
|
|
|
+#define _UTF_16 "UTF-16BE//"
|
|
|
|
+#define _UTF_32 "UTF-32BE//"
|
|
|
|
+#else // __BYTE_ORDER__
|
|
|
|
+#error Invalid Byte Order!
|
|
|
|
+#endif // __BYTE_ORDER__
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+static size_t _Conv(iconv_t cd, char **pszIn, size_t nCbIn, char **pszOut, size_t nCbOut, size_t *pnTruncated)
|
|
|
|
+{
|
|
|
|
+ size_t nRet = nCbOut;
|
|
|
|
+ iconv(cd, pszIn, &nCbIn, pszOut, &nCbOut);
|
|
|
|
+ if(pnTruncated)
|
|
|
|
+ *pnTruncated = nCbIn;
|
|
|
|
+ return nRet - nCbOut;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+size_t wcs16len(const char16_t *psz)
|
|
|
|
+{
|
|
|
|
+ const char16_t *p = psz;
|
|
|
|
+ while(*p)
|
|
|
|
+ p++;
|
|
|
|
+ return (size_t)(p - psz);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+size_t wcs32len(const char32_t *psz)
|
|
|
|
+{
|
|
|
|
+ const char32_t *p = psz;
|
|
|
|
+ while(*p)
|
|
|
|
+ p++;
|
|
|
|
+ return (size_t)(p - psz);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+size_t EncToUtf8(const char *pszEncIn, const void *pszIn, size_t nCbIn, char *pszOut, size_t nCbOut)
|
|
|
|
+{
|
|
|
|
+ if(pszEncIn && pszIn && pszOut && nCbOut && nCbIn != (size_t)-1)
|
|
|
|
+ {
|
|
|
|
+ iconv_t desc = iconv_open("UTF-8//", pszEncIn);
|
|
|
|
+
|
|
|
|
+ if(desc != (iconv_t)-1)
|
|
|
|
+ {
|
|
|
|
+ size_t nRet;
|
|
|
|
+ size_t nTrunc;
|
|
|
|
+ char *pIn = (char*)pszIn;
|
|
|
|
+ memset(pszOut, 0, nCbOut);
|
|
|
|
+ nRet = _Conv(desc, &pIn, nCbIn, &pszOut, nCbOut - 1, &nTrunc);
|
|
|
|
+ iconv_close(desc);
|
|
|
|
+ return nRet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+size_t Utf8ToLatin1(const char *pszIn, size_t nCbIn, char *pszOut, size_t nCbOut)
|
|
|
|
+{
|
|
|
|
+ if(pszIn && pszOut && nCbOut)
|
|
|
|
+ {
|
|
|
|
+ iconv_t desc = iconv_open("LATIN1//", "UTF-8//");
|
|
|
|
+
|
|
|
|
+ if(desc != (iconv_t)-1)
|
|
|
|
+ {
|
|
|
|
+ size_t nRet;
|
|
|
|
+ size_t nTrunc;
|
|
|
|
+ char *pIn = (char*)pszIn;
|
|
|
|
+ if(nCbIn == (size_t)-1)
|
|
|
|
+ nCbIn = strlen(pszIn);
|
|
|
|
+ memset(pszOut, 0, nCbOut);
|
|
|
|
+ nRet = _Conv(desc, &pIn, nCbIn, &pszOut, nCbOut - 1, &nTrunc);
|
|
|
|
+ iconv_close(desc);
|
|
|
|
+ return nRet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+size_t Latin1ToUtf8(const char *pszIn, size_t nCbIn, char *pszOut, size_t nCbOut)
|
|
|
|
+{
|
|
|
|
+ if(pszIn && pszOut && nCbOut)
|
|
|
|
+ {
|
|
|
|
+ iconv_t desc = iconv_open("UTF-8//", "LATIN1//");
|
|
|
|
+
|
|
|
|
+ if(desc != (iconv_t)-1)
|
|
|
|
+ {
|
|
|
|
+ size_t nRet;
|
|
|
|
+ size_t nTrunc;
|
|
|
|
+ char *pIn = (char*)pszIn;
|
|
|
|
+ if(nCbIn == (size_t)-1)
|
|
|
|
+ nCbIn = strlen(pszIn);
|
|
|
|
+ memset(pszOut, 0, nCbOut);
|
|
|
|
+ nRet = _Conv(desc, &pIn, nCbIn, &pszOut, nCbOut - 1, &nTrunc);
|
|
|
|
+ iconv_close(desc);
|
|
|
|
+ return nRet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+size_t Utf8ToUtf16(const char *pszIn, size_t nCbIn, char16_t *pszOut, size_t nCChOut)
|
|
|
|
+{
|
|
|
|
+ if(pszIn && pszOut && nCChOut)
|
|
|
|
+ {
|
|
|
|
+ iconv_t desc = iconv_open(_UTF_16, "UTF-8//");
|
|
|
|
+
|
|
|
|
+ if(desc != (iconv_t)-1)
|
|
|
|
+ {
|
|
|
|
+ size_t nRet;
|
|
|
|
+ size_t nTrunc;
|
|
|
|
+ char *pIn = (char*)pszIn;
|
|
|
|
+ if(nCbIn == (size_t)-1)
|
|
|
|
+ nCbIn = strlen(pszIn);
|
|
|
|
+ memset(pszOut, 0, nCChOut * sizeof(char16_t));
|
|
|
|
+ nRet = _Conv(desc, &pIn, nCbIn, (char**)&pszOut, (nCChOut - 1) * sizeof(char16_t), &nTrunc);
|
|
|
|
+ iconv_close(desc);
|
|
|
|
+ return nRet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+size_t Utf16ToUtf8(const char16_t *pszIn, size_t nCChIn, char *pszOut, size_t nCbOut)
|
|
|
|
+{
|
|
|
|
+ if(pszIn && pszOut && nCbOut)
|
|
|
|
+ {
|
|
|
|
+ iconv_t desc = iconv_open("UTF-8//", _UTF_16);
|
|
|
|
+
|
|
|
|
+ if(desc != (iconv_t)-1)
|
|
|
|
+ {
|
|
|
|
+ size_t nRet;
|
|
|
|
+ size_t nTrunc;
|
|
|
|
+ char *pIn = (char*)pszIn;
|
|
|
|
+ if(nCChIn == (size_t)-1)
|
|
|
|
+ nCChIn = wcs16len(pszIn);
|
|
|
|
+ memset(pszOut, 0, nCbOut);
|
|
|
|
+ nRet = _Conv(desc, &pIn, nCChIn * sizeof(char16_t), &pszOut, nCbOut - 1, &nTrunc);
|
|
|
|
+ iconv_close(desc);
|
|
|
|
+ return nRet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+size_t Utf8ToUtf32(const char *pszIn, size_t nCbIn, char32_t *pszOut, size_t nCChOut)
|
|
|
|
+{
|
|
|
|
+ if(pszIn && pszOut && nCChOut)
|
|
|
|
+ {
|
|
|
|
+ iconv_t desc = iconv_open(_UTF_32, "UTF-8//");
|
|
|
|
+
|
|
|
|
+ if(desc != (iconv_t)-1)
|
|
|
|
+ {
|
|
|
|
+ size_t nRet;
|
|
|
|
+ size_t nTrunc;
|
|
|
|
+ char *pIn = (char*)pszIn;
|
|
|
|
+ if(nCbIn == (size_t)-1)
|
|
|
|
+ nCbIn = strlen(pszIn);
|
|
|
|
+ memset(pszOut, 0, nCChOut * sizeof(char32_t));
|
|
|
|
+ nRet = _Conv(desc, &pIn, nCbIn, (char**)&pszOut, (nCChOut - 1) * sizeof(char32_t), &nTrunc);
|
|
|
|
+ iconv_close(desc);
|
|
|
|
+ return nRet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+size_t Utf32ToUtf8(const char32_t *pszIn, size_t nCChIn, char *pszOut, size_t nCbOut)
|
|
|
|
+{
|
|
|
|
+ if(pszIn && pszOut && nCbOut)
|
|
|
|
+ {
|
|
|
|
+ iconv_t desc = iconv_open("UTF-8//", _UTF_32);
|
|
|
|
+
|
|
|
|
+ if(desc != (iconv_t)-1)
|
|
|
|
+ {
|
|
|
|
+ size_t nRet;
|
|
|
|
+ size_t nTrunc;
|
|
|
|
+ char *pIn = (char*)pszIn;
|
|
|
|
+ if(nCChIn == (size_t)-1)
|
|
|
|
+ nCChIn = wcs32len(pszIn);
|
|
|
|
+ memset(pszOut, 0, nCbOut);
|
|
|
|
+ nRet = _Conv(desc, &pIn, nCChIn * sizeof(char32_t), &pszOut, nCbOut - 1, &nTrunc);
|
|
|
|
+ iconv_close(desc);
|
|
|
|
+ return nRet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+size_t Utf8ToWcs(const char *pszIn, size_t nCbIn, wchar_t *pszOut, size_t nCChOut)
|
|
|
|
+{
|
|
|
|
+ if(pszIn && pszOut && nCChOut)
|
|
|
|
+ {
|
|
|
|
+ iconv_t desc = iconv_open("WCHAR_T//", "UTF-8//");
|
|
|
|
+
|
|
|
|
+ if(desc != (iconv_t)-1)
|
|
|
|
+ {
|
|
|
|
+ size_t nRet;
|
|
|
|
+ size_t nTrunc;
|
|
|
|
+ char *pIn = (char*)pszIn;
|
|
|
|
+ if(nCbIn == (size_t)-1)
|
|
|
|
+ nCbIn = strlen(pszIn);
|
|
|
|
+ memset(pszOut, 0, nCChOut * sizeof(wchar_t));
|
|
|
|
+ nRet = _Conv(desc, &pIn, nCbIn, (char**)&pszOut, (nCChOut - 1) * sizeof(wchar_t), &nTrunc);
|
|
|
|
+ iconv_close(desc);
|
|
|
|
+ return nRet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+size_t WcsToUtf8(const wchar_t *pszIn, size_t nCChIn, char *pszOut, size_t nCbOut)
|
|
|
|
+{
|
|
|
|
+ if(pszIn && pszOut && nCbOut)
|
|
|
|
+ {
|
|
|
|
+ iconv_t desc = iconv_open("UTF-8//", "WCHAR_T//");
|
|
|
|
+
|
|
|
|
+ if(desc != (iconv_t)-1)
|
|
|
|
+ {
|
|
|
|
+ size_t nRet;
|
|
|
|
+ size_t nTrunc;
|
|
|
|
+ char *pIn = (char*)pszIn;
|
|
|
|
+ if(nCChIn == (size_t)-1)
|
|
|
|
+ nCChIn = wcslen(pszIn);
|
|
|
|
+ memset(pszOut, 0, nCbOut);
|
|
|
|
+ nRet = _Conv(desc, &pIn, nCChIn * sizeof(wchar_t), &pszOut, nCbOut - 1, &nTrunc);
|
|
|
|
+ iconv_close(desc);
|
|
|
|
+ return nRet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|