红联Linux门户
Linux帮助

Linux下UTF 32和UTF 16互相转换代码

发布时间:2015-01-30 09:53:07来源:linux网站作者:richie12

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