update: 调整mobile.scell函数的返回值为table,一次性返回足够多的信息, 并可以容纳更多信息
[LuatOS.git] / components / iconv / ucs2_to_gb2312.c
blob54f21bceb6746ce0b0e06291b655c57adee9244e
1 /**************************************************************************
2 * Copyright (C), AirM2M Tech. Co., Ltd.
4 * Name: ucs2_to_gb2312.c
5 * Author: liweiqiang
6 * Version: V0.1
7 * Date: 2013/7/15
9 * Description:
10 * ucs2 ת»» gb2312
11 **************************************************************************/
13 #include <stdint.h>
14 #include "stdio.h"
15 #include "errno.h"
17 #include "ucs2_to_gb2312_table.h"
18 #include "ucs2_to_gb2312_offset.h"
20 const uint8_t number_of_bit_1[256] =
22 0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03,
23 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
24 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
25 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
26 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
27 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
28 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
29 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
30 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
31 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
32 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
33 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
34 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
35 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
36 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
37 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
38 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
39 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
40 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
41 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
42 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
43 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
44 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
45 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
46 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
47 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
48 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
49 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
50 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
51 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
52 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
53 0x05, 0x06, 0x06, 0x07, 0x06, 0x07, 0x07, 0x08,
56 /* 0x4E00 <= ucs2 < 0xA000 */
57 static uint16_t get_ucs2_offset(uint16_t ucs2)
59 uint16_t offset, page, tmp;
60 uint8_t *mirror_ptr, ch;
62 page = (ucs2>>8) - 0x4E;
63 ucs2 &= 0xFF;
65 tmp = ucs2>>6; /* now 0 <= tmp < 4 */
66 offset = ucs2_index_table_4E00_9FFF[page][tmp];
67 mirror_ptr = (uint8_t*)&ucs2_mirror_4E00_9FFF[page][tmp<<3]; /* [0, 8, 16, 24] */
69 tmp = ucs2&0x3F; /* mod 64 */
71 while(tmp >= 8)
73 offset += number_of_bit_1[*mirror_ptr];
74 mirror_ptr++;
75 tmp -= 8;
78 ch = *mirror_ptr;
79 if(ch&(0x1<<tmp))
80 { /* Ok , this ucs2 can be covert to GB2312. */
81 while(tmp)
83 if(ch&0x1)
84 offset++;
85 ch>>=1;
86 tmp--;
88 return offset;
91 return (uint16_t)(-1);
94 uint16_t unicode_to_gb2312(uint16_t ucs2, uint8_t marks)
96 uint16_t gb = 0xA1A1;
97 if(0x80 > ucs2)
99 // can be convert to ASCII char
100 gb = ucs2;
102 else
104 if((0x4E00 <= ucs2) && (0xA000 > ucs2))
106 uint16_t offset = get_ucs2_offset(ucs2);
107 if((uint16_t)(-1) != offset)
109 gb = ucs2_to_gb2312_table[offset];
112 else if (marks == 0)
114 uint16_t u16count = sizeof(tab_UCS2_to_GBK)/4;
115 for(uint16_t ui=0; ui < u16count; ui++)
117 if(ucs2 == tab_UCS2_to_GBK[ui][0])
119 gb = tab_UCS2_to_GBK[ui][1];
125 return gb;
128 /*+\NEW\liweiqiang\2013.11.26\ÍêÉÆgb2312<->ucs2(ucs2be)±àÂëת»»*/
129 static size_t iconv_ucs2_to_gb2312_endian(char **_inbuf, size_t *inbytesleft, char **_outbuf, size_t *outbytesleft, int endian)
131 uint16_t gb2312 = 0xA1A1;
132 uint16_t ucs2;
133 size_t gb_length = 0;
134 uint16_t *ucs2buf = (uint16_t*)*_inbuf;
135 char *outbuf = (char *)*_outbuf;
136 size_t inlen = *inbytesleft/2;
137 size_t outlen = *outbytesleft;
138 size_t ret = 0;
140 while(inlen > 0)
142 if(gb_length+2 > outlen)
144 errno = E2BIG;
145 ret = -1;
146 goto ucs2_to_gb2312_exit;
149 ucs2 = *ucs2buf++;
151 if(endian == 1)
152 ucs2 = (ucs2<<8)|(ucs2>>8);
154 gb2312 = unicode_to_gb2312(ucs2, 0);
155 //End 7205
157 if(0x80 > gb2312)
159 // can be convert to ASCII char
160 *outbuf++ = (uint8_t)gb2312;
161 gb_length++;
163 else
165 *outbuf++ = (uint8_t)(gb2312>>8);
166 *outbuf++ = (uint8_t)(gb2312);
167 gb_length += 2;
170 inlen--;
173 if(inlen > 0)
175 errno = EINVAL;
176 ret = -1;
179 ucs2_to_gb2312_exit:
180 *inbytesleft = inlen;
181 *outbytesleft -= gb_length;
183 return ret;
186 size_t iconv_ucs2_to_gb2312(char **_inbuf, size_t *inbytesleft, char **_outbuf, size_t *outbytesleft)
188 return iconv_ucs2_to_gb2312_endian(_inbuf, inbytesleft, _outbuf, outbytesleft, 0);
191 size_t iconv_ucs2be_to_gb2312(char **_inbuf, size_t *inbytesleft, char **_outbuf, size_t *outbytesleft)
193 return iconv_ucs2_to_gb2312_endian(_inbuf, inbytesleft, _outbuf, outbytesleft, 1);
195 /*-\NEW\liweiqiang\2013.11.26\ÍêÉÆgb2312<->ucs2(ucs2be)±àÂëת»»*/