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