]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libiconv_modules/JOHAB/citrus_johab.c
Upgrade Unbound to 1.6.1. More to follow.
[FreeBSD/FreeBSD.git] / lib / libiconv_modules / JOHAB / citrus_johab.c
1 /* $FreeBSD$ */
2 /* $NetBSD: citrus_johab.c,v 1.4 2008/06/14 16:01:07 tnozaki Exp $ */
3
4 /*-
5  * SPDX-License-Identifier: BSD-2-Clause
6  *
7  * Copyright (c)2006 Citrus Project,
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 #include <sys/cdefs.h>
32 #include <sys/types.h>
33
34 #include <assert.h>
35 #include <errno.h>
36 #include <limits.h>
37 #include <stdbool.h>
38 #include <stddef.h>
39 #include <stdint.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <wchar.h>
44
45 #include "citrus_namespace.h"
46 #include "citrus_types.h"
47 #include "citrus_bcs.h"
48 #include "citrus_module.h"
49 #include "citrus_stdenc.h"
50 #include "citrus_johab.h"
51
52 /* ----------------------------------------------------------------------
53  * private stuffs used by templates
54  */
55
56 typedef struct {
57         int      chlen;
58         char     ch[2];
59 } _JOHABState;
60
61 typedef struct {
62         int      dummy;
63 } _JOHABEncodingInfo;
64
65 #define _CEI_TO_EI(_cei_)               (&(_cei_)->ei)
66 #define _CEI_TO_STATE(_cei_, _func_)    (_cei_)->states.s_##_func_
67
68 #define _FUNCNAME(m)                    _citrus_JOHAB_##m
69 #define _ENCODING_INFO                  _JOHABEncodingInfo
70 #define _ENCODING_STATE                 _JOHABState
71 #define _ENCODING_MB_CUR_MAX(_ei_)              2
72 #define _ENCODING_IS_STATE_DEPENDENT            0
73 #define _STATE_NEEDS_EXPLICIT_INIT(_ps_)        0
74
75
76 static __inline void
77 /*ARGSUSED*/
78 _citrus_JOHAB_init_state(_JOHABEncodingInfo * __restrict ei __unused,
79     _JOHABState * __restrict psenc)
80 {
81
82         psenc->chlen = 0;
83 }
84
85 #if 0
86 static __inline void
87 /*ARGSUSED*/
88 _citrus_JOHAB_pack_state(_JOHABEncodingInfo * __restrict ei __unused,
89     void * __restrict pspriv, const _JOHABState * __restrict psenc)
90 {
91
92         memcpy(pspriv, (const void *)psenc, sizeof(*psenc));
93 }
94
95 static __inline void
96 /*ARGSUSED*/
97 _citrus_JOHAB_unpack_state(_JOHABEncodingInfo * __restrict ei __unused,
98     _JOHABState * __restrict psenc, const void * __restrict pspriv)
99 {
100
101         memcpy((void *)psenc, pspriv, sizeof(*psenc));
102 }
103 #endif
104
105 static void
106 /*ARGSUSED*/
107 _citrus_JOHAB_encoding_module_uninit(_JOHABEncodingInfo *ei __unused)
108 {
109
110         /* ei may be null */
111 }
112
113 static int
114 /*ARGSUSED*/
115 _citrus_JOHAB_encoding_module_init(_JOHABEncodingInfo * __restrict ei __unused,
116     const void * __restrict var __unused, size_t lenvar __unused)
117 {
118
119         /* ei may be null */
120         return (0);
121 }
122
123 static __inline bool
124 ishangul(int l, int t)
125 {
126
127         return ((l >= 0x84 && l <= 0xD3) &&
128             ((t >= 0x41 && t <= 0x7E) || (t >= 0x81 && t <= 0xFE)));
129 }
130
131 static __inline bool
132 isuda(int l, int t)
133 {
134
135         return ((l == 0xD8) &&
136             ((t >= 0x31 && t <= 0x7E) || (t >= 0x91 && t <= 0xFE)));
137 }
138
139 static __inline bool
140 ishanja(int l, int t)
141 {
142
143         return (((l >= 0xD9 && l <= 0xDE) || (l >= 0xE0 && l <= 0xF9)) &&
144             ((t >= 0x31 && t <= 0x7E) || (t >= 0x91 && t <= 0xFE)));
145 }
146
147 static int
148 /*ARGSUSED*/
149 _citrus_JOHAB_mbrtowc_priv(_JOHABEncodingInfo * __restrict ei,
150     wchar_t * __restrict pwc, char ** __restrict s, size_t n,
151     _JOHABState * __restrict psenc, size_t * __restrict nresult)
152 {
153         char *s0;
154         int l, t;
155
156         if (*s == NULL) {
157                 _citrus_JOHAB_init_state(ei, psenc);
158                 *nresult = _ENCODING_IS_STATE_DEPENDENT;
159                 return (0);
160         }
161         s0 = *s;
162
163         switch (psenc->chlen) {
164         case 0:
165                 if (n-- < 1)
166                         goto restart;
167                 l = *s0++ & 0xFF;
168                 if (l <= 0x7F) {
169                         if (pwc != NULL)
170                                 *pwc = (wchar_t)l;
171                         *nresult = (l == 0) ? 0 : 1;
172                         *s = s0;
173                         return (0);
174                 }
175                 psenc->ch[psenc->chlen++] = l;
176                 break;
177         case 1:
178                 l = psenc->ch[0] & 0xFF;
179                 break;
180         default:
181                 return (EINVAL);
182         }
183         if (n-- < 1) {
184 restart:
185                 *nresult = (size_t)-2;
186                 *s = s0;
187                 return (0);
188         }
189         t = *s0++ & 0xFF;
190         if (!ishangul(l, t) && !isuda(l, t) && !ishanja(l, t)) {
191                 *nresult = (size_t)-1;
192                 return (EILSEQ);
193         }
194         if (pwc != NULL)
195                 *pwc = (wchar_t)(l << 8 | t);
196         *nresult = s0 - *s;
197         *s = s0;
198         psenc->chlen = 0;
199
200         return (0);
201 }
202
203 static int
204 /*ARGSUSED*/
205 _citrus_JOHAB_wcrtomb_priv(_JOHABEncodingInfo * __restrict ei __unused,
206     char * __restrict s, size_t n, wchar_t wc,
207     _JOHABState * __restrict psenc, size_t * __restrict nresult)
208 {
209         int l, t;
210
211         if (psenc->chlen != 0)
212                 return (EINVAL);
213
214         /* XXX assume wchar_t as int */
215         if ((uint32_t)wc <= 0x7F) {
216                 if (n < 1)
217                         goto e2big;
218                 *s = wc & 0xFF;
219                 *nresult = 1;
220         } else if ((uint32_t)wc <= 0xFFFF) {
221                 if (n < 2) {
222 e2big:
223                         *nresult = (size_t)-1;
224                         return (E2BIG);
225                 }
226                 l = (wc >> 8) & 0xFF;
227                 t = wc & 0xFF;
228                 if (!ishangul(l, t) && !isuda(l, t) && !ishanja(l, t))
229                         goto ilseq;
230                 *s++ = l;
231                 *s = t;
232                 *nresult = 2;
233         } else {
234 ilseq:
235                 *nresult = (size_t)-1;
236                 return (EILSEQ);
237         }
238         return (0);
239
240 }
241
242 static __inline int
243 /*ARGSUSED*/
244 _citrus_JOHAB_stdenc_wctocs(_JOHABEncodingInfo * __restrict ei __unused,
245     _csid_t * __restrict csid, _index_t * __restrict idx, wchar_t wc)
246 {
247         int m, l, linear, t;
248
249         /* XXX assume wchar_t as int */
250         if ((uint32_t)wc <= 0x7F) {
251                 *idx = (_index_t)wc;
252                 *csid = 0;
253         } else if ((uint32_t)wc <= 0xFFFF) {
254                 l = (wc >> 8) & 0xFF;
255                 t = wc & 0xFF;
256                 if (ishangul(l, t) || isuda(l, t)) {
257                         *idx = (_index_t)wc;
258                         *csid = 1;
259                 } else {
260                         if (l >= 0xD9 && l <= 0xDE) {
261                                 linear = l - 0xD9;
262                                 m = 0x21;
263                         } else if (l >= 0xE0 && l <= 0xF9) {
264                                 linear = l - 0xE0;
265                                 m = 0x4A;
266                         } else
267                                 return (EILSEQ);
268                         linear *= 188;
269                         if (t >= 0x31 && t <= 0x7E)
270                                 linear += t - 0x31;
271                         else if (t >= 0x91 && t <= 0xFE)
272                                 linear += t - 0x43;
273                         else
274                                 return (EILSEQ);
275                         l = (linear / 94) + m;
276                         t = (linear % 94) + 0x21;
277                         *idx = (_index_t)((l << 8) | t);
278                         *csid = 2;
279                 }
280         } else
281                 return (EILSEQ);
282         return (0);
283 }
284
285 static __inline int
286 /*ARGSUSED*/
287 _citrus_JOHAB_stdenc_cstowc(_JOHABEncodingInfo * __restrict ei __unused,
288     wchar_t * __restrict wc, _csid_t csid, _index_t idx)
289 {
290         int m, n, l, linear, t;
291
292         switch (csid) {
293         case 0:
294         case 1:
295                 *wc = (wchar_t)idx;
296                 break;
297         case 2:
298                 if (idx >= 0x2121 && idx <= 0x2C71) {
299                         m = 0xD9;
300                         n = 0x21;
301                 } else if (idx >= 0x4A21 && idx <= 0x7D7E) {
302                         m = 0xE0;
303                         n = 0x4A;
304                 } else
305                         return (EILSEQ);
306                 l = ((idx >> 8) & 0xFF) - n;
307                 t = (idx & 0xFF) - 0x21;
308                 linear = (l * 94) + t;
309                 l = (linear / 188) + m;
310                 t = linear % 188;
311                 t += (t <= 0x4D) ? 0x31 : 0x43;
312                 break;
313         default:
314                 return (EILSEQ);
315         }
316         return (0);
317 }
318
319 static __inline int
320 /*ARGSUSED*/
321 _citrus_JOHAB_stdenc_get_state_desc_generic(_JOHABEncodingInfo * __restrict ei __unused,
322     _JOHABState * __restrict psenc, int * __restrict rstate)
323 {
324
325         *rstate = (psenc->chlen == 0) ? _STDENC_SDGEN_INITIAL :
326             _STDENC_SDGEN_INCOMPLETE_CHAR;
327         return (0);
328 }
329
330 /* ----------------------------------------------------------------------
331  * public interface for stdenc
332  */
333
334 _CITRUS_STDENC_DECLS(JOHAB);
335 _CITRUS_STDENC_DEF_OPS(JOHAB);
336
337 #include "citrus_stdenc_template.h"