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 CS0_SEQ2 0x28 /* ( */ 40 #define CS0_SEQ3 0x42 /* B */ 41 42 #define CS1_SEQ2 0x24 /* $ */ 43 #define CS1_SEQ3 0x28 /* ( */ 44 #define CS1_SEQ4 0x51 /* Q */ 45 46 #define CS3_SEQ2 0x24 /* $ */ 47 #define CS3_SEQ3 0x28 /* ( */ 48 #define CS3_SEQ4 0x50 /* P */ 49 50 struct _icv_state { 51 int _st_cset; 52 }; 53 54 void * 55 _icv_open(void) 56 { 57 void *cd; 58 struct _icv_state *st; 59 60 cd = _icv_open_unicode(sizeof (struct _icv_state)); 61 62 if (cd != NULL) { 63 st = (struct _icv_state *)(_icv_get_ext(cd)); 64 st->_st_cset = CS_0; 65 } 66 67 return (cd); 68 } 69 70 void 71 _icv_close(void *cd) 72 { 73 _icv_close_unicode(cd); 74 return; 75 } 76 77 size_t 78 _icv_iconv(void *cd, char **inbuf, size_t *inbytesleft, 79 char **outbuf, size_t *outbytesleft) 80 { 81 unsigned int u32; /* UTF-32 */ 82 unsigned short e16; /* 16-bit EUC */ 83 unsigned char ic; 84 size_t rv = (size_t)0; 85 86 struct _icv_state *st = (struct _icv_state *)(_icv_get_ext(cd)); 87 int cset; 88 89 unsigned char *ip; 90 size_t ileft; 91 char *op; 92 size_t oleft; 93 94 /* 95 * If inbuf and/or *inbuf are NULL, reset conversion descriptor 96 * and put escape sequence if needed. 97 */ 98 if ((inbuf == NULL) || (*inbuf == NULL)) { 99 if (st->_st_cset != CS_0) { 100 if ((outbuf != NULL) && (*outbuf != NULL) 101 && (outbytesleft != NULL)) { 102 op = (char *)*outbuf; 103 oleft = *outbytesleft; 104 NPUT(ESC, "RESET-SEQ-ESC"); 105 NPUT(CS0_SEQ2, "RESET-SEQ2"); 106 NPUT(CS0_SEQ3, "RESET-SEQ3"); 107 *outbuf = (char *)op; 108 *outbytesleft = oleft; 109 } 110 st->_st_cset = CS_0; 111 _icv_reset_unicode(cd); 112 } 113 return ((size_t)0); 114 } 115 116 cset = st->_st_cset; 117 118 ip = (unsigned char *)*inbuf; 119 ileft = *inbytesleft; 120 op = *outbuf; 121 oleft = *outbytesleft; 122 123 while (ileft != 0) { 124 GETU(&u32) 125 126 e16 = _jfp_u32_to_euc16(u32); 127 128 switch (e16 & 0x8080) { 129 case 0x0000: /* CS0 */ 130 if (cset != CS_0) { 131 NPUT(ESC, "CS0-SEQ-ESC"); 132 NPUT(CS0_SEQ2, "CS0-SEQ2"); 133 NPUT(CS0_SEQ3, "CS0-SEQ3"); 134 cset = CS_0; 135 } 136 ic = (unsigned char)e16; 137 NPUT(ic, "CS0"); 138 break; 139 case 0x8080: /* CS1 */ 140 if (cset != CS_1) { 141 NPUT(ESC, "CS1-SEQ-ESC"); 142 NPUT(CS1_SEQ2, "CS1-SEQ2"); 143 NPUT(CS1_SEQ3, "CS1-SEQ3"); 144 NPUT(CS1_SEQ4, "CS1-SEQ4"); 145 cset = CS_1; 146 } 147 ic = (unsigned char)((e16 >> 8) & 0x7f); 148 NPUT(ic, "CS1-1"); 149 ic = (unsigned char)(e16 & 0x7f); 150 NPUT(ic, "CS1-2"); 151 break; 152 case 0x0080: /* CS2 */ 153 if (cset != CS_0) { 154 NPUT(ESC, "CS2-REPL-SEQ-ESC"); 155 NPUT(CS0_SEQ2, "CS2-REPL-SEQ2"); 156 NPUT(CS0_SEQ3, "CS2-REPL-SEQ3"); 157 cset = CS_0; 158 } 159 ic = DEF_SINGLE; 160 NPUT(ic, "CS2-REPL"); 161 break; 162 case 0x8000: /* CS3 */ 163 if (cset != CS_3) { 164 NPUT(ESC, "CS3-SEQ-ESC"); 165 NPUT(CS3_SEQ2, "CS3-SEQ2"); 166 NPUT(CS3_SEQ3, "CS3-SEQ3"); 167 NPUT(CS3_SEQ4, "CS3-SEQ4"); 168 cset = CS_3; 169 } 170 ic = (unsigned char)((e16 >> 8) & 0x7f); 171 NPUT(ic, "CS3-1"); 172 ic = (unsigned char)(e16 & 0x7f); 173 NPUT(ic, "CS3-2"); 174 break; 175 } 176 177 next: 178 /* 179 * One character successfully converted so update 180 * values outside of this function's stack. 181 */ 182 *inbuf = (char *)ip; 183 *inbytesleft = ileft; 184 *outbuf = op; 185 *outbytesleft = oleft; 186 187 st->_st_cset = cset; 188 } 189 190 ret: 191 192 DEBUGPRINTERROR 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