/* Mapping tables for JOHAB handling.
- Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1998-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jungshik Shin <jshin@pantheon.yale.edu>
and 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 <stdint.h>
#include <ksc5601.h>
static const uint32_t final_to_ucs[31] =
{
L'\0', L'\0', 0x3133, L'\0', 0x3135, 0x3136, L'\0', L'\0',
- 0x313a, 0x313b, 0x314c, 0x313d, 0x313e, 0x313f,
- 0x3140, L'\0', L'\0', L'\0', 0x3144, L'\0', L'\0', L'\0',
+ 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f,
+ 0x3140, L'\0', L'\0', 0x3144, L'\0', L'\0', L'\0', L'\0',
L'\0', L'\0', L'\0', L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'
};
static const int mid_to_bit[21] =
{
- 0x0060, 0x0080, 0x00a0, 0x00c0, 0x00e0,
+ 0x0060, 0x0080, 0x00a0, 0x00c0, 0x00e0,
0x0140, 0x0160, 0x0180, 0x01a0, 0x01c0, 0x1e0,
0x0240, 0x0260, 0x0280, 0x02a0, 0x02c0, 0x02e0,
0x0340, 0x0360, 0x0380, 0x03a0
0x9041,
0x8446, 0x8447,
0x9441, 0x9841, 0x9c41,
- 0x844a, 0x844b, 0x844c, 0x844d, 0x884e, 0x884f, 0x8450,
+ 0x844a, 0x844b, 0x844c, 0x844d, 0x844e, 0x844f, 0x8450,
0xa041, 0xa441, 0xa841,
0x8454,
0xac41, 0xb041, 0xb441, 0xb841, 0xbc41,
- 0xc041, 0xc441, 0xc841, 0xca41, 0xd041,
+ 0xc041, 0xc441, 0xc841, 0xcc41, 0xd041,
0x8461, 0x8481, 0x84a1, 0x84c1, 0x84e1,
0x8541, 0x8561, 0x8581, 0x85a1, 0x85c1, 0x85e1,
0x8641, 0x8661, 0x8681, 0x86a1, 0x86c1, 0x86e1,
};
-static inline uint32_t
+static uint32_t
johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
{
if (idx <= 0xdefe)
#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 JOHAB to UCS4. */
{ \
uint32_t ch = *inptr; \
\
- /* half-width Korean Currency WON sign \
- if (ch == 0x5c) \
- ch = 0x20a9; \
- else if (ch < 0x7f) \
- ch = (uint32_t) ch; \
- */ \
- if (ch < 0x7f) \
- /* Plain ASCII. */ \
- ++inptr; \
+ if (ch <= 0x7f) \
+ { \
+ /* Plain ISO646-KR. */ \
+ if (ch == 0x5c) \
+ ch = 0x20a9; /* half-width Korean Currency WON sign */ \
+ ++inptr; \
+ } \
/* Johab : 1. Hangul \
1st byte : 0x84-0xd3 \
2nd byte : 0x41-0x7e, 0x81-0xfe \
0xd831-0xd87e and 0xd891-0xd8fe are user-defined area */ \
else \
{ \
- if (ch > 0xf9 || ch == 0xdf || (ch > 0x7e && ch < 0x84) \
- || (ch > 0xd3 && ch < 0xd9)) \
+ if (__builtin_expect (ch > 0xf9, 0) \
+ || __builtin_expect (ch == 0xdf, 0) \
+ || (__builtin_expect (ch > 0x7e, 0) && ch < 0x84) \
+ || (__builtin_expect (ch > 0xd3, 0) && ch < 0xd9)) \
{ \
/* These are illegal. */ \
- if (! ignore_errors_p ()) \
- { \
- /* This is an illegal character. */ \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
- } \
- \
- ++inptr; \
- ++*converted; \
- continue; \
+ STANDARD_FROM_LOOP_ERR_HANDLER (1); \
} \
else \
{ \
uint32_t ch2; \
uint_fast32_t idx; \
\
- if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
+ if (__glibc_unlikely (inptr + 1 >= inend)) \
{ \
/* The second character is not available. Store the \
intermediate result. */ \
\
ch2 = inptr[1]; \
idx = ch * 256 + ch2; \
- if (ch <= 0xd3) \
+ if (__glibc_likely (ch <= 0xd3)) \
{ \
/* Hangul */ \
- uint_fast32_t i, m, f; \
+ int_fast32_t i, m, f; \
\
i = init[(idx & 0x7c00) >> 10]; \
m = mid[(idx & 0x03e0) >> 5]; \
f = final[idx & 0x001f]; \
\
- if (i == -1 || m == -1 || f == -1) \
+ if (__builtin_expect (i == -1, 0) \
+ || __builtin_expect (m == -1, 0) \
+ || __builtin_expect (f == -1, 0)) \
{ \
/* This is illegal. */ \
- if (! ignore_errors_p ()) \
- { \
- /* This is an illegal character. */ \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
- } \
- \
- ++inptr; \
- ++*converted; \
- continue; \
+ STANDARD_FROM_LOOP_ERR_HANDLER (1); \
} \
else if (i > 0 && m > 0) \
ch = ((i - 1) * 21 + (m - 1)) * 28 + f + 0xac00; \
ch = init_to_ucs[i - 1]; \
else if (i == 0 && m > 0 && f == 0) \
ch = 0x314e + m; /* 0x314f + m - 1 */ \
- else if (i == 0 && m == 0 && f > 0) \
+ else if (__builtin_expect ((i | m) == 0, 1) \
+ && __builtin_expect (f > 0, 1)) \
ch = final_to_ucs[f - 1]; /* round trip?? */ \
else \
{ \
/* This is illegal. */ \
- if (! ignore_errors_p ()) \
- { \
- /* This is an illegal character. */ \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
- } \
- \
- ++inptr; \
- ++*converted; \
- continue; \
+ STANDARD_FROM_LOOP_ERR_HANDLER (1); \
} \
} \
else \
{ \
- if (ch2 < 0x31 || (ch2 > 0x7e && ch2 < 0x91) || ch2 == 0xff) \
+ if (__builtin_expect (ch2 < 0x31, 0) \
+ || (__builtin_expect (ch2 > 0x7e, 0) && ch2 < 0x91) \
+ || __builtin_expect (ch2, 0) == 0xff \
+ || (__builtin_expect (ch, 0) == 0xd9 && ch2 > 0xe8) \
+ || (__builtin_expect (ch, 0) == 0xda \
+ && ch2 > 0xa0 && ch2 < 0xd4) \
+ || (__builtin_expect (ch, 0) == 0xde && ch2 > 0xf1)) \
{ \
/* This is illegal. */ \
- if (! ignore_errors_p ()) \
- { \
- /* This is an illegal character. */ \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
- } \
- \
- ++inptr; \
- ++*converted; \
- continue; \
- } \
- else if (ch == 0xda && ch2 > 0xa0 && ch2 < 0xd4) \
- { \
- /* This is illegal. Modern Hangul Jaso is defined \
- elsewhere in Johab */ \
- if (! ignore_errors_p ()) \
- { \
- /* This is an illegal character. */ \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
- } \
- \
- ++inptr; \
- ++*converted; \
- continue; \
+ STANDARD_FROM_LOOP_ERR_HANDLER (1); \
} \
else \
{ \
+ ch2 - (ch2 > 0x90 \
? 0x43 : 0x31)]; \
else \
- ch = __ksc5601_hanja_to_ucs[(ch - 0xe0) *192 \
+ ch = __ksc5601_hanja_to_ucs[(ch - 0xe0) *192 \
+ ch2 - (ch2 > 0x90 \
?0x43 : 0x31)];\
*/ \
} \
} \
\
- if (ch == 0) \
+ if (__glibc_unlikely (ch == 0)) \
{ \
/* This is an illegal character. */ \
- if (! ignore_errors_p ()) \
- { \
- /* This is an illegal character. */ \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
- } \
- \
- inptr += 2; \
- ++*converted; \
- continue; \
+ STANDARD_FROM_LOOP_ERR_HANDLER (2); \
} \
\
inptr += 2; \
put32 (outptr, ch); \
outptr += 4; \
}
+#define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+ { \
+ if (c <= 0x7f) \
+ return (c == 0x5c ? 0x20a9 : c); \
+ else \
+ return WEOF; \
+ }
#include <iconv/loop.c>
cp = from_ucs4_lat1[ch]; \
*/ \
\
- if (ch < 0x7f) \
+ if (ch <= 0x7f && ch != 0x5c) \
*outptr++ = ch; \
else \
{ \
if (ch >= 0xac00 && ch <= 0xd7a3) \
{ \
- if (NEED_LENGTH_TEST && outptr + 2 > outend) \
+ if (__glibc_unlikely (outptr + 2 > outend)) \
{ \
result = __GCONV_FULL_OUTPUT; \
break; \
{ \
ch = jamo_from_ucs_table[ch - 0x3131]; \
\
- if (NEED_LENGTH_TEST && outptr + 2 > outend) \
+ if (__glibc_unlikely (outptr + 2 > outend)) \
{ \
result = __GCONV_FULL_OUTPUT; \
break; \
size_t written; \
uint32_t temp; \
\
- written = ucs4_to_ksc5601_hanja (ch, outptr, \
- (NEED_LENGTH_TEST \
- ? outend - outptr : 2)); \
- if (NEED_LENGTH_TEST && written == 0) \
+ written = ucs4_to_ksc5601_hanja (ch, outptr, outend - outptr); \
+ if (__builtin_expect (written, 1) == 0) \
{ \
result = __GCONV_FULL_OUTPUT; \
break; \
} \
- if (written == __UNKNOWN_10646_CHAR) \
+ if (__glibc_unlikely (written == __UNKNOWN_10646_CHAR)) \
{ \
- if (! ignore_errors_p ()) \
- { \
- /* This is an illegal character. */ \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
- } \
- \
- inptr += 4; \
- ++*converted; \
- continue; \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
} \
\
outptr[0] -= 0x4a; \
\
outptr += 2; \
} \
+ else if (ch == 0x20a9) \
+ *outptr++ = 0x5c; \
else \
{ \
size_t written; \
+ uint32_t temp; \
\
- written = ucs4_to_ksc5601_sym (ch, outptr, \
- (NEED_LENGTH_TEST \
- ? outend - outptr : 2)); \
- if (NEED_LENGTH_TEST && written == 0) \
+ written = ucs4_to_ksc5601_sym (ch, outptr, outend - outptr); \
+ if (__builtin_expect (written, 1) == 0) \
{ \
result = __GCONV_FULL_OUTPUT; \
break; \
} \
- if (written == __UNKNOWN_10646_CHAR) \
+ if (__builtin_expect (written == __UNKNOWN_10646_CHAR, 0) \
+ || (outptr[0] == 0x22 && outptr[1] > 0x68)) \
{ \
- if (! ignore_errors_p ()) \
- { \
- /* This is an illegal character. */ \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
- } \
- \
- inptr += 4; \
- ++*converted; \
- continue; \
+ UNICODE_TAG_HANDLER (ch, 4); \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
} \
\
- outptr[0] -= 0x4a; \
- outptr[1] += 0x80; \
- \
- outptr[1] += (outptr[0] % 2 \
- ? 0 : (outptr[1] > 0xee ? 0x43 : 0x31)); \
- outptr[1] -= 0xa1; \
- outptr[0] /= 2; \
- outptr[0] += 0xe0; \
+ temp = (outptr[0] < 0x4a ? outptr[0] + 0x191 : outptr[0] + 0x176);\
+ outptr[1] += (temp % 2 ? 0x5e : 0); \
+ outptr[1] += (outptr[1] < 0x6f ? 0x10 : 0x22); \
+ outptr[0] = temp / 2; \
\
outptr += 2; \
} \
\
inptr += 4; \
}
+#define LOOP_NEED_FLAGS
#include <iconv/loop.c>