xref: /titanic_50/usr/src/lib/iconv_modules/zh/common/zh_TW-iso2022-CN-EXT%zh_TW-big5.c (revision 880d797826457b77414b37d531cc3e1aa166ecbe)
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