1219019Sgabor/* $FreeBSD: stable/10/lib/libc/iconv/citrus_none.c 326241 2017-11-27 02:44:36Z pfg $ */
2219019Sgabor/* $NetBSD: citrus_none.c,v 1.18 2008/06/14 16:01:07 tnozaki Exp $ */
3219019Sgabor
4219019Sgabor/*-
5219019Sgabor * Copyright (c) 2002 Citrus Project,
6219019Sgabor * Copyright (c) 2010 Gabor Kovesdan <gabor@FreeBSD.org>,
7219019Sgabor * All rights reserved.
8219019Sgabor *
9219019Sgabor * Redistribution and use in source and binary forms, with or without
10219019Sgabor * modification, are permitted provided that the following conditions
11219019Sgabor * are met:
12219019Sgabor * 1. Redistributions of source code must retain the above copyright
13219019Sgabor *    notice, this list of conditions and the following disclaimer.
14219019Sgabor * 2. Redistributions in binary form must reproduce the above copyright
15219019Sgabor *    notice, this list of conditions and the following disclaimer in the
16219019Sgabor *    documentation and/or other materials provided with the distribution.
17219019Sgabor *
18219019Sgabor * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19219019Sgabor * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20219019Sgabor * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21219019Sgabor * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22219019Sgabor * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23219019Sgabor * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24219019Sgabor * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25219019Sgabor * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26219019Sgabor * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27219019Sgabor * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28219019Sgabor * SUCH DAMAGE.
29219019Sgabor */
30219019Sgabor
31219019Sgabor#include <sys/cdefs.h>
32219019Sgabor#include <sys/types.h>
33219019Sgabor
34219019Sgabor#include <assert.h>
35219019Sgabor#include <errno.h>
36219019Sgabor#include <iconv.h>
37219019Sgabor#include <stddef.h>
38219019Sgabor#include <stdio.h>
39219019Sgabor#include <stdlib.h>
40219019Sgabor#include <string.h>
41219019Sgabor#include <wchar.h>
42219019Sgabor
43219019Sgabor#include "citrus_namespace.h"
44219019Sgabor#include "citrus_types.h"
45219019Sgabor#include "citrus_module.h"
46219019Sgabor#include "citrus_none.h"
47219019Sgabor#include "citrus_stdenc.h"
48219019Sgabor
49219019Sgabor_CITRUS_STDENC_DECLS(NONE);
50219019Sgabor_CITRUS_STDENC_DEF_OPS(NONE);
51219019Sgaborstruct _citrus_stdenc_traits _citrus_NONE_stdenc_traits = {
52219019Sgabor	0,	/* et_state_size */
53219019Sgabor	1,	/* mb_cur_max */
54219019Sgabor};
55219019Sgabor
56219019Sgaborstatic int
57219019Sgabor_citrus_NONE_stdenc_init(struct _citrus_stdenc * __restrict ce,
58219019Sgabor    const void *var __unused, size_t lenvar __unused,
59219019Sgabor    struct _citrus_stdenc_traits * __restrict et)
60219019Sgabor{
61219019Sgabor
62219019Sgabor	et->et_state_size = 0;
63219019Sgabor	et->et_mb_cur_max = 1;
64219019Sgabor
65219019Sgabor	ce->ce_closure = NULL;
66219019Sgabor
67219019Sgabor	return (0);
68219019Sgabor}
69219019Sgabor
70219019Sgaborstatic void
71219019Sgabor_citrus_NONE_stdenc_uninit(struct _citrus_stdenc *ce __unused)
72219019Sgabor{
73219019Sgabor
74219019Sgabor}
75219019Sgabor
76219019Sgaborstatic int
77219019Sgabor_citrus_NONE_stdenc_init_state(struct _citrus_stdenc * __restrict ce __unused,
78219019Sgabor    void * __restrict ps __unused)
79219019Sgabor{
80219019Sgabor
81219019Sgabor	return (0);
82219019Sgabor}
83219019Sgabor
84219019Sgaborstatic int
85219019Sgabor_citrus_NONE_stdenc_mbtocs(struct _citrus_stdenc * __restrict ce __unused,
86282275Stijl    _csid_t *csid, _index_t *idx, char **s, size_t n,
87219019Sgabor    void *ps __unused, size_t *nresult, struct iconv_hooks *hooks)
88219019Sgabor{
89219019Sgabor
90219019Sgabor	if (n < 1) {
91219019Sgabor		*nresult = (size_t)-2;
92219019Sgabor		return (0);
93219019Sgabor	}
94219019Sgabor
95219019Sgabor	*csid = 0;
96219019Sgabor	*idx = (_index_t)(unsigned char)*(*s)++;
97219019Sgabor	*nresult = *idx == 0 ? 0 : 1;
98219019Sgabor
99219019Sgabor	if ((hooks != NULL) && (hooks->uc_hook != NULL))
100219019Sgabor		hooks->uc_hook((unsigned int)*idx, hooks->data);
101219019Sgabor
102219019Sgabor	return (0);
103219019Sgabor}
104219019Sgabor
105219019Sgaborstatic int
106219019Sgabor_citrus_NONE_stdenc_cstomb(struct _citrus_stdenc * __restrict ce __unused,
107219019Sgabor    char *s, size_t n, _csid_t csid, _index_t idx, void *ps __unused,
108219019Sgabor    size_t *nresult, struct iconv_hooks *hooks __unused)
109219019Sgabor{
110219019Sgabor
111219019Sgabor	if (csid == _CITRUS_CSID_INVALID) {
112219019Sgabor		*nresult = 0;
113219019Sgabor		return (0);
114219019Sgabor	}
115219019Sgabor	if (csid != 0)
116219019Sgabor		return (EILSEQ);
117219019Sgabor
118219019Sgabor	if ((idx & 0x000000FF) == idx) {
119219019Sgabor		if (n < 1) {
120219019Sgabor			*nresult = (size_t)-1;
121219019Sgabor			return (E2BIG);
122219019Sgabor		}
123219019Sgabor		*s = (char)idx;
124219019Sgabor		*nresult = 1;
125219019Sgabor	} else if ((idx & 0x0000FFFF) == idx) {
126219019Sgabor		if (n < 2) {
127219019Sgabor			*nresult = (size_t)-1;
128219019Sgabor			return (E2BIG);
129219019Sgabor		}
130219019Sgabor		s[0] = (char)idx;
131219019Sgabor		/* XXX: might be endian dependent */
132219019Sgabor		s[1] = (char)(idx >> 8);
133219019Sgabor		*nresult = 2;
134219019Sgabor	} else if ((idx & 0x00FFFFFF) == idx) {
135219019Sgabor		if (n < 3) {
136219019Sgabor			*nresult = (size_t)-1;
137219019Sgabor			return (E2BIG);
138219019Sgabor		}
139219019Sgabor		s[0] = (char)idx;
140219019Sgabor		/* XXX: might be endian dependent */
141219019Sgabor		s[1] = (char)(idx >> 8);
142219019Sgabor		s[2] = (char)(idx >> 16);
143219019Sgabor		*nresult = 3;
144219019Sgabor	} else {
145219019Sgabor		if (n < 3) {
146219019Sgabor			*nresult = (size_t)-1;
147219019Sgabor			return (E2BIG);
148219019Sgabor		}
149219019Sgabor		s[0] = (char)idx;
150219019Sgabor		/* XXX: might be endian dependent */
151219019Sgabor		s[1] = (char)(idx >> 8);
152219019Sgabor		s[2] = (char)(idx >> 16);
153219019Sgabor		s[3] = (char)(idx >> 24);
154219019Sgabor		*nresult = 4;
155219019Sgabor	}
156219019Sgabor
157219019Sgabor	return (0);
158219019Sgabor}
159219019Sgabor
160219019Sgaborstatic int
161219019Sgabor_citrus_NONE_stdenc_mbtowc(struct _citrus_stdenc * __restrict ce __unused,
162282275Stijl    _wc_t * __restrict pwc, char ** __restrict s, size_t n,
163219019Sgabor    void * __restrict pspriv __unused, size_t * __restrict nresult,
164219019Sgabor    struct iconv_hooks *hooks)
165219019Sgabor{
166219019Sgabor
167326241Spfg	if (*s == NULL) {
168219019Sgabor		*nresult = 0;
169219019Sgabor		return (0);
170219019Sgabor	}
171219019Sgabor	if (n == 0) {
172219019Sgabor		*nresult = (size_t)-2;
173219019Sgabor		return (0);
174219019Sgabor	}
175219019Sgabor
176219019Sgabor	if (pwc != NULL)
177219019Sgabor		*pwc = (_wc_t)(unsigned char) **s;
178219019Sgabor
179326241Spfg	*nresult = **s == '\0' ? 0 : 1;
180219019Sgabor
181219019Sgabor	if ((hooks != NULL) && (hooks->wc_hook != NULL))
182219019Sgabor		hooks->wc_hook(*pwc, hooks->data);
183219019Sgabor
184219019Sgabor	return (0);
185219019Sgabor}
186219019Sgabor
187219019Sgaborstatic int
188219019Sgabor_citrus_NONE_stdenc_wctomb(struct _citrus_stdenc * __restrict ce __unused,
189219019Sgabor    char * __restrict s, size_t n, _wc_t wc,
190219019Sgabor    void * __restrict pspriv __unused, size_t * __restrict nresult,
191219019Sgabor    struct iconv_hooks *hooks __unused)
192219019Sgabor{
193219019Sgabor
194219019Sgabor	if ((wc & ~0xFFU) != 0) {
195219019Sgabor		*nresult = (size_t)-1;
196219019Sgabor		return (EILSEQ);
197219019Sgabor	}
198219019Sgabor	if (n == 0) {
199219019Sgabor		*nresult = (size_t)-1;
200225678Sgabor		return (E2BIG);
201219019Sgabor	}
202219019Sgabor
203219019Sgabor	*nresult = 1;
204219019Sgabor	if (s != NULL && n > 0)
205219019Sgabor		*s = (char)wc;
206219019Sgabor
207219019Sgabor	return (0);
208219019Sgabor}
209219019Sgabor
210219019Sgaborstatic int
211219019Sgabor_citrus_NONE_stdenc_put_state_reset(struct _citrus_stdenc * __restrict ce __unused,
212219019Sgabor    char * __restrict s __unused, size_t n __unused,
213219019Sgabor    void * __restrict pspriv __unused, size_t * __restrict nresult)
214219019Sgabor{
215219019Sgabor
216219019Sgabor	*nresult = 0;
217219019Sgabor
218219019Sgabor	return (0);
219219019Sgabor}
220219019Sgabor
221219019Sgaborstatic int
222219019Sgabor_citrus_NONE_stdenc_get_state_desc(struct _stdenc * __restrict ce __unused,
223219019Sgabor    void * __restrict ps __unused, int id,
224219019Sgabor    struct _stdenc_state_desc * __restrict d)
225219019Sgabor{
226219019Sgabor	int ret = 0;
227219019Sgabor
228219019Sgabor	switch (id) {
229219019Sgabor	case _STDENC_SDID_GENERIC:
230219019Sgabor		d->u.generic.state = _STDENC_SDGEN_INITIAL;
231219019Sgabor		break;
232219019Sgabor	default:
233219019Sgabor		ret = EOPNOTSUPP;
234219019Sgabor	}
235219019Sgabor
236219019Sgabor	return (ret);
237219019Sgabor}
238