mbsrtowcs.c revision 129154
138363Swpaul/*-
238363Swpaul * Copyright (c) 2002-2004 Tim J. Robbins.
338363Swpaul * All rights reserved.
438363Swpaul *
538363Swpaul * Redistribution and use in source and binary forms, with or without
638363Swpaul * modification, are permitted provided that the following conditions
738363Swpaul * are met:
838363Swpaul * 1. Redistributions of source code must retain the above copyright
938363Swpaul *    notice, this list of conditions and the following disclaimer.
1038363Swpaul * 2. Redistributions in binary form must reproduce the above copyright
1138363Swpaul *    notice, this list of conditions and the following disclaimer in the
1238363Swpaul *    documentation and/or other materials provided with the distribution.
1338363Swpaul *
1438363Swpaul * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1538363Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1638363Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1738363Swpaul * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1838363Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1938363Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2038363Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2138363Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2238363Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2338363Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2438363Swpaul * SUCH DAMAGE.
2538363Swpaul */
2638363Swpaul
2738363Swpaul#include <sys/cdefs.h>
2838363Swpaul__FBSDID("$FreeBSD: head/lib/libc/locale/mbsrtowcs.c 129154 2004-05-12 14:26:54Z tjr $");
2938363Swpaul
3038363Swpaul#include <errno.h>
3138363Swpaul#include <limits.h>
3246204Swpaul#include <stdlib.h>
3338363Swpaul#include <wchar.h>
3438363Swpaul#include "mblocal.h"
3538363Swpaul
3638363Swpaulsize_t
3738363Swpaulmbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len,
3838363Swpaul    mbstate_t * __restrict ps)
3938363Swpaul{
4038363Swpaul	static mbstate_t mbs;
4138363Swpaul	const char *s;
4238363Swpaul	size_t nchr;
4338363Swpaul	wchar_t wc;
4438363Swpaul	int nb;
4538363Swpaul
4638363Swpaul	s = *src;
4738363Swpaul	nchr = 0;
4838363Swpaul
4938363Swpaul	if (ps == NULL)
5038363Swpaul		ps = &mbs;
5138363Swpaul	if (dst == NULL) {
5238363Swpaul		for (;;) {
5338363Swpaul			if ((nb = (int)__mbrtowc(&wc, s, MB_CUR_MAX, ps)) < 0)
5438363Swpaul				/* Invalid sequence - mbrtowc() sets errno. */
5538363Swpaul				return ((size_t)-1);
5638363Swpaul			else if (nb == 0)
5738363Swpaul				return (nchr);
5838363Swpaul			s += nb;
5938363Swpaul			nchr++;
6038363Swpaul		}
6138363Swpaul		/*NOTREACHED*/
6238363Swpaul	}
6338363Swpaul
6438363Swpaul	while (len-- > 0) {
6538363Swpaul		if ((nb = (int)__mbrtowc(dst, s, MB_CUR_MAX, ps)) < 0) {
6638363Swpaul			*src = s;
6738363Swpaul			return ((size_t)-1);
6838363Swpaul		} else if (nb == 0) {
6938363Swpaul			*src = NULL;
7038363Swpaul			return (nchr);
7138363Swpaul		}
7238363Swpaul		s += nb;
7338363Swpaul		nchr++;
7438363Swpaul		dst++;
7538363Swpaul	}
7638363Swpaul	*src = s;
7738363Swpaul	return (nchr);
7838363Swpaul}
7938363Swpaul