Code:
// Converts UTF-8 string to UTF-16
WCHAR *utf8_to_utf16 (const char *utf8, WCHAR *_utf16)
{
WCHAR *utf16 = _utf16;
do {
BYTE c = utf8[0]; UINT c32;
if (c<=0x7F) c32 = c;
else if (c<=0xBF) c32 = '?';
else if (c<=0xDF) c32 = ((c&0x1F) << 6) + (utf8[1]&0x3F), utf8++;
else if (c<=0xEF) c32 = ((c&0x0F) <<12) + ((utf8[1]&0x3F) << 6) + (utf8[2]&0x3F), utf8+=2;
else c32 = ((c&0x0F) <<18) + ((utf8[1]&0x3F) <<12) + ((utf8[2]&0x3F) << 6) + (utf8[3]&0x3F), utf8+=3;
// Now c32 represents full 32-bit Unicode char
if (c32 <= 0xFFFF) *utf16++ = c32;
else c32-=0x10000, *utf16++ = c32/0x400 + 0xd800, *utf16++ = c32%0x400 + 0xdc00;
} while (*utf8++);
return _utf16;
}
// Converts UTF-16 string to UTF-8
char *utf16_to_utf8 (const WCHAR *utf16, char *_utf8)
{
char *utf8 = _utf8;
do {
UINT c = utf16[0];
if (0xd800<=c && c<=0xdbff && 0xdc00<=utf16[1] && utf16[1]<=0xdfff)
c = (c - 0xd800)*0x400 + (UINT)(*++utf16 - 0xdc00) + 0x10000;
// Now c represents full 32-bit Unicode char
if (c<=0x7F) *utf8++ = c;
else if (c<=0x07FF) *utf8++ = 0xC0|(c>> 6)&0x1F, *utf8++ = 0x80|(c>> 0)&0x3F;
else if (c<=0xFFFF) *utf8++ = 0xE0|(c>>12)&0x0F, *utf8++ = 0x80|(c>> 6)&0x3F, *utf8++ = 0x80|(c>> 0)&0x3F;
else *utf8++ = 0xF0|(c>>18)&0x0F, *utf8++ = 0x80|(c>>12)&0x3F, *utf8++ = 0x80|(c>> 6)&0x3F, *utf8++ = 0x80|(c>> 0)&0x3F;
} while (*utf16++);
return _utf8;
}