123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- #include <errno.h>
- #include <string.h>
- #include <iconv.h>
- #include "conv.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;
- }
|