#include #include #include #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; }