Back to index

glibc  2.9
euc-cn.c
Go to the documentation of this file.
00001 /* Mapping tables for EUC-CN handling.
00002    Copyright (C) 1998, 1999, 2000-2002 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <dlfcn.h>
00022 #include <gb2312.h>
00023 #include <stdint.h>
00024 
00025 /* Definitions used in the body of the `gconv' function.  */
00026 #define CHARSET_NAME        "EUC-CN//"
00027 #define FROM_LOOP           from_euc_cn
00028 #define TO_LOOP                    to_euc_cn
00029 #define DEFINE_INIT         1
00030 #define DEFINE_FINI         1
00031 #define MIN_NEEDED_FROM            1
00032 #define MAX_NEEDED_FROM            2
00033 #define MIN_NEEDED_TO              4
00034 
00035 
00036 /* First define the conversion function from EUC-CN to UCS4.  */
00037 #define MIN_NEEDED_INPUT    MIN_NEEDED_FROM
00038 #define MAX_NEEDED_INPUT    MAX_NEEDED_FROM
00039 #define MIN_NEEDED_OUTPUT   MIN_NEEDED_TO
00040 #define LOOPFCT                    FROM_LOOP
00041 #define BODY \
00042   {                                                                  \
00043     uint32_t ch = *inptr;                                            \
00044                                                                      \
00045     if (ch <= 0x7f)                                                  \
00046       ++inptr;                                                              \
00047     else                                                             \
00048       if ((__builtin_expect (ch <= 0xa0, 0) && ch != 0x8e && ch != 0x8f)      \
00049          || __builtin_expect (ch > 0xfe, 0))                                \
00050        {                                                             \
00051          /* This is illegal.  */                                     \
00052          STANDARD_FROM_LOOP_ERR_HANDLER (1);                                \
00053        }                                                             \
00054       else                                                           \
00055        {                                                             \
00056          /* Two or more byte character.  First test whether the             \
00057             next byte is also available.  */                                \
00058          const unsigned char *endp;                                         \
00059                                                                      \
00060          if (__builtin_expect (inptr + 1 >= inend, 0))                      \
00061            {                                                         \
00062              /* The second character is not available.  Store               \
00063                the intermediate result.  */                                 \
00064              result = __GCONV_INCOMPLETE_INPUT;                      \
00065              break;                                                  \
00066            }                                                         \
00067                                                                      \
00068          ch = inptr[1];                                              \
00069                                                                      \
00070          /* All second bytes of a multibyte character must be >= 0xa1. */    \
00071          if (__builtin_expect (ch < 0xa1, 0))                               \
00072            STANDARD_FROM_LOOP_ERR_HANDLER (1);                              \
00073                                                                      \
00074          /* This is code set 1: GB 2312-80.  */                      \
00075          endp = inptr;                                                      \
00076                                                                      \
00077          ch = gb2312_to_ucs4 (&endp, 2, 0x80);                              \
00078          if (__builtin_expect (ch == __UNKNOWN_10646_CHAR, 0))              \
00079            {                                                         \
00080              /* This is an illegal character.  */                           \
00081              STANDARD_FROM_LOOP_ERR_HANDLER (2);                     \
00082            }                                                         \
00083                                                                      \
00084          inptr += 2;                                                 \
00085        }                                                             \
00086                                                                      \
00087     put32 (outptr, ch);                                                     \
00088     outptr += 4;                                                     \
00089   }
00090 #define LOOP_NEED_FLAGS
00091 #define ONEBYTE_BODY \
00092   {                                                                  \
00093     if (c < 0x80)                                                    \
00094       return c;                                                             \
00095     else                                                             \
00096       return WEOF;                                                   \
00097   }
00098 #include <iconv/loop.c>
00099 
00100 
00101 /* Next, define the other direction.  */
00102 #define MIN_NEEDED_INPUT    MIN_NEEDED_TO
00103 #define MIN_NEEDED_OUTPUT   MIN_NEEDED_FROM
00104 #define MAX_NEEDED_OUTPUT   MAX_NEEDED_FROM
00105 #define LOOPFCT                    TO_LOOP
00106 #define BODY \
00107   {                                                                  \
00108     uint32_t ch = get32 (inptr);                                     \
00109                                                                      \
00110     if (ch <= L'\x7f')                                                      \
00111       /* It's plain ASCII.  */                                              \
00112       *outptr++ = (unsigned char) ch;                                       \
00113     else                                                             \
00114       {                                                                     \
00115        size_t found;                                                 \
00116                                                                      \
00117        found = ucs4_to_gb2312 (ch, outptr, outend - outptr);                \
00118        if (__builtin_expect (found, 1) != 0)                                \
00119          {                                                           \
00120            if (__builtin_expect (found, 0) == __UNKNOWN_10646_CHAR)         \
00121              {                                                              \
00122               UNICODE_TAG_HANDLER (ch, 4);                                  \
00123                                                                      \
00124               /* Illegal character.  */                              \
00125               STANDARD_TO_LOOP_ERR_HANDLER (4);                      \
00126              }                                                              \
00127                                                                      \
00128            /* It's a GB 2312 character, adjust it for EUC-CN.  */           \
00129            *outptr++ += 0x80;                                               \
00130            *outptr++ += 0x80;                                               \
00131          }                                                           \
00132        else                                                          \
00133          {                                                           \
00134            /* We ran out of space.  */                                      \
00135            result = __GCONV_FULL_OUTPUT;                             \
00136            break;                                                    \
00137          }                                                           \
00138       }                                                                     \
00139     inptr += 4;                                                             \
00140   }
00141 #define LOOP_NEED_FLAGS
00142 #include <iconv/loop.c>
00143 
00144 
00145 /* Now define the toplevel functions.  */
00146 #include <iconv/skeleton.c>