(root)/
gettext-0.22.4/
gettext-tools/
libgettextpo/
uniconv/
u8-conv-from-enc.c
       1  /* Conversion to UTF-8 from legacy encodings.
       2     Copyright (C) 2002, 2006-2007, 2009-2023 Free Software Foundation, Inc.
       3  
       4     This file is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU Lesser General Public License as
       6     published by the Free Software Foundation; either version 2.1 of the
       7     License, or (at your option) any later version.
       8  
       9     This file is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  /* Written by Bruno Haible <bruno@clisp.org>.  */
      18  
      19  #include <config.h>
      20  
      21  /* Specification.  */
      22  #include "uniconv.h"
      23  
      24  #include <errno.h>
      25  #include <stdlib.h>
      26  #include <string.h>
      27  
      28  #include "c-strcaseeq.h"
      29  #include "striconveha.h"
      30  #include "unistr.h"
      31  
      32  uint8_t *
      33  u8_conv_from_encoding (const char *fromcode,
      34                         enum iconv_ilseq_handler handler,
      35                         const char *src, size_t srclen,
      36                         size_t *offsets,
      37                         uint8_t *resultbuf, size_t *lengthp)
      38  {
      39    if (STRCASEEQ (fromcode, "UTF-8", 'U','T','F','-','8',0,0,0,0))
      40      {
      41        /* Conversion from UTF-8 to UTF-8.  No need to go through iconv().  */
      42        uint8_t *result;
      43  
      44        if (u8_check ((const uint8_t *) src, srclen))
      45          {
      46            errno = EILSEQ;
      47            return NULL;
      48          }
      49  
      50        if (offsets != NULL)
      51          {
      52            size_t i;
      53  
      54            for (i = 0; i < srclen; )
      55              {
      56                int count = u8_mblen ((const uint8_t *) src + i, srclen - i);
      57                /* We can rely on count > 0 because of the previous u8_check.  */
      58                if (count <= 0)
      59                  abort ();
      60                offsets[i] = i;
      61                i++;
      62                while (--count > 0)
      63                  offsets[i++] = (size_t)(-1);
      64              }
      65          }
      66  
      67        /* Memory allocation.  */
      68        if (resultbuf != NULL && *lengthp >= srclen)
      69          result = resultbuf;
      70        else
      71          {
      72            result = (uint8_t *) malloc (srclen > 0 ? srclen : 1);
      73            if (result == NULL)
      74              {
      75                errno = ENOMEM;
      76                return NULL;
      77              }
      78          }
      79  
      80        if (srclen > 0)
      81          memcpy ((char *) result, src, srclen);
      82        *lengthp = srclen;
      83        return result;
      84      }
      85    else
      86      {
      87        char *result = (char *) resultbuf;
      88        size_t length = *lengthp;
      89  
      90        if (mem_iconveha (src, srclen, fromcode, "UTF-8", true, handler,
      91                          offsets, &result, &length) < 0)
      92          return NULL;
      93  
      94        if (result == NULL) /* when (resultbuf == NULL && length == 0)  */
      95          {
      96            result = (char *) malloc (1);
      97            if (result == NULL)
      98              {
      99                errno = ENOMEM;
     100                return NULL;
     101              }
     102          }
     103        *lengthp = length;
     104        return (uint8_t *) result;
     105      }
     106  }