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