1 /* Generic conversion to and from 8bit charsets, 2 converting from UCS using gaps. 3 Copyright (C) 1997-2022 Free Software Foundation, Inc. 4 This file is part of the GNU C Library. 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, see 18 <https://www.gnu.org/licenses/>. */ 19 20 #include <dlfcn.h> 21 #include <stdint.h> 22 23 struct gap 24 { 25 uint16_t start; 26 uint16_t end; 27 int32_t idx; 28 }; 29 30 /* Now we can include the tables. */ 31 #include TABLES 32 33 #ifndef NONNUL 34 # define NONNUL(c) ((c) != '\0') 35 #endif 36 37 38 #define FROM_LOOP from_gap 39 #define TO_LOOP to_gap 40 #define DEFINE_INIT 1 41 #define DEFINE_FINI 1 42 #define MIN_NEEDED_FROM 1 43 #define MIN_NEEDED_TO 4 44 #define ONE_DIRECTION 0 45 46 47 /* First define the conversion function from the 8bit charset to UCS4. */ 48 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM 49 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO 50 #define LOOPFCT FROM_LOOP 51 #define BODY \ 52 { \ 53 uint32_t ch = to_ucs4[*inptr]; \ 54 \ 55 if (HAS_HOLES && __builtin_expect (ch == L'\0', 0) && NONNUL (*inptr)) \ 56 { \ 57 /* This is an illegal character. */ \ 58 STANDARD_FROM_LOOP_ERR_HANDLER (1); \ 59 } \ 60 else \ 61 { \ 62 put32 (outptr, ch); \ 63 outptr += 4; \ 64 } \ 65 \ 66 ++inptr; \ 67 } 68 #define LOOP_NEED_FLAGS 69 #define ONEBYTE_BODY \ 70 { \ 71 uint32_t ch = to_ucs4[c]; \ 72 \ 73 if (HAS_HOLES && __builtin_expect (ch == L'\0', 0) && NONNUL (c)) \ 74 return WEOF; \ 75 else \ 76 return ch; \ 77 } 78 #include <iconv/loop.c> 79 80 81 /* Next, define the other direction. */ 82 #define MIN_NEEDED_INPUT MIN_NEEDED_TO 83 #define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM 84 #define LOOPFCT TO_LOOP 85 #define BODY \ 86 { \ 87 const struct gap *rp = from_idx; \ 88 uint32_t ch = get32 (inptr); \ 89 unsigned char res; \ 90 \ 91 if (__glibc_unlikely (ch >= 0xffff)) \ 92 { \ 93 UNICODE_TAG_HANDLER (ch, 4); \ 94 rp = NULL; \ 95 } \ 96 else \ 97 while (ch > rp->end) \ 98 ++rp; \ 99 if (__builtin_expect (rp == NULL, 0) \ 100 || __builtin_expect (ch < rp->start, 0) \ 101 || (res = from_ucs4[ch + rp->idx], \ 102 __builtin_expect (res, '\1') == '\0' && ch != 0)) \ 103 { \ 104 /* This is an illegal character. */ \ 105 STANDARD_TO_LOOP_ERR_HANDLER (4); \ 106 } \ 107 \ 108 *outptr++ = res; \ 109 inptr += 4; \ 110 } 111 #define LOOP_NEED_FLAGS 112 #include <iconv/loop.c> 113 114 115 /* Now define the toplevel functions. */ 116 #include <iconv/skeleton.c> 117