Home | History | Annotate | Download | only in solaris
      1 /*-
      2  * Copyright (c) 2002-2004 Tim J. Robbins.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     23  * SUCH DAMAGE.
     24  */
     25 
     26 
     27 size_t
     28 wcsnrtombs_l(char * __restrict dst, const wchar_t ** __restrict src,
     29     size_t nwc, size_t len, mbstate_t * __restrict ps, locale_t loc)
     30 {
     31   FIX_LOCALE(loc);
     32   mbstate_t mbsbak;
     33   char buf[MB_CUR_MAX_L(loc)];
     34   const wchar_t *s;
     35   size_t nbytes;
     36   size_t nb;
     37 
     38   s = *src;
     39   nbytes = 0;
     40 
     41   if (dst == NULL) {
     42     while (nwc-- > 0) {
     43       if ((nb = wcrtomb_l(buf, *s, ps, loc)) == (size_t)-1)
     44         /* Invalid character - wcrtomb() sets errno. */
     45         return ((size_t)-1);
     46       else if (*s == L'\0')
     47         return (nbytes + nb - 1);
     48       s++;
     49       nbytes += nb;
     50     }
     51     return (nbytes);
     52   }
     53 
     54   while (len > 0 && nwc-- > 0) {
     55     if (len > (size_t)MB_CUR_MAX_L(loc)) {
     56       /* Enough space to translate in-place. */
     57       if ((nb = wcrtomb_l(dst, *s, ps, loc)) == (size_t)-1) {
     58         *src = s;
     59         return ((size_t)-1);
     60       }
     61     } else {
     62       /*
     63        * May not be enough space; use temp. buffer.
     64        *
     65        * We need to save a copy of the conversion state
     66        * here so we can restore it if the multibyte
     67        * character is too long for the buffer.
     68        */
     69       mbsbak = *ps;
     70       if ((nb = wcrtomb_l(buf, *s, ps, loc)) == (size_t)-1) {
     71         *src = s;
     72         return ((size_t)-1);
     73       }
     74       if (nb > (int)len) {
     75         /* MB sequence for character won't fit. */
     76         *ps = mbsbak;
     77         break;
     78       }
     79       memcpy(dst, buf, nb);
     80     }
     81     if (*s == L'\0') {
     82       *src = NULL;
     83       return (nbytes + nb - 1);
     84     }
     85     s++;
     86     dst += nb;
     87     len -= nb;
     88     nbytes += nb;
     89   }
     90   *src = s;
     91   return (nbytes);
     92 }
     93 
     94