root/maint/gnulib/lib/mbsrtowcs-impl.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. FUNC

   1 /* Convert string to wide string.
   2    Copyright (C) 2008-2021 Free Software Foundation, Inc.
   3    Written by Bruno Haible <bruno@clisp.org>, 2008.
   4 
   5    This file is free software: you can redistribute it and/or modify
   6    it under the terms of the GNU Lesser General Public License as
   7    published by the Free Software Foundation; either version 2.1 of the
   8    License, or (at your option) any later version.
   9 
  10    This file is distributed in the hope that it will be useful,
  11    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13    GNU Lesser General Public License for more details.
  14 
  15    You should have received a copy of the GNU Lesser General Public License
  16    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  17 
  18 size_t
  19 FUNC (DCHAR_T *dest, const char **srcp, size_t len, mbstate_t *ps)
     /* [previous][next][first][last][top][bottom][index][help] */
  20 {
  21   if (ps == NULL)
  22     ps = &INTERNAL_STATE;
  23   {
  24     const char *src = *srcp;
  25 
  26     if (dest != NULL)
  27       {
  28         DCHAR_T *destptr = dest;
  29 
  30         for (; len > 0; destptr++, len--)
  31           {
  32             size_t src_avail;
  33             size_t ret;
  34 
  35             /* An optimized variant of
  36                src_avail = strnlen1 (src, MB_LEN_MAX);  */
  37             if (src[0] == '\0')
  38               src_avail = 1;
  39             else if (src[1] == '\0')
  40               src_avail = 2;
  41             else if (src[2] == '\0')
  42               src_avail = 3;
  43             else if (MB_LEN_MAX <= 4 || src[3] == '\0')
  44               src_avail = 4;
  45             else
  46               src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4);
  47 
  48             /* Parse the next multibyte character.  */
  49             ret = MBRTOWC (destptr, src, src_avail, ps);
  50 
  51             if (ret == (size_t)(-2))
  52               /* Encountered a multibyte character that extends past a '\0' byte
  53                  or that is longer than MB_LEN_MAX bytes.  Cannot happen.  */
  54               abort ();
  55 
  56             if (ret == (size_t)(-1))
  57               goto bad_input;
  58             if (ret == 0)
  59               {
  60                 src = NULL;
  61                 /* Here mbsinit (ps).  */
  62                 break;
  63               }
  64             src += ret;
  65           }
  66 
  67         *srcp = src;
  68         return destptr - dest;
  69       }
  70     else
  71       {
  72         /* Ignore dest and len, don't store *srcp at the end, and
  73            don't clobber *ps.  */
  74         mbstate_t state = *ps;
  75         size_t totalcount = 0;
  76 
  77         for (;; totalcount++)
  78           {
  79             size_t src_avail;
  80             size_t ret;
  81 
  82             /* An optimized variant of
  83                src_avail = strnlen1 (src, MB_LEN_MAX);  */
  84             if (src[0] == '\0')
  85               src_avail = 1;
  86             else if (src[1] == '\0')
  87               src_avail = 2;
  88             else if (src[2] == '\0')
  89               src_avail = 3;
  90             else if (MB_LEN_MAX <= 4 || src[3] == '\0')
  91               src_avail = 4;
  92             else
  93               src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4);
  94 
  95             /* Parse the next multibyte character.  */
  96             ret = MBRTOWC (NULL, src, src_avail, &state);
  97 
  98             if (ret == (size_t)(-2))
  99               /* Encountered a multibyte character that extends past a '\0' byte
 100                  or that is longer than MB_LEN_MAX bytes.  Cannot happen.  */
 101               abort ();
 102 
 103             if (ret == (size_t)(-1))
 104               goto bad_input2;
 105             if (ret == 0)
 106               {
 107                 /* Here mbsinit (&state).  */
 108                 break;
 109               }
 110             src += ret;
 111           }
 112 
 113         return totalcount;
 114       }
 115 
 116    bad_input:
 117     *srcp = src;
 118    bad_input2:
 119     errno = EILSEQ;
 120     return (size_t)(-1);
 121   }
 122 }

/* [previous][next][first][last][top][bottom][index][help] */