update: 重构libgnss,解决air530z-bd及air780epvg出现的问题
[LuatOS.git] / components / iconv / gb2312_to_ucs2.c
blob0abb0e099da641a77c68bd6808d3b44f1f063381
1 /**************************************************************************
2 * Copyright (C), AirM2M Tech. Co., Ltd.
4 * Name: gb2312_to_ucs2.c
5 * Author: liweiqiang
6 * Version: V0.1
7 * Date: 2013/11/26
9 * Description:
10 * gb2312 ת»» ucs2
11 **************************************************************************/
12 #include <stdint.h>
13 #include "stdio.h"
14 #include "errno.h"
16 #include "gb2312_to_ucs2_table.h"
18 uint16_t gb2312_to_ucs(uint16_t gb2312)
20 uint16_t ucs;
21 uint8_t gb = gb2312;
23 if (gb < 0x80)
25 ucs = gb;
27 else
29 uint16_t offset = ((gb2312 >> 8) - 0xA0) * 94 + ((gb2312 & 0x00ff) - 0xA1);
30 ucs = gb2312_to_ucs2_table[offset];
33 return ucs;
36 size_t iconv_gb2312_to_ucs2_endian(char **_inbuf, size_t *inbytesleft, char **_outbuf, size_t *outbytesleft, int endian)
38 uint16_t offset,gb2312;
39 char *gbbuf = *_inbuf;
40 uint16_t *ucs2buf = (uint16_t*)*_outbuf;
41 uint16_t ucs2;
42 size_t ucs2len = 0;
43 size_t inlen = *inbytesleft;
44 size_t outlen = *outbytesleft;
45 size_t ret = 0;
47 while(inlen > 0)
49 if(ucs2len+2 > outlen)
51 errno = E2BIG;
52 ret = -1;
53 goto gb2312_to_ucs2_exit;
56 gb2312 = *gbbuf++;
58 if(gb2312 < 0x80)
60 ucs2 = gb2312;
61 inlen--;
63 else if(inlen >= 2)
65 gb2312 = (gb2312<<8) + ((*gbbuf++)&0x00ff);
66 inlen -= 2;
68 offset = ((gb2312>>8) - 0xA0)*94/*(0xFE-0xA1+1)*/ + ((gb2312&0x00ff) - 0xA1);
69 ucs2 = gb2312_to_ucs2_table[offset];
71 else
73 break;
76 if(endian == 1)
77 ucs2 = (ucs2<<8)|(ucs2>>8);
79 *ucs2buf++ = ucs2;
80 ucs2len += 2;
83 if(inlen > 0)
85 errno = EINVAL;
86 ret = -1;
89 gb2312_to_ucs2_exit:
90 *_inbuf = gbbuf;
92 *inbytesleft = inlen;
93 *outbytesleft -= ucs2len;
95 return ret;
98 size_t iconv_gb2312_to_ucs2(char **_inbuf, size_t *inbytesleft, char **_outbuf, size_t *outbytesleft)
100 return iconv_gb2312_to_ucs2_endian(_inbuf, inbytesleft, _outbuf, outbytesleft, 0);
103 size_t iconv_gb2312_to_ucs2be(char **_inbuf, size_t *inbytesleft, char **_outbuf, size_t *outbytesleft)
105 return iconv_gb2312_to_ucs2_endian(_inbuf, inbytesleft, _outbuf, outbytesleft, 1);