~ubuntu-branches/ubuntu/natty/eglibc/natty-security

« back to all changes in this revision

Viewing changes to iconvdata/ksc5601.h

  • Committer: Bazaar Package Importer
  • Author(s): Aurelien Jarno
  • Date: 2009-05-05 09:54:14 UTC
  • Revision ID: james.westby@ubuntu.com-20090505095414-c45qsg9ixjheohru
ImportĀ upstreamĀ versionĀ 2.9

Show diffs side-by-side

added added

removed removed

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