1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1995 by Sun Microsystems, Inc.
23 * All Rights Reserved.
24 */
25
26
27 #include <errno.h>
28 #include "ktable.h"
29 #include "hangulcode.h"
30
31 static unsigned short _johap92_to_wansung(unsigned short code);
32
33 /**** _ I C V _ O P E N ****/
34
_icv_open()35 void* _icv_open()
36 {
37 return((void*)MAGIC_NUMBER);
38 } /* end of void* _icv_open(). */
39
40
41 /**** _ I C V _ C L O S E ****/
42
_icv_close(int * cd)43 void _icv_close(int* cd)
44 {
45 if (!cd || cd != (int*)MAGIC_NUMBER)
46 errno = EBADF;
47 } /* end of void _icv_close(int*). */
48
49
50 /**** _ I C V _ I C O N V ****/
51
_icv_iconv(int * cd,char ** inbuf,size_t * inbufleft,char ** outbuf,size_t * outbufleft)52 size_t _icv_iconv(int* cd, char** inbuf, size_t* inbufleft,
53 char** outbuf, size_t* outbufleft)
54 {
55 size_t ret_val = 0;
56 unsigned char* ib;
57 unsigned char* ob;
58 unsigned char* ibtail;
59 unsigned char* obtail;
60
61 if (!cd || cd != (int*)MAGIC_NUMBER)
62 {
63 errno = EBADF;
64 return((size_t)-1);
65 }
66
67 if (!inbuf || !(*inbuf))
68 return((size_t)0);
69
70 ib = (unsigned char*)*inbuf;
71 ob = (unsigned char*)*outbuf;
72 ibtail = ib + *inbufleft;
73 obtail = ob + *outbufleft;
74
75 while (ib < ibtail)
76 {
77 if (!(*ib & 0x80))
78 {
79 if (ob >= obtail)
80 {
81 errno = E2BIG;
82 ret_val = (size_t)-1;
83 break;
84 }
85 *ob++ = *ib++;
86 }
87 else
88 {
89 unsigned short result;
90
91 if ((ibtail - ib) < 2)
92 {
93 errno = EINVAL;
94 ret_val = (size_t)-1;
95 break;
96 }
97
98 result = _johap92_to_wansung((unsigned short)(*ib)<<8 |
99 (unsigned short)(*(ib + 1)));
100 if (result != FAILED && result != ILLEGAL_SEQ)
101 {
102 if ((obtail - ob) < 2)
103 {
104 errno = E2BIG;
105 ret_val = (size_t)-1;
106 break;
107 }
108 *ob++ = (unsigned char)(result >> 8);
109 *ob++ = (unsigned char)(result & 0xFF);
110 }
111 else
112 {
113 errno = EILSEQ;
114 ret_val = (size_t)-1;
115 break;
116 }
117 ib += 2;
118 }
119 }
120
121 *inbuf = (char*)ib;
122 *inbufleft = ibtail - ib;
123 *outbuf = (char*)ob;
124 *outbufleft = obtail - ob;
125
126 return(ret_val);
127 } /* end of size_t _icv_iconv(int*, char**, size_t*, char**, size_t*). */
128
129
130 /**** _ J O H A P 9 2 _ T O _ W A N S U N G ****/
131
_johap92_to_wansung(unsigned short code)132 static unsigned short _johap92_to_wansung(unsigned short code)
133 {
134 short ci, v, cf;
135 short mask;
136 int disp, i;
137 int ch1, ch2;
138 long cfbit;
139
140 ch1 = code >> 8;
141 ch2 = code & 0xff;
142
143 if ((ch1 >= 0x84 && ch1 <= 0xd3) && ((ch2 >= 0x41 && ch2 <= 0x7e) ||
144 (ch2 >= 0x81 && ch2 <= 0xfe))) /* Hangul */
145 {
146 ci = CHOSUNG(code) - 0x02;
147 v = JOONGSUNG(code) - ((unsigned short)(JOONGSUNG(code) - 2) /
148 8 * 2 + 3);
149 cf = JONGSUNG(code) - (unsigned short)JONGSUNG(code) / 18;
150
151 if (v < 0)
152 return(0xA4A0 + Y19_32[CHOSUNG(code) - 1]);
153 if (ci < 0)
154 {
155 if (cf <= 1)
156 return(0xA4BF + v);
157 return(ILLEGAL_SEQ);
158 }
159
160 for (cfbit = cmp_bitmap[ci][v], disp = 0, i = 0; i < cf; i++)
161 {
162 if (cfbit & BIT_MASK)
163 disp++;
164 cfbit >>= 1;
165 }
166
167 if (!(cfbit & BIT_MASK))
168 return(ILLEGAL_SEQ);
169
170 code = cmp_srchtbl[ci][v] + disp;
171 mask = cmp_srchtbl[ci][v] & 0xff;
172 if ((mask + disp) > 0xfe)
173 code += SKIP;
174
175 return(code);
176 }
177 else if ((ch2 >= 0x31 && ch2 <= 0x7e) || (ch2 >= 0x91 && ch2 <= 0xfe))
178 {
179 if (ch1 >= 0xe0 && ch1 <= 0xf9) /* Hanja */
180 {
181 code = (0xca + (ch1 - 0xe0) * 2 + ch2 / 0xa1) << 8;
182 return(code | ((ch2 > 0xa0) ? ch2
183 : ch2 + 0x70 - ((ch2 / 0x91) * 0x12)));
184 }
185 else if (ch1 >= 0xd9 && ch1 <= 0xde) /* Graphic characters */
186 {
187 code = (0xa1 + (ch1 - 0xd9) * 2 + ch2 / 0xa1) << 8;
188 return(code | ((ch2 > 0xa0) ? ch2
189 : ch2 + 0x70 - ((ch2 / 0x91) * 0x12)));
190 }
191 else if (ch1 == 0xd8) /* User definable characters */
192 return((ch2 > 0xa0) ? 0xfe00 | ch2 : 0xc900
193 | (ch2 + 0x70 - ((ch2 / 0x91) * 0x12)));
194 }
195
196 return(FAILED);
197 } /* end og static unsigned short _johap92_to_wansung(unsigned short). */
198