1*0db70a6aSJohn Marino /* $FreeBSD: head/lib/libiconv_modules/UTF1632/citrus_utf1632.c 281550 2015-04-15 09:09:20Z tijl $ */
20d5acd74SJohn Marino /* $NetBSD: citrus_utf1632.c,v 1.9 2008/06/14 16:01:08 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/endian.h>
320d5acd74SJohn Marino #include <sys/types.h>
330d5acd74SJohn Marino
340d5acd74SJohn Marino #include <assert.h>
350d5acd74SJohn Marino #include <errno.h>
360d5acd74SJohn Marino #include <limits.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_module.h"
460d5acd74SJohn Marino #include "citrus_stdenc.h"
470d5acd74SJohn Marino #include "citrus_bcs.h"
480d5acd74SJohn Marino
490d5acd74SJohn Marino #include "citrus_utf1632.h"
500d5acd74SJohn Marino
510d5acd74SJohn Marino
520d5acd74SJohn Marino /* ----------------------------------------------------------------------
530d5acd74SJohn Marino * private stuffs used by templates
540d5acd74SJohn Marino */
550d5acd74SJohn Marino
560d5acd74SJohn Marino typedef struct {
570d5acd74SJohn Marino int chlen;
580d5acd74SJohn Marino int current_endian;
590d5acd74SJohn Marino uint8_t ch[4];
600d5acd74SJohn Marino } _UTF1632State;
610d5acd74SJohn Marino
620d5acd74SJohn Marino #define _ENDIAN_UNKNOWN 0
630d5acd74SJohn Marino #define _ENDIAN_BIG 1
640d5acd74SJohn Marino #define _ENDIAN_LITTLE 2
650d5acd74SJohn Marino #if BYTE_ORDER == BIG_ENDIAN
660d5acd74SJohn Marino #define _ENDIAN_INTERNAL _ENDIAN_BIG
670d5acd74SJohn Marino #define _ENDIAN_SWAPPED _ENDIAN_LITTLE
680d5acd74SJohn Marino #else
690d5acd74SJohn Marino #define _ENDIAN_INTERNAL _ENDIAN_LITTLE
700d5acd74SJohn Marino #define _ENDIAN_SWAPPED _ENDIAN_BIG
710d5acd74SJohn Marino #endif
720d5acd74SJohn Marino #define _MODE_UTF32 0x00000001U
730d5acd74SJohn Marino #define _MODE_FORCE_ENDIAN 0x00000002U
740d5acd74SJohn Marino
750d5acd74SJohn Marino typedef struct {
760d5acd74SJohn Marino int preffered_endian;
770d5acd74SJohn Marino unsigned int cur_max;
780d5acd74SJohn Marino uint32_t mode;
790d5acd74SJohn Marino } _UTF1632EncodingInfo;
800d5acd74SJohn Marino
810d5acd74SJohn Marino #define _FUNCNAME(m) _citrus_UTF1632_##m
820d5acd74SJohn Marino #define _ENCODING_INFO _UTF1632EncodingInfo
830d5acd74SJohn Marino #define _ENCODING_STATE _UTF1632State
840d5acd74SJohn Marino #define _ENCODING_MB_CUR_MAX(_ei_) ((_ei_)->cur_max)
850d5acd74SJohn Marino #define _ENCODING_IS_STATE_DEPENDENT 0
860d5acd74SJohn Marino #define _STATE_NEEDS_EXPLICIT_INIT(_ps_) 0
870d5acd74SJohn Marino
880d5acd74SJohn Marino
890d5acd74SJohn Marino static __inline void
900d5acd74SJohn Marino /*ARGSUSED*/
_citrus_UTF1632_init_state(_UTF1632EncodingInfo * ei __unused,_UTF1632State * s)910d5acd74SJohn Marino _citrus_UTF1632_init_state(_UTF1632EncodingInfo *ei __unused,
920d5acd74SJohn Marino _UTF1632State *s)
930d5acd74SJohn Marino {
940d5acd74SJohn Marino
950d5acd74SJohn Marino memset(s, 0, sizeof(*s));
960d5acd74SJohn Marino }
970d5acd74SJohn Marino
980d5acd74SJohn Marino static int
_citrus_UTF1632_mbrtowc_priv(_UTF1632EncodingInfo * ei,wchar_t * pwc,char ** s,size_t n,_UTF1632State * psenc,size_t * nresult)990d5acd74SJohn Marino _citrus_UTF1632_mbrtowc_priv(_UTF1632EncodingInfo *ei, wchar_t *pwc,
100*0db70a6aSJohn Marino char **s, size_t n, _UTF1632State *psenc, size_t *nresult)
1010d5acd74SJohn Marino {
102*0db70a6aSJohn Marino char *s0;
1030d5acd74SJohn Marino size_t result;
1040d5acd74SJohn Marino wchar_t wc = L'\0';
1050d5acd74SJohn Marino int chlenbak, endian, needlen;
1060d5acd74SJohn Marino
1070d5acd74SJohn Marino s0 = *s;
1080d5acd74SJohn Marino
1090d5acd74SJohn Marino if (s0 == NULL) {
1100d5acd74SJohn Marino _citrus_UTF1632_init_state(ei, psenc);
1110d5acd74SJohn Marino *nresult = 0; /* state independent */
1120d5acd74SJohn Marino return (0);
1130d5acd74SJohn Marino }
1140d5acd74SJohn Marino
1150d5acd74SJohn Marino result = 0;
1160d5acd74SJohn Marino chlenbak = psenc->chlen;
1170d5acd74SJohn Marino
1180d5acd74SJohn Marino refetch:
1190d5acd74SJohn Marino needlen = ((ei->mode & _MODE_UTF32) != 0 || chlenbak >= 2) ? 4 : 2;
1200d5acd74SJohn Marino
1210d5acd74SJohn Marino while (chlenbak < needlen) {
1220d5acd74SJohn Marino if (n == 0)
1230d5acd74SJohn Marino goto restart;
1240d5acd74SJohn Marino psenc->ch[chlenbak++] = *s0++;
1250d5acd74SJohn Marino n--;
1260d5acd74SJohn Marino result++;
1270d5acd74SJohn Marino }
1280d5acd74SJohn Marino
1290d5acd74SJohn Marino /* judge endian marker */
1300d5acd74SJohn Marino if ((ei->mode & _MODE_UTF32) == 0) {
1310d5acd74SJohn Marino /* UTF16 */
1320d5acd74SJohn Marino if (psenc->ch[0] == 0xFE && psenc->ch[1] == 0xFF) {
1330d5acd74SJohn Marino psenc->current_endian = _ENDIAN_BIG;
1340d5acd74SJohn Marino chlenbak = 0;
1350d5acd74SJohn Marino goto refetch;
1360d5acd74SJohn Marino } else if (psenc->ch[0] == 0xFF && psenc->ch[1] == 0xFE) {
1370d5acd74SJohn Marino psenc->current_endian = _ENDIAN_LITTLE;
1380d5acd74SJohn Marino chlenbak = 0;
1390d5acd74SJohn Marino goto refetch;
1400d5acd74SJohn Marino }
1410d5acd74SJohn Marino } else {
1420d5acd74SJohn Marino /* UTF32 */
1430d5acd74SJohn Marino if (psenc->ch[0] == 0x00 && psenc->ch[1] == 0x00 &&
1440d5acd74SJohn Marino psenc->ch[2] == 0xFE && psenc->ch[3] == 0xFF) {
1450d5acd74SJohn Marino psenc->current_endian = _ENDIAN_BIG;
1460d5acd74SJohn Marino chlenbak = 0;
1470d5acd74SJohn Marino goto refetch;
1480d5acd74SJohn Marino } else if (psenc->ch[0] == 0xFF && psenc->ch[1] == 0xFE &&
1490d5acd74SJohn Marino psenc->ch[2] == 0x00 && psenc->ch[3] == 0x00) {
1500d5acd74SJohn Marino psenc->current_endian = _ENDIAN_LITTLE;
1510d5acd74SJohn Marino chlenbak = 0;
1520d5acd74SJohn Marino goto refetch;
1530d5acd74SJohn Marino }
1540d5acd74SJohn Marino }
1550d5acd74SJohn Marino endian = ((ei->mode & _MODE_FORCE_ENDIAN) != 0 ||
1560d5acd74SJohn Marino psenc->current_endian == _ENDIAN_UNKNOWN) ? ei->preffered_endian :
1570d5acd74SJohn Marino psenc->current_endian;
1580d5acd74SJohn Marino
1590d5acd74SJohn Marino /* get wc */
1600d5acd74SJohn Marino if ((ei->mode & _MODE_UTF32) == 0) {
1610d5acd74SJohn Marino /* UTF16 */
1620d5acd74SJohn Marino if (needlen == 2) {
1630d5acd74SJohn Marino switch (endian) {
1640d5acd74SJohn Marino case _ENDIAN_LITTLE:
1650d5acd74SJohn Marino wc = (psenc->ch[0] |
1660d5acd74SJohn Marino ((wchar_t)psenc->ch[1] << 8));
1670d5acd74SJohn Marino break;
1680d5acd74SJohn Marino case _ENDIAN_BIG:
1690d5acd74SJohn Marino wc = (psenc->ch[1] |
1700d5acd74SJohn Marino ((wchar_t)psenc->ch[0] << 8));
1710d5acd74SJohn Marino break;
1720d5acd74SJohn Marino default:
1730d5acd74SJohn Marino goto ilseq;
1740d5acd74SJohn Marino }
1750d5acd74SJohn Marino if (wc >= 0xD800 && wc <= 0xDBFF) {
1760d5acd74SJohn Marino /* surrogate high */
1770d5acd74SJohn Marino needlen = 4;
1780d5acd74SJohn Marino goto refetch;
1790d5acd74SJohn Marino }
1800d5acd74SJohn Marino } else {
1810d5acd74SJohn Marino /* surrogate low */
1820d5acd74SJohn Marino wc -= 0xD800; /* wc : surrogate high (see above) */
1830d5acd74SJohn Marino wc <<= 10;
1840d5acd74SJohn Marino switch (endian) {
1850d5acd74SJohn Marino case _ENDIAN_LITTLE:
1860d5acd74SJohn Marino if (psenc->ch[3] < 0xDC || psenc->ch[3] > 0xDF)
1870d5acd74SJohn Marino goto ilseq;
1880d5acd74SJohn Marino wc |= psenc->ch[2];
1890d5acd74SJohn Marino wc |= (wchar_t)(psenc->ch[3] & 3) << 8;
1900d5acd74SJohn Marino break;
1910d5acd74SJohn Marino case _ENDIAN_BIG:
1920d5acd74SJohn Marino if (psenc->ch[2]<0xDC || psenc->ch[2]>0xDF)
1930d5acd74SJohn Marino goto ilseq;
1940d5acd74SJohn Marino wc |= psenc->ch[3];
1950d5acd74SJohn Marino wc |= (wchar_t)(psenc->ch[2] & 3) << 8;
1960d5acd74SJohn Marino break;
1970d5acd74SJohn Marino default:
1980d5acd74SJohn Marino goto ilseq;
1990d5acd74SJohn Marino }
2000d5acd74SJohn Marino wc += 0x10000;
2010d5acd74SJohn Marino }
2020d5acd74SJohn Marino } else {
2030d5acd74SJohn Marino /* UTF32 */
2040d5acd74SJohn Marino switch (endian) {
2050d5acd74SJohn Marino case _ENDIAN_LITTLE:
2060d5acd74SJohn Marino wc = (psenc->ch[0] |
2070d5acd74SJohn Marino ((wchar_t)psenc->ch[1] << 8) |
2080d5acd74SJohn Marino ((wchar_t)psenc->ch[2] << 16) |
2090d5acd74SJohn Marino ((wchar_t)psenc->ch[3] << 24));
2100d5acd74SJohn Marino break;
2110d5acd74SJohn Marino case _ENDIAN_BIG:
2120d5acd74SJohn Marino wc = (psenc->ch[3] |
2130d5acd74SJohn Marino ((wchar_t)psenc->ch[2] << 8) |
2140d5acd74SJohn Marino ((wchar_t)psenc->ch[1] << 16) |
2150d5acd74SJohn Marino ((wchar_t)psenc->ch[0] << 24));
2160d5acd74SJohn Marino break;
2170d5acd74SJohn Marino default:
2180d5acd74SJohn Marino goto ilseq;
2190d5acd74SJohn Marino }
2200d5acd74SJohn Marino if (wc >= 0xD800 && wc <= 0xDFFF)
2210d5acd74SJohn Marino goto ilseq;
2220d5acd74SJohn Marino }
2230d5acd74SJohn Marino
2240d5acd74SJohn Marino
2250d5acd74SJohn Marino *pwc = wc;
2260d5acd74SJohn Marino psenc->chlen = 0;
2270d5acd74SJohn Marino *nresult = result;
2280d5acd74SJohn Marino *s = s0;
2290d5acd74SJohn Marino
2300d5acd74SJohn Marino return (0);
2310d5acd74SJohn Marino
2320d5acd74SJohn Marino ilseq:
2330d5acd74SJohn Marino *nresult = (size_t)-1;
2340d5acd74SJohn Marino psenc->chlen = 0;
2350d5acd74SJohn Marino return (EILSEQ);
2360d5acd74SJohn Marino
2370d5acd74SJohn Marino restart:
2380d5acd74SJohn Marino *nresult = (size_t)-2;
2390d5acd74SJohn Marino psenc->chlen = chlenbak;
2400d5acd74SJohn Marino *s = s0;
2410d5acd74SJohn Marino return (0);
2420d5acd74SJohn Marino }
2430d5acd74SJohn Marino
2440d5acd74SJohn Marino static int
_citrus_UTF1632_wcrtomb_priv(_UTF1632EncodingInfo * ei,char * s,size_t n,wchar_t wc,_UTF1632State * psenc,size_t * nresult)2450d5acd74SJohn Marino _citrus_UTF1632_wcrtomb_priv(_UTF1632EncodingInfo *ei, char *s, size_t n,
2460d5acd74SJohn Marino wchar_t wc, _UTF1632State *psenc, size_t *nresult)
2470d5acd74SJohn Marino {
2480d5acd74SJohn Marino wchar_t wc2;
2490d5acd74SJohn Marino static const char _bom[4] = {
2500d5acd74SJohn Marino 0x00, 0x00, 0xFE, 0xFF,
2510d5acd74SJohn Marino };
2520d5acd74SJohn Marino const char *bom = &_bom[0];
2530d5acd74SJohn Marino size_t cnt;
2540d5acd74SJohn Marino
2550d5acd74SJohn Marino cnt = (size_t)0;
2560d5acd74SJohn Marino if (psenc->current_endian == _ENDIAN_UNKNOWN) {
2570d5acd74SJohn Marino if ((ei->mode & _MODE_FORCE_ENDIAN) == 0) {
2580d5acd74SJohn Marino if (ei->mode & _MODE_UTF32)
2590d5acd74SJohn Marino cnt = 4;
2600d5acd74SJohn Marino else {
2610d5acd74SJohn Marino cnt = 2;
2620d5acd74SJohn Marino bom += 2;
2630d5acd74SJohn Marino }
2640d5acd74SJohn Marino if (n < cnt)
2650d5acd74SJohn Marino goto e2big;
2660d5acd74SJohn Marino memcpy(s, bom, cnt);
2670d5acd74SJohn Marino s += cnt, n -= cnt;
2680d5acd74SJohn Marino }
2690d5acd74SJohn Marino psenc->current_endian = ei->preffered_endian;
2700d5acd74SJohn Marino }
2710d5acd74SJohn Marino
2720d5acd74SJohn Marino wc2 = 0;
2730d5acd74SJohn Marino if ((ei->mode & _MODE_UTF32)==0) {
2740d5acd74SJohn Marino /* UTF16 */
2750d5acd74SJohn Marino if (wc > 0xFFFF) {
2760d5acd74SJohn Marino /* surrogate */
2770d5acd74SJohn Marino if (wc > 0x10FFFF)
2780d5acd74SJohn Marino goto ilseq;
2790d5acd74SJohn Marino if (n < 4)
2800d5acd74SJohn Marino goto e2big;
2810d5acd74SJohn Marino cnt += 4;
2820d5acd74SJohn Marino wc -= 0x10000;
2830d5acd74SJohn Marino wc2 = (wc & 0x3FF) | 0xDC00;
2840d5acd74SJohn Marino wc = (wc>>10) | 0xD800;
2850d5acd74SJohn Marino } else {
2860d5acd74SJohn Marino if (n < 2)
2870d5acd74SJohn Marino goto e2big;
2880d5acd74SJohn Marino cnt += 2;
2890d5acd74SJohn Marino }
2900d5acd74SJohn Marino
2910d5acd74SJohn Marino surrogate:
2920d5acd74SJohn Marino switch (psenc->current_endian) {
2930d5acd74SJohn Marino case _ENDIAN_BIG:
2940d5acd74SJohn Marino s[1] = wc;
2950d5acd74SJohn Marino s[0] = (wc >>= 8);
2960d5acd74SJohn Marino break;
2970d5acd74SJohn Marino case _ENDIAN_LITTLE:
2980d5acd74SJohn Marino s[0] = wc;
2990d5acd74SJohn Marino s[1] = (wc >>= 8);
3000d5acd74SJohn Marino break;
3010d5acd74SJohn Marino }
3020d5acd74SJohn Marino if (wc2 != 0) {
3030d5acd74SJohn Marino wc = wc2;
3040d5acd74SJohn Marino wc2 = 0;
3050d5acd74SJohn Marino s += 2;
3060d5acd74SJohn Marino goto surrogate;
3070d5acd74SJohn Marino }
3080d5acd74SJohn Marino } else {
3090d5acd74SJohn Marino /* UTF32 */
3100d5acd74SJohn Marino if (wc >= 0xD800 && wc <= 0xDFFF)
3110d5acd74SJohn Marino goto ilseq;
3120d5acd74SJohn Marino if (n < 4)
3130d5acd74SJohn Marino goto e2big;
3140d5acd74SJohn Marino cnt += 4;
3150d5acd74SJohn Marino switch (psenc->current_endian) {
3160d5acd74SJohn Marino case _ENDIAN_BIG:
3170d5acd74SJohn Marino s[3] = wc;
3180d5acd74SJohn Marino s[2] = (wc >>= 8);
3190d5acd74SJohn Marino s[1] = (wc >>= 8);
3200d5acd74SJohn Marino s[0] = (wc >>= 8);
3210d5acd74SJohn Marino break;
3220d5acd74SJohn Marino case _ENDIAN_LITTLE:
3230d5acd74SJohn Marino s[0] = wc;
3240d5acd74SJohn Marino s[1] = (wc >>= 8);
3250d5acd74SJohn Marino s[2] = (wc >>= 8);
3260d5acd74SJohn Marino s[3] = (wc >>= 8);
3270d5acd74SJohn Marino break;
3280d5acd74SJohn Marino }
3290d5acd74SJohn Marino }
3300d5acd74SJohn Marino *nresult = cnt;
3310d5acd74SJohn Marino
3320d5acd74SJohn Marino return (0);
3330d5acd74SJohn Marino
3340d5acd74SJohn Marino ilseq:
3350d5acd74SJohn Marino *nresult = (size_t)-1;
3360d5acd74SJohn Marino return (EILSEQ);
3370d5acd74SJohn Marino e2big:
3380d5acd74SJohn Marino *nresult = (size_t)-1;
3390d5acd74SJohn Marino return (E2BIG);
3400d5acd74SJohn Marino }
3410d5acd74SJohn Marino
3420d5acd74SJohn Marino static void
parse_variable(_UTF1632EncodingInfo * __restrict ei,const void * __restrict var,size_t lenvar)3430d5acd74SJohn Marino parse_variable(_UTF1632EncodingInfo * __restrict ei,
3440d5acd74SJohn Marino const void * __restrict var, size_t lenvar)
3450d5acd74SJohn Marino {
3460d5acd74SJohn Marino const char *p;
3470d5acd74SJohn Marino
3480d5acd74SJohn Marino p = var;
3490d5acd74SJohn Marino while (lenvar > 0) {
3500d5acd74SJohn Marino switch (*p) {
3510d5acd74SJohn Marino case 'B':
3520d5acd74SJohn Marino case 'b':
3530d5acd74SJohn Marino MATCH(big, ei->preffered_endian = _ENDIAN_BIG);
3540d5acd74SJohn Marino break;
3550d5acd74SJohn Marino case 'L':
3560d5acd74SJohn Marino case 'l':
3570d5acd74SJohn Marino MATCH(little, ei->preffered_endian = _ENDIAN_LITTLE);
3580d5acd74SJohn Marino break;
3590d5acd74SJohn Marino case 'i':
3600d5acd74SJohn Marino case 'I':
3610d5acd74SJohn Marino MATCH(internal, ei->preffered_endian = _ENDIAN_INTERNAL);
3620d5acd74SJohn Marino break;
3630d5acd74SJohn Marino case 's':
3640d5acd74SJohn Marino case 'S':
3650d5acd74SJohn Marino MATCH(swapped, ei->preffered_endian = _ENDIAN_SWAPPED);
3660d5acd74SJohn Marino break;
3670d5acd74SJohn Marino case 'F':
3680d5acd74SJohn Marino case 'f':
3690d5acd74SJohn Marino MATCH(force, ei->mode |= _MODE_FORCE_ENDIAN);
3700d5acd74SJohn Marino break;
3710d5acd74SJohn Marino case 'U':
3720d5acd74SJohn Marino case 'u':
3730d5acd74SJohn Marino MATCH(utf32, ei->mode |= _MODE_UTF32);
3740d5acd74SJohn Marino break;
3750d5acd74SJohn Marino }
3760d5acd74SJohn Marino p++;
3770d5acd74SJohn Marino lenvar--;
3780d5acd74SJohn Marino }
3790d5acd74SJohn Marino }
3800d5acd74SJohn Marino
3810d5acd74SJohn Marino static int
3820d5acd74SJohn Marino /*ARGSUSED*/
_citrus_UTF1632_encoding_module_init(_UTF1632EncodingInfo * __restrict ei,const void * __restrict var,size_t lenvar)3830d5acd74SJohn Marino _citrus_UTF1632_encoding_module_init(_UTF1632EncodingInfo * __restrict ei,
3840d5acd74SJohn Marino const void * __restrict var, size_t lenvar)
3850d5acd74SJohn Marino {
3860d5acd74SJohn Marino
3870d5acd74SJohn Marino memset((void *)ei, 0, sizeof(*ei));
3880d5acd74SJohn Marino
3890d5acd74SJohn Marino parse_variable(ei, var, lenvar);
3900d5acd74SJohn Marino
3910d5acd74SJohn Marino ei->cur_max = ((ei->mode&_MODE_UTF32) == 0) ? 6 : 8;
3920d5acd74SJohn Marino /* 6: endian + surrogate */
3930d5acd74SJohn Marino /* 8: endian + normal */
3940d5acd74SJohn Marino
3950d5acd74SJohn Marino if (ei->preffered_endian == _ENDIAN_UNKNOWN) {
3960d5acd74SJohn Marino ei->preffered_endian = _ENDIAN_BIG;
3970d5acd74SJohn Marino }
3980d5acd74SJohn Marino
3990d5acd74SJohn Marino return (0);
4000d5acd74SJohn Marino }
4010d5acd74SJohn Marino
4020d5acd74SJohn Marino static void
4030d5acd74SJohn Marino /*ARGSUSED*/
_citrus_UTF1632_encoding_module_uninit(_UTF1632EncodingInfo * ei __unused)4040d5acd74SJohn Marino _citrus_UTF1632_encoding_module_uninit(_UTF1632EncodingInfo *ei __unused)
4050d5acd74SJohn Marino {
4060d5acd74SJohn Marino
4070d5acd74SJohn Marino }
4080d5acd74SJohn Marino
4090d5acd74SJohn Marino static __inline int
4100d5acd74SJohn Marino /*ARGSUSED*/
_citrus_UTF1632_stdenc_wctocs(_UTF1632EncodingInfo * __restrict ei __unused,_csid_t * __restrict csid,_index_t * __restrict idx,_wc_t wc)4110d5acd74SJohn Marino _citrus_UTF1632_stdenc_wctocs(_UTF1632EncodingInfo * __restrict ei __unused,
4120d5acd74SJohn Marino _csid_t * __restrict csid, _index_t * __restrict idx, _wc_t wc)
4130d5acd74SJohn Marino {
4140d5acd74SJohn Marino
4150d5acd74SJohn Marino *csid = 0;
4160d5acd74SJohn Marino *idx = (_index_t)wc;
4170d5acd74SJohn Marino
4180d5acd74SJohn Marino return (0);
4190d5acd74SJohn Marino }
4200d5acd74SJohn Marino
4210d5acd74SJohn Marino static __inline int
4220d5acd74SJohn Marino /*ARGSUSED*/
_citrus_UTF1632_stdenc_cstowc(_UTF1632EncodingInfo * __restrict ei __unused,_wc_t * __restrict wc,_csid_t csid,_index_t idx)4230d5acd74SJohn Marino _citrus_UTF1632_stdenc_cstowc(_UTF1632EncodingInfo * __restrict ei __unused,
4240d5acd74SJohn Marino _wc_t * __restrict wc, _csid_t csid, _index_t idx)
4250d5acd74SJohn Marino {
4260d5acd74SJohn Marino
4270d5acd74SJohn Marino if (csid != 0)
4280d5acd74SJohn Marino return (EILSEQ);
4290d5acd74SJohn Marino
4300d5acd74SJohn Marino *wc = (_wc_t)idx;
4310d5acd74SJohn Marino
4320d5acd74SJohn Marino return (0);
4330d5acd74SJohn Marino }
4340d5acd74SJohn Marino
4350d5acd74SJohn Marino static __inline int
4360d5acd74SJohn Marino /*ARGSUSED*/
_citrus_UTF1632_stdenc_get_state_desc_generic(_UTF1632EncodingInfo * __restrict ei __unused,_UTF1632State * __restrict psenc,int * __restrict rstate)4370d5acd74SJohn Marino _citrus_UTF1632_stdenc_get_state_desc_generic(_UTF1632EncodingInfo * __restrict ei __unused,
4380d5acd74SJohn Marino _UTF1632State * __restrict psenc, int * __restrict rstate)
4390d5acd74SJohn Marino {
4400d5acd74SJohn Marino
4410d5acd74SJohn Marino *rstate = (psenc->chlen == 0) ? _STDENC_SDGEN_INITIAL :
4420d5acd74SJohn Marino _STDENC_SDGEN_INCOMPLETE_CHAR;
4430d5acd74SJohn Marino return (0);
4440d5acd74SJohn Marino }
4450d5acd74SJohn Marino
4460d5acd74SJohn Marino /* ----------------------------------------------------------------------
4470d5acd74SJohn Marino * public interface for stdenc
4480d5acd74SJohn Marino */
4490d5acd74SJohn Marino
4500d5acd74SJohn Marino _CITRUS_STDENC_DECLS(UTF1632);
4510d5acd74SJohn Marino _CITRUS_STDENC_DEF_OPS(UTF1632);
4520d5acd74SJohn Marino
4530d5acd74SJohn Marino #include "citrus_stdenc_template.h"
454