1 /* Access functions for JISX0208 conversion. 2 Copyright (C) 1997-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 #ifndef _JIS0208_H 20 #define _JIS0208_H 1 21 22 #include <gconv.h> 23 #include <stdint.h> 24 25 /* Struct for table with indices in UCS mapping table. */ 26 struct jisx0208_ucs_idx 27 { 28 uint16_t start; 29 uint16_t end; 30 uint16_t idx; 31 }; 32 33 34 /* Conversion table. */ 35 extern const uint16_t __jis0208_to_ucs[]; 36 37 #define JIS0208_LAT1_MIN 0xa2 38 #define JIS0208_LAT1_MAX 0xf7 39 extern const char __jisx0208_from_ucs4_lat1[JIS0208_LAT1_MAX + 1 40 - JIS0208_LAT1_MIN][2]; 41 extern const char __jisx0208_from_ucs4_greek[0xc1][2]; 42 extern const struct jisx0208_ucs_idx __jisx0208_from_ucs_idx[]; 43 extern const char __jisx0208_from_ucs_tab[][2]; 44 45 uint32_t(always_inline)46static inline uint32_t 47 __attribute ((always_inline)) 48 jisx0208_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset) 49 { 50 unsigned char ch = *(*s); 51 unsigned char ch2; 52 int idx; 53 54 if (ch < offset || (ch - offset) <= 0x20) 55 return __UNKNOWN_10646_CHAR; 56 57 if (avail < 2) 58 return 0; 59 60 ch2 = (*s)[1]; 61 if (ch2 < offset || (ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f) 62 return __UNKNOWN_10646_CHAR; 63 64 idx = (ch - 0x21 - offset) * 94 + (ch2 - 0x21 - offset); 65 if (idx >= 0x1e80) 66 return __UNKNOWN_10646_CHAR; 67 68 (*s) += 2; 69 70 return __jis0208_to_ucs[idx] ?: ((*s) -= 2, __UNKNOWN_10646_CHAR); 71 } 72 73 size_t(always_inline)74static inline size_t 75 __attribute ((always_inline)) 76 ucs4_to_jisx0208 (uint32_t wch, unsigned char *s, size_t avail) 77 { 78 unsigned int ch = (unsigned int) wch; 79 const char *cp; 80 81 if (avail < 2) 82 return 0; 83 84 if (ch >= JIS0208_LAT1_MIN && ch <= JIS0208_LAT1_MAX) 85 cp = __jisx0208_from_ucs4_lat1[ch - JIS0208_LAT1_MIN]; 86 else if (ch >= 0x391 && ch <= 0x451) 87 cp = __jisx0208_from_ucs4_greek[ch - 0x391]; 88 else 89 { 90 const struct jisx0208_ucs_idx *rp = __jisx0208_from_ucs_idx; 91 92 if (ch >= 0xffff) 93 return __UNKNOWN_10646_CHAR; 94 while (ch > rp->end) 95 ++rp; 96 if (ch >= rp->start) 97 cp = __jisx0208_from_ucs_tab[rp->idx + ch - rp->start]; 98 else 99 return __UNKNOWN_10646_CHAR; 100 } 101 102 if (cp[0] == '\0') 103 return __UNKNOWN_10646_CHAR; 104 105 s[0] = cp[0]; 106 s[1] = cp[1]; 107 108 return 2; 109 } 110 111 #endif /* jis0208.h */ 112