xref: /onnv-gate/usr/src/lib/libbc/libc/gen/common/euc.multibyte.c (revision 722:636b850d4ee9)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * Copyright 1989 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <sys/types.h>
300Sstevel@tonic-gate #include "codeset.h"
310Sstevel@tonic-gate #include "mbextern.h"
320Sstevel@tonic-gate #include "euc.h"
330Sstevel@tonic-gate #include <limits.h>
340Sstevel@tonic-gate 
350Sstevel@tonic-gate #define EUCMASK	0x8080		/* All id bits */
360Sstevel@tonic-gate #define MASK0	0x0000		/* Code Set 0 */
370Sstevel@tonic-gate #define MASK1	0x8080		/* Code Set 1 */
380Sstevel@tonic-gate #define MASK2	0x0080		/* Code Set 2 */
390Sstevel@tonic-gate #define MASK3	0x8000		/* Code Set 3 */
400Sstevel@tonic-gate 
410Sstevel@tonic-gate #define EUCWID1	eucinfo->_eucw1
420Sstevel@tonic-gate #define EUCWID2	eucinfo->_eucw2
430Sstevel@tonic-gate #define EUCWID3	eucinfo->_eucw3
440Sstevel@tonic-gate 
45*722Smuffin int	_wctomb_euc(char *, wchar_t);
46*722Smuffin 
47*722Smuffin int
_mbtowc_euc(wchar_t * wchar,char * s,size_t n)48*722Smuffin _mbtowc_euc(wchar_t *wchar, char *s, size_t n)
490Sstevel@tonic-gate {
50*722Smuffin 	int length;
51*722Smuffin 	wchar_t intcode;
52*722Smuffin 	int c;
530Sstevel@tonic-gate 	char *olds = (char *)s;
540Sstevel@tonic-gate 	wchar_t mask;
550Sstevel@tonic-gate         eucwidth_t * eucinfo = (eucwidth_t *)_code_set_info.code_info;
560Sstevel@tonic-gate 
570Sstevel@tonic-gate 	if(n <= 0)
580Sstevel@tonic-gate 		return(-1);
590Sstevel@tonic-gate 	if(s == (char *)0)
60*722Smuffin 		return (0);
610Sstevel@tonic-gate 	c = (unsigned char)*s++;
620Sstevel@tonic-gate 	if(c < 0200) {
630Sstevel@tonic-gate 		if(wchar)
640Sstevel@tonic-gate 			*wchar = c;
65*722Smuffin 		return (c ? 1 : 0);
660Sstevel@tonic-gate 	}
670Sstevel@tonic-gate 	intcode = 0;
680Sstevel@tonic-gate 	if (c == SS2) {
690Sstevel@tonic-gate 		if(!(length = EUCWID2)) {
700Sstevel@tonic-gate 			if(wchar)
710Sstevel@tonic-gate 				*wchar = c;
72*722Smuffin 			return (1);
730Sstevel@tonic-gate 		}
740Sstevel@tonic-gate 		mask = MASK2;
750Sstevel@tonic-gate 	} else if(c == SS3) {
760Sstevel@tonic-gate 		if(!(length = EUCWID3)) {
770Sstevel@tonic-gate 			if(wchar)
780Sstevel@tonic-gate 				*wchar = c;
79*722Smuffin 			return (1);
800Sstevel@tonic-gate 		}
810Sstevel@tonic-gate 		mask = MASK3;
820Sstevel@tonic-gate 	} else {
830Sstevel@tonic-gate 		if(iscntrl(c)) {
840Sstevel@tonic-gate 			if(wchar)
850Sstevel@tonic-gate 				*wchar = c;
86*722Smuffin 			return (1);
870Sstevel@tonic-gate 		}
880Sstevel@tonic-gate 		length = EUCWID1 - 1;
890Sstevel@tonic-gate 		mask = MASK1;
900Sstevel@tonic-gate 		intcode = c & 0177;
910Sstevel@tonic-gate 	}
920Sstevel@tonic-gate 	if(length + 1 > n)
93*722Smuffin 		return (-1);
940Sstevel@tonic-gate 	while(length--) {
950Sstevel@tonic-gate 		if((c = (unsigned char)*s++) < 0200 || iscntrl(c))
96*722Smuffin 			return (-1);
970Sstevel@tonic-gate 		intcode = (intcode << 8) | (c & 0177);
980Sstevel@tonic-gate 	}
990Sstevel@tonic-gate 	if(wchar)
1000Sstevel@tonic-gate 		*wchar = intcode | mask;
101*722Smuffin 	return ((char *)s - olds);
1020Sstevel@tonic-gate }
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate size_t
_mbstowcs_euc(wchar_t * pwcs,char * s,size_t n)106*722Smuffin _mbstowcs_euc(wchar_t *pwcs, char *s, size_t n)
1070Sstevel@tonic-gate {
108*722Smuffin 	int		i, j;
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate 	j=0;
1110Sstevel@tonic-gate 	while(*s) {
1120Sstevel@tonic-gate 		if(j>=n)
1130Sstevel@tonic-gate 			break;
1140Sstevel@tonic-gate 		i=_mbtowc_euc(pwcs+j, s, MB_LEN_MAX);
1150Sstevel@tonic-gate 		if(i==-1)
116*722Smuffin 			return (-1);
1170Sstevel@tonic-gate 		s+=i;
1180Sstevel@tonic-gate 		++j;
1190Sstevel@tonic-gate 	}
1200Sstevel@tonic-gate 	if(j<n)
1210Sstevel@tonic-gate 		pwcs[j]=0;
122*722Smuffin 	return (j);
1230Sstevel@tonic-gate }
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate size_t
_wcstombs_euc(char * s,wchar_t * pwcs,size_t n)127*722Smuffin _wcstombs_euc(char *s, wchar_t *pwcs, size_t n)
1280Sstevel@tonic-gate {
129*722Smuffin 	wchar_t	wc;
130*722Smuffin 	int		i;
131*722Smuffin 	int		r=n; /* Rest of bytes. */
132*722Smuffin 	char		*t;
1330Sstevel@tonic-gate 	char			mbbuf[MB_LEN_MAX+1];
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate 	while(wc=(*pwcs++)) {
1360Sstevel@tonic-gate 		i=_wctomb_euc(mbbuf, wc);
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 		if (i>r)
1390Sstevel@tonic-gate 			break;
140*722Smuffin 		if (i==-1) return (-1);
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate 		r-=i;
1430Sstevel@tonic-gate 		for (t=mbbuf;i>0;--i){
1440Sstevel@tonic-gate 			/* Copy each byte. */
1450Sstevel@tonic-gate 			*(s++)=*(t++);
1460Sstevel@tonic-gate 		}
1470Sstevel@tonic-gate 	}
1480Sstevel@tonic-gate 	if (r>0)
1490Sstevel@tonic-gate 		/* Has enough room for NUL. */
1500Sstevel@tonic-gate 		*s=0;
151*722Smuffin 	return (n-r);
1520Sstevel@tonic-gate }
1530Sstevel@tonic-gate 
154*722Smuffin int
_wctomb_euc(char * s,wchar_t wchar)155*722Smuffin _wctomb_euc(char *s, wchar_t wchar)
1560Sstevel@tonic-gate {
1570Sstevel@tonic-gate         eucwidth_t * eucinfo = (eucwidth_t *)_code_set_info.code_info;
1580Sstevel@tonic-gate 	char *olds = s;
159*722Smuffin 	int size, index;
1600Sstevel@tonic-gate 	unsigned char d;
1610Sstevel@tonic-gate 	if(!s)
1620Sstevel@tonic-gate 		return(0);
1630Sstevel@tonic-gate 	if( wchar <= 0177 || wchar <= 0377 && iscntrl(wchar)) {
1640Sstevel@tonic-gate 		*s++ = wchar;
165*722Smuffin 		return (wchar ? 1 : 0);
1660Sstevel@tonic-gate 	}
1670Sstevel@tonic-gate 	switch(wchar & EUCMASK) {
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 		case MASK1:
1700Sstevel@tonic-gate 			size = EUCWID1;
1710Sstevel@tonic-gate 			break;
1720Sstevel@tonic-gate 
1730Sstevel@tonic-gate 		case MASK2:
1740Sstevel@tonic-gate 			*s++ = SS2;
1750Sstevel@tonic-gate 			size = EUCWID2;
1760Sstevel@tonic-gate 			break;
1770Sstevel@tonic-gate 
1780Sstevel@tonic-gate 		case MASK3:
1790Sstevel@tonic-gate 			*s++ = SS3;
1800Sstevel@tonic-gate 			size = EUCWID3;
1810Sstevel@tonic-gate 			break;
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate 		default:
184*722Smuffin 			return (-1);
1850Sstevel@tonic-gate 	}
1860Sstevel@tonic-gate 	index = size;
1870Sstevel@tonic-gate 	while(index--) {
1880Sstevel@tonic-gate 		d = wchar | 0200;
1890Sstevel@tonic-gate 		wchar >>= 8;
1900Sstevel@tonic-gate 		if(iscntrl(d))
191*722Smuffin 			return (-1);
1920Sstevel@tonic-gate 		s[index] = d;
1930Sstevel@tonic-gate 	}
194*722Smuffin 	return (s + size - olds);
1950Sstevel@tonic-gate }
196