xref: /titanic_50/usr/src/lib/libbc/libc/gen/common/euc.multibyte.c (revision eab227978ccdaa5a7cc9fd92ace768915dae3a2b)
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 #include <sys/types.h>
30 #include "codeset.h"
31 #include "mbextern.h"
32 #include "euc.h"
33 #include <limits.h>
34 
35 #define EUCMASK	0x8080		/* All id bits */
36 #define MASK0	0x0000		/* Code Set 0 */
37 #define MASK1	0x8080		/* Code Set 1 */
38 #define MASK2	0x0080		/* Code Set 2 */
39 #define MASK3	0x8000		/* Code Set 3 */
40 
41 #define EUCWID1	eucinfo->_eucw1
42 #define EUCWID2	eucinfo->_eucw2
43 #define EUCWID3	eucinfo->_eucw3
44 
45 int	_wctomb_euc(char *, wchar_t);
46 
47 int
48 _mbtowc_euc(wchar_t *wchar, char *s, size_t n)
49 {
50 	int length;
51 	wchar_t intcode;
52 	int c;
53 	char *olds = (char *)s;
54 	wchar_t mask;
55         eucwidth_t * eucinfo = (eucwidth_t *)_code_set_info.code_info;
56 
57 	if(n <= 0)
58 		return(-1);
59 	if(s == (char *)0)
60 		return (0);
61 	c = (unsigned char)*s++;
62 	if(c < 0200) {
63 		if(wchar)
64 			*wchar = c;
65 		return (c ? 1 : 0);
66 	}
67 	intcode = 0;
68 	if (c == SS2) {
69 		if(!(length = EUCWID2)) {
70 			if(wchar)
71 				*wchar = c;
72 			return (1);
73 		}
74 		mask = MASK2;
75 	} else if(c == SS3) {
76 		if(!(length = EUCWID3)) {
77 			if(wchar)
78 				*wchar = c;
79 			return (1);
80 		}
81 		mask = MASK3;
82 	} else {
83 		if(iscntrl(c)) {
84 			if(wchar)
85 				*wchar = c;
86 			return (1);
87 		}
88 		length = EUCWID1 - 1;
89 		mask = MASK1;
90 		intcode = c & 0177;
91 	}
92 	if(length + 1 > n)
93 		return (-1);
94 	while(length--) {
95 		if((c = (unsigned char)*s++) < 0200 || iscntrl(c))
96 			return (-1);
97 		intcode = (intcode << 8) | (c & 0177);
98 	}
99 	if(wchar)
100 		*wchar = intcode | mask;
101 	return ((char *)s - olds);
102 }
103 
104 
105 size_t
106 _mbstowcs_euc(wchar_t *pwcs, char *s, size_t n)
107 {
108 	int		i, j;
109 
110 	j=0;
111 	while(*s) {
112 		if(j>=n)
113 			break;
114 		i=_mbtowc_euc(pwcs+j, s, MB_LEN_MAX);
115 		if(i==-1)
116 			return (-1);
117 		s+=i;
118 		++j;
119 	}
120 	if(j<n)
121 		pwcs[j]=0;
122 	return (j);
123 }
124 
125 
126 size_t
127 _wcstombs_euc(char *s, wchar_t *pwcs, size_t n)
128 {
129 	wchar_t	wc;
130 	int		i;
131 	int		r=n; /* Rest of bytes. */
132 	char		*t;
133 	char			mbbuf[MB_LEN_MAX+1];
134 
135 	while(wc=(*pwcs++)) {
136 		i=_wctomb_euc(mbbuf, wc);
137 
138 		if (i>r)
139 			break;
140 		if (i==-1) return (-1);
141 
142 		r-=i;
143 		for (t=mbbuf;i>0;--i){
144 			/* Copy each byte. */
145 			*(s++)=*(t++);
146 		}
147 	}
148 	if (r>0)
149 		/* Has enough room for NUL. */
150 		*s=0;
151 	return (n-r);
152 }
153 
154 int
155 _wctomb_euc(char *s, wchar_t wchar)
156 {
157         eucwidth_t * eucinfo = (eucwidth_t *)_code_set_info.code_info;
158 	char *olds = s;
159 	int size, index;
160 	unsigned char d;
161 	if(!s)
162 		return(0);
163 	if( wchar <= 0177 || wchar <= 0377 && iscntrl(wchar)) {
164 		*s++ = wchar;
165 		return (wchar ? 1 : 0);
166 	}
167 	switch(wchar & EUCMASK) {
168 
169 		case MASK1:
170 			size = EUCWID1;
171 			break;
172 
173 		case MASK2:
174 			*s++ = SS2;
175 			size = EUCWID2;
176 			break;
177 
178 		case MASK3:
179 			*s++ = SS3;
180 			size = EUCWID3;
181 			break;
182 
183 		default:
184 			return (-1);
185 	}
186 	index = size;
187 	while(index--) {
188 		d = wchar | 0200;
189 		wchar >>= 8;
190 		if(iscntrl(d))
191 			return (-1);
192 		s[index] = d;
193 	}
194 	return (s + size - olds);
195 }
196