1175553Sache/*-
2175553Sache * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved.
3175553Sache * Copyright (c) 1993
4175553Sache *	The Regents of the University of California.  All rights reserved.
5175553Sache *
6175553Sache * This code is derived from software contributed to Berkeley by
7175553Sache * Paul Borman at Krystal Technologies.
8175553Sache *
9227753Stheraven * Copyright (c) 2011 The FreeBSD Foundation
10227753Stheraven * All rights reserved.
11227753Stheraven * Portions of this software were developed by David Chisnall
12227753Stheraven * under sponsorship from the FreeBSD Foundation.
13227753Stheraven *
14175553Sache * Redistribution and use in source and binary forms, with or without
15175553Sache * modification, are permitted provided that the following conditions
16175553Sache * are met:
17175553Sache * 1. Redistributions of source code must retain the above copyright
18175553Sache *    notice, this list of conditions and the following disclaimer.
19175553Sache * 2. Redistributions in binary form must reproduce the above copyright
20175553Sache *    notice, this list of conditions and the following disclaimer in the
21175553Sache *    documentation and/or other materials provided with the distribution.
22175553Sache * 4. Neither the name of the University nor the names of its contributors
23175553Sache *    may be used to endorse or promote products derived from this software
24175553Sache *    without specific prior written permission.
25175553Sache *
26175553Sache * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27175553Sache * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28175553Sache * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29175553Sache * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30175553Sache * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31175553Sache * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32175553Sache * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33175553Sache * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34175553Sache * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35175553Sache * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36175553Sache * SUCH DAMAGE.
37175553Sache */
38175553Sache
39175553Sache#include <sys/cdefs.h>
40175553Sache__FBSDID("$FreeBSD$");
41175553Sache
42175553Sache#include <errno.h>
43175553Sache#include <limits.h>
44175553Sache#include <runetype.h>
45175553Sache#include <stddef.h>
46175553Sache#include <stdio.h>
47175553Sache#include <stdlib.h>
48175553Sache#include <string.h>
49175553Sache#include <wchar.h>
50175553Sache#include "mblocal.h"
51175553Sache
52175553Sachestatic size_t	_ascii_mbrtowc(wchar_t * __restrict, const char * __restrict,
53175553Sache		    size_t, mbstate_t * __restrict);
54175553Sachestatic int	_ascii_mbsinit(const mbstate_t *);
55175553Sachestatic size_t	_ascii_mbsnrtowcs(wchar_t * __restrict dst,
56175553Sache		    const char ** __restrict src, size_t nms, size_t len,
57175553Sache		    mbstate_t * __restrict ps __unused);
58175553Sachestatic size_t	_ascii_wcrtomb(char * __restrict, wchar_t,
59175553Sache		    mbstate_t * __restrict);
60175553Sachestatic size_t	_ascii_wcsnrtombs(char * __restrict, const wchar_t ** __restrict,
61175553Sache		    size_t, size_t, mbstate_t * __restrict);
62175553Sache
63175553Sacheint
64227753Stheraven_ascii_init(struct xlocale_ctype *l,_RuneLocale *rl)
65175553Sache{
66175553Sache
67227753Stheraven	l->__mbrtowc = _ascii_mbrtowc;
68227753Stheraven	l->__mbsinit = _ascii_mbsinit;
69227753Stheraven	l->__mbsnrtowcs = _ascii_mbsnrtowcs;
70227753Stheraven	l->__wcrtomb = _ascii_wcrtomb;
71227753Stheraven	l->__wcsnrtombs = _ascii_wcsnrtombs;
72227753Stheraven	l->runes = rl;
73227753Stheraven	l->__mb_cur_max = 1;
74227753Stheraven	l->__mb_sb_limit = 128;
75175553Sache	return(0);
76175553Sache}
77175553Sache
78175553Sachestatic int
79175553Sache_ascii_mbsinit(const mbstate_t *ps __unused)
80175553Sache{
81175553Sache
82175553Sache	/*
83175553Sache	 * Encoding is not state dependent - we are always in the
84175553Sache	 * initial state.
85175553Sache	 */
86175553Sache	return (1);
87175553Sache}
88175553Sache
89175553Sachestatic size_t
90175553Sache_ascii_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n,
91175553Sache    mbstate_t * __restrict ps __unused)
92175553Sache{
93175553Sache
94175553Sache	if (s == NULL)
95175553Sache		/* Reset to initial shift state (no-op) */
96175553Sache		return (0);
97175553Sache	if (n == 0)
98175553Sache		/* Incomplete multibyte sequence */
99175553Sache		return ((size_t)-2);
100175553Sache	if (*s & 0x80) {
101175553Sache		errno = EILSEQ;
102175553Sache		return ((size_t)-1);
103175553Sache	}
104175553Sache	if (pwc != NULL)
105175553Sache		*pwc = (unsigned char)*s;
106175553Sache	return (*s == '\0' ? 0 : 1);
107175553Sache}
108175553Sache
109175553Sachestatic size_t
110175553Sache_ascii_wcrtomb(char * __restrict s, wchar_t wc,
111175553Sache    mbstate_t * __restrict ps __unused)
112175553Sache{
113175553Sache
114175553Sache	if (s == NULL)
115175553Sache		/* Reset to initial shift state (no-op) */
116175553Sache		return (1);
117175553Sache	if (wc < 0 || wc > 127) {
118175553Sache		errno = EILSEQ;
119175553Sache		return ((size_t)-1);
120175553Sache	}
121175553Sache	*s = (unsigned char)wc;
122175553Sache	return (1);
123175553Sache}
124175553Sache
125175553Sachestatic size_t
126175553Sache_ascii_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src,
127175553Sache    size_t nms, size_t len, mbstate_t * __restrict ps __unused)
128175553Sache{
129175553Sache	const char *s;
130175553Sache	size_t nchr;
131175553Sache
132175553Sache	if (dst == NULL) {
133175553Sache		for (s = *src; nms > 0 && *s != '\0'; s++, nms--) {
134175553Sache			if (*s & 0x80) {
135175553Sache				errno = EILSEQ;
136175553Sache				return ((size_t)-1);
137175553Sache			}
138175553Sache		}
139175553Sache		return (s - *src);
140175553Sache	}
141175553Sache
142175553Sache	s = *src;
143175553Sache	nchr = 0;
144175553Sache	while (len-- > 0 && nms-- > 0) {
145175553Sache		if (*s & 0x80) {
146301069Sache			*src = s;
147175553Sache			errno = EILSEQ;
148175553Sache			return ((size_t)-1);
149175553Sache		}
150175553Sache		if ((*dst++ = (unsigned char)*s++) == L'\0') {
151175553Sache			*src = NULL;
152175553Sache			return (nchr);
153175553Sache		}
154175553Sache		nchr++;
155175553Sache	}
156175553Sache	*src = s;
157175553Sache	return (nchr);
158175553Sache}
159175553Sache
160175553Sachestatic size_t
161175553Sache_ascii_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src,
162175553Sache    size_t nwc, size_t len, mbstate_t * __restrict ps __unused)
163175553Sache{
164175553Sache	const wchar_t *s;
165175553Sache	size_t nchr;
166175553Sache
167175553Sache	if (dst == NULL) {
168175553Sache		for (s = *src; nwc > 0 && *s != L'\0'; s++, nwc--) {
169175553Sache			if (*s < 0 || *s > 127) {
170175553Sache				errno = EILSEQ;
171175553Sache				return ((size_t)-1);
172175553Sache			}
173175553Sache		}
174175553Sache		return (s - *src);
175175553Sache	}
176175553Sache
177175553Sache	s = *src;
178175553Sache	nchr = 0;
179175553Sache	while (len-- > 0 && nwc-- > 0) {
180175553Sache		if (*s < 0 || *s > 127) {
181301069Sache			*src = s;
182175553Sache			errno = EILSEQ;
183175553Sache			return ((size_t)-1);
184175553Sache		}
185175553Sache		if ((*dst++ = *s++) == '\0') {
186175553Sache			*src = NULL;
187175553Sache			return (nchr);
188175553Sache		}
189175553Sache		nchr++;
190175553Sache	}
191175553Sache	*src = s;
192175553Sache	return (nchr);
193175553Sache}
194175553Sache
195