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