10db70a6aSJohn Marino /* $FreeBSD: head/lib/libiconv_modules/GBK2K/citrus_gbk2k.c 281550 2015-04-15 09:09:20Z tijl $ */
20d5acd74SJohn Marino /* $NetBSD: citrus_gbk2k.c,v 1.7 2008/06/14 16:01:07 tnozaki Exp $ */
30d5acd74SJohn Marino 
40d5acd74SJohn Marino /*-
50d5acd74SJohn Marino  * Copyright (c)2003 Citrus Project,
60d5acd74SJohn Marino  * All rights reserved.
70d5acd74SJohn Marino  *
80d5acd74SJohn Marino  * Redistribution and use in source and binary forms, with or without
90d5acd74SJohn Marino  * modification, are permitted provided that the following conditions
100d5acd74SJohn Marino  * are met:
110d5acd74SJohn Marino  * 1. Redistributions of source code must retain the above copyright
120d5acd74SJohn Marino  *    notice, this list of conditions and the following disclaimer.
130d5acd74SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
140d5acd74SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
150d5acd74SJohn Marino  *    documentation and/or other materials provided with the distribution.
160d5acd74SJohn Marino  *
170d5acd74SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
180d5acd74SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
190d5acd74SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
200d5acd74SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
210d5acd74SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
220d5acd74SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
230d5acd74SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
240d5acd74SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
250d5acd74SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
260d5acd74SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
270d5acd74SJohn Marino  * SUCH DAMAGE.
280d5acd74SJohn Marino  */
290d5acd74SJohn Marino 
300d5acd74SJohn Marino #include <sys/cdefs.h>
310d5acd74SJohn Marino #include <sys/types.h>
320d5acd74SJohn Marino 
330d5acd74SJohn Marino #include <assert.h>
340d5acd74SJohn Marino #include <errno.h>
350d5acd74SJohn Marino #include <limits.h>
360d5acd74SJohn Marino #include <stdbool.h>
370d5acd74SJohn Marino #include <stddef.h>
380d5acd74SJohn Marino #include <stdio.h>
390d5acd74SJohn Marino #include <stdlib.h>
400d5acd74SJohn Marino #include <string.h>
410d5acd74SJohn Marino #include <wchar.h>
420d5acd74SJohn Marino 
430d5acd74SJohn Marino #include "citrus_namespace.h"
440d5acd74SJohn Marino #include "citrus_types.h"
450d5acd74SJohn Marino #include "citrus_bcs.h"
460d5acd74SJohn Marino #include "citrus_module.h"
470d5acd74SJohn Marino #include "citrus_stdenc.h"
480d5acd74SJohn Marino #include "citrus_gbk2k.h"
490d5acd74SJohn Marino 
500d5acd74SJohn Marino 
510d5acd74SJohn Marino /* ----------------------------------------------------------------------
520d5acd74SJohn Marino  * private stuffs used by templates
530d5acd74SJohn Marino  */
540d5acd74SJohn Marino 
550d5acd74SJohn Marino typedef struct _GBK2KState {
560d5acd74SJohn Marino 	int	 chlen;
570d5acd74SJohn Marino 	char	 ch[4];
580d5acd74SJohn Marino } _GBK2KState;
590d5acd74SJohn Marino 
600d5acd74SJohn Marino typedef struct {
610d5acd74SJohn Marino 	int	 mb_cur_max;
620d5acd74SJohn Marino } _GBK2KEncodingInfo;
630d5acd74SJohn Marino 
640d5acd74SJohn Marino #define _CEI_TO_EI(_cei_)		(&(_cei_)->ei)
650d5acd74SJohn Marino #define _CEI_TO_STATE(_cei_, _func_)	(_cei_)->states.s_##_func_
660d5acd74SJohn Marino 
670d5acd74SJohn Marino #define _FUNCNAME(m)			_citrus_GBK2K_##m
680d5acd74SJohn Marino #define _ENCODING_INFO			_GBK2KEncodingInfo
690d5acd74SJohn Marino #define _ENCODING_STATE			_GBK2KState
700d5acd74SJohn Marino #define _ENCODING_MB_CUR_MAX(_ei_)	(_ei_)->mb_cur_max
710d5acd74SJohn Marino #define _ENCODING_IS_STATE_DEPENDENT	0
720d5acd74SJohn Marino #define _STATE_NEEDS_EXPLICIT_INIT(_ps_)	0
730d5acd74SJohn Marino 
740d5acd74SJohn Marino static __inline void
750d5acd74SJohn Marino /*ARGSUSED*/
_citrus_GBK2K_init_state(_GBK2KEncodingInfo * __restrict ei __unused,_GBK2KState * __restrict s)760d5acd74SJohn Marino _citrus_GBK2K_init_state(_GBK2KEncodingInfo * __restrict ei __unused,
770d5acd74SJohn Marino     _GBK2KState * __restrict s)
780d5acd74SJohn Marino {
790d5acd74SJohn Marino 
800d5acd74SJohn Marino 	memset(s, 0, sizeof(*s));
810d5acd74SJohn Marino }
820d5acd74SJohn Marino 
83*71ea2de5SJohn Marino #if 0
840d5acd74SJohn Marino static __inline void
850d5acd74SJohn Marino /*ARGSUSED*/
860d5acd74SJohn Marino _citrus_GBK2K_pack_state(_GBK2KEncodingInfo * __restrict ei __unused,
870d5acd74SJohn Marino     void * __restrict pspriv, const _GBK2KState * __restrict s)
880d5acd74SJohn Marino {
890d5acd74SJohn Marino 
900d5acd74SJohn Marino 	memcpy(pspriv, (const void *)s, sizeof(*s));
910d5acd74SJohn Marino }
920d5acd74SJohn Marino 
930d5acd74SJohn Marino static __inline void
940d5acd74SJohn Marino /*ARGSUSED*/
950d5acd74SJohn Marino _citrus_GBK2K_unpack_state(_GBK2KEncodingInfo * __restrict ei __unused,
960d5acd74SJohn Marino     _GBK2KState * __restrict s, const void * __restrict pspriv)
970d5acd74SJohn Marino {
980d5acd74SJohn Marino 
990d5acd74SJohn Marino 	memcpy((void *)s, pspriv, sizeof(*s));
1000d5acd74SJohn Marino }
101*71ea2de5SJohn Marino #endif
1020d5acd74SJohn Marino 
1030d5acd74SJohn Marino static  __inline bool
_mb_singlebyte(int c)1040d5acd74SJohn Marino _mb_singlebyte(int c)
1050d5acd74SJohn Marino {
1060d5acd74SJohn Marino 
1070d5acd74SJohn Marino 	return ((c & 0xff) <= 0x7f);
1080d5acd74SJohn Marino }
1090d5acd74SJohn Marino 
1100d5acd74SJohn Marino static __inline bool
_mb_leadbyte(int c)1110d5acd74SJohn Marino _mb_leadbyte(int c)
1120d5acd74SJohn Marino {
1130d5acd74SJohn Marino 
1140d5acd74SJohn Marino 	c &= 0xff;
1150d5acd74SJohn Marino 	return (0x81 <= c && c <= 0xfe);
1160d5acd74SJohn Marino }
1170d5acd74SJohn Marino 
1180d5acd74SJohn Marino static __inline bool
_mb_trailbyte(int c)1190d5acd74SJohn Marino _mb_trailbyte(int c)
1200d5acd74SJohn Marino {
1210d5acd74SJohn Marino 
1220d5acd74SJohn Marino 	c &= 0xff;
1230d5acd74SJohn Marino 	return ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfe));
1240d5acd74SJohn Marino }
1250d5acd74SJohn Marino 
1260d5acd74SJohn Marino static __inline bool
_mb_surrogate(int c)1270d5acd74SJohn Marino _mb_surrogate(int c)
1280d5acd74SJohn Marino {
1290d5acd74SJohn Marino 
1300d5acd74SJohn Marino 	c &= 0xff;
1310d5acd74SJohn Marino 	return (0x30 <= c && c <= 0x39);
1320d5acd74SJohn Marino }
1330d5acd74SJohn Marino 
1340d5acd74SJohn Marino static __inline int
_mb_count(wchar_t v)1350d5acd74SJohn Marino _mb_count(wchar_t v)
1360d5acd74SJohn Marino {
1370d5acd74SJohn Marino 	uint32_t c;
1380d5acd74SJohn Marino 
1390d5acd74SJohn Marino 	c = (uint32_t)v; /* XXX */
1400d5acd74SJohn Marino 	if (!(c & 0xffffff00))
1410d5acd74SJohn Marino 		return (1);
1420d5acd74SJohn Marino 	if (!(c & 0xffff0000))
1430d5acd74SJohn Marino 		return (2);
1440d5acd74SJohn Marino 	return (4);
1450d5acd74SJohn Marino }
1460d5acd74SJohn Marino 
1470d5acd74SJohn Marino #define	_PSENC		(psenc->ch[psenc->chlen - 1])
1480d5acd74SJohn Marino #define	_PUSH_PSENC(c)	(psenc->ch[psenc->chlen++] = (c))
1490d5acd74SJohn Marino 
1500d5acd74SJohn Marino static int
_citrus_GBK2K_mbrtowc_priv(_GBK2KEncodingInfo * __restrict ei,wchar_t * __restrict pwc,char ** __restrict s,size_t n,_GBK2KState * __restrict psenc,size_t * __restrict nresult)1510d5acd74SJohn Marino _citrus_GBK2K_mbrtowc_priv(_GBK2KEncodingInfo * __restrict ei,
1520db70a6aSJohn Marino     wchar_t * __restrict pwc, char ** __restrict s, size_t n,
1530d5acd74SJohn Marino     _GBK2KState * __restrict psenc, size_t * __restrict nresult)
1540d5acd74SJohn Marino {
1550db70a6aSJohn Marino 	char *s0, *s1;
1560d5acd74SJohn Marino 	wchar_t wc;
1570d5acd74SJohn Marino 	int chlenbak, len;
1580d5acd74SJohn Marino 
1590d5acd74SJohn Marino 	s0 = *s;
1600d5acd74SJohn Marino 
1610d5acd74SJohn Marino 	if (s0 == NULL) {
1620d5acd74SJohn Marino 		/* _citrus_GBK2K_init_state(ei, psenc); */
1630d5acd74SJohn Marino 		psenc->chlen = 0;
1640d5acd74SJohn Marino 		*nresult = 0;
1650d5acd74SJohn Marino 		return (0);
1660d5acd74SJohn Marino 	}
1670d5acd74SJohn Marino 
1680d5acd74SJohn Marino 	chlenbak = psenc->chlen;
1690d5acd74SJohn Marino 
1700d5acd74SJohn Marino 	switch (psenc->chlen) {
1710d5acd74SJohn Marino 	case 3:
1720d5acd74SJohn Marino 		if (!_mb_leadbyte (_PSENC))
1730d5acd74SJohn Marino 			goto invalid;
1740d5acd74SJohn Marino 	/* FALLTHROUGH */
1750d5acd74SJohn Marino 	case 2:
1760d5acd74SJohn Marino 		if (!_mb_surrogate(_PSENC) || _mb_trailbyte(_PSENC))
1770d5acd74SJohn Marino 			goto invalid;
1780d5acd74SJohn Marino 	/* FALLTHROUGH */
1790d5acd74SJohn Marino 	case 1:
1800d5acd74SJohn Marino 		if (!_mb_leadbyte (_PSENC))
1810d5acd74SJohn Marino 			goto invalid;
1820d5acd74SJohn Marino 	/* FALLTHOROUGH */
1830d5acd74SJohn Marino 	case 0:
1840d5acd74SJohn Marino 		break;
1850d5acd74SJohn Marino 	default:
1860d5acd74SJohn Marino 		goto invalid;
1870d5acd74SJohn Marino 	}
1880d5acd74SJohn Marino 
1890d5acd74SJohn Marino 	for (;;) {
1900d5acd74SJohn Marino 		if (n-- < 1)
1910d5acd74SJohn Marino 			goto restart;
1920d5acd74SJohn Marino 
1930d5acd74SJohn Marino 		_PUSH_PSENC(*s0++);
1940d5acd74SJohn Marino 
1950d5acd74SJohn Marino 		switch (psenc->chlen) {
1960d5acd74SJohn Marino 		case 1:
1970d5acd74SJohn Marino 			if (_mb_singlebyte(_PSENC))
1980d5acd74SJohn Marino 				goto convert;
1990d5acd74SJohn Marino 			if (_mb_leadbyte  (_PSENC))
2000d5acd74SJohn Marino 				continue;
2010d5acd74SJohn Marino 			goto ilseq;
2020d5acd74SJohn Marino 		case 2:
2030d5acd74SJohn Marino 			if (_mb_trailbyte (_PSENC))
2040d5acd74SJohn Marino 				goto convert;
2050d5acd74SJohn Marino 			if (ei->mb_cur_max == 4 &&
2060d5acd74SJohn Marino 			    _mb_surrogate (_PSENC))
2070d5acd74SJohn Marino 				continue;
2080d5acd74SJohn Marino 			goto ilseq;
2090d5acd74SJohn Marino 		case 3:
2100d5acd74SJohn Marino 			if (_mb_leadbyte  (_PSENC))
2110d5acd74SJohn Marino 				continue;
2120d5acd74SJohn Marino 			goto ilseq;
2130d5acd74SJohn Marino 		case 4:
2140d5acd74SJohn Marino 			if (_mb_surrogate (_PSENC))
2150d5acd74SJohn Marino 				goto convert;
2160d5acd74SJohn Marino 			goto ilseq;
2170d5acd74SJohn Marino 		}
2180d5acd74SJohn Marino 	}
2190d5acd74SJohn Marino 
2200d5acd74SJohn Marino convert:
2210d5acd74SJohn Marino 	len = psenc->chlen;
2220d5acd74SJohn Marino 	s1  = &psenc->ch[0];
2230d5acd74SJohn Marino 	wc  = 0;
2240d5acd74SJohn Marino 	while (len-- > 0)
2250d5acd74SJohn Marino 		wc = (wc << 8) | (*s1++ & 0xff);
2260d5acd74SJohn Marino 
2270d5acd74SJohn Marino 	if (pwc != NULL)
2280d5acd74SJohn Marino 		*pwc = wc;
2290d5acd74SJohn Marino 	*s = s0;
2300d5acd74SJohn Marino 	*nresult = (wc == 0) ? 0 : psenc->chlen - chlenbak;
2310d5acd74SJohn Marino 	/* _citrus_GBK2K_init_state(ei, psenc); */
2320d5acd74SJohn Marino 	psenc->chlen = 0;
2330d5acd74SJohn Marino 
2340d5acd74SJohn Marino 	return (0);
2350d5acd74SJohn Marino 
2360d5acd74SJohn Marino restart:
2370d5acd74SJohn Marino 	*s = s0;
2380d5acd74SJohn Marino 	*nresult = (size_t)-2;
2390d5acd74SJohn Marino 
2400d5acd74SJohn Marino 	return (0);
2410d5acd74SJohn Marino 
2420d5acd74SJohn Marino invalid:
2430d5acd74SJohn Marino 	return (EINVAL);
2440d5acd74SJohn Marino 
2450d5acd74SJohn Marino ilseq:
2460d5acd74SJohn Marino 	*nresult = (size_t)-1;
2470d5acd74SJohn Marino 	return (EILSEQ);
2480d5acd74SJohn Marino }
2490d5acd74SJohn Marino 
2500d5acd74SJohn Marino static int
_citrus_GBK2K_wcrtomb_priv(_GBK2KEncodingInfo * __restrict ei,char * __restrict s,size_t n,wchar_t wc,_GBK2KState * __restrict psenc,size_t * __restrict nresult)2510d5acd74SJohn Marino _citrus_GBK2K_wcrtomb_priv(_GBK2KEncodingInfo * __restrict ei,
2520d5acd74SJohn Marino     char * __restrict s, size_t n, wchar_t wc, _GBK2KState * __restrict psenc,
2530d5acd74SJohn Marino     size_t * __restrict nresult)
2540d5acd74SJohn Marino {
2550d5acd74SJohn Marino 	size_t len;
2560d5acd74SJohn Marino 	int ret;
2570d5acd74SJohn Marino 
2580d5acd74SJohn Marino 	if (psenc->chlen != 0) {
2590d5acd74SJohn Marino 		ret = EINVAL;
2600d5acd74SJohn Marino 		goto err;
2610d5acd74SJohn Marino 	}
2620d5acd74SJohn Marino 
2630d5acd74SJohn Marino 	len = _mb_count(wc);
2640d5acd74SJohn Marino 	if (n < len) {
2650d5acd74SJohn Marino 		ret = E2BIG;
2660d5acd74SJohn Marino 		goto err;
2670d5acd74SJohn Marino 	}
2680d5acd74SJohn Marino 
2690d5acd74SJohn Marino 	switch (len) {
2700d5acd74SJohn Marino 	case 1:
2710d5acd74SJohn Marino 		if (!_mb_singlebyte(_PUSH_PSENC(wc     ))) {
2720d5acd74SJohn Marino 			ret = EILSEQ;
2730d5acd74SJohn Marino 			goto err;
2740d5acd74SJohn Marino 		}
2750d5acd74SJohn Marino 		break;
2760d5acd74SJohn Marino 	case 2:
2770d5acd74SJohn Marino 		if (!_mb_leadbyte  (_PUSH_PSENC(wc >> 8)) ||
2780d5acd74SJohn Marino 		    !_mb_trailbyte (_PUSH_PSENC(wc))) {
2790d5acd74SJohn Marino 			ret = EILSEQ;
2800d5acd74SJohn Marino 			goto err;
2810d5acd74SJohn Marino 		}
2820d5acd74SJohn Marino 		break;
2830d5acd74SJohn Marino 	case 4:
2840d5acd74SJohn Marino 		if (ei->mb_cur_max != 4 ||
2850d5acd74SJohn Marino 		    !_mb_leadbyte  (_PUSH_PSENC(wc >> 24)) ||
2860d5acd74SJohn Marino 		    !_mb_surrogate (_PUSH_PSENC(wc >> 16)) ||
2870d5acd74SJohn Marino 		    !_mb_leadbyte  (_PUSH_PSENC(wc >>  8)) ||
2880d5acd74SJohn Marino 		    !_mb_surrogate (_PUSH_PSENC(wc))) {
2890d5acd74SJohn Marino 			ret = EILSEQ;
2900d5acd74SJohn Marino 			goto err;
2910d5acd74SJohn Marino 		}
2920d5acd74SJohn Marino 		break;
2930d5acd74SJohn Marino 	}
2940d5acd74SJohn Marino 
2950d5acd74SJohn Marino 	memcpy(s, psenc->ch, psenc->chlen);
2960d5acd74SJohn Marino 	*nresult = psenc->chlen;
2970d5acd74SJohn Marino 	/* _citrus_GBK2K_init_state(ei, psenc); */
2980d5acd74SJohn Marino 	psenc->chlen = 0;
2990d5acd74SJohn Marino 
3000d5acd74SJohn Marino 	return (0);
3010d5acd74SJohn Marino 
3020d5acd74SJohn Marino err:
3030d5acd74SJohn Marino 	*nresult = (size_t)-1;
3040d5acd74SJohn Marino 	return (ret);
3050d5acd74SJohn Marino }
3060d5acd74SJohn Marino 
3070d5acd74SJohn Marino static __inline int
3080d5acd74SJohn Marino /*ARGSUSED*/
_citrus_GBK2K_stdenc_wctocs(_GBK2KEncodingInfo * __restrict ei __unused,_csid_t * __restrict csid,_index_t * __restrict idx,wchar_t wc)3090d5acd74SJohn Marino _citrus_GBK2K_stdenc_wctocs(_GBK2KEncodingInfo * __restrict ei __unused,
3100d5acd74SJohn Marino     _csid_t * __restrict csid, _index_t * __restrict idx, wchar_t wc)
3110d5acd74SJohn Marino {
3120d5acd74SJohn Marino 	uint8_t ch, cl;
3130d5acd74SJohn Marino 
3140d5acd74SJohn Marino 	if ((uint32_t)wc < 0x80) {
3150d5acd74SJohn Marino 		/* ISO646 */
3160d5acd74SJohn Marino 		*csid = 0;
3170d5acd74SJohn Marino 		*idx = (_index_t)wc;
3180d5acd74SJohn Marino 	} else if ((uint32_t)wc >= 0x10000) {
3190d5acd74SJohn Marino 		/* GBKUCS : XXX */
3200d5acd74SJohn Marino 		*csid = 3;
3210d5acd74SJohn Marino 		*idx = (_index_t)wc;
3220d5acd74SJohn Marino 	} else {
3230d5acd74SJohn Marino 		ch = (uint8_t)(wc >> 8);
3240d5acd74SJohn Marino 		cl = (uint8_t)wc;
3250d5acd74SJohn Marino 		if (ch >= 0xA1 && cl >= 0xA1) {
3260d5acd74SJohn Marino 			/* EUC G1 */
3270d5acd74SJohn Marino 			*csid = 1;
3280d5acd74SJohn Marino 			*idx = (_index_t)wc & 0x7F7FU;
3290d5acd74SJohn Marino 		} else {
3300d5acd74SJohn Marino 			/* extended area (0x8140-) */
3310d5acd74SJohn Marino 			*csid = 2;
3320d5acd74SJohn Marino 			*idx = (_index_t)wc;
3330d5acd74SJohn Marino 		}
3340d5acd74SJohn Marino 	}
3350d5acd74SJohn Marino 
3360d5acd74SJohn Marino 	return (0);
3370d5acd74SJohn Marino }
3380d5acd74SJohn Marino 
3390d5acd74SJohn Marino static __inline int
3400d5acd74SJohn Marino /*ARGSUSED*/
_citrus_GBK2K_stdenc_cstowc(_GBK2KEncodingInfo * __restrict ei,wchar_t * __restrict wc,_csid_t csid,_index_t idx)3410d5acd74SJohn Marino _citrus_GBK2K_stdenc_cstowc(_GBK2KEncodingInfo * __restrict ei,
3420d5acd74SJohn Marino     wchar_t * __restrict wc, _csid_t csid, _index_t idx)
3430d5acd74SJohn Marino {
3440d5acd74SJohn Marino 
3450d5acd74SJohn Marino 	switch (csid) {
3460d5acd74SJohn Marino 	case 0:
3470d5acd74SJohn Marino 		/* ISO646 */
3480d5acd74SJohn Marino 		*wc = (wchar_t)idx;
3490d5acd74SJohn Marino 		break;
3500d5acd74SJohn Marino 	case 1:
3510d5acd74SJohn Marino 		/* EUC G1 */
3520d5acd74SJohn Marino 		*wc = (wchar_t)idx | 0x8080U;
3530d5acd74SJohn Marino 		break;
3540d5acd74SJohn Marino 	case 2:
3550d5acd74SJohn Marino 		/* extended area */
3560d5acd74SJohn Marino 		*wc = (wchar_t)idx;
3570d5acd74SJohn Marino 		break;
3580d5acd74SJohn Marino 	case 3:
3590d5acd74SJohn Marino 		/* GBKUCS : XXX */
3600d5acd74SJohn Marino 		if (ei->mb_cur_max != 4)
3610d5acd74SJohn Marino 			return (EINVAL);
3620d5acd74SJohn Marino 		*wc = (wchar_t)idx;
3630d5acd74SJohn Marino 		break;
3640d5acd74SJohn Marino 	default:
3650d5acd74SJohn Marino 		return (EILSEQ);
3660d5acd74SJohn Marino 	}
3670d5acd74SJohn Marino 
3680d5acd74SJohn Marino 	return (0);
3690d5acd74SJohn Marino }
3700d5acd74SJohn Marino 
3710d5acd74SJohn Marino static __inline int
3720d5acd74SJohn Marino /*ARGSUSED*/
_citrus_GBK2K_stdenc_get_state_desc_generic(_GBK2KEncodingInfo * __restrict ei __unused,_GBK2KState * __restrict psenc,int * __restrict rstate)3730d5acd74SJohn Marino _citrus_GBK2K_stdenc_get_state_desc_generic(_GBK2KEncodingInfo * __restrict ei __unused,
3740d5acd74SJohn Marino     _GBK2KState * __restrict psenc, int * __restrict rstate)
3750d5acd74SJohn Marino {
3760d5acd74SJohn Marino 
3770d5acd74SJohn Marino 	*rstate = (psenc->chlen == 0) ? _STDENC_SDGEN_INITIAL :
3780d5acd74SJohn Marino 	    _STDENC_SDGEN_INCOMPLETE_CHAR;
3790d5acd74SJohn Marino 	return (0);
3800d5acd74SJohn Marino }
3810d5acd74SJohn Marino 
3820d5acd74SJohn Marino static int
3830d5acd74SJohn Marino /*ARGSUSED*/
_citrus_GBK2K_encoding_module_init(_GBK2KEncodingInfo * __restrict ei,const void * __restrict var,size_t lenvar)3840d5acd74SJohn Marino _citrus_GBK2K_encoding_module_init(_GBK2KEncodingInfo * __restrict ei,
3850d5acd74SJohn Marino     const void * __restrict var, size_t lenvar)
3860d5acd74SJohn Marino {
3870d5acd74SJohn Marino 	const char *p;
3880d5acd74SJohn Marino 
3890d5acd74SJohn Marino 	p = var;
3900d5acd74SJohn Marino 	memset((void *)ei, 0, sizeof(*ei));
3910d5acd74SJohn Marino 	ei->mb_cur_max = 4;
3920d5acd74SJohn Marino 	while (lenvar > 0) {
3930d5acd74SJohn Marino 		switch (_bcs_tolower(*p)) {
3940d5acd74SJohn Marino 		case '2':
3950d5acd74SJohn Marino 			MATCH("2byte", ei->mb_cur_max = 2);
3960d5acd74SJohn Marino 			break;
3970d5acd74SJohn Marino 		}
3980d5acd74SJohn Marino 		p++;
3990d5acd74SJohn Marino 		lenvar--;
4000d5acd74SJohn Marino 	}
4010d5acd74SJohn Marino 
4020d5acd74SJohn Marino 	return (0);
4030d5acd74SJohn Marino }
4040d5acd74SJohn Marino 
4050d5acd74SJohn Marino static void
4060d5acd74SJohn Marino /*ARGSUSED*/
_citrus_GBK2K_encoding_module_uninit(_GBK2KEncodingInfo * ei __unused)4070d5acd74SJohn Marino _citrus_GBK2K_encoding_module_uninit(_GBK2KEncodingInfo *ei __unused)
4080d5acd74SJohn Marino {
4090d5acd74SJohn Marino 
4100d5acd74SJohn Marino }
4110d5acd74SJohn Marino 
4120d5acd74SJohn Marino /* ----------------------------------------------------------------------
4130d5acd74SJohn Marino  * public interface for stdenc
4140d5acd74SJohn Marino  */
4150d5acd74SJohn Marino 
4160d5acd74SJohn Marino _CITRUS_STDENC_DECLS(GBK2K);
4170d5acd74SJohn Marino _CITRUS_STDENC_DEF_OPS(GBK2K);
4180d5acd74SJohn Marino 
4190d5acd74SJohn Marino #include "citrus_stdenc_template.h"
420