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. 5 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. 10 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. 15 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 19 02111-1307 USA. */ 20 21 #include <errno.h> 22 #include <gconv.h> 23 #include <stdint.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <wchar.h> 27 #include <gconv_int.h> 28 29 #include <libroot/wchar_private.h> 30 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" 37 38 39 /* Convert from ISO 646-IRV to the internal (UCS4-like) format. */ 40 #define DEFINE_INIT 0 41 #define DEFINE_FINI 0 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 49 50 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM 51 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO 52 #define LOOPFCT FROM_LOOP 53 #define BODY \ 54 { \ 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); \ 61 } else { \ 62 /* It's an one byte sequence. */ \ 63 *((uint32_t*)outptr) = *inptr++; \ 64 outptr += sizeof(uint32_t); \ 65 } \ 66 } 67 #define LOOP_NEED_FLAGS 68 #include <iconv/loop.c> 69 #include <iconv/skeleton.c> 70 71 72 /* Convert from the internal (UCS4-like) format to ISO 646-IRV. */ 73 #define DEFINE_INIT 0 74 #define DEFINE_FINI 0 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 82 83 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM 84 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO 85 #define LOOPFCT FROM_LOOP 86 #define BODY \ 87 { \ 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); \ 91 } else { \ 92 /* It's an one byte sequence. */ \ 93 *outptr++ = *((const uint32_t*)inptr); \ 94 inptr += sizeof(uint32_t); \ 95 } \ 96 } 97 #define LOOP_NEED_FLAGS 98 #include <iconv/loop.c> 99 #include <iconv/skeleton.c> 100 101 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 114 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 120 #define BODY \ 121 { \ 122 size_t inLen = inend - inptr; \ 123 mbstate_t *state = step_data->__statep; \ 124 size_t result \ 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); \ 134 ++inptr; \ 135 } else { \ 136 /* a character has been converted */ \ 137 inptr += result; \ 138 outptr += sizeof(wchar_t); \ 139 } \ 140 } 141 #define LOOP_NEED_FLAGS 142 #include <iconv/loop.c> 143 #include <iconv/skeleton.c> 144 145 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 158 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 164 #define BODY \ 165 { \ 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); \ 174 ++outptr; \ 175 } else { \ 176 /* a character has been converted */ \ 177 outptr += result; \ 178 inptr += sizeof(wchar_t); \ 179 } \ 180 } 181 #define LOOP_NEED_FLAGS 182 #include <iconv/loop.c> 183 #include <iconv/skeleton.c> 184