Back to index

glibc  2.9
armscii-8.c
Go to the documentation of this file.
00001 /* Conversion to and from ARMSCII-8
00002    Copyright (C) 1997-1999, 2000-2002, 2004 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
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 <stdint.h>
00023 
00024 /* Definitions used in the body of the `gconv' function.  */
00025 #define CHARSET_NAME        "ARMSCII-8//"
00026 #define FROM_LOOP           from_armscii_8
00027 #define TO_LOOP                    to_armscii_8
00028 #define DEFINE_INIT         1
00029 #define DEFINE_FINI         1
00030 #define MIN_NEEDED_FROM            1
00031 #define MIN_NEEDED_TO              4
00032 
00033 
00034 static const uint16_t map_from_armscii_8[0xfe - 0xa2 + 1] =
00035   {
00036     0x0587, 0x0589, 0x0029, 0x0028, 0x00bb, 0x00ab, 0x2014, 0x002e,
00037     0x055d, 0x002c, 0x002d, 0x058a, 0x2026, 0x055c, 0x055b, 0x055e,
00038     0x0531, 0x0561, 0x0532, 0x0562, 0x0533, 0x0563, 0x0534, 0x0564,
00039     0x0535, 0x0565, 0x0536, 0x0566, 0x0537, 0x0567, 0x0538, 0x0568,
00040     0x0539, 0x0569, 0x053a, 0x056a, 0x053b, 0x056b, 0x053c, 0x056c,
00041     0x053d, 0x056d, 0x053e, 0x056e, 0x053f, 0x056f, 0x0540, 0x0570,
00042     0x0541, 0x0571, 0x0542, 0x0572, 0x0543, 0x0573, 0x0544, 0x0574,
00043     0x0545, 0x0575, 0x0546, 0x0576, 0x0547, 0x0577, 0x0548, 0x0578,
00044     0x0549, 0x0579, 0x054a, 0x057a, 0x054b, 0x057b, 0x054c, 0x057c,
00045     0x054d, 0x057d, 0x054e, 0x057e, 0x054f, 0x057f, 0x0550, 0x0580,
00046     0x0551, 0x0581, 0x0552, 0x0582, 0x0553, 0x0583, 0x0554, 0x0584,
00047     0x0555, 0x0585, 0x0556, 0x0586, 0x055a
00048   };
00049 
00050 
00051 /* First define the conversion function from ARMSCII-8 to UCS4.  */
00052 #define MIN_NEEDED_INPUT    MIN_NEEDED_FROM
00053 #define MIN_NEEDED_OUTPUT   MIN_NEEDED_TO
00054 #define LOOPFCT                    FROM_LOOP
00055 #define BODY \
00056   {                                                                  \
00057     uint_fast8_t ch = *inptr;                                               \
00058                                                                      \
00059     if (ch <= 0xa0)                                                  \
00060       {                                                                     \
00061         /* Upto and including 0xa0 the ARMSCII-8 corresponds to Unicode.  */  \
00062         *((uint32_t *) outptr) = ch;                                        \
00063         outptr += sizeof (uint32_t);                                        \
00064       }                                                                     \
00065     else if (ch >= 0xa2 && ch <= 0xfe)                                      \
00066       {                                                                     \
00067         /* Use the table.  */                                               \
00068         *((uint32_t *) outptr) = map_from_armscii_8[ch - 0xa2];                    \
00069         outptr += sizeof (uint32_t);                                        \
00070       }                                                                     \
00071     else                                                             \
00072       {                                                                     \
00073        /* This is an illegal character.  */                                 \
00074        STANDARD_FROM_LOOP_ERR_HANDLER (1);                                  \
00075       }                                                                     \
00076                                                                      \
00077     ++inptr;                                                         \
00078   }
00079 #define LOOP_NEED_FLAGS
00080 #define ONEBYTE_BODY \
00081   {                                                                  \
00082     if (c <= 0xa0)                                                   \
00083       /* Upto and including 0xa0 the ARMSCII-8 corresponds to Unicode.  */    \
00084       return c;                                                             \
00085     else if (c >= 0xa2 && c <= 0xfe)                                        \
00086       /* Use the table.  */                                          \
00087       return map_from_armscii_8[c - 0xa2];                                  \
00088     else                                                             \
00089       return WEOF;                                                   \
00090   }
00091 #include <iconv/loop.c>
00092 
00093 
00094 static const unsigned char map_to_armscii_8[0x58a - 0x531 + 1] =
00095   {
00096     0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, 0xc0,
00097     0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0,
00098     0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 0xe0,
00099     0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0,
00100     0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0x00, 0x00,
00101     0x00, 0xfe, 0xb0, 0xaf, 0xaa, 0xb1, 0x00, 0x00,
00102     0xb3, 0xb5, 0xb7, 0xb9, 0xbb, 0xbd, 0xbf, 0xc1,
00103     0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf, 0xd1,
00104     0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf, 0xe1,
00105     0xe3, 0xe5, 0xe7, 0xe9, 0xeb, 0xed, 0xef, 0xf1,
00106     0xf3, 0xf5, 0xf7, 0xf9, 0xfb, 0xfd, 0xa2, 0x00,
00107     0xa3, 0xad
00108   };
00109 
00110 
00111 /* Next, define the other direction.  */
00112 #define MIN_NEEDED_INPUT    MIN_NEEDED_TO
00113 #define MIN_NEEDED_OUTPUT   MIN_NEEDED_FROM
00114 #define LOOPFCT                    TO_LOOP
00115 #define BODY \
00116   {                                                                  \
00117     uint32_t ch = *((const uint32_t *) inptr);                              \
00118                                                                      \
00119     if (ch <= 0xa0)                                                  \
00120       /* Upto and including 0xa0 the ARMSCII-8 corresponds to Unicode.  */    \
00121       *outptr = (unsigned char) ch;                                         \
00122     else if (ch == 0xab)                                             \
00123       *outptr = 0xa7;                                                       \
00124     else if (ch == 0xbb)                                             \
00125       *outptr = 0xa6;                                                       \
00126     else if (ch >= 0x531 && ch <= 0x58a)                             \
00127       {                                                                     \
00128        unsigned char oc = map_to_armscii_8[ch - 0x531];              \
00129                                                                      \
00130        if (oc == 0)                                                  \
00131          /* No valid mapping.  */                                    \
00132          goto err;                                                   \
00133                                                                      \
00134        *outptr = oc;                                                 \
00135       }                                                                     \
00136     else if (ch == 0x2014)                                           \
00137       *outptr = 0xa8;                                                       \
00138     else if (ch == 0x2026)                                           \
00139       *outptr = 0xae;                                                       \
00140     else                                                             \
00141       {                                                                     \
00142        UNICODE_TAG_HANDLER (ch, 4);                                         \
00143                                                                      \
00144        /* We have an illegal character.  */                                 \
00145       err:                                                           \
00146        STANDARD_TO_LOOP_ERR_HANDLER (4);                             \
00147       }                                                                     \
00148     ++outptr;                                                        \
00149     inptr += 4;                                                             \
00150   }
00151 #define LOOP_NEED_FLAGS
00152 #include <iconv/loop.c>
00153 
00154 
00155 /* Now define the toplevel functions.  */
00156 #include <iconv/skeleton.c>