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 31 #include "japanese.h" 32 #include "jfp_iconv_unicode.h" 33 34 #define JFP_U2E_ICONV_X0213 35 #include "jfp_ucs2_to_euc16.h" 36 37 #define DEF_SINGLE '?' 38 39 #define INVL 0xff 40 41 static const unsigned char rowtosj1_x0213_p1[] = { 42 /* 1 2 3 4 5 6 7 */ 43 INVL, 0x81, 0x81, 0x82, 0x82, 0x83, 0x83, 0x84, 44 /* 8 9 10 11 12 13 14 15 */ 45 0x84, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 46 /* 16 17 18 19 20 21 22 23 */ 47 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8b, 0x8b, 0x8c, 48 /* 24 25 26 27 28 29 30 31 */ 49 0x8c, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x90, 50 /* 32 33 34 35 36 37 38 39 */ 51 0x90, 0x91, 0x91, 0x92, 0x92, 0x93, 0x93, 0x94, 52 /* 40 41 42 43 44 45 46 47 */ 53 0x94, 0x95, 0x95, 0x96, 0x96, 0x97, 0x97, 0x98, 54 /* 48 49 50 51 52 53 54 55 */ 55 0x98, 0x99, 0x99, 0x9a, 0x9a, 0x9b, 0x9b, 0x9c, 56 /* 56 57 58 59 60 61 62 63 */ 57 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9f, 0x9f, 0xe0, 58 /* 64 65 66 67 68 69 70 71 */ 59 0xe0, 0xe1, 0xe1, 0xe2, 0xe2, 0xe3, 0xe3, 0xe4, 60 /* 72 73 74 75 76 77 78 79 */ 61 0xe4, 0xe5, 0xe5, 0xe6, 0xe6, 0xe7, 0xe7, 0xe8, 62 /* 80 81 82 83 84 85 86 87 */ 63 0xe8, 0xe9, 0xe9, 0xea, 0xea, 0xeb, 0xeb, 0xec, 64 /* 88 89 90 91 92 93 94 */ 65 0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef 66 }; 67 68 static const unsigned char rowtosj1_x0213_p2[] = { 69 /* 1 2 3 4 5 6 7 */ 70 INVL, 0xf0, INVL, 0xf1, 0xf1, 0xf2, INVL, INVL, 71 /* 8 9 10 11 12 13 14 15 */ 72 0xf0, INVL, INVL, INVL, 0xf2, 0xf3, 0xf3, 0xf4, 73 /* 16 17 18 19 20 21 22 23 */ 74 INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL, 75 /* 24 25 26 27 28 29 30 31 */ 76 INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL, 77 /* 32 33 34 35 36 37 38 39 */ 78 INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL, 79 /* 40 41 42 43 44 45 46 47 */ 80 INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL, 81 /* 48 49 50 51 52 53 54 55 */ 82 INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL, 83 /* 56 57 58 59 60 61 62 63 */ 84 INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL, 85 /* 64 65 66 67 68 69 70 71 */ 86 INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL, 87 /* 72 73 74 75 76 77 78 79 */ 88 INVL, INVL, INVL, INVL, INVL, INVL, 0xf4, 0xf5, 89 /* 80 81 82 83 84 85 86 87 */ 90 0xf5, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8, 0xf8, 0xf9, 91 /* 88 89 90 91 92 93 94 */ 92 0xf9, 0xfa, 0xfa, 0xfb, 0xfb, 0xfc, 0xfc 93 }; 94 95 static unsigned char e16tosj_x0213( 96 unsigned short e16, 97 unsigned char *pc2) 98 { 99 unsigned char c1; 100 unsigned char r, c; 101 102 /* range check (if valid for plane 1 or 2) for e16 103 has been done by the caller side */ 104 105 r = (e16 >> 8) - 0xa0; 106 107 if ((e16 & 0x8080) == 0x8080) { /* Plane 1 */ 108 c1 = rowtosj1_x0213_p1[r]; 109 } else { /* Plane 2 */ 110 c1 = rowtosj1_x0213_p2[r]; 111 } 112 113 c = (e16 & 0x7f) - 0x20; 114 115 if ((r % 2) == 1) { /* odd row */ 116 *pc2 = (c - 1) + 0x40; 117 if (*pc2 >= 0x7f) { 118 (*pc2)++; 119 } 120 } else { /* even row */ 121 *pc2 = (c - 1) + 0x9f; 122 } 123 124 return (c1); 125 } 126 127 void * 128 _icv_open(void) 129 { 130 return (_icv_open_unicode((size_t)0)); 131 } 132 133 void 134 _icv_close(void *cd) 135 { 136 _icv_close_unicode(cd); 137 return; 138 } 139 140 size_t 141 _icv_iconv(void *cd, char **inbuf, size_t *inbytesleft, 142 char **outbuf, size_t *outbytesleft) 143 { 144 unsigned int u32; /* UTF-32 */ 145 unsigned short e16; /* 16-bit EUC */ 146 unsigned char ic1, ic2; 147 size_t rv = (size_t)0; 148 149 unsigned char *ip; 150 size_t ileft; 151 char *op; 152 size_t oleft; 153 154 /* 155 * If inbuf and/or *inbuf are NULL, reset conversion descriptor 156 * and put escape sequence if needed. 157 */ 158 if ((inbuf == NULL) || (*inbuf == NULL)) { 159 _icv_reset_unicode(cd); 160 return ((size_t)0); 161 } 162 163 ip = (unsigned char *)*inbuf; 164 ileft = *inbytesleft; 165 op = *outbuf; 166 oleft = *outbytesleft; 167 168 while (ileft != 0) { 169 GETU(&u32) 170 171 e16 = _jfp_u32_to_euc16(u32); 172 173 switch (e16 & 0x8080) { 174 case 0x0000: /* ASCII */ 175 ic1 = (unsigned char)e16; 176 NPUT(ic1, "ASCII"); 177 break; 178 case 0x8080: /* PLANE1 */ 179 ic1 = e16tosj_x0213(e16, &ic2); 180 NPUT(ic1, "PLANE1-1"); 181 NPUT(ic2, "PLANE1-2"); 182 break; 183 case 0x0080: /* KANA */ 184 ic1 = (unsigned char)e16; 185 NPUT(ic1, "KANA"); 186 break; 187 case 0x8000: /* CS3 */ 188 ic1 = e16tosj_x0213(e16, &ic2); 189 NPUT(ic1, "PLANE2-1"); 190 NPUT(ic2, "PLANE2-2"); 191 break; 192 } 193 194 next: 195 /* 196 * One character successfully converted so update 197 * values outside of this function's stack. 198 */ 199 *inbuf = (char *)ip; 200 *inbytesleft = ileft; 201 *outbuf = op; 202 *outbytesleft = oleft; 203 } 204 205 ret: 206 207 DEBUGPRINTERROR 208 209 /* 210 * Return value for successful return is not defined by XPG 211 * so return same as *inbytesleft as existing codes do. 212 */ 213 return ((rv == (size_t)-1) ? rv : *inbytesleft); 214 } 215