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 1994-2003 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <errno.h> 29 #include <euc.h> 30 #define JFP_ICONV_STATELESS 31 #include "japanese.h" 32 33 void * 34 _icv_open(void) 35 { 36 return (_icv_open_stateless()); 37 } 38 39 void 40 _icv_close(void *cd) 41 { 42 _icv_close_stateless(cd); 43 return; 44 } 45 46 size_t 47 _icv_iconv(void *cd, char **inbuf, size_t *inbytesleft, 48 char **outbuf, size_t *outbytesleft) 49 { 50 int stat; 51 unsigned char *ip, ic; 52 char *op; 53 size_t ileft, oleft; 54 size_t retval; 55 56 stat = ST_INIT; 57 58 /* 59 * If inbuf and/or *inbuf are NULL, reset conversion descriptor 60 * and put escape sequence if needed. 61 */ 62 if ((inbuf == NULL) || (*inbuf == NULL)) { 63 /* nothing to do here for this module */ 64 return ((size_t)0); 65 } 66 67 ip = (unsigned char *)*inbuf; 68 op = *outbuf; 69 ileft = *inbytesleft; 70 oleft = *outbytesleft; 71 72 /* 73 * Main loop; basically 1 loop per 1 input byte 74 */ 75 76 while ((int)ileft > 0) { 77 GET(ic); 78 if (stat == ST_INCS1) { 79 PUT(((ic & CMASK) - 0x20)); 80 stat = ST_INIT; 81 continue; 82 } else if (stat == ST_INCS3) { 83 PUT(((ic & CMASK) - 0x20)); 84 GET(ic); 85 PUT(((ic & CMASK) - 0x20)); 86 stat = ST_INIT; 87 continue; 88 } 89 if (ISASC((int)ic)) { /* ASCII */ 90 errno = EILSEQ; 91 retval = (size_t)ERR_RETURN; 92 goto ret; 93 } else if (ISCS1(ic)) { /* CS_1 starts */ 94 if ((int)ileft > 0) { 95 if (ISCS1(ic) && ISCS1(*ip)) { 96 if (oleft < JISW1) { 97 UNGET(); 98 errno = E2BIG; 99 retval = (size_t)ERR_RETURN; 100 goto ret; 101 } 102 stat = ST_INCS1; 103 PUT(((ic & CMASK) - 0x20)); 104 continue; 105 } else { 106 errno = EILSEQ; 107 retval = (size_t)ERR_RETURN; 108 goto ret; 109 } 110 } else { /* input fragment of Kanji */ 111 UNGET(); 112 errno = EINVAL; 113 retval = (size_t)ERR_RETURN; 114 goto ret; 115 } 116 } else if (ic == SS2) { /* Kana starts */ 117 errno = EILSEQ; 118 retval = (size_t)ERR_RETURN; 119 goto ret; 120 } else if (ic == SS3) { /* JISX0212 starts */ 121 if (ileft >= EUCW3) { 122 if (ISCS3(*ip) && ISCS3(*(ip + 1))) { 123 if (oleft < JISW3) { 124 UNGET(); 125 errno = E2BIG; 126 retval = (size_t)ERR_RETURN; 127 goto ret; 128 } 129 stat = ST_INCS3; 130 continue; 131 } else { 132 errno = EILSEQ; 133 retval = (size_t)ERR_RETURN; 134 goto ret; 135 } 136 } else { /* input fragment of JISX0212 */ 137 UNGET(); 138 errno = EINVAL; 139 retval = (size_t)ERR_RETURN; 140 goto ret; 141 } 142 } else { 143 UNGET(); 144 errno = EILSEQ; 145 retval = (size_t)ERR_RETURN; 146 goto ret; 147 } 148 } 149 retval = ileft; 150 ret: 151 *inbuf = (char *)ip; 152 *inbytesleft = ileft; 153 ret2: 154 *outbuf = op; 155 *outbytesleft = oleft; 156 157 return (retval); 158 } 159