UNICODE(UTF-16)与UTF-8编码的相互转换

时间:2023-01-11 12:14:23

我们通常所说的UNICODE其实是UTF-16,下面这几个函数实现UNICODE(UTF-16)与UTF-8编码的相互转换。

[cpp] view plaincopy
  1. /** 
  2.  * This file implement functions of: 
  3.  * 
  4.  * 1. UTF-16 character to UTF-8 chaaracter converting. 
  5.  * 2. UTF-8 character to UTF-16 character converting. 
  6.  * 
  7.  * 3. UTF-16 string to UTF-8 string converting. 
  8.  * 4. UTF-8 string to UTF-16 string converting. 
  9.  */  
  10. /* Maximum bytes of a utf-8 character */  
  11. #define MAX_CHARACTER_SIZE    8  
  12. /** 
  13.  * UnicodeToUTF8 - convert unicode char to UTF-8 char 
  14.  * @unicode: a UNICODE(utf-16) character 
  15.  * @p: a buffer to contain a utf-8 characters 
  16.  * 
  17.  * @return: One step over the end of the utf-8 character buffer 
  18.  */  
  19. unsigned char * UnicodeToUTF8( int unicode, unsigned char *p)  
  20. {  
  21.     unsigned char *e = NULL;  
  22.     if((e = p))  
  23.     {  
  24.         if(unicode < 0x80)  
  25.         {  
  26.             *e++ = unicode;  
  27.         }  
  28.         else if(unicode < 0x800)  
  29.         {  
  30.             /* <11011111> < 000 0000 0000> */  
  31.             *e++ = ((unicode >> 6) & 0x1f)|0xc0;  
  32.             *e++ = (unicode & 0x3f)|0x80;   
  33.         }  
  34.         else if(unicode < 0x10000)  
  35.         {  
  36.             /* <11101111> <0000 0000 0000 0000> */  
  37.             *e++ = ((unicode >> 12) & 0x0f)|0xe0;   
  38.             *e++ = ((unicode >> 6) & 0x3f)|0x80;  
  39.             *e++ = (unicode & 0x3f)|0x80;   
  40.         }  
  41.         else if(unicode < 0x200000)  
  42.         {  
  43.             /* <11110111> <0 0000 0000 0000 0000 0000> */  
  44.             *e++ = ((unicode >> 18) & 0x07)|0xf0;   
  45.             *e++ = ((unicode >> 12) & 0x3f)|0x80;  
  46.             *e++ = ((unicode >> 6) & 0x3f)|0x80;  
  47.             *e++ = (unicode & 0x3f)|0x80;   
  48.         }  
  49.         else if(unicode < 0x4000000)  
  50.         {  
  51.             /* <11111011> <00 0000 0000 0000 0000 0000 0000> */  
  52.             *e++ = ((unicode >> 24) & 0x03)|0xf8 ;   
  53.             *e++ = ((unicode >> 18) & 0x3f)|0x80;  
  54.             *e++ = ((unicode >> 12) & 0x3f)|0x80;  
  55.             *e++ = ((unicode >> 6) & 0x3f)|0x80;  
  56.             *e++ = (unicode & 0x3f)|0x80;   
  57.         }  
  58.         else  
  59.         {  
  60.             /* <11111101> <0000 0000 0000 0000 0000 0000 0000 0000> */  
  61.             *e++ = ((unicode >> 30) & 0x01)|0xfc;   
  62.             *e++ = ((unicode >> 24) & 0x3f)|0x80;  
  63.             *e++ = ((unicode >> 18) & 0x3f)|0x80;  
  64.             *e++ = ((unicode >> 12) & 0x3f)|0x80;  
  65.             *e++ = ((unicode >> 6) & 0x3f)|0x80;  
  66.             *e++ = (unicode & 0x3f)|0x80;   
  67.         }  
  68.     }  
  69.     /* Return One step over the end of the utf-8 character buffer */  
  70.     return e;  
  71. }  
  72. /** 
  73.  * UTF8ToUnicode - convert UTF-8 char to unicode char 
  74.  * @ch: A buffer contain a utf-8 character 
  75.  * @unicode: Contain the converted utf-16 character 
  76.  * 
  77.  * @return: Bytes count of the utf-8 character (1 ~ 6), 
  78.  *          can be used to step to next utf-8 character when convert a utf-8 string to a utf-16 string 
  79.  */  
  80. int UTF8ToUnicode (unsigned char *ch, int *unicode)  
  81. {  
  82.     unsigned char *p = NULL;  
  83.     int e = 0, n = 0;  
  84.     if((p = ch) && unicode)  
  85.     {  
  86.         if(*p >= 0xfc)  
  87.         {  
  88.             /* 6:<11111100> */  
  89.             e = (p[0] & 0x01) << 30;  
  90.             e |= (p[1] & 0x3f) << 24;  
  91.             e |= (p[2] & 0x3f) << 18;  
  92.             e |= (p[3] & 0x3f) << 12;  
  93.             e |= (p[4] & 0x3f) << 6;  
  94.             e |= (p[5] & 0x3f);  
  95.             n = 6;  
  96.         }  
  97.         else if(*p >= 0xf8)   
  98.         {  
  99.             /* 5:<11111000> */  
  100.             e = (p[0] & 0x03) << 24;  
  101.             e |= (p[1] & 0x3f) << 18;  
  102.             e |= (p[2] & 0x3f) << 12;  
  103.             e |= (p[3] & 0x3f) << 6;  
  104.             e |= (p[4] & 0x3f);  
  105.             n = 5;  
  106.         }  
  107.         else if(*p >= 0xf0)  
  108.         {  
  109.             /* 4:<11110000> */  
  110.             e = (p[0] & 0x07) << 18;  
  111.             e |= (p[1] & 0x3f) << 12;  
  112.             e |= (p[2] & 0x3f) << 6;  
  113.             e |= (p[3] & 0x3f);  
  114.             n = 4;  
  115.         }  
  116.         else if(*p >= 0xe0)  
  117.         {  
  118.             /* 3:<11100000> */  
  119.             e = (p[0] & 0x0f) << 12;  
  120.             e |= (p[1] & 0x3f) << 6;  
  121.             e |= (p[2] & 0x3f);  
  122.             n = 3;  
  123.         }  
  124.         else if(*p >= 0xc0)   
  125.         {  
  126.             /* 2:<11000000> */  
  127.             e = (p[0] & 0x1f) << 6;  
  128.             e |= (p[1] & 0x3f);  
  129.             n = 2;  
  130.         }  
  131.         else   
  132.         {  
  133.             e = p[0];  
  134.             n = 1;  
  135.         }  
  136.         *unicode = e;  
  137.     }  
  138.     /* Return bytes count of this utf-8 character */  
  139.     return n;  
  140. }  
  141. /** 
  142.  * UnicodeStrToUTF8Str - Convert a utf-16 string to a utf-8 string 
  143.  * @unicde_str: A utf-16 string 
  144.  * @utf8_str: A buffer to contain utf-8 string 
  145.  * @utf8_str_size: Maximum size of the utf-8 string buffer 
  146.  * 
  147.  * @return: One step over the end of the last utf-8 character 
  148.  */  
  149. unsigned char * UnicodeStrToUTF8Str (unsigned short * unicode_str,  
  150.                             unsigned char * utf8_str, int utf8_str_size)  
  151. {  
  152.     int unicode = 0;  
  153.     unsigned char *e = NULL, *s = NULL;  
  154.     unsigned char utf8_ch[MAX_CHARACTER_SIZE];   
  155.     s = utf8_str;  
  156.     if ((unicode_str) && (s))  
  157.     {  
  158.         while ((unicode = (int) (*unicode_str++)))  
  159.         {  
  160.             memset (utf8_ch, 0, sizeof (utf8_ch));  
  161.               
  162.             if ((e = UnicodeToUTF8 (unicode, utf8_ch)) > utf8_ch)  
  163.             {  
  164.                 *e = '/0';  
  165.                   
  166.                 /* Judge whether exceed the destination buffer */  
  167.                 if ((s - utf8_str + strlen ((const char *) utf8_ch)) >= utf8_str_size)  
  168.                 {  
  169.                     return s;  
  170.                 }  
  171.                 else  
  172.                 {  
  173.                     memcpy (s, utf8_ch, strlen ((const char *) utf8_ch));  
  174.                     s += strlen ((const char *) utf8_ch);  
  175.                     *s = '/0';  
  176.                 }  
  177.             }  
  178.             else  
  179.             {  
  180.                 /* Converting error occurs */  
  181.                 return s;  
  182.             }  
  183.         }  
  184.     }  
  185.       
  186.     return s;  
  187. }  
  188. /** 
  189.  * UTF8StrToUnicodeStr - Convert a utf-8 stirng to a utf-16 string 
  190.  * @utf8_str: A utf-8 string 
  191.  * @unicode_str: A buffer to contain utf-16 string 
  192.  * @unicode_str_size: Maximum size of the utf-16 string buffer 
  193.  * 
  194.  * @return: Number of utf-16 character 
  195.  */  
  196. int UTF8StrToUnicodeStr (unsigned char * utf8_str,  
  197.                     unsigned short * unicode_str, int unicode_str_size)  
  198. {  
  199.     int unicode = 0;  
  200.     int n = 0;  
  201.     int count = 0;  
  202.     unsigned char *s = NULL;  
  203.     unsigned short *e = NULL;  
  204.       
  205.     s = utf8_str;  
  206.     e = unicode_str;  
  207.       
  208.     if ((utf8_str) && (unicode_str))  
  209.     {  
  210.         while (*s)  
  211.         {  
  212.             if ((n = UTF8ToUnicode (s, &unicode)) > 0)  
  213.             {  
  214.                 if ((count + 1) >= unicode_str_size)  
  215.                 {  
  216.                     return count;  
  217.                 }  
  218.                 else  
  219.                 {  
  220.                     *e = (unsigned short) unicode;  
  221.                     e++;  
  222.                     *e = 0;  
  223.                       
  224.                     /* Step to next utf-8 character */  
  225.                     s += n;  
  226.                 }  
  227.             }  
  228.             else  
  229.             {  
  230.                 /* Converting error occurs */  
  231.                 return count;  
  232.             }  
  233.         }  
  234.     }  
  235.       
  236.     return count;  
  237. }