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 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 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 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 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 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