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"
42 #define KICONV_UCS_COMBINE 0x1
43 #define KICONV_UCS_FROM_UTF8 0x2
44 #define KICONV_UCS_TO_UTF8 0x4
45 #define KICONV_UCS_FROM_LE 0x8
46 #define KICONV_UCS_TO_LE 0x10
47 #define KICONV_UCS_FROM_UTF16 0x20
48 #define KICONV_UCS_TO_UTF16 0x40
49 #define KICONV_UCS_UCS4 0x80
51 #define ENCODING_UTF16 "UTF-16BE"
52 #define ENCODING_UTF8 "UTF-8"
66 static uint32_t
utf8_to_ucs4(
const char *src,
size_t *utf8width,
size_t srclen);
67 static u_char *
ucs4_to_utf8(uint32_t ucs4,
char * dst,
size_t *utf8width,
size_t dstlen);
72 MODULE_DEPEND(
iconv_ucs, libiconv, 2, 2, 2);
90 struct iconv_cspair *csp,
struct iconv_cspair *cspf,
void **dpp)
94 const char *from, *to;
96 dp = (
struct iconv_ucs *)kobj_create((
struct kobj_class*)dcp, M_ICONV, M_WAITOK);
98 from = cspf ? cspf->cp_from : csp->cp_from;
157 dp->
d_cspf->cp_refcount--;
159 dp->
d_csp->cp_refcount--;
161 dp->
d_csp->cp_refcount--;
162 kobj_delete((
struct kobj*)data, M_ICONV);
173 size_t in, on, ir, or, inlen, outlen, ucslen;
179 if (inbuf == NULL || *inbuf == NULL || outbuf == NULL || *outbuf == NULL)
186 while (ir > 0 && or > 0) {
203 if (casetype == KICONV_FROM_LOWER && dp->
ctype) {
205 }
else if (casetype == KICONV_FROM_UPPER && dp->
ctype) {
209 if ((code >= 0xd800 && code < 0xe000) || code >= 0x110000 ) {
230 for (q = ucs, i = ucslen - 1 ; i >= 0 ; i--)
231 *q++ = (code >> (i << 3)) & 0xff;
239 &ucslen, casetype & (KICONV_FROM_LOWER | KICONV_FROM_UPPER));
256 if ((*q & 0xfc) == 0xd8) {
281 if ((*q & 0xfc) != 0xdc) {
300 code = (ucs[0] << 8) | ucs[1];
303 if (casetype == KICONV_LOWER && dp->
ctype) {
305 }
else if (casetype == KICONV_UPPER && dp->
ctype) {
322 &or, casetype & (KICONV_LOWER | KICONV_UPPER));
368 *inbytesleft -= in - ir;
369 *outbytesleft -= on - or;
396 return (ENCODING_UNICODE);
420 if ((*src & 0x80) == 0) {
429 }
else if ((*src & 0xe0) == 0xc0) {
438 }
else if ((*src & 0xf0) == 0xe0) {
447 }
else if ((*src & 0xf8) == 0xf0) {
469 for (i = 1 ; i < w ; i++) {
470 if ((*(src + i) & 0xc0) != 0x80) {
476 ucs4 |= *(src + i) & 0x3f;
484 ucs4_to_utf8(uint32_t ucs4,
char *dst,
size_t *utf8width,
size_t dstlen)
495 }
else if (ucs4 < 0x800) {
498 }
else if (ucs4 < 0x10000) {
501 }
else if (ucs4 < 0x200000) {
515 for (i = w - 1 ; i >= 1 ; i--) {
517 *(p + i) = (ucs4 & 0x3f) | 0x80;
530 return ((((code - 0x10000) << 6) & 0x3ff0000) |
531 ((code - 0x10000) & 0x3ff) | 0xd800dc00);
537 return ((((ucs[0] & 0x3) << 18) | (ucs[1] << 10) |
538 ((ucs[2] & 0x3) << 8) | ucs[3]) + 0x10000);
static int iconv_ucs_init(struct iconv_converter_class *dcp)
struct iconv_cspair * d_csp
#define KICONV_UCS_COMBINE
static int iconv_ucs_conv(void *d2p, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft, int convchar, int casetype)
static struct @0 unicode_family[]
static uint32_t utf8_to_ucs4(const char *src, size_t *utf8width, size_t srclen)
#define KICONV_UCS_FROM_UTF16
int iconv_close(void *handle)
static int iconv_ucs_close(void *data)
int iconv_open(const char *to, const char *from, void **handle)
static u_char * ucs4_to_utf8(uint32_t ucs4, char *dst, size_t *utf8width, size_t dstlen)
int iconv_add(const char *converter, const char *to, const char *from)
static kobj_method_t iconv_ucs_methods[]
int towlower(int c, void *handle)
#define KICONV_UCS_FROM_UTF8
struct iconv_cspair * d_cspf
int towupper(int c, void *handle)
static uint32_t encode_surrogate(uint32_t code)
int strcasecmp(const char *s1, const char *s2)
static int iconv_ucs_done(struct iconv_converter_class *dcp)
int iconv_convchr_case(void *handle, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft, int casetype)
#define KICONV_UCS_FROM_LE
#define KICONV_UCS_TO_UTF16
static int iconv_ucs_open(struct iconv_converter_class *dcp, struct iconv_cspair *csp, struct iconv_cspair *cspf, void **dpp)
#define KICONV_UCS_TO_UTF8
int strcmp(const char *s1, const char *s2)
static uint32_t decode_surrogate(const u_char *ucs)
KICONV_CONVERTER(ucs, sizeof(struct iconv_ucs))
static const char * iconv_ucs_name(struct iconv_converter_class *dcp)