root/maint/gnulib/lib/uniconv/u-conv-to-enc.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. FUNC

   1 /* Conversion from UTF-16/UTF-32 to legacy encodings.
   2    Copyright (C) 2002, 2006-2021 Free Software Foundation, Inc.
   3 
   4    This file is free software.
   5    It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+".
   6    You can redistribute it and/or modify it under either
   7      - the terms of the GNU Lesser General Public License as published
   8        by the Free Software Foundation; either version 3, or (at your
   9        option) any later version, or
  10      - the terms of the GNU General Public License as published by the
  11        Free Software Foundation; either version 2, or (at your option)
  12        any later version, or
  13      - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+".
  14 
  15    This file is distributed in the hope that it will be useful,
  16    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18    Lesser General Public License and the GNU General Public License
  19    for more details.
  20 
  21    You should have received a copy of the GNU Lesser General Public
  22    License and of the GNU General Public License along with this
  23    program.  If not, see <https://www.gnu.org/licenses/>.  */
  24 
  25 char *
  26 FUNC (const char *tocode,
     /* [previous][next][first][last][top][bottom][index][help] */
  27       enum iconv_ilseq_handler handler,
  28       const UNIT *src, size_t srclen,
  29       size_t *offsets,
  30       char *resultbuf, size_t *lengthp)
  31 {
  32 #if HAVE_UTF_NAME
  33   size_t *scaled_offsets;
  34   char *result;
  35   size_t length;
  36 
  37   if (offsets != NULL && srclen > 0)
  38     {
  39       scaled_offsets =
  40         (size_t *) malloc (srclen * sizeof (UNIT) * sizeof (size_t));
  41       if (scaled_offsets == NULL)
  42         {
  43           errno = ENOMEM;
  44           return NULL;
  45         }
  46     }
  47   else
  48     scaled_offsets = NULL;
  49 
  50   result = resultbuf;
  51   length = *lengthp;
  52   if (mem_iconveha ((const char *) src, srclen * sizeof (UNIT),
  53                     UTF_NAME, tocode,
  54                     handler == iconveh_question_mark, handler,
  55                     scaled_offsets, &result, &length) < 0)
  56     {
  57       int saved_errno = errno;
  58       free (scaled_offsets);
  59       errno = saved_errno;
  60       return NULL;
  61     }
  62 
  63   if (offsets != NULL)
  64     {
  65       /* Convert scaled_offsets[srclen * sizeof (UNIT)] to
  66          offsets[srclen].  */
  67       size_t i;
  68 
  69       for (i = 0; i < srclen; i++)
  70         offsets[i] = scaled_offsets[i * sizeof (UNIT)];
  71       free (scaled_offsets);
  72     }
  73 
  74   if (result == NULL) /* when (resultbuf == NULL && length == 0)  */
  75     {
  76       result = (char *) malloc (1);
  77       if (result == NULL)
  78         {
  79           errno = ENOMEM;
  80           return NULL;
  81         }
  82     }
  83   *lengthp = length;
  84   return result;
  85 #else
  86   uint8_t tmpbuf[4096];
  87   size_t tmpbufsize = SIZEOF (tmpbuf);
  88   uint8_t *utf8_src;
  89   size_t utf8_srclen;
  90   size_t *scaled_offsets;
  91   char *result;
  92 
  93   utf8_src = U_TO_U8 (src, srclen, tmpbuf, &tmpbufsize);
  94   if (utf8_src == NULL)
  95     return NULL;
  96   utf8_srclen = tmpbufsize;
  97 
  98   if (offsets != NULL && utf8_srclen > 0)
  99     {
 100       scaled_offsets = (size_t *) malloc (utf8_srclen * sizeof (size_t));
 101       if (scaled_offsets == NULL)
 102         {
 103           if (utf8_src != tmpbuf)
 104             free (utf8_src);
 105           errno = ENOMEM;
 106           return NULL;
 107         }
 108     }
 109   else
 110     scaled_offsets = NULL;
 111 
 112   result = u8_conv_to_encoding (tocode, handler, utf8_src, utf8_srclen,
 113                                 scaled_offsets, resultbuf, lengthp);
 114   if (result == NULL)
 115     {
 116       int saved_errno = errno;
 117       free (scaled_offsets);
 118       if (utf8_src != tmpbuf)
 119         free (utf8_src);
 120       errno = saved_errno;
 121       return NULL;
 122     }
 123   if (offsets != NULL)
 124     {
 125       size_t iunit;     /* offset into src */
 126       size_t i8;        /* offset into utf8_src */
 127 
 128       for (iunit = 0; iunit < srclen; iunit++)
 129         offsets[iunit] = (size_t)(-1);
 130 
 131       iunit = 0;
 132       i8 = 0;
 133       while (iunit < srclen && i8 < utf8_srclen)
 134         {
 135           int countunit;
 136           int count8;
 137 
 138           offsets[iunit] = scaled_offsets[i8];
 139 
 140           countunit = U_MBLEN (src + iunit, srclen - iunit);
 141           count8 = u8_mblen (utf8_src + i8, utf8_srclen - i8);
 142           if (countunit < 0 || count8 < 0)
 143             abort ();
 144           iunit += countunit;
 145           i8 += count8;
 146         }
 147       /* Check that utf8_src has been traversed entirely.  */
 148       if (i8 < utf8_srclen)
 149         abort ();
 150       /* Check that src has been traversed entirely, except possibly for an
 151          incomplete sequence of units at the end.  */
 152       if (iunit < srclen)
 153         {
 154           offsets[iunit] = *lengthp;
 155           if (!(U_MBLEN (src + iunit, srclen - iunit) < 0))
 156             abort ();
 157         }
 158       free (scaled_offsets);
 159     }
 160   if (utf8_src != tmpbuf)
 161     free (utf8_src);
 162   return result;
 163 #endif
 164 }

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