Linux下UTF 32和UTF 16互相转换代码:
#define DECLARE_WCS2UTF16CONV int _len; (_len); wchar_t * _wcs; (_wcs); unsigned short * _utf16; (_utf16)
#define WCS2UTF16(wcs) \
(((_wcs = wcs) == NULL) ? NULL : (\
_len = (utf16len(_wcs)+1),\
wcs2utf16(_wcs, (unsigned short *) alloca(_len*2), _len)))
#define UTF162WCS(utf16) \
(((_utf16 = utf16) == NULL) ? NULL : (\
_len = (xwcslen(_utf16)+1),\
utf162wcs(_utf16,(wchar_t *)alloca(_len*2),_len)))
unsigned short * wcs2utf16(wchar_t *wcs, unsigned short * utf16, int len)
{
int wc;
wchar_t *end = wcs + len;
unsigned short * ret = utf16;
while(wcs < end)
{
wc = *(wcs++);
if (wc > 0xFFFF)
{
wc -= 0x0010000UL;
*utf16++ = 0xD800 | (wc >> 10);
*utf16++ = 0xDC00 | (wc & 0x03FF);
}
else
{
*utf16++ = wc;
}
}
return ret;
}
wchar_t * utf162wcs(unsigned short * utf16,wchar_t *wcs,int len)
{
int utf;
unsigned short h;
unsigned short l;
wchar_t * ret = wcs;
while(utf = *utf16++)
{
if(utf<0xD800||utf>0xDFFF)
{
*wcs++ = utf;
}
else
{
h = utf - 0xD800;
l = *(utf16++) - 0xDC00;
*wcs++ = ((h<<10) | l ) + 0x10000;
}
}
return ret;
}
int xwcslen(unsigned short *utf16)
{
int utf;
int ret = 0;
while(utf = *utf16++)
ret += ((utf < 0xD800) || (utf > 0xDFFF)) ? 2 :1;
return ret;
}
int utf16len(wchar_t *wcs)
{
int wc;
int ret = 0;
while(wc = *wcs++)
ret += wc > 0xFFFF ? 2 : 1;
return ret;
}