(root)/
glibc-2.38/
iconvdata/
ksc5601.h
       1  /* Access functions for KS C 5601-1992 based encoding conversion.
       2     Copyright (C) 1998-2023 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 _KSC5601_H
      20  #define _KSC5601_H	1
      21  
      22  #define KSC5601_HANGUL 2350
      23  #define KSC5601_HANJA  4888
      24  #define KSC5601_SYMBOL  989
      25  
      26  #include <gconv.h>
      27  #include <stdint.h>
      28  
      29  /* Structure to map from UCS to KSC.  This structure should be packed
      30     on all platforms.  */
      31  struct map
      32  {
      33    uint16_t ucs;
      34    char val[2];
      35  };
      36  
      37  /* Conversion table.  */
      38  extern const uint16_t __ksc5601_hangul_to_ucs[KSC5601_HANGUL];
      39  extern const uint16_t __ksc5601_sym_to_ucs[];
      40  extern const struct map __ksc5601_sym_from_ucs[KSC5601_SYMBOL];
      41  extern const uint16_t __ksc5601_hanja_to_ucs[KSC5601_HANJA];
      42  extern const struct map __ksc5601_hanja_from_ucs[KSC5601_HANJA];
      43  
      44  
      45  static inline uint32_t
      46  __attribute ((always_inline))
      47  ksc5601_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset)
      48  {
      49    unsigned char ch = **s;
      50    unsigned char ch2;
      51    int idx;
      52  
      53    if (avail < 2)
      54      return 0;
      55  
      56    /* row 94(0x7e) and row 41(0x49) are user-defined area in KS C 5601 */
      57  
      58    if (ch < offset || (ch - offset) <= 0x20 || (ch - offset) >= 0x7e
      59        || (ch - offset) == 0x49)
      60      return __UNKNOWN_10646_CHAR;
      61  
      62    ch2 = (*s)[1];
      63    if (ch2 < offset || (ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f)
      64      return __UNKNOWN_10646_CHAR;
      65  
      66    idx = (ch - offset - 0x21) * 94 + (ch2 - offset - 0x21);
      67  
      68    /* 1410 = 15 * 94 , 3760 = 40 * 94
      69       Hangul in KS C 5601 : row 16 - row 40 */
      70  
      71    *s += 2;
      72  
      73    if (idx >= 1410 && idx < 1410 + KSC5601_HANGUL)
      74      return (__ksc5601_hangul_to_ucs[idx - 1410]
      75  	    ?: (*s -= 2, __UNKNOWN_10646_CHAR));
      76    else if (idx >= 3854)
      77      /* Hanja : row 42 - row 93 : 3854 = 94 * (42-1) */
      78     return (__ksc5601_hanja_to_ucs[idx - 3854]
      79  	   ?: (*s -= 2, __UNKNOWN_10646_CHAR));
      80    else if (idx <= 1114)
      81      return __ksc5601_sym_to_ucs[idx] ?: (*s -= 2, __UNKNOWN_10646_CHAR);
      82  
      83    *s -= 2;
      84    return __UNKNOWN_10646_CHAR;
      85  }
      86  
      87  static inline size_t
      88  __attribute ((always_inline))
      89  ucs4_to_ksc5601_hangul (uint32_t wch, unsigned char *s, size_t avail)
      90  {
      91    int l = 0;
      92    int u = KSC5601_HANGUL - 1;
      93    uint32_t try;
      94  
      95    while (l <= u)
      96      {
      97        int m = (l + u) / 2;
      98        try = (uint32_t) __ksc5601_hangul_to_ucs[m];
      99        if (try > wch)
     100  	u = m - 1;
     101        else if (try < wch)
     102  	l= m + 1;
     103        else
     104  	{
     105  	  if (avail < 2)
     106  	    return 0;
     107  
     108  	  s[0] = (m / 94) + 0x30;
     109  	  s[1] = (m % 94) + 0x21;
     110  
     111  	  return 2;
     112  	}
     113      }
     114  
     115    return __UNKNOWN_10646_CHAR;
     116  }
     117  
     118  
     119  static inline size_t
     120  __attribute ((always_inline))
     121  ucs4_to_ksc5601_hanja (uint32_t wch, unsigned char *s, size_t avail)
     122  {
     123    int l = 0;
     124    int u = KSC5601_HANJA - 1;
     125    uint32_t try;
     126  
     127    while (l <= u)
     128      {
     129        int m = (l + u) / 2;
     130        try = (uint32_t) __ksc5601_hanja_from_ucs[m].ucs;
     131        if (try > wch)
     132  	u=m-1;
     133        else if (try < wch)
     134  	l = m + 1;
     135        else
     136  	{
     137  	  if (avail < 2)
     138  	    return 0;
     139  
     140  	  s[0] = __ksc5601_hanja_from_ucs[m].val[0];
     141  	  s[1] = __ksc5601_hanja_from_ucs[m].val[1];
     142  
     143  	  return 2;
     144  	}
     145      }
     146  
     147    return __UNKNOWN_10646_CHAR;
     148  }
     149  
     150  static inline  size_t
     151  __attribute ((always_inline))
     152  ucs4_to_ksc5601_sym (uint32_t wch, unsigned char *s, size_t avail)
     153  {
     154    int l = 0;
     155    int u = KSC5601_SYMBOL - 1;
     156    uint32_t try;
     157  
     158    while (l <= u)
     159      {
     160        int m = (l + u) / 2;
     161        try = __ksc5601_sym_from_ucs[m].ucs;
     162        if (try > wch)
     163  	u = m - 1;
     164        else if (try < wch)
     165  	l = m + 1;
     166        else
     167  	{
     168  	  if (avail < 2)
     169  	    return 0;
     170  
     171  	  s[0] = __ksc5601_sym_from_ucs[m].val[0];
     172  	  s[1] = __ksc5601_sym_from_ucs[m].val[1];
     173  
     174  	  return 2;
     175  	}
     176      }
     177  
     178    return __UNKNOWN_10646_CHAR;
     179  }
     180  
     181  
     182  static inline size_t
     183  __attribute ((always_inline))
     184  ucs4_to_ksc5601 (uint32_t wch, unsigned char *s, size_t avail)
     185  {
     186    if (wch >= 0xac00 && wch <= 0xd7a3)
     187      return ucs4_to_ksc5601_hangul (wch, s, avail);
     188    else if ((wch >= 0x4e00 && wch <= 0x9fff)
     189  	   || (wch >= 0xf900 && wch <= 0xfa0b))
     190      return ucs4_to_ksc5601_hanja (wch, s, avail);
     191    else
     192      return ucs4_to_ksc5601_sym (wch, s, avail);
     193  }
     194  
     195  #endif /* ksc5601.h */