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