27 #include <sys/cdefs.h>
30 #include <sys/param.h>
31 #include <sys/kernel.h>
32 #include <sys/systm.h>
33 #include <sys/malloc.h>
34 #include <sys/iconv.h>
36 #include "iconv_converter_if.h"
46 #define C2I1(c) ((c) & 0x8000 ? ((c) & 0xff) | 0x100 : (c) & 0xff)
47 #define C2I2(c) ((c) & 0x8000 ? ((c) >> 8) & 0x7f : ((c) >> 8) & 0xff)
62 struct iconv_cspair *csp,
struct iconv_cspair *cspf,
void **dpp)
65 uint32_t *headp, **idxp;
68 dp = (
struct iconv_xlat16 *)kobj_create((
struct kobj_class*)dcp, M_ICONV, M_WAITOK);
69 headp = (uint32_t *)((caddr_t)csp->cp_data +
sizeof(dp->
d_table));
70 idxp = (uint32_t **)csp->cp_data;
71 for (i = 0 ; i < 0x200 ; i++) {
81 if (
strcmp(csp->cp_to, KICONV_WCTYPE_NAME) != 0) {
105 dp->
d_csp->cp_refcount--;
106 kobj_delete((
struct kobj*)data, M_ICONV);
119 size_t in, on, ir, or, inlen;
122 uint16_t c1, c2, ctmp;
124 if (inbuf == NULL || *inbuf == NULL || outbuf == NULL || *outbuf == NULL)
131 while(ir > 0 && or > 0) {
136 c1 = ir > 1 ? *(src+1) & 0xff : 0;
140 c1 = c2 & 0x80 ? c1 | 0x100 : c1;
141 c2 = c2 & 0x80 ? c2 & 0x7f : c2;
150 if (casetype == KICONV_FROM_LOWER && dp->
f_ctp)
151 ctmp =
towlower(((u_char)*src << 8) | (u_char)*(src + 1),
153 else if (casetype == KICONV_FROM_UPPER && dp->
f_ctp)
154 ctmp =
towupper(((u_char)*src << 8) | (u_char)*(src + 1),
173 if (casetype & (KICONV_FROM_LOWER|KICONV_FROM_UPPER))
176 if (casetype == KICONV_FROM_LOWER) {
179 else if (code & XLAT16_HAS_FROM_LOWER_CASE)
180 ctmp = (u_char)(code >> 16);
181 }
else if (casetype == KICONV_FROM_UPPER) {
184 else if (code & XLAT16_HAS_FROM_UPPER_CASE)
185 ctmp = (u_char)(code >> 16);
188 c1 =
C2I1(ctmp << 8);
189 c2 =
C2I2(ctmp << 8);
199 nullin = (code & XLAT16_ACCEPT_NULL_IN) ? 1 : 0;
200 if (inlen == 1 && nullin) {
211 u = (u_char)(code >> 8);
214 #ifdef XLAT16_ACCEPT_3BYTE_CHR
215 if (code & XLAT16_IS_3BYTE_CHR) {
222 *dst++ = (u_char)(code >> 16);
226 if (u || code & XLAT16_ACCEPT_NULL_OUT) {
233 if (casetype == KICONV_LOWER && dp->
t_ctp) {
235 u = (u_char)(code >> 8);
238 if (casetype == KICONV_UPPER && dp->
t_ctp) {
240 u = (u_char)(code >> 8);
249 if (casetype == KICONV_LOWER) {
252 else if (code & XLAT16_HAS_LOWER_CASE)
253 l = (u_char)(code >> 16);
255 if (casetype == KICONV_UPPER) {
258 else if (code & XLAT16_HAS_UPPER_CASE)
259 l = (u_char)(code >> 16);
271 if ((u_char)*(src+1) == 0 && !nullin ) {
289 *inbytesleft -= in - ir;
290 *outbytesleft -= on - or;
304 register int c1, c2, out;
309 }
else if (c < 0x10000) {
315 if (dp->
d_table[c1] && dp->
d_table[c1][c2] & XLAT16_HAS_LOWER_CASE) {
317 out = dp->
d_table[c1][c2] & 0xffff;
318 if ((out & 0xff) == 0)
319 out = (out >> 8) & 0xff;
329 register int c1, c2, out;
334 }
else if (c < 0x10000) {
340 if (dp->
d_table[c1] && dp->
d_table[c1][c2] & XLAT16_HAS_UPPER_CASE) {
341 out = dp->
d_table[c1][c2] & 0xffff;
342 if ((out & 0xff) == 0)
343 out = (out >> 8) & 0xff;
354 KOBJMETHOD(iconv_converter_init, iconv_xlat16_init),
355 KOBJMETHOD(iconv_converter_done, iconv_xlat16_done),
static int iconv_xlat16_tolower(void *d2p, register int c)
static int iconv_xlat16_conv(void *d2p, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft, int convchar, int casetype)
int iconv_close(void *handle)
int iconv_open(const char *to, const char *from, void **handle)
int towlower(int c, void *handle)
static int iconv_xlat16_close(void *data)
static int iconv_xlat16_toupper(void *d2p, register int c)
static const char * iconv_xlat16_name(struct iconv_converter_class *dcp)
int towupper(int c, void *handle)
static kobj_method_t iconv_xlat16_methods[]
uint32_t * d_table[0x200]
static int iconv_xlat16_open(struct iconv_converter_class *dcp, struct iconv_cspair *csp, struct iconv_cspair *cspf, void **dpp)
KICONV_CONVERTER(xlat16, sizeof(struct iconv_xlat16))
struct iconv_cspair * d_csp
int strcmp(const char *s1, const char *s2)