15af32e75SAxel Dörfler /* Simple transformations functions. 287e239b9SJérôme Duval Copyright (C) 1997-2003, 2004 Free Software Foundation, Inc. 35af32e75SAxel Dörfler This file is part of the GNU C Library. 45af32e75SAxel Dörfler Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. 55af32e75SAxel Dörfler 65af32e75SAxel Dörfler The GNU C Library is free software; you can redistribute it and/or 75af32e75SAxel Dörfler modify it under the terms of the GNU Lesser General Public 85af32e75SAxel Dörfler License as published by the Free Software Foundation; either 95af32e75SAxel Dörfler version 2.1 of the License, or (at your option) any later version. 105af32e75SAxel Dörfler 115af32e75SAxel Dörfler The GNU C Library is distributed in the hope that it will be useful, 125af32e75SAxel Dörfler but WITHOUT ANY WARRANTY; without even the implied warranty of 135af32e75SAxel Dörfler MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 145af32e75SAxel Dörfler Lesser General Public License for more details. 155af32e75SAxel Dörfler 165af32e75SAxel Dörfler You should have received a copy of the GNU Lesser General Public 175af32e75SAxel Dörfler License along with the GNU C Library; if not, write to the Free 185af32e75SAxel Dörfler Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 195af32e75SAxel Dörfler 02111-1307 USA. */ 205af32e75SAxel Dörfler 215af32e75SAxel Dörfler #include <errno.h> 225af32e75SAxel Dörfler #include <gconv.h> 235af32e75SAxel Dörfler #include <stdint.h> 245af32e75SAxel Dörfler #include <stdlib.h> 255af32e75SAxel Dörfler #include <string.h> 265af32e75SAxel Dörfler #include <wchar.h> 275af32e75SAxel Dörfler #include <gconv_int.h> 285af32e75SAxel Dörfler 29*2370b92eSOliver Tappe #include <libroot/wchar_private.h> 30*2370b92eSOliver Tappe 315af32e75SAxel Dörfler #define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, BtowcFct, \ 325af32e75SAxel Dörfler MinF, MaxF, MinT, MaxT) \ 335af32e75SAxel Dörfler extern int Fct (struct __gconv_step *, struct __gconv_step_data *, \ 345af32e75SAxel Dörfler __const unsigned char **, __const unsigned char *, \ 355af32e75SAxel Dörfler unsigned char **, size_t *, int, int); 365af32e75SAxel Dörfler #include "gconv_builtin.h" 375af32e75SAxel Dörfler 385af32e75SAxel Dörfler 395af32e75SAxel Dörfler /* Convert from ISO 646-IRV to the internal (UCS4-like) format. */ 405af32e75SAxel Dörfler #define DEFINE_INIT 0 415af32e75SAxel Dörfler #define DEFINE_FINI 0 425af32e75SAxel Dörfler #define MIN_NEEDED_FROM 1 435af32e75SAxel Dörfler #define MIN_NEEDED_TO 4 445af32e75SAxel Dörfler #define FROM_DIRECTION 1 455af32e75SAxel Dörfler #define FROM_LOOP ascii_internal_loop 465af32e75SAxel Dörfler #define TO_LOOP ascii_internal_loop /* This is not used. */ 475af32e75SAxel Dörfler #define FUNCTION_NAME __gconv_transform_ascii_internal 485af32e75SAxel Dörfler #define ONE_DIRECTION 1 495af32e75SAxel Dörfler 505af32e75SAxel Dörfler #define MIN_NEEDED_INPUT MIN_NEEDED_FROM 515af32e75SAxel Dörfler #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO 525af32e75SAxel Dörfler #define LOOPFCT FROM_LOOP 535af32e75SAxel Dörfler #define BODY \ 545af32e75SAxel Dörfler { \ 55*2370b92eSOliver Tappe if (__builtin_expect(*inptr > '\x7f', 0)) { \ 565af32e75SAxel Dörfler /* The value is too large. We don't try transliteration here since \ 575af32e75SAxel Dörfler this is not an error because of the lack of possibilities to \ 585af32e75SAxel Dörfler represent the result. This is a genuine bug in the input since \ 595af32e75SAxel Dörfler ASCII does not allow such values. */ \ 605af32e75SAxel Dörfler STANDARD_FROM_LOOP_ERR_HANDLER(1); \ 61*2370b92eSOliver Tappe } else { \ 625af32e75SAxel Dörfler /* It's an one byte sequence. */ \ 6387e239b9SJérôme Duval *((uint32_t*)outptr) = *inptr++; \ 6487e239b9SJérôme Duval outptr += sizeof(uint32_t); \ 65*2370b92eSOliver Tappe } \ 665af32e75SAxel Dörfler } 675af32e75SAxel Dörfler #define LOOP_NEED_FLAGS 685af32e75SAxel Dörfler #include <iconv/loop.c> 695af32e75SAxel Dörfler #include <iconv/skeleton.c> 705af32e75SAxel Dörfler 715af32e75SAxel Dörfler 725af32e75SAxel Dörfler /* Convert from the internal (UCS4-like) format to ISO 646-IRV. */ 735af32e75SAxel Dörfler #define DEFINE_INIT 0 745af32e75SAxel Dörfler #define DEFINE_FINI 0 755af32e75SAxel Dörfler #define MIN_NEEDED_FROM 4 765af32e75SAxel Dörfler #define MIN_NEEDED_TO 1 775af32e75SAxel Dörfler #define FROM_DIRECTION 1 785af32e75SAxel Dörfler #define FROM_LOOP internal_ascii_loop 795af32e75SAxel Dörfler #define TO_LOOP internal_ascii_loop /* This is not used. */ 805af32e75SAxel Dörfler #define FUNCTION_NAME __gconv_transform_internal_ascii 815af32e75SAxel Dörfler #define ONE_DIRECTION 1 825af32e75SAxel Dörfler 835af32e75SAxel Dörfler #define MIN_NEEDED_INPUT MIN_NEEDED_FROM 845af32e75SAxel Dörfler #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO 855af32e75SAxel Dörfler #define LOOPFCT FROM_LOOP 865af32e75SAxel Dörfler #define BODY \ 875af32e75SAxel Dörfler { \ 88*2370b92eSOliver Tappe if (__builtin_expect(*((const uint32_t*)inptr) > 0x7f, 0)) { \ 895af32e75SAxel Dörfler UNICODE_TAG_HANDLER(*((const uint32_t*)inptr), 4); \ 905af32e75SAxel Dörfler STANDARD_TO_LOOP_ERR_HANDLER(4); \ 91*2370b92eSOliver Tappe } else { \ 925af32e75SAxel Dörfler /* It's an one byte sequence. */ \ 9387e239b9SJérôme Duval *outptr++ = *((const uint32_t*)inptr); \ 9487e239b9SJérôme Duval inptr += sizeof(uint32_t); \ 95*2370b92eSOliver Tappe } \ 965af32e75SAxel Dörfler } 975af32e75SAxel Dörfler #define LOOP_NEED_FLAGS 985af32e75SAxel Dörfler #include <iconv/loop.c> 995af32e75SAxel Dörfler #include <iconv/skeleton.c> 1005af32e75SAxel Dörfler 1015af32e75SAxel Dörfler 102*2370b92eSOliver Tappe /* Convert from multibyte to wchar_t format. */ 1035af32e75SAxel Dörfler #define DEFINE_INIT 0 1045af32e75SAxel Dörfler #define DEFINE_FINI 0 1055af32e75SAxel Dörfler #define MIN_NEEDED_FROM 1 106*2370b92eSOliver Tappe #define MAX_NEEDED_FROM MB_LEN_MAX 1075af32e75SAxel Dörfler #define MIN_NEEDED_TO 4 108*2370b92eSOliver Tappe #define MAX_NEEDED_TO 4 1095af32e75SAxel Dörfler #define FROM_DIRECTION 1 110*2370b92eSOliver Tappe #define FROM_LOOP multibyte_wchar_loop 111*2370b92eSOliver Tappe #define TO_LOOP multibyte_wchar_loop /* This is not used. */ 112*2370b92eSOliver Tappe #define FUNCTION_NAME __gconv_transform_multibyte_wchar 1135af32e75SAxel Dörfler #define ONE_DIRECTION 1 1145af32e75SAxel Dörfler 1155af32e75SAxel Dörfler #define MIN_NEEDED_INPUT MIN_NEEDED_FROM 1165af32e75SAxel Dörfler #define MAX_NEEDED_INPUT MAX_NEEDED_FROM 1175af32e75SAxel Dörfler #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO 118*2370b92eSOliver Tappe #define MAX_NEEDED_OUTPUT MAX_NEEDED_TO 1195af32e75SAxel Dörfler #define LOOPFCT FROM_LOOP 1205af32e75SAxel Dörfler #define BODY \ 1215af32e75SAxel Dörfler { \ 122*2370b92eSOliver Tappe size_t inLen = inend - inptr; \ 123*2370b92eSOliver Tappe mbstate_t *state = step_data->__statep; \ 124*2370b92eSOliver Tappe size_t result \ 125*2370b92eSOliver Tappe = __mbrtowc((wchar_t*)outptr, (const char*)inptr, inLen, state); \ 126*2370b92eSOliver Tappe if (result == (size_t)-1) { \ 127*2370b92eSOliver Tappe /* illegal character, skip it */ \ 128*2370b92eSOliver Tappe STANDARD_FROM_LOOP_ERR_HANDLER(1); \ 129*2370b92eSOliver Tappe } else if (result == (size_t)-2) { \ 130*2370b92eSOliver Tappe /* input too short, do nothing */ \ 131*2370b92eSOliver Tappe } else if (result == 0) { \ 132*2370b92eSOliver Tappe /* termination character found */ \ 133*2370b92eSOliver Tappe outptr += sizeof(wchar_t); \ 1345af32e75SAxel Dörfler ++inptr; \ 135*2370b92eSOliver Tappe } else { \ 136*2370b92eSOliver Tappe /* a character has been converted */ \ 137*2370b92eSOliver Tappe inptr += result; \ 138*2370b92eSOliver Tappe outptr += sizeof(wchar_t); \ 1395af32e75SAxel Dörfler } \ 1405af32e75SAxel Dörfler } 1415af32e75SAxel Dörfler #define LOOP_NEED_FLAGS 1425af32e75SAxel Dörfler #include <iconv/loop.c> 1435af32e75SAxel Dörfler #include <iconv/skeleton.c> 1445af32e75SAxel Dörfler 1455af32e75SAxel Dörfler 146*2370b92eSOliver Tappe /* Convert from wchar_t to multibyte format. */ 1475af32e75SAxel Dörfler #define DEFINE_INIT 0 1485af32e75SAxel Dörfler #define DEFINE_FINI 0 1495af32e75SAxel Dörfler #define MIN_NEEDED_FROM 4 150*2370b92eSOliver Tappe #define MAX_NEEDED_FROM 4 151*2370b92eSOliver Tappe #define MIN_NEEDED_TO MB_LEN_MAX 152*2370b92eSOliver Tappe #define MAX_NEEDED_TO MB_LEN_MAX 1535af32e75SAxel Dörfler #define FROM_DIRECTION 1 154*2370b92eSOliver Tappe #define FROM_LOOP wchar_multibyte_loop 155*2370b92eSOliver Tappe #define TO_LOOP wchar_multibyte_loop /* This is not used. */ 156*2370b92eSOliver Tappe #define FUNCTION_NAME __gconv_transform_wchar_multibyte 1575af32e75SAxel Dörfler #define ONE_DIRECTION 1 1585af32e75SAxel Dörfler 1595af32e75SAxel Dörfler #define MIN_NEEDED_INPUT MIN_NEEDED_FROM 160*2370b92eSOliver Tappe #define MAX_NEEDED_INPUT MAX_NEEDED_FROM 1615af32e75SAxel Dörfler #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO 162*2370b92eSOliver Tappe #define MAX_NEEDED_OUTPUT MAX_NEEDED_TO 1635af32e75SAxel Dörfler #define LOOPFCT FROM_LOOP 1645af32e75SAxel Dörfler #define BODY \ 1655af32e75SAxel Dörfler { \ 166*2370b92eSOliver Tappe mbstate_t *state = step_data->__statep; \ 167*2370b92eSOliver Tappe size_t result = __wcrtomb((char*)outptr, *(wchar_t*)inptr, state); \ 168*2370b92eSOliver Tappe if (result == (size_t)-1) { \ 169*2370b92eSOliver Tappe /* illegal character, skip it */ \ 170*2370b92eSOliver Tappe STANDARD_TO_LOOP_ERR_HANDLER(sizeof(wchar_t)); \ 171*2370b92eSOliver Tappe } else if (result == 0) { \ 172*2370b92eSOliver Tappe /* termination character found */ \ 173*2370b92eSOliver Tappe inptr += sizeof(wchar_t); \ 174*2370b92eSOliver Tappe ++outptr; \ 175*2370b92eSOliver Tappe } else { \ 176*2370b92eSOliver Tappe /* a character has been converted */ \ 177*2370b92eSOliver Tappe outptr += result; \ 178*2370b92eSOliver Tappe inptr += sizeof(wchar_t); \ 1795af32e75SAxel Dörfler } \ 1805af32e75SAxel Dörfler } 1815af32e75SAxel Dörfler #define LOOP_NEED_FLAGS 1825af32e75SAxel Dörfler #include <iconv/loop.c> 1835af32e75SAxel Dörfler #include <iconv/skeleton.c> 184