iconv_xlat16.c (146573) | iconv_xlat16.c (194638) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 2003, Ryuichiro Imura | 2 * Copyright (c) 2003, 2005 Ryuichiro Imura |
3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright --- 9 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright --- 9 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/libkern/iconv_xlat16.c 146573 2005-05-24 15:38:08Z imura $"); | 28__FBSDID("$FreeBSD: head/sys/libkern/iconv_xlat16.c 194638 2009-06-22 17:09:46Z delphij $"); |
29 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> 35 36#include "iconv_converter_if.h" 37 38/* 39 * "XLAT16" converter 40 */ 41 42#ifdef MODULE_DEPEND 43MODULE_DEPEND(iconv_xlat16, libiconv, 2, 2, 2); 44#endif 45 | 29 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> 35 36#include "iconv_converter_if.h" 37 38/* 39 * "XLAT16" converter 40 */ 41 42#ifdef MODULE_DEPEND 43MODULE_DEPEND(iconv_xlat16, libiconv, 2, 2, 2); 44#endif 45 |
46#define C2I1(c) ((c) & 0x8000 ? ((c) & 0xff) | 0x100 : (c) & 0xff) 47#define C2I2(c) ((c) & 0x8000 ? ((c) >> 8) & 0x7f : ((c) >> 8) & 0xff) 48 |
|
46/* 47 * XLAT16 converter instance 48 */ 49struct iconv_xlat16 { 50 KOBJ_FIELDS; 51 uint32_t * d_table[0x200]; | 49/* 50 * XLAT16 converter instance 51 */ 52struct iconv_xlat16 { 53 KOBJ_FIELDS; 54 uint32_t * d_table[0x200]; |
55 void * f_ctp; 56 void * t_ctp; |
|
52 struct iconv_cspair * d_csp; 53}; 54 55static int 56iconv_xlat16_open(struct iconv_converter_class *dcp, 57 struct iconv_cspair *csp, struct iconv_cspair *cspf, void **dpp) 58{ 59 struct iconv_xlat16 *dp; --- 7 unchanged lines hidden (view full) --- 67 if (*idxp) { 68 dp->d_table[i] = headp; 69 headp += 0x80; 70 } else { 71 dp->d_table[i] = NULL; 72 } 73 idxp++; 74 } | 57 struct iconv_cspair * d_csp; 58}; 59 60static int 61iconv_xlat16_open(struct iconv_converter_class *dcp, 62 struct iconv_cspair *csp, struct iconv_cspair *cspf, void **dpp) 63{ 64 struct iconv_xlat16 *dp; --- 7 unchanged lines hidden (view full) --- 72 if (*idxp) { 73 dp->d_table[i] = headp; 74 headp += 0x80; 75 } else { 76 dp->d_table[i] = NULL; 77 } 78 idxp++; 79 } |
80 81 if (strcmp(csp->cp_to, KICONV_WCTYPE_NAME) != 0) { 82 if (iconv_open(KICONV_WCTYPE_NAME, csp->cp_from, &dp->f_ctp) != 0) 83 dp->f_ctp = NULL; 84 if (iconv_open(KICONV_WCTYPE_NAME, csp->cp_to, &dp->t_ctp) != 0) 85 dp->t_ctp = NULL; 86 } else { 87 dp->f_ctp = dp->t_ctp = dp; 88 } 89 |
|
75 dp->d_csp = csp; 76 csp->cp_refcount++; 77 *dpp = (void*)dp; 78 return (0); 79} 80 81static int 82iconv_xlat16_close(void *data) 83{ 84 struct iconv_xlat16 *dp = data; 85 | 90 dp->d_csp = csp; 91 csp->cp_refcount++; 92 *dpp = (void*)dp; 93 return (0); 94} 95 96static int 97iconv_xlat16_close(void *data) 98{ 99 struct iconv_xlat16 *dp = data; 100 |
101 if (dp->f_ctp && dp->f_ctp != data) 102 iconv_close(dp->f_ctp); 103 if (dp->t_ctp && dp->t_ctp != data) 104 iconv_close(dp->t_ctp); |
|
86 dp->d_csp->cp_refcount--; 87 kobj_delete((struct kobj*)data, M_ICONV); 88 return (0); 89} 90 91static int 92iconv_xlat16_conv(void *d2p, const char **inbuf, 93 size_t *inbytesleft, char **outbuf, size_t *outbytesleft, 94 int convchar, int casetype) 95{ 96 struct iconv_xlat16 *dp = (struct iconv_xlat16*)d2p; 97 const char *src; 98 char *dst; 99 int nullin, ret = 0; 100 size_t in, on, ir, or, inlen; 101 uint32_t code; 102 u_char u, l; | 105 dp->d_csp->cp_refcount--; 106 kobj_delete((struct kobj*)data, M_ICONV); 107 return (0); 108} 109 110static int 111iconv_xlat16_conv(void *d2p, const char **inbuf, 112 size_t *inbytesleft, char **outbuf, size_t *outbytesleft, 113 int convchar, int casetype) 114{ 115 struct iconv_xlat16 *dp = (struct iconv_xlat16*)d2p; 116 const char *src; 117 char *dst; 118 int nullin, ret = 0; 119 size_t in, on, ir, or, inlen; 120 uint32_t code; 121 u_char u, l; |
103 uint16_t c1, c2; | 122 uint16_t c1, c2, ctmp; |
104 105 if (inbuf == NULL || *inbuf == NULL || outbuf == NULL || *outbuf == NULL) 106 return (0); 107 ir = in = *inbytesleft; 108 or = on = *outbytesleft; 109 src = *inbuf; 110 dst = *outbuf; 111 112 while(ir > 0 && or > 0) { 113 114 inlen = 0; | 123 124 if (inbuf == NULL || *inbuf == NULL || outbuf == NULL || *outbuf == NULL) 125 return (0); 126 ir = in = *inbytesleft; 127 or = on = *outbytesleft; 128 src = *inbuf; 129 dst = *outbuf; 130 131 while(ir > 0 && or > 0) { 132 133 inlen = 0; |
115 code = '\0'; | 134 code = 0; |
116 117 c1 = ir > 1 ? *(src+1) & 0xff : 0; 118 c2 = *src & 0xff; | 135 136 c1 = ir > 1 ? *(src+1) & 0xff : 0; 137 c2 = *src & 0xff; |
138 ctmp = 0; |
|
119 120 c1 = c2 & 0x80 ? c1 | 0x100 : c1; 121 c2 = c2 & 0x80 ? c2 & 0x7f : c2; 122 | 139 140 c1 = c2 & 0x80 ? c1 | 0x100 : c1; 141 c2 = c2 & 0x80 ? c2 & 0x7f : c2; 142 |
123 if (ir > 1 && dp->d_table[c1]) { | 143 if (ir > 1 && dp->d_table[c1] && dp->d_table[c1][c2]) { |
124 /* 125 * inbuf char is a double byte char 126 */ | 144 /* 145 * inbuf char is a double byte char 146 */ |
127 code = dp->d_table[c1][c2]; 128 if (code) 129 inlen = 2; | 147 inlen = 2; 148 149 /* toupper,tolower */ 150 if (casetype == KICONV_FROM_LOWER && dp->f_ctp) 151 ctmp = towlower(((u_char)*src << 8) | (u_char)*(src + 1), 152 dp->f_ctp); 153 else if (casetype == KICONV_FROM_UPPER && dp->f_ctp) 154 ctmp = towupper(((u_char)*src << 8) | (u_char)*(src + 1), 155 dp->f_ctp); 156 if (ctmp) { 157 c1 = C2I1(ctmp); 158 c2 = C2I2(ctmp); 159 } |
130 } 131 132 if (inlen == 0) { 133 c1 &= 0xff00; 134 if (!dp->d_table[c1]) { 135 ret = -1; 136 break; 137 } 138 /* 139 * inbuf char is a single byte char 140 */ 141 inlen = 1; | 160 } 161 162 if (inlen == 0) { 163 c1 &= 0xff00; 164 if (!dp->d_table[c1]) { 165 ret = -1; 166 break; 167 } 168 /* 169 * inbuf char is a single byte char 170 */ 171 inlen = 1; |
142 code = dp->d_table[c1][c2]; 143 if (!code) { 144 ret = -1; 145 break; | 172 173 if (casetype & (KICONV_FROM_LOWER|KICONV_FROM_UPPER)) 174 code = dp->d_table[c1][c2]; 175 176 if (casetype == KICONV_FROM_LOWER) { 177 if (dp->f_ctp) 178 ctmp = towlower((u_char)*src, dp->f_ctp); 179 else if (code & XLAT16_HAS_FROM_LOWER_CASE) 180 ctmp = (u_char)(code >> 16); 181 } else if (casetype == KICONV_FROM_UPPER) { 182 if (dp->f_ctp) 183 ctmp = towupper((u_char)*src, dp->f_ctp); 184 else if (code & XLAT16_HAS_FROM_UPPER_CASE) 185 ctmp = (u_char)(code >> 16); |
146 } | 186 } |
187 if (ctmp) { 188 c1 = C2I1(ctmp << 8); 189 c2 = C2I2(ctmp << 8); 190 } |
|
147 } 148 | 191 } 192 |
193 code = dp->d_table[c1][c2]; 194 if (!code) { 195 ret = -1; 196 break; 197 } 198 |
|
149 nullin = (code & XLAT16_ACCEPT_NULL_IN) ? 1 : 0; 150 if (inlen == 1 && nullin) { 151 /* 152 * XLAT16_ACCEPT_NULL_IN requires inbuf has 2byte 153 */ 154 ret = -1; 155 break; 156 } 157 158 /* 159 * now start translation 160 */ | 199 nullin = (code & XLAT16_ACCEPT_NULL_IN) ? 1 : 0; 200 if (inlen == 1 && nullin) { 201 /* 202 * XLAT16_ACCEPT_NULL_IN requires inbuf has 2byte 203 */ 204 ret = -1; 205 break; 206 } 207 208 /* 209 * now start translation 210 */ |
161 if ((casetype == KICONV_FROM_LOWER && code & XLAT16_HAS_FROM_LOWER_CASE) || 162 (casetype == KICONV_FROM_UPPER && code & XLAT16_HAS_FROM_UPPER_CASE)) { 163 c2 = (u_char)(code >> 16); 164 c1 = c2 & 0x80 ? 0x100 : 0; 165 c2 = c2 & 0x80 ? c2 & 0x7f : c2; 166 code = dp->d_table[c1][c2]; 167 } 168 | |
169 u = (u_char)(code >> 8); 170 l = (u_char)code; 171 172#ifdef XLAT16_ACCEPT_3BYTE_CHR 173 if (code & XLAT16_IS_3BYTE_CHR) { 174 if (or < 3) { 175 ret = -1; 176 break; --- 4 unchanged lines hidden (view full) --- 181 or -= 3; 182 } else 183#endif 184 if (u || code & XLAT16_ACCEPT_NULL_OUT) { 185 if (or < 2) { 186 ret = -1; 187 break; 188 } | 211 u = (u_char)(code >> 8); 212 l = (u_char)code; 213 214#ifdef XLAT16_ACCEPT_3BYTE_CHR 215 if (code & XLAT16_IS_3BYTE_CHR) { 216 if (or < 3) { 217 ret = -1; 218 break; --- 4 unchanged lines hidden (view full) --- 223 or -= 3; 224 } else 225#endif 226 if (u || code & XLAT16_ACCEPT_NULL_OUT) { 227 if (or < 2) { 228 ret = -1; 229 break; 230 } |
231 232 /* toupper,tolower */ 233 if (casetype == KICONV_LOWER && dp->t_ctp) { 234 code = towlower((uint16_t)code, dp->t_ctp); 235 u = (u_char)(code >> 8); 236 l = (u_char)code; 237 } 238 if (casetype == KICONV_UPPER && dp->t_ctp) { 239 code = towupper((uint16_t)code, dp->t_ctp); 240 u = (u_char)(code >> 8); 241 l = (u_char)code; 242 } 243 |
|
189 *dst++ = u; 190 *dst++ = l; 191 or -= 2; 192 } else { | 244 *dst++ = u; 245 *dst++ = l; 246 or -= 2; 247 } else { |
193 if ((casetype == KICONV_LOWER && code & XLAT16_HAS_LOWER_CASE) || 194 (casetype == KICONV_UPPER && code & XLAT16_HAS_UPPER_CASE)) 195 *dst++ = (u_char)(code >> 16); 196 else 197 *dst++ = l; | 248 /* toupper,tolower */ 249 if (casetype == KICONV_LOWER) { 250 if (dp->t_ctp) 251 l = (u_char)towlower(l, dp->t_ctp); 252 else if (code & XLAT16_HAS_LOWER_CASE) 253 l = (u_char)(code >> 16); 254 } 255 if (casetype == KICONV_UPPER) { 256 if (dp->t_ctp) 257 l = (u_char)towupper(l, dp->t_ctp); 258 else if (code & XLAT16_HAS_UPPER_CASE) 259 l = (u_char)(code >> 16); 260 } 261 262 *dst++ = l; |
198 or--; 199 } 200 201 if (inlen == 2) { 202 /* 203 * there is a case that inbuf char is a single 204 * byte char while inlen == 2 205 */ --- 21 unchanged lines hidden (view full) --- 227} 228 229static const char * 230iconv_xlat16_name(struct iconv_converter_class *dcp) 231{ 232 return ("xlat16"); 233} 234 | 263 or--; 264 } 265 266 if (inlen == 2) { 267 /* 268 * there is a case that inbuf char is a single 269 * byte char while inlen == 2 270 */ --- 21 unchanged lines hidden (view full) --- 292} 293 294static const char * 295iconv_xlat16_name(struct iconv_converter_class *dcp) 296{ 297 return ("xlat16"); 298} 299 |
300static int 301iconv_xlat16_tolower(void *d2p, register int c) 302{ 303 struct iconv_xlat16 *dp = (struct iconv_xlat16*)d2p; 304 register int c1, c2, out; 305 306 if (c < 0x100) { 307 c1 = C2I1(c << 8); 308 c2 = C2I2(c << 8); 309 } else if (c < 0x10000) { 310 c1 = C2I1(c); 311 c2 = C2I2(c); 312 } else 313 return (c); 314 315 if (dp->d_table[c1] && dp->d_table[c1][c2] & XLAT16_HAS_LOWER_CASE) { 316 /*return (int)(dp->d_table[c1][c2] & 0xffff);*/ 317 out = dp->d_table[c1][c2] & 0xffff; 318 if ((out & 0xff) == 0) 319 out = (out >> 8) & 0xff; 320 return (out); 321 } else 322 return (c); 323} 324 325static int 326iconv_xlat16_toupper(void *d2p, register int c) 327{ 328 struct iconv_xlat16 *dp = (struct iconv_xlat16*)d2p; 329 register int c1, c2, out; 330 331 if (c < 0x100) { 332 c1 = C2I1(c << 8); 333 c2 = C2I2(c << 8); 334 } else if (c < 0x10000) { 335 c1 = C2I1(c); 336 c2 = C2I2(c); 337 } else 338 return (c); 339 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; 344 return (out); 345 } else 346 return (c); 347} 348 |
|
235static kobj_method_t iconv_xlat16_methods[] = { 236 KOBJMETHOD(iconv_converter_open, iconv_xlat16_open), 237 KOBJMETHOD(iconv_converter_close, iconv_xlat16_close), 238 KOBJMETHOD(iconv_converter_conv, iconv_xlat16_conv), 239#if 0 240 KOBJMETHOD(iconv_converter_init, iconv_xlat16_init), 241 KOBJMETHOD(iconv_converter_done, iconv_xlat16_done), 242#endif 243 KOBJMETHOD(iconv_converter_name, iconv_xlat16_name), | 349static kobj_method_t iconv_xlat16_methods[] = { 350 KOBJMETHOD(iconv_converter_open, iconv_xlat16_open), 351 KOBJMETHOD(iconv_converter_close, iconv_xlat16_close), 352 KOBJMETHOD(iconv_converter_conv, iconv_xlat16_conv), 353#if 0 354 KOBJMETHOD(iconv_converter_init, iconv_xlat16_init), 355 KOBJMETHOD(iconv_converter_done, iconv_xlat16_done), 356#endif 357 KOBJMETHOD(iconv_converter_name, iconv_xlat16_name), |
358 KOBJMETHOD(iconv_converter_tolower, iconv_xlat16_tolower), 359 KOBJMETHOD(iconv_converter_toupper, iconv_xlat16_toupper), |
|
244 {0, 0} 245}; 246 247KICONV_CONVERTER(xlat16, sizeof(struct iconv_xlat16)); | 360 {0, 0} 361}; 362 363KICONV_CONVERTER(xlat16, sizeof(struct iconv_xlat16)); |