wcsrtombs.c revision 102050
1193326Sed/*- 2193326Sed * Copyright (c) 2002 Tim J. Robbins. 3193326Sed * All rights reserved. 4193326Sed * 5193326Sed * Redistribution and use in source and binary forms, with or without 6193326Sed * modification, are permitted provided that the following conditions 7193326Sed * are met: 8193326Sed * 1. Redistributions of source code must retain the above copyright 9193326Sed * notice, this list of conditions and the following disclaimer. 10193326Sed * 2. Redistributions in binary form must reproduce the above copyright 11193326Sed * notice, this list of conditions and the following disclaimer in the 12193326Sed * documentation and/or other materials provided with the distribution. 13193326Sed * 14193326Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15193326Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16193326Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17193326Sed * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18193326Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19204643Srdivacky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20210299Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21198092Srdivacky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22204643Srdivacky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23193326Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24210299Sed * SUCH DAMAGE. 25198092Srdivacky */ 26193326Sed 27221345Sdim#include <sys/cdefs.h> 28239462Sdim__FBSDID("$FreeBSD: head/lib/libc/locale/wcsrtombs.c 102050 2002-08-18 06:30:10Z tjr $"); 29234353Sdim 30234353Sdim#include <errno.h> 31234353Sdim#include <limits.h> 32234353Sdim#include <stdlib.h> 33234353Sdim#include <string.h> 34234353Sdim#include <wchar.h> 35234353Sdim 36239462Sdimsize_t 37234353Sdimwcsrtombs(char *__restrict dst, const wchar_t **__restrict src, size_t len, 38227737Sdim mbstate_t *__restrict ps __unused) 39212904Sdim{ 40212904Sdim char buf[MB_LEN_MAX]; 41193326Sed const wchar_t *s; 42193326Sed size_t nbytes; 43193326Sed int nb; 44199482Srdivacky 45193326Sed s = *src; 46223017Sdim nbytes = 0; 47206084Srdivacky 48212904Sdim if (dst == NULL) { 49223017Sdim for (;;) { 50223017Sdim if ((nb = (int)wcrtomb(buf, *s, NULL)) < 0) 51212904Sdim /* Invalid character - wcrtomb() sets errno. */ 52218893Sdim return ((size_t)-1); 53212904Sdim else if (*s == L'\0') 54212904Sdim return (nbytes + nb - 1); 55212904Sdim s++; 56218893Sdim nbytes += nb; 57218893Sdim } 58193326Sed /*NOTREACHED*/ 59193326Sed } 60194613Sed 61239462Sdim while (len > 0) { 62239462Sdim if (len > (size_t)MB_CUR_MAX) { 63239462Sdim /* Enough space to translate in-place. */ 64193380Sed if ((nb = (int)wcrtomb(dst, *s, NULL)) < 0) { 65193326Sed *src = s; 66239462Sdim return ((size_t)-1); 67239462Sdim } 68193326Sed } else { 69193326Sed /* May not be enough space; use temp. buffer. */ 70193326Sed if ((nb = (int)wcrtomb(buf, *s, NULL)) < 0) { 71193326Sed *src = s; 72234353Sdim return ((size_t)-1); 73234353Sdim } 74234353Sdim if (nb > (int)len) 75234353Sdim /* MB sequence for character won't fit. */ 76234353Sdim break; 77234353Sdim memcpy(dst, buf, nb); 78234353Sdim } 79234353Sdim if (*s == L'\0') { 80234353Sdim *src = NULL; 81234353Sdim return (nbytes + nb - 1); 82234353Sdim } 83226633Sdim s++; 84226633Sdim dst += nb; 85208600Srdivacky len -= nb; 86226633Sdim nbytes += nb; 87234353Sdim } 88234353Sdim *src = s; 89226633Sdim return (nbytes); 90226633Sdim} 91234353Sdim