1 /* Simple transformations functions.
2 Copyright (C) 1997-2003, 2004 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 #include <gconv_int.h>
29 #include <libroot/wchar_private.h>
31 #define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, BtowcFct, \
32 MinF, MaxF, MinT, MaxT) \
33 extern int Fct (struct __gconv_step *, struct __gconv_step_data *, \
34 __const unsigned char **, __const unsigned char *, \
35 unsigned char **, size_t *, int, int);
36 #include "gconv_builtin.h"
39 /* Convert from ISO 646-IRV to the internal (UCS4-like) format. */
42 #define MIN_NEEDED_FROM 1
43 #define MIN_NEEDED_TO 4
44 #define FROM_DIRECTION 1
45 #define FROM_LOOP ascii_internal_loop
46 #define TO_LOOP ascii_internal_loop /* This is not used. */
47 #define FUNCTION_NAME __gconv_transform_ascii_internal
48 #define ONE_DIRECTION 1
50 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
51 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
52 #define LOOPFCT FROM_LOOP
55 if (__builtin_expect(*inptr > '\x7f', 0)) { \
56 /* The value is too large. We don't try transliteration here since \
57 this is not an error because of the lack of possibilities to \
58 represent the result. This is a genuine bug in the input since \
59 ASCII does not allow such values. */ \
60 STANDARD_FROM_LOOP_ERR_HANDLER(1); \
62 /* It's an one byte sequence. */ \
63 *((uint32_t*)outptr) = *inptr++; \
64 outptr += sizeof(uint32_t); \
67 #define LOOP_NEED_FLAGS
68 #include <iconv/loop.c>
69 #include <iconv/skeleton.c>
72 /* Convert from the internal (UCS4-like) format to ISO 646-IRV. */
75 #define MIN_NEEDED_FROM 4
76 #define MIN_NEEDED_TO 1
77 #define FROM_DIRECTION 1
78 #define FROM_LOOP internal_ascii_loop
79 #define TO_LOOP internal_ascii_loop /* This is not used. */
80 #define FUNCTION_NAME __gconv_transform_internal_ascii
81 #define ONE_DIRECTION 1
83 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
84 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
85 #define LOOPFCT FROM_LOOP
88 if (__builtin_expect(*((const uint32_t*)inptr) > 0x7f, 0)) { \
89 UNICODE_TAG_HANDLER(*((const uint32_t*)inptr), 4); \
90 STANDARD_TO_LOOP_ERR_HANDLER(4); \
92 /* It's an one byte sequence. */ \
93 *outptr++ = *((const uint32_t*)inptr); \
94 inptr += sizeof(uint32_t); \
97 #define LOOP_NEED_FLAGS
98 #include <iconv/loop.c>
99 #include <iconv/skeleton.c>
102 /* Convert from multibyte to wchar_t format. */
103 #define DEFINE_INIT 0
104 #define DEFINE_FINI 0
105 #define MIN_NEEDED_FROM 1
106 #define MAX_NEEDED_FROM MB_LEN_MAX
107 #define MIN_NEEDED_TO 4
108 #define MAX_NEEDED_TO 4
109 #define FROM_DIRECTION 1
110 #define FROM_LOOP multibyte_wchar_loop
111 #define TO_LOOP multibyte_wchar_loop /* This is not used. */
112 #define FUNCTION_NAME __gconv_transform_multibyte_wchar
113 #define ONE_DIRECTION 1
115 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
116 #define MAX_NEEDED_INPUT MAX_NEEDED_FROM
117 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
118 #define MAX_NEEDED_OUTPUT MAX_NEEDED_TO
119 #define LOOPFCT FROM_LOOP
122 size_t inLen = inend - inptr; \
123 mbstate_t *state = step_data->__statep; \
125 = __mbrtowc((wchar_t*)outptr, (const char*)inptr, inLen, state); \
126 if (result == (size_t)-1) { \
127 /* illegal character, skip it */ \
128 STANDARD_FROM_LOOP_ERR_HANDLER(1); \
129 } else if (result == (size_t)-2) { \
130 /* input too short, do nothing */ \
131 } else if (result == 0) { \
132 /* termination character found */ \
133 outptr += sizeof(wchar_t); \
136 /* a character has been converted */ \
138 outptr += sizeof(wchar_t); \
141 #define LOOP_NEED_FLAGS
142 #include <iconv/loop.c>
143 #include <iconv/skeleton.c>
146 /* Convert from wchar_t to multibyte format. */
147 #define DEFINE_INIT 0
148 #define DEFINE_FINI 0
149 #define MIN_NEEDED_FROM 4
150 #define MAX_NEEDED_FROM 4
151 #define MIN_NEEDED_TO MB_LEN_MAX
152 #define MAX_NEEDED_TO MB_LEN_MAX
153 #define FROM_DIRECTION 1
154 #define FROM_LOOP wchar_multibyte_loop
155 #define TO_LOOP wchar_multibyte_loop /* This is not used. */
156 #define FUNCTION_NAME __gconv_transform_wchar_multibyte
157 #define ONE_DIRECTION 1
159 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
160 #define MAX_NEEDED_INPUT MAX_NEEDED_FROM
161 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
162 #define MAX_NEEDED_OUTPUT MAX_NEEDED_TO
163 #define LOOPFCT FROM_LOOP
166 mbstate_t *state = step_data->__statep; \
167 size_t result = __wcrtomb((char*)outptr, *(wchar_t*)inptr, state); \
168 if (result == (size_t)-1) { \
169 /* illegal character, skip it */ \
170 STANDARD_TO_LOOP_ERR_HANDLER(sizeof(wchar_t)); \
171 } else if (result == 0) { \
172 /* termination character found */ \
173 inptr += sizeof(wchar_t); \
176 /* a character has been converted */ \
178 inptr += sizeof(wchar_t); \
181 #define LOOP_NEED_FLAGS
182 #include <iconv/loop.c>
183 #include <iconv/skeleton.c>