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 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 #include <stdlib.h> 28 #include <errno.h> 29 #include <euc.h> 30 #include "japanese.h" 31 #include "jfp_iconv_unicode.h" 32 33 #define JFP_J2U_ICONV_X0213 34 #include "jfp_jis_to_ucs2.h" 35 36 void * 37 _icv_open(void) 38 { 39 return (_icv_open_unicode((size_t)0)); 40 } 41 42 void 43 _icv_close(void *cd) 44 { 45 _icv_close_unicode(cd); 46 return; 47 } 48 49 size_t 50 _icv_iconv(void *cd, char **inbuf, size_t *inbytesleft, 51 char **outbuf, size_t *outbytesleft) 52 { 53 unsigned int u32; /* UTF-32 */ 54 unsigned short e16; /* 16-bit EUC */ 55 unsigned char ic1, ic2, ic3; /* 1st, 2nd, and 3rd bytes of a char */ 56 size_t rv = (size_t)0; /* return value of this function */ 57 58 unsigned char *ip; 59 size_t ileft; 60 char *op; 61 size_t oleft; 62 63 /* 64 * If inbuf and/or *inbuf are NULL, reset conversion descriptor 65 * and put escape sequence if needed. 66 */ 67 if ((inbuf == NULL) || (*inbuf == NULL)) { 68 _icv_reset_unicode(cd); 69 return ((size_t)0); 70 } 71 72 ip = (unsigned char *)*inbuf; 73 ileft = *inbytesleft; 74 op = *outbuf; 75 oleft = *outbytesleft; 76 77 while (ileft != 0) { 78 NGET(ic1, "never fail here"); /* get 1st byte */ 79 80 if (ISASC(ic1)) { /* CS0; 1 byte */ 81 u32 = (unsigned int)_jfp_tbl_jisx0201roman_to_ucs2[ic1]; 82 PUTU(u32, "CS0"); 83 } else if (ISCS1(ic1)) { /* JIS X 0213 plane 1; 2 bytes */ 84 NGET(ic2, "CS1-2"); 85 if (ISCS1(ic2)) { /* 2nd byte check passed */ 86 e16 = (ic1 << 8) | ic2; 87 u32 = (unsigned int)_jfp_tbl_jisx0208_to_ucs2[ 88 (ic1 - 0xa1) * 94 + (ic2 - 0xa1)]; 89 if (IFHISUR(u32)) { 90 u32 = _jfp_lookup_x0213_nonbmp( 91 e16, u32); 92 PUTU(u32, "CS1->NONBMP"); 93 } else if (u32 == 0xffff) { 94 /* need to compose */ 95 unsigned int u32_2; 96 u32 = _jfp_lookup_x0213_compose( 97 e16, &u32_2); 98 PUTU(u32, "CS1->CP1"); 99 PUTU(u32_2, "CS1->CP2"); 100 } else { 101 PUTU(u32, "CS1->BMP"); 102 } 103 } else { /* 2nd byte check failed */ 104 RETERROR(EILSEQ, "CS1-2") 105 } 106 } else if (ic1 == SS2) { /* JIS X 0201 Kana; 2 bytes */ 107 NGET(ic2, "CS2-2"); 108 if (ISCS2(ic2)) { /* 2nd byte check passed */ 109 u32 = (unsigned int) 110 _jfp_tbl_jisx0201kana_to_ucs2[ic2 - 0xa1]; 111 PUTU(u32, "CS2->Kana"); 112 } else { /* 2nd byte check failed */ 113 RETERROR(EILSEQ, "CS2-2") 114 } 115 } else if (ic1 == SS3) { /* JIS X 0213 plane 2; 3 bytes */ 116 NGET(ic2, "CS3-2"); 117 if (ISCS3(ic2)) { /* 2nd byte check passed */ 118 NGET(ic3, "CS3-3"); 119 if (ISCS3(ic3)) { /* 3rd byte check passed */ 120 e16 = (ic2 << 8) | (ic3 & 0x7f); 121 u32 = (unsigned int) 122 _jfp_tbl_jisx0213p2_to_ucs2[ 123 (ic2 - 0xa1) * 94 + (ic3 - 0xa1)]; 124 if (IFHISUR(u32)) { 125 u32 = _jfp_lookup_x0213_nonbmp( 126 e16, u32); 127 PUTU(u32, "CS3->NONBMP"); 128 } else { 129 PUTU(u32, "CS3->BMP"); 130 } 131 } else { /* 3rd byte check failed */ 132 RETERROR(EILSEQ, "CS3-3") 133 } 134 } else { /* 2nd byte check failed */ 135 RETERROR(EILSEQ, "CS3-2") 136 } 137 } else if (ISC1CTRLEUC(ic1)) { /* C1 control; 1 byte */ 138 u32 = ic1; 139 PUTU(u32, "E2BIG C1CTRL"); 140 } else { /* 1st byte check failed */ 141 RETERROR(EILSEQ, "CS?-1") 142 } 143 144 /* 145 * One character successfully converted so update 146 * values outside of this function's stack. 147 */ 148 *inbuf = (char *)ip; 149 *inbytesleft = ileft; 150 *outbuf = op; 151 *outbytesleft = oleft; 152 } 153 154 ret: 155 DEBUGPRINTERROR 156 157 /* 158 * Return value for successful return is not defined by XPG 159 * so return same as *inbytesleft as existing codes do. 160 */ 161 return ((rv == (size_t)-1) ? rv : *inbytesleft); 162 } 163