1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1997, by Sun Microsystems, Inc.
23 * All rights reserved.
24 */
25
26
27 /*
28 Converts From: ISO2022-CN-EXT encoding.
29 Converts To: Taiwanese BIG5 encoding
30 */
31
32 #include "iso2022-cn.h"
33 #include "cns11643_big5.h"
34 #include "gb2312_big5_TW.h"
35
36 /* Forward reference the functions constrained to the scope of this file */
37 static int chinese_to_big5( _iconv_st *, unsigned char **, size_t *, int);
38 static int gb_to_big5( _iconv_st*, unsigned char**, size_t* );
39
40 extern int errno;
41
42 size_t
_icv_iconv(_iconv_st * st,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)43 _icv_iconv(_iconv_st *st, char **inbuf, size_t *inbytesleft,
44 char **outbuf, size_t *outbytesleft)
45 {
46 return iso2022_icv_iconv(st, inbuf, inbytesleft, (unsigned char**) outbuf, outbytesleft,
47 chinese_to_big5);
48 }
49
50 static int
cns_big5_comp(const void * p1,const void * p2)51 cns_big5_comp(const void *p1, const void *p2)
52 {
53 table_t *ptr1 = (table_t*) p1, *ptr2 = (table_t*) p2;
54 long result = ptr1->key - ptr2->key;
55 return result == 0 ? 0 : result > 0 ? 1 : -1;
56 }
57
58 static int
chinese_to_big5(_iconv_st * st,unsigned char ** outbuf,size_t * outbytesleft,int plane_no)59 chinese_to_big5( _iconv_st *st, unsigned char **outbuf, size_t *outbytesleft, int plane_no )
60 {
61
62 table_t key, *ptr;
63 if ( st->SSfunc == NULL && st->SOcharset == 'A') { /* GB2312 */
64 return gb_to_big5(st, outbuf, outbytesleft);
65 }
66
67 if ( plane_no < 0 || plane_no > 2 )/* Not a big5 */
68 return (1);
69
70 key.key = (unsigned long) ((st->keepc[0] & 0xff) << 8) + (st->keepc[1] & 0xff);
71 if (plane_no == 1)
72 ptr = (table_t*) bsearch(&key, cns_big5_tab1, MAX_CNS1_NUM, sizeof(table_t), cns_big5_comp);
73 else
74 ptr = (table_t*) bsearch(&key, cns_big5_tab2, MAX_CNS2_NUM, sizeof(table_t), cns_big5_comp);
75
76 if ( ptr == 0 || ptr->value == 0 )
77 return (1); /* No BIG5 code for this CNS code */
78
79 if ( *outbytesleft < 2 ){
80 st->_errno = errno = E2BIG;
81 return (-1);
82 }
83 *(*outbuf)++ = (unsigned char) ((ptr->value >> 8) & 0xff);
84 *(*outbuf)++ = (unsigned char) (ptr->value & 0xff);
85 (*outbytesleft) -= 2;
86
87 return (0);
88 }
89
90
91 static int
gb_big5_comp(const void * p1,const void * p2)92 gb_big5_comp(const void *p1, const void *p2)
93 {
94 gb_big5 *ptr1 = (gb_big5*) p1, *ptr2 = (gb_big5*) p2;
95 long result = ptr1->gbcode - ptr2->gbcode;
96 return result == 0 ? 0 : result > 0 ? 1 : -1;
97 }
98
99 static int
gb_to_big5(_iconv_st * st,unsigned char ** outbuf,size_t * outbytesleft)100 gb_to_big5( _iconv_st *st, unsigned char **outbuf, size_t *outbytesleft )
101 {
102 gb_big5 *ptr, key;
103
104 key.gbcode = (unsigned long) ((st->keepc[0] | MSB) << 8) + (st->keepc[1] | MSB);
105 ptr = (gb_big5*) bsearch(&key, gb_big5_tab, BIG5MAX, sizeof(gb_big5), gb_big5_comp);
106
107 if ( ptr && ptr->big5code > 0 ) {
108 if ( *outbytesleft < 2 ){
109 st->_errno = errno = E2BIG;
110 return (-1);
111 }
112 *(*outbuf)++ = (unsigned char) ((ptr->big5code >> 8) & 0xff);
113 *(*outbuf)++ = (unsigned char) (ptr->big5code & 0xff);
114 (*outbytesleft) -= 2;
115
116 return (0);
117 }
118 else
119 return (1); /* No BIG5 code for this CNS code */
120 }
121