1132497Stjr/*- 2132497Stjr * Copyright (c) 2002-2004 Tim J. Robbins. 3227753Stheraven * 4227753Stheraven * Copyright (c) 2011 The FreeBSD Foundation 5132497Stjr * All rights reserved. 6227753Stheraven * Portions of this software were developed by David Chisnall 7227753Stheraven * under sponsorship from the FreeBSD Foundation. 8227753Stheraven * All rights reserved. 9132497Stjr * 10132497Stjr * Redistribution and use in source and binary forms, with or without 11132497Stjr * modification, are permitted provided that the following conditions 12132497Stjr * are met: 13132497Stjr * 1. Redistributions of source code must retain the above copyright 14132497Stjr * notice, this list of conditions and the following disclaimer. 15132497Stjr * 2. Redistributions in binary form must reproduce the above copyright 16132497Stjr * notice, this list of conditions and the following disclaimer in the 17132497Stjr * documentation and/or other materials provided with the distribution. 18132497Stjr * 19132497Stjr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20132497Stjr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21132497Stjr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22132497Stjr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23132497Stjr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24132497Stjr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25132497Stjr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26132497Stjr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27132497Stjr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28132497Stjr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29132497Stjr * SUCH DAMAGE. 30132497Stjr */ 31132497Stjr 32132497Stjr#include <sys/cdefs.h> 33132497Stjr__FBSDID("$FreeBSD$"); 34132497Stjr 35132497Stjr#include <errno.h> 36132497Stjr#include <limits.h> 37132497Stjr#include <stdlib.h> 38132497Stjr#include <wchar.h> 39132497Stjr#include "mblocal.h" 40132497Stjr 41132497Stjrsize_t 42227753Stheravenmbsnrtowcs_l(wchar_t * __restrict dst, const char ** __restrict src, 43227753Stheraven size_t nms, size_t len, mbstate_t * __restrict ps, locale_t locale) 44227753Stheraven{ 45227753Stheraven FIX_LOCALE(locale); 46227753Stheraven if (ps == NULL) 47227753Stheraven ps = &locale->mbsnrtowcs; 48227753Stheraven return (XLOCALE_CTYPE(locale)->__mbsnrtowcs(dst, src, nms, len, ps)); 49227753Stheraven} 50227753Stheravensize_t 51132497Stjrmbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, 52132497Stjr size_t nms, size_t len, mbstate_t * __restrict ps) 53132497Stjr{ 54227753Stheraven return mbsnrtowcs_l(dst, src, nms, len, ps, __get_locale()); 55132497Stjr} 56132497Stjr 57132497Stjrsize_t 58132497Stjr__mbsnrtowcs_std(wchar_t * __restrict dst, const char ** __restrict src, 59132497Stjr size_t nms, size_t len, mbstate_t * __restrict ps) 60132497Stjr{ 61132497Stjr const char *s; 62132497Stjr size_t nchr; 63132497Stjr wchar_t wc; 64132497Stjr size_t nb; 65227753Stheraven struct xlocale_ctype *ct = XLOCALE_CTYPE(__get_locale()); 66132497Stjr 67132497Stjr s = *src; 68132497Stjr nchr = 0; 69132497Stjr 70132497Stjr if (dst == NULL) { 71132497Stjr for (;;) { 72227753Stheraven if ((nb = ct->__mbrtowc(&wc, s, nms, ps)) == (size_t)-1) 73132497Stjr /* Invalid sequence - mbrtowc() sets errno. */ 74132497Stjr return ((size_t)-1); 75132497Stjr else if (nb == 0 || nb == (size_t)-2) 76132497Stjr return (nchr); 77132497Stjr s += nb; 78132497Stjr nms -= nb; 79132497Stjr nchr++; 80132497Stjr } 81132497Stjr /*NOTREACHED*/ 82132497Stjr } 83132497Stjr 84132497Stjr while (len-- > 0) { 85227753Stheraven if ((nb = ct->__mbrtowc(dst, s, nms, ps)) == (size_t)-1) { 86132497Stjr *src = s; 87132497Stjr return ((size_t)-1); 88132497Stjr } else if (nb == (size_t)-2) { 89132497Stjr *src = s + nms; 90132497Stjr return (nchr); 91132497Stjr } else if (nb == 0) { 92132497Stjr *src = NULL; 93132497Stjr return (nchr); 94132497Stjr } 95132497Stjr s += nb; 96132497Stjr nms -= nb; 97132497Stjr nchr++; 98132497Stjr dst++; 99132497Stjr } 100132497Stjr *src = s; 101132497Stjr return (nchr); 102132497Stjr} 103