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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1989 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #if !defined(lint) && defined(SCCSIDS) 30 static char *sccsid = "%Z%%M% %I% %E% SMI"; 31 #endif 32 33 #include <sys/types.h> 34 #include "codeset.h" 35 #include "mbextern.h" 36 #include "euc.h" 37 #include <limits.h> 38 39 #define EUCMASK 0x8080 /* All id bits */ 40 #define MASK0 0x0000 /* Code Set 0 */ 41 #define MASK1 0x8080 /* Code Set 1 */ 42 #define MASK2 0x0080 /* Code Set 2 */ 43 #define MASK3 0x8000 /* Code Set 3 */ 44 45 #define EUCWID1 eucinfo->_eucw1 46 #define EUCWID2 eucinfo->_eucw2 47 #define EUCWID3 eucinfo->_eucw3 48 49 int _mbtowc_euc(wchar, s, n) 50 wchar_t *wchar; 51 char *s; 52 size_t n; 53 { 54 register int length; 55 register wchar_t intcode; 56 register c; 57 char *olds = (char *)s; 58 wchar_t mask; 59 eucwidth_t * eucinfo = (eucwidth_t *)_code_set_info.code_info; 60 61 if(n <= 0) 62 return(-1); 63 if(s == (char *)0) 64 return 0; 65 c = (unsigned char)*s++; 66 if(c < 0200) { 67 if(wchar) 68 *wchar = c; 69 return(c ? 1 : 0); 70 } 71 intcode = 0; 72 if (c == SS2) { 73 if(!(length = EUCWID2)) { 74 if(wchar) 75 *wchar = c; 76 return(1); 77 } 78 mask = MASK2; 79 } else if(c == SS3) { 80 if(!(length = EUCWID3)) { 81 if(wchar) 82 *wchar = c; 83 return(1); 84 } 85 mask = MASK3; 86 } else { 87 if(iscntrl(c)) { 88 if(wchar) 89 *wchar = c; 90 return(1); 91 } 92 length = EUCWID1 - 1; 93 mask = MASK1; 94 intcode = c & 0177; 95 } 96 if(length + 1 > n) 97 return(-1); 98 while(length--) { 99 if((c = (unsigned char)*s++) < 0200 || iscntrl(c)) 100 return(-1); 101 intcode = (intcode << 8) | (c & 0177); 102 } 103 if(wchar) 104 *wchar = intcode | mask; 105 return((char *)s - olds); 106 } 107 108 109 size_t 110 _mbstowcs_euc(pwcs, s, n) 111 wchar_t *pwcs; 112 char *s; 113 size_t n; 114 { 115 register int i, j; 116 117 j=0; 118 while(*s) { 119 if(j>=n) 120 break; 121 i=_mbtowc_euc(pwcs+j, s, MB_LEN_MAX); 122 if(i==-1) 123 return -1; 124 s+=i; 125 ++j; 126 } 127 if(j<n) 128 pwcs[j]=0; 129 return j; 130 } 131 132 133 size_t 134 _wcstombs_euc(s, pwcs, n) 135 char *s; 136 wchar_t *pwcs; 137 size_t n; 138 { 139 register wchar_t wc; 140 register int i; 141 register int r=n; /* Rest of bytes. */ 142 register char *t; 143 char mbbuf[MB_LEN_MAX+1]; 144 145 while(wc=(*pwcs++)) { 146 i=_wctomb_euc(mbbuf, wc); 147 148 if (i>r) 149 break; 150 if (i==-1) return -1; 151 152 r-=i; 153 for (t=mbbuf;i>0;--i){ 154 /* Copy each byte. */ 155 *(s++)=*(t++); 156 } 157 } 158 if (r>0) 159 /* Has enough room for NUL. */ 160 *s=0; 161 return n-r; 162 } 163 164 int _wctomb_euc(s, wchar) 165 char *s; 166 wchar_t wchar; 167 { 168 eucwidth_t * eucinfo = (eucwidth_t *)_code_set_info.code_info; 169 char *olds = s; 170 register int size, index; 171 unsigned char d; 172 if(!s) 173 return(0); 174 if( wchar <= 0177 || wchar <= 0377 && iscntrl(wchar)) { 175 *s++ = wchar; 176 return(wchar ? 1 : 0); 177 } 178 switch(wchar & EUCMASK) { 179 180 case MASK1: 181 size = EUCWID1; 182 break; 183 184 case MASK2: 185 *s++ = SS2; 186 size = EUCWID2; 187 break; 188 189 case MASK3: 190 *s++ = SS3; 191 size = EUCWID3; 192 break; 193 194 default: 195 return(-1); 196 } 197 index = size; 198 while(index--) { 199 d = wchar | 0200; 200 wchar >>= 8; 201 if(iscntrl(d)) 202 return(-1); 203 s[index] = d; 204 } 205 return(s + size - olds); 206 } 207