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 AND PERMISSION NOTICE 23 * 24 * Copyright (c) 1991-2005 Unicode, Inc. All rights reserved. Distributed 25 * under the Terms of Use in http://www.unicode.org/copyright.html. 26 * 27 * This file has been modified by Sun Microsystems, Inc. 28 */ 29 /* 30 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 31 * Use is subject to license terms. 32 */ 33 34 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <errno.h> 38 #include <euc.h> 39 40 #include "japanese.h" 41 #include "jfp_iconv_unicode.h" 42 43 #ifdef JAVA_CONV_COMPAT 44 #define JFP_U2E_ICONV_JAVA 45 #elif JFP_ICONV_MS932 46 #define JFP_U2E_ICONV_MS932 47 #else 48 #define JFP_U2E_ICONV 49 #endif 50 #include "jfp_ucs2_to_euc16.h" 51 52 #define DEF_SINGLE '?' 53 54 static unsigned short lookuptbl(unsigned short); 55 56 void * 57 _icv_open(void) 58 { 59 return (_icv_open_unicode((size_t)0)); 60 } 61 62 void 63 _icv_close(void *cd) 64 { 65 _icv_close_unicode(cd); 66 return; 67 } 68 69 size_t 70 _icv_iconv(void *cd, char **inbuf, size_t *inbytesleft, 71 char **outbuf, size_t *outbytesleft) 72 { 73 unsigned char ic; 74 size_t rv = (size_t)0; 75 unsigned int ucs4; 76 unsigned short euc16; 77 unsigned short dest; 78 79 unsigned char *ip; 80 size_t ileft; 81 char *op; 82 size_t oleft; 83 84 /* 85 * If inbuf and/or *inbuf are NULL, reset conversion descriptor 86 * and put escape sequence if needed. 87 */ 88 if ((inbuf == NULL) || (*inbuf == NULL)) { 89 _icv_reset_unicode(cd); 90 return ((size_t)0); 91 } 92 93 ip = (unsigned char *)*inbuf; 94 ileft = *inbytesleft; 95 op = *outbuf; 96 oleft = *outbytesleft; 97 98 while (ileft != 0) { 99 GETU(&ucs4); 100 101 if (ucs4 > 0xffff) { 102 /* non-BMP */ 103 NPUT((unsigned char)DEF_SINGLE, "non-BMP(replaced)"); 104 } else { 105 euc16 = _jfp_ucs2_to_euc16((unsigned short)ucs4); 106 107 switch (euc16 & 0x8080) { 108 case 0x0000: /* CS0 */ 109 if (ISC1CTRL((unsigned char)euc16)) { 110 NPUT((unsigned char)'?', 111 "CS0-C1CTRL(replaced)") 112 } else { 113 ic = (unsigned char)euc16; 114 NPUT(ic, "CS0-1"); 115 } 116 break; 117 case 0x8080: /* CS1 */ 118 ic = (unsigned short)((euc16 >> 8) & 0x7f); 119 NPUT(jis208tosj1[ic], "CS1-1"); 120 /* 121 * for even number row (Ku), add 0x80 to 122 * look latter half of jistosj2[] array 123 */ 124 ic = (unsigned char)((euc16 & 0x7f) 125 + (((ic % 2) == 0) ? 0x80 : 0x00)); 126 NPUT(jistosj2[ic], "CS1-2"); 127 break; 128 case 0x0080: /* CS2 */ 129 ic = (unsigned char)euc16; 130 NPUT(ic, "CS2-1"); 131 break; 132 case 0x8000: /* CS3 */ 133 ic = (unsigned short)((euc16 >> 8) & 0x7f); 134 if (euc16 == 0xa271) { 135 /* NUMERO SIGN */ 136 NPUT(0x87, "CS3-NUMERO-1"); 137 NPUT(0x82, "CS3-NUMERO-2"); 138 } else if (ic < 0x75) { /* check if IBM VDC */ 139 dest = lookuptbl(euc16 & 0x7f7f); 140 if (dest == 0xffff) { 141 NPUT((unsigned char)'?', 142 "CS3-NoSJIS(replaced)") 143 } else { 144 #ifdef JAVA_CONV_COMPAT 145 NPUT((unsigned char)'?', 146 "CS3-IBM(replaced)") 147 #else /* !JAVA_CONV_COMPAT */ 148 /* avoid putting NUL ('\0') */ 149 if (dest > 0xff) { 150 NPUT((dest >> 8) & 0xff, 151 "CS3-IBM-1"); 152 NPUT(dest & 0xff, 153 "CS3-IBM-2"); 154 } else { 155 NPUT(dest & 0xff, 156 "CS3-IBM-1"); 157 } 158 #endif /* JAVA_CONV_COMPAT */ 159 } 160 } else { 161 NPUT(jis212tosj1[ic], "CS3-1"); 162 /* 163 * for even number row (Ku), add 0x80 to 164 * look latter half of jistosj2[] array 165 */ 166 ic = (unsigned short)((euc16 & 0x7f) 167 + (((ic % 2) == 0) ? 168 0x80 : 0x00)); 169 NPUT(jistosj2[ic], "CS3-2"); 170 } 171 break; 172 } 173 } 174 175 next: 176 /* 177 * One character successfully converted so update 178 * values outside of this function's stack. 179 */ 180 *inbuf = (char *)ip; 181 *inbytesleft = ileft; 182 *outbuf = op; 183 *outbytesleft = oleft; 184 } 185 186 ret: 187 188 #if defined(DEBUG) 189 if (rv == (size_t)-1) { 190 fprintf(stderr, "DEBUG: errno=%d: %s\n", errno, debugmsg); 191 } 192 #endif /* DEBUG */ 193 194 /* 195 * Return value for successful return is not defined by XPG 196 * so return same as *inbytesleft as existing codes do. 197 */ 198 return ((rv == (size_t)-1) ? rv : *inbytesleft); 199 } 200 201 /* 202 * lookuptbl() 203 * Return the index number if its index-ed number 204 * is the same as dest value. 205 */ 206 static unsigned short 207 lookuptbl(unsigned short dest) 208 { 209 unsigned short tmp; 210 int i; 211 int sz = (sizeof (sjtoibmext) / sizeof (sjtoibmext[0])); 212 213 for (i = 0; i < sz; i++) { 214 tmp = (sjtoibmext[i] & 0x7f7f); 215 if (tmp == dest) 216 return ((i + 0xfa40 + ((i / 0xc0) * 0x40))); 217 } 218 return (0x3f); 219 } 220