Simplify step data handling.
[kopensolaris-gnu/glibc.git] / iconvdata / ksc5601.h
1 /* Access functions for KS C 5601-1992 based encoding conversion.
2    Copyright (C) 1998 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 Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    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    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
20 #ifndef _KSC5601_H
21 #define _KSC5601_H      1
22
23 #define KSC5601_HANGUL 2350
24 #define KSC5601_HANJA  4888
25 #define KSC5601_SYMBOL  986
26
27 #include <gconv.h>
28 #include <stdint.h>
29
30 /* Conversion table.  */
31 extern const uint16_t ksc5601_hangul_to_ucs[KSC5601_HANGUL];
32 extern const uint16_t ksc5601_sym_to_ucs[];
33 extern const uint16_t ksc5601_sym_from_ucs[KSC5601_SYMBOL][2];
34 extern const uint16_t ksc5601_hanja_to_ucs[KSC5601_HANJA];
35 extern const uint16_t ksc5601_hanja_from_ucs[KSC5601_HANJA][2];
36
37
38 /*
39 static inline wchar_t
40 ksc5601_to_ucs4 (char **s, size_t avail)
41 */
42 static inline wchar_t
43 ksc5601_to_ucs4 (uint16_t s)
44 {
45   unsigned char ch = s / 256;
46   unsigned char ch2;
47   int idx;
48
49   /* row 94(0x7e) and row 41(0x49) are user-defined area in KS C 5601 */
50
51   if (ch <= 0x20 || ch >= 0x7e || ch == 0x49)
52     return UNKNOWN_10646_CHAR;
53
54   ch2 = s % 256;
55   if (ch2 <= 0x20 || ch2 >= 0x7f)
56     return UNKNOWN_10646_CHAR;
57
58   idx = (ch - 0x21) * 94 + (ch2 - 0x21);
59
60   /* 1410 = 15 * 94 , 3760 = 40 * 94
61      Hangul in KS C 5601 : row 16 - row 40 */
62
63   if (idx >= 1410 && idx < 3760)
64     return ksc5601_hangul_to_ucs[idx-1410];
65   else if (idx > 3854)
66     /* Hanja : row 42 - row 93 : 3854 = 94 * (42-1) */
67    return ksc5601_hanja_to_ucs[idx-3854];
68   else
69     return ksc5601_sym_to_ucs[idx] ?: UNKNOWN_10646_CHAR;
70 }
71
72 static inline size_t
73 ucs4_to_ksc5601_hangul (wchar_t wch, uint16_t *s)
74 {
75   int l=0,m,u=KSC5601_HANGUL-1;
76   wchar_t try;
77
78   while (l <= u)
79     {
80       try = (wchar_t) ksc5601_hangul_to_ucs[m=(l+u)/2];
81       if (try > wch)
82         u = m - 1;
83       else if (try < wch)
84         l= m + 1;
85       else
86         {
87           *s = (uint16_t) ((m / 94) * 256  + m % 94 + 0x3021) ;
88           return 2;
89         }
90     }
91   return  0;
92 }
93
94
95 static inline size_t
96 ucs4_to_ksc5601_hanja (wchar_t wch, uint16_t *s)
97 {
98   int l=0,m,u=KSC5601_HANJA-1;
99   wchar_t try;
100
101   while (l <= u)
102     {
103       try = (wchar_t) ksc5601_hanja_from_ucs[m=(l+u)/2][0];
104       if (try > wch)
105         u=m-1;
106       else if (try < wch)
107         l = m + 1;
108       else
109         {
110           *s = ksc5601_hanja_from_ucs[m][1];
111           return 2;
112         }
113     }
114   return 0;
115 }
116
117 static inline  size_t
118 ucs4_to_ksc5601_sym (wchar_t wch, uint16_t *s)
119 {
120   int l = 0;
121   int m;
122   int u = KSC5601_SYMBOL - 1;
123   wchar_t try;
124
125   while (l <= u)
126     {
127       m = (l + u) / 2;
128       try = ksc5601_sym_from_ucs[m][0];
129       if (try > wch)
130         u = m - 1;
131       else if (try < wch)
132         l = m + 1;
133       else
134         {
135           *s = ksc5601_sym_from_ucs[m][1];
136           return 2;
137         }
138     }
139   return 0;
140 }
141
142
143 /*
144 static inline size_t
145 ucs4_to_ksc5601 (wchar_t wch, char **s, size_t avail)
146 */
147
148 static inline size_t
149 ucs4_to_ksc5601 (wchar_t ch, uint16_t *s)
150 {
151   *s = (uint16_t) UNKNOWN_10646_CHAR;  /* FIXIT */
152
153   if (ch >= 0xac00 && ch <= 0xd7a3)
154     return ucs4_to_ksc5601_hangul (ch, s);
155   else if (ch >= 0x4e00 && ch <= 0x9fff ||  ch >= 0xf900 && ch <= 0xfa0b)
156     return ucs4_to_ksc5601_hanja (ch, s);
157   else
158     return ucs4_to_ksc5601_sym (ch, s);
159 }
160
161 #endif /* ksc5601.h */