root/maint/gnulib/lib/mbsnrtowcs-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 3 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 srclen, 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 (; srclen > 0 && 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, MIN (srclen, MB_LEN_MAX));  */
  37             if (srclen == 1 || src[0] == '\0')
  38               src_avail = 1;
  39             else if (srclen == 2 || src[1] == '\0')
  40               src_avail = 2;
  41             else if (srclen == 3 || src[2] == '\0')
  42               src_avail = 3;
  43             else if (MB_LEN_MAX <= 4 || srclen == 4 || src[3] == '\0')
  44               src_avail = 4;
  45             else
  46               src_avail = 4 + strnlen1 (src + 4, MIN (srclen, 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             srclen -= ret;
  66           }
  67 
  68         *srcp = src;
  69         return destptr - dest;
  70       }
  71     else
  72       {
  73         /* Ignore dest and len, don't store *srcp at the end, and
  74            don't clobber *ps.  */
  75         mbstate_t state = *ps;
  76         size_t totalcount = 0;
  77 
  78         for (; srclen > 0; totalcount++)
  79           {
  80             size_t src_avail;
  81             size_t ret;
  82 
  83             /* An optimized variant of
  84                src_avail = strnlen1 (src, MIN (srclen, MB_LEN_MAX));  */
  85             if (srclen == 1 || src[0] == '\0')
  86               src_avail = 1;
  87             else if (srclen == 2 || src[1] == '\0')
  88               src_avail = 2;
  89             else if (srclen == 3 || src[2] == '\0')
  90               src_avail = 3;
  91             else if (MB_LEN_MAX <= 4 || srclen == 4 || src[3] == '\0')
  92               src_avail = 4;
  93             else
  94               src_avail = 4 + strnlen1 (src + 4, MIN (srclen, MB_LEN_MAX) - 4);
  95 
  96             /* Parse the next multibyte character.  */
  97             ret = MBRTOWC (NULL, src, src_avail, &state);
  98 
  99             if (ret == (size_t)(-2))
 100               /* Encountered a multibyte character that extends past a '\0' byte
 101                  or that is longer than MB_LEN_MAX bytes.  Cannot happen.  */
 102               abort ();
 103 
 104             if (ret == (size_t)(-1))
 105               goto bad_input2;
 106             if (ret == 0)
 107               {
 108                 /* Here mbsinit (&state).  */
 109                 break;
 110               }
 111             src += ret;
 112             srclen -= ret;
 113           }
 114 
 115         return totalcount;
 116       }
 117 
 118    bad_input:
 119     *srcp = src;
 120    bad_input2:
 121     errno = EILSEQ;
 122     return (size_t)(-1);
 123   }
 124 }

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