xref: /haiku/src/system/libroot/posix/glibc/iconv/gconv_simple.c (revision 25a7b01d15612846f332751841da3579db313082)
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