/* Generic conversion to and from ANSI_X3.110-1983.
- Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1998-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+#include <dlfcn.h>
#include <gconv.h>
#include <stdint.h>
#include <string.h>
/* 0x00dc */ "\xc8\x55", "\xc2\x59", "\xec\x00", "\xfb\x00", "\xc1\x61",
/* 0x00e1 */ "\xc2\x61", "\xc3\x61", "\xc4\x61", "\xc8\x61", "\xca\x61",
/* 0x00e6 */ "\xf1\x00", "\xcb\x63", "\xc1\x65", "\xc2\x65", "\xc3\x65",
- /* 0x00eb */ "\xc8\x65", "\xc1\x69", "\xc2\xe9", "\xc3\x69", "\xc8\x69",
+ /* 0x00eb */ "\xc8\x65", "\xc1\x69", "\xc2\x69", "\xc3\x69", "\xc8\x69",
/* 0x00f0 */ "\xf3\x00", "\xc4\x6e", "\xc1\x6f", "\xc2\x6f", "\xc3\x6f",
/* 0x00f5 */ "\xc4\x6f", "\xc8\x6f", "\xb8\x00", "\xf9\x00", "\xc1\x75",
/* 0x00fa */ "\xc2\x75", "\xc3\x75", "\xc8\x75", "\xc2\x79", "\xfc\x00",
#define MIN_NEEDED_FROM 1
#define MAX_NEEDED_FROM 2
#define MIN_NEEDED_TO 4
+#define ONE_DIRECTION 0
/* First define the conversion function from ANSI_X3.110 to UCS4. */
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
#define BODY \
{ \
uint32_t ch = *inptr; \
+ int incr; \
\
- if (ch >= 0xc1 && ch <= 0xcf) \
+ if (__builtin_expect (ch >= 0xc1, 0) && ch <= 0xcf) \
{ \
- /* Composed character. First test whether the next character \
+ /* Composed character. First test whether the next byte \
is also available. */ \
uint32_t ch2; \
\
- if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
+ if (inptr + 1 >= inend) \
{ \
/* The second character is not available. */ \
result = __GCONV_INCOMPLETE_INPUT; \
\
ch2 = inptr[1]; \
\
- if (ch2 < 0x20 || ch2 >= 0x80) \
+ if (__builtin_expect (ch2 < 0x20, 0) \
+ || __builtin_expect (ch2 >= 0x80, 0)) \
{ \
/* This is illegal. */ \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
+ STANDARD_FROM_LOOP_ERR_HANDLER (1); \
+ } \
+ else \
+ { \
+ ch = to_ucs4_comb[ch - 0xc1][ch2 - 0x20]; \
+ incr = 2; \
} \
- \
- ch = to_ucs4_comb[ch - 0xc1][ch2 - 0x20]; \
- \
- inptr += 2; \
} \
else \
{ \
ch = to_ucs4[ch]; \
- ++inptr; \
+ incr = 1; \
} \
\
- if (ch == 0 && *inptr != '\0') \
+ if (__builtin_expect (ch == 0, 0) && *inptr != '\0') \
{ \
/* This is an illegal character. */ \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
+ STANDARD_FROM_LOOP_ERR_HANDLER (incr); \
+ } \
+ else \
+ { \
+ put32 (outptr, ch); \
+ outptr += 4; \
} \
\
- *((uint32_t *) outptr)++ = ch; \
+ inptr += incr; \
+ }
+#define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+ { \
+ uint32_t ch = to_ucs4[c]; \
+ \
+ if (__builtin_expect (ch == 0, 0) && c != '\0') \
+ return WEOF; \
+ else \
+ return ch; \
}
#include <iconv/loop.c>
#define BODY \
{ \
char tmp[2]; \
- uint32_t ch = *((uint32_t *) inptr); \
+ uint32_t ch = get32 (inptr); \
const char *cp; \
\
- if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0])) \
+ if (__builtin_expect (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]), \
+ 0)) \
{ \
if (ch == 0x2c7) \
cp = "\xcf\x20"; \
tmp[1] = ' '; \
cp = tmp; \
} \
- else if (ch >= 0x2014 && ch <= 0x2026) \
+ else if (ch >= 0x2014 && ch <= 0x201d) \
{ \
- static const char map[19] = \
- "\xd0\x00\x00\x00\xa9\xb9\x00\x00\xaa\xba\x00\x00\x00\x00" \
- "\xd4\x00\x00\x00\xe0"; \
+ static const char map[10] = \
+ "\xd0\x00\x00\x00\xa9\xb9\x00\x00\xaa\xba"; \
\
tmp[0] = map[ch - 0x2014]; \
if (tmp[0] == '\0') \
{ \
/* Illegal characters. */ \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
+ } \
+ tmp[1] = '\0'; \
+ cp = tmp; \
+ } \
+ else if (ch >= 0x2122 && ch <= 0x2126) \
+ { \
+ static const char map[5] = \
+ "\xd4\x00\x00\x00\xe0"; \
+ \
+ tmp[0] = map[ch - 0x2122]; \
+ if (tmp[0] == '\0') \
+ { \
+ /* Illegal characters. */ \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
} \
tmp[1] = '\0'; \
cp = tmp; \
cp = "\xd7"; \
else if (ch == 0x253c) \
cp = "\xe5"; \
- else if (ch >= 0x2571 && ch <= 0x2572) \
+ else if (ch >= 0x2571 && ch <= 0x2572) \
{ \
tmp[0] = 0xd8 + ch - 0x2571; \
tmp[1] = '\0'; \
cp = tmp; \
} \
- else if (ch >= 0x25e2 && ch <= 0x25e3) \
+ else if (ch >= 0x25e2 && ch <= 0x25e3) \
{ \
tmp[0] = 0xda + ch - 0x25e2; \
tmp[1] = '\0'; \
cp = tmp; \
} \
- else if (ch == 0x266a) \
+ else if (__builtin_expect (ch, 0x266a) == 0x266a) \
cp = "\xd5"; \
else \
{ \
+ UNICODE_TAG_HANDLER (ch, 4); \
+ \
/* Illegal characters. */ \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
} \
} \
else \
{ \
cp = from_ucs4[ch]; \
\
- if (cp[0] == '\0' && ch != 0) \
+ if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \
{ \
- /* Illegal. */ \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
+ /* Illegal characters. */ \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
} \
} \
\
/* Now test for a possible second byte and write this if possible. */ \
if (cp[1] != '\0') \
{ \
- if (NEED_LENGTH_TEST && outptr >= outend) \
+ if (__glibc_unlikely (outptr >= outend)) \
{ \
/* The result does not fit into the buffer. */ \
--outptr; \
\
inptr += 4; \
}
+#define LOOP_NEED_FLAGS
#include <iconv/loop.c>