(root)/
glibc-2.38/
iconvdata/
euc-cn.c
       1  /* Mapping tables for EUC-CN handling.
       2     Copyright (C) 1998-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library 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 GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <dlfcn.h>
      20  #include <gb2312.h>
      21  #include <stdint.h>
      22  
      23  /* Definitions used in the body of the `gconv' function.  */
      24  #define CHARSET_NAME		"EUC-CN//"
      25  #define FROM_LOOP		from_euc_cn
      26  #define TO_LOOP			to_euc_cn
      27  #define DEFINE_INIT		1
      28  #define DEFINE_FINI		1
      29  #define MIN_NEEDED_FROM		1
      30  #define MAX_NEEDED_FROM		2
      31  #define MIN_NEEDED_TO		4
      32  #define ONE_DIRECTION		0
      33  
      34  
      35  /* First define the conversion function from EUC-CN to UCS4.  */
      36  #define MIN_NEEDED_INPUT	MIN_NEEDED_FROM
      37  #define MAX_NEEDED_INPUT	MAX_NEEDED_FROM
      38  #define MIN_NEEDED_OUTPUT	MIN_NEEDED_TO
      39  #define LOOPFCT			FROM_LOOP
      40  #define BODY \
      41    {									      \
      42      uint32_t ch = *inptr;						      \
      43  									      \
      44      if (ch <= 0x7f)							      \
      45        ++inptr;								      \
      46      else								      \
      47        if ((__builtin_expect (ch <= 0xa0, 0) && ch != 0x8e && ch != 0x8f)      \
      48  	  || __builtin_expect (ch > 0xfe, 0))				      \
      49  	{								      \
      50  	  /* This is illegal.  */					      \
      51  	  STANDARD_FROM_LOOP_ERR_HANDLER (1);				      \
      52  	}								      \
      53        else								      \
      54  	{								      \
      55  	  /* Two or more byte character.  First test whether the	      \
      56  	     next byte is also available.  */				      \
      57  	  const unsigned char *endp;					      \
      58  									      \
      59  	  if (__glibc_unlikely (inptr + 1 >= inend))			      \
      60  	    {								      \
      61  	      /* The second character is not available.  Store		      \
      62  		 the intermediate result.  */				      \
      63  	      result = __GCONV_INCOMPLETE_INPUT;			      \
      64  	      break;							      \
      65  	    }								      \
      66  									      \
      67  	  ch = inptr[1];						      \
      68  									      \
      69  	  /* All second bytes of a multibyte character must be >= 0xa1. */    \
      70  	  if (__glibc_unlikely (ch < 0xa1))				      \
      71  	    STANDARD_FROM_LOOP_ERR_HANDLER (1);				      \
      72  									      \
      73  	  /* This is code set 1: GB 2312-80.  */			      \
      74  	  endp = inptr;							      \
      75  									      \
      76  	  ch = gb2312_to_ucs4 (&endp, 2, 0x80);				      \
      77  	  if (__glibc_unlikely (ch == __UNKNOWN_10646_CHAR))		      \
      78  	    {								      \
      79  	      /* This is an illegal character.  */			      \
      80  	      STANDARD_FROM_LOOP_ERR_HANDLER (2);			      \
      81  	    }								      \
      82  									      \
      83  	  inptr += 2;							      \
      84  	}								      \
      85  									      \
      86      put32 (outptr, ch);							      \
      87      outptr += 4;							      \
      88    }
      89  #define LOOP_NEED_FLAGS
      90  #define ONEBYTE_BODY \
      91    {									      \
      92      if (c < 0x80)							      \
      93        return c;								      \
      94      else								      \
      95        return WEOF;							      \
      96    }
      97  #include <iconv/loop.c>
      98  
      99  
     100  /* Next, define the other direction.  */
     101  #define MIN_NEEDED_INPUT	MIN_NEEDED_TO
     102  #define MIN_NEEDED_OUTPUT	MIN_NEEDED_FROM
     103  #define MAX_NEEDED_OUTPUT	MAX_NEEDED_FROM
     104  #define LOOPFCT			TO_LOOP
     105  #define BODY \
     106    {									      \
     107      uint32_t ch = get32 (inptr);					      \
     108  									      \
     109      if (ch <= L'\x7f')							      \
     110        /* It's plain ASCII.  */						      \
     111        *outptr++ = (unsigned char) ch;					      \
     112      else								      \
     113        {									      \
     114  	size_t found;							      \
     115  									      \
     116  	found = ucs4_to_gb2312 (ch, outptr, outend - outptr);		      \
     117  	if (__builtin_expect (found, 1) != 0)				      \
     118  	  {								      \
     119  	    if (__builtin_expect (found, 0) == __UNKNOWN_10646_CHAR)	      \
     120  	      {								      \
     121  		UNICODE_TAG_HANDLER (ch, 4);				      \
     122  									      \
     123  		/* Illegal character.  */				      \
     124  		STANDARD_TO_LOOP_ERR_HANDLER (4);			      \
     125  	      }								      \
     126  									      \
     127  	    /* It's a GB 2312 character, adjust it for EUC-CN.  */	      \
     128  	    *outptr++ += 0x80;						      \
     129  	    *outptr++ += 0x80;						      \
     130  	  }								      \
     131  	else								      \
     132  	  {								      \
     133  	    /* We ran out of space.  */					      \
     134  	    result = __GCONV_FULL_OUTPUT;				      \
     135  	    break;							      \
     136  	  }								      \
     137        }									      \
     138      inptr += 4;								      \
     139    }
     140  #define LOOP_NEED_FLAGS
     141  #include <iconv/loop.c>
     142  
     143  
     144  /* Now define the toplevel functions.  */
     145  #include <iconv/skeleton.c>