(root)/
gettext-0.22.4/
gettext-runtime/
gnulib-lib/
unistr/
u8-uctomb.c
       1  /* Store a character in UTF-8 string.
       2     Copyright (C) 2002, 2005-2006, 2009-2023 Free Software Foundation, Inc.
       3     Written by Bruno Haible <bruno@clisp.org>, 2002.
       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  #include <config.h>
      19  
      20  #if defined IN_LIBUNISTRING
      21  /* Tell unistr.h to declare u8_uctomb as 'extern', not 'static inline'.  */
      22  # include "unistring-notinline.h"
      23  #endif
      24  
      25  /* Specification.  */
      26  #include "unistr.h"
      27  
      28  #include "attribute.h"
      29  
      30  #if !HAVE_INLINE
      31  
      32  int
      33  u8_uctomb (uint8_t *s, ucs4_t uc, ptrdiff_t n)
      34  {
      35    if (uc < 0x80)
      36      {
      37        if (n > 0)
      38          {
      39            s[0] = uc;
      40            return 1;
      41          }
      42        /* else return -2, below.  */
      43      }
      44    else
      45      {
      46        int count;
      47  
      48        if (uc < 0x800)
      49          count = 2;
      50        else if (uc < 0x10000)
      51          {
      52            if (uc < 0xd800 || uc >= 0xe000)
      53              count = 3;
      54            else
      55              return -1;
      56          }
      57        else if (uc < 0x110000)
      58          count = 4;
      59        else
      60          return -1;
      61  
      62        if (n >= count)
      63          {
      64            switch (count) /* note: code falls through cases! */
      65              {
      66              case 4: s[3] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x10000;
      67                FALLTHROUGH;
      68              case 3: s[2] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x800;
      69                FALLTHROUGH;
      70              case 2: s[1] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0xc0;
      71            /*case 1:*/ s[0] = uc;
      72              }
      73            return count;
      74          }
      75      }
      76    return -2;
      77  }
      78  
      79  #endif