15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * CDDL HEADER START
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * The contents of this file are subject to the terms of the
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Common Development and Distribution License (the "License").
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * You may not use this file except in compliance with the License.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * or http://www.opensolaris.org/os/licensing.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * See the License for the specific language governing permissions
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * and limitations under the License.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * When distributing Covered Code, include this CDDL HEADER in each
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * If applicable, add the following below this CDDL HEADER, with the
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * fields enclosed by brackets "[]" replaced with your own identifying
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * information: Portions Copyright [yyyy] [name of copyright owner]
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * CDDL HEADER END
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Use is subject to license terms.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#pragma ident "%Z%%M% %I% %E% SMI"
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/types.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/param.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/sysmacros.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/systm.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/debug.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/kmem.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/sunddi.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/byteorder.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/errno.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/modctl.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/u8_textprep.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/kiconv.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/kiconv_cck_common.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/kiconv_tc.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/kiconv_big5_utf8.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/kiconv_euctw_utf8.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/kiconv_hkscs_utf8.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/kiconv_cp950hkscs_utf8.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/kiconv_utf8_big5.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/kiconv_utf8_euctw.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/kiconv_utf8_cp950hkscs.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#include <sys/kiconv_utf8_hkscs.h>
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/* 4 HKSCS-2004 code points map to 2 Unicode code points separately. */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic uchar_t hkscs_special_sequence[][4] = {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy { 0xc3, 0x8a, 0xcc, 0x84 }, /* 0x8862 */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy { 0xc3, 0x8a, 0xcc, 0x8c }, /* 0x8864 */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy { 0xc3, 0xaa, 0xcc, 0x84 }, /* 0x88a3 */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy { 0xc3, 0xaa, 0xcc, 0x8c } /* 0x88a5 */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy};
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/* 4 Unicode code point pair map to 1 HKSCS-2004 code point. */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic uint32_t ucs_special_sequence[] = {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy 0x8866, /* U+00ca */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy 0x8862, /* U+00ca U+0304 */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy 0x8864, /* U+00ca U+030c */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy 0x88a7, /* U+00ea */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy 0x88a3, /* U+00ea U+0304 */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy 0x88a5 /* U+00ea U+030c */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy};
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yytypedef int8_t (*kiconv_big5toutf8_t)(uint32_t value, uchar_t *ob,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *obtail, size_t *ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t utf8_to_big5(uint32_t utf8, uchar_t **inbuf, uchar_t *ibtail,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ob, uchar_t *obtail, size_t *ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t utf8_to_euctw(uint32_t utf8, uchar_t **inbuf, uchar_t *ibtail,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ob, uchar_t *obtail, size_t *ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t utf8_to_cp950hkscs(uint32_t utf8, uchar_t **inbuf,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ibtail, uchar_t *ob, uchar_t *obtail, size_t *ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t utf8_to_big5hkscs(uint32_t utf8, uchar_t **inbuf, uchar_t *ibtail,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ob, uchar_t *obtail, size_t *ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t big5_to_utf8(uint32_t big5_val, uchar_t *ob, uchar_t *obtail,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t big5hkscs_to_utf8(uint32_t hkscs_val, uchar_t *ob,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *obtail, size_t *ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t cp950hkscs_to_utf8(uint32_t hkscs_val, uchar_t *ob,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *obtail, size_t *ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t euctw_to_utf8(size_t plane_no, uint32_t euctw_val,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ob, uchar_t *obtail, size_t *ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic uint32_t get_unicode_from_UDA(size_t plane_no, uchar_t byte1,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t byte2);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#define KICONV_TC_BIG5 (0x01)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#define KICONV_TC_BIG5HKSCS (0x02)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#define KICONV_TC_CP950HKSCS (0x03)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#define KICONV_TC_EUCTW (0x04)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy#define KICONV_TC_MAX_MAGIC_ID (0x04)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic void *
15d9d0b528387242011cdcc6190c9e598cfe3a07yyopen_fr_big5()
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return ((void *)KICONV_TC_BIG5);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic void *
15d9d0b528387242011cdcc6190c9e598cfe3a07yyopen_fr_big5hkscs()
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return ((void *)KICONV_TC_BIG5HKSCS);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic void *
15d9d0b528387242011cdcc6190c9e598cfe3a07yyopen_fr_cp950hkscs()
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return ((void *)KICONV_TC_CP950HKSCS);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic void *
15d9d0b528387242011cdcc6190c9e598cfe3a07yyopen_fr_euctw()
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return ((void *)KICONV_TC_EUCTW);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int
15d9d0b528387242011cdcc6190c9e598cfe3a07yyclose_fr_tc(void *s)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if ((uintptr_t)s > KICONV_TC_MAX_MAGIC_ID)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (EBADF);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (0);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Common convertor from BIG5/HKSCS(BIG5-HKSCS or CP950-HKSCS) to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconv_fr_big5_common(void *kcd, char **inbuf, size_t *inbytesleft,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy char **outbuf, size_t *outbytesleft, int *errno,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy kiconv_big5toutf8_t ptr_big5touf8)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ob;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ibtail;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *obtail;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t ret_val;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy int8_t sz;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uint32_t big5_val;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /* Check on the kiconv code conversion descriptor. */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (kcd == NULL || kcd == (void *)-1) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *errno = EBADF;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return ((size_t)-1);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /* If this is a state reset request, process and return. */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (inbuf == NULL || *inbuf == NULL) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (0);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ret_val = 0;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ib = (uchar_t *)*inbuf;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ob = (uchar_t *)*outbuf;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ibtail = ib + *inbytesleft;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy obtail = ob + *outbytesleft;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy while (ib < ibtail) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (KICONV_IS_ASCII(*ib)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (ob >= obtail) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(E2BIG);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = *ib++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy continue;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Issue EILSEQ error if the first byte is not a
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * valid BIG5/HKSCS leading byte.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (! KICONV_TC_IS_BIG5_1st_BYTE(*ib)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(EILSEQ);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Issue EINVAL error if input buffer has an incomplete
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * character at the end of the buffer.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (ibtail - ib < 2) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(EINVAL);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Issue EILSEQ error if the remaining bytes is not
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * a valid BIG5/HKSCS byte.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (! KICONV_TC_IS_BIG5_2nd_BYTE(*(ib + 1))) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(EILSEQ);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /* Now we have a valid BIG5/HKSCS character. */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy big5_val = (uint32_t)(*ib) << 8 | *(ib + 1);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy sz = ptr_big5touf8(big5_val, ob, obtail, &ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (sz < 0) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(E2BIG);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ib += 2;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ob += sz;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *inbuf = (char *)ib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *inbytesleft = ibtail - ib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *outbuf = (char *)ob;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *outbytesleft = obtail - ob;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * String based Common convertor from BIG5/HKSCS(BIG5-HKSCS or CP950-HKSCS)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconvstr_fr_big5_common(uchar_t *ib, size_t *inlen, uchar_t *ob,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *outlen, int flag, int *errno,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy kiconv_big5toutf8_t ptr_big5touf8)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *oldib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ibtail;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *obtail;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t ret_val;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy int8_t sz;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uint32_t big5_val;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy boolean_t do_not_ignore_null;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ret_val = 0;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ibtail = ib + *inlen;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy obtail = ob + *outlen;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy do_not_ignore_null = ((flag & KICONV_IGNORE_NULL) == 0);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy while (ib < ibtail) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (*ib == '\0' && do_not_ignore_null)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy break;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (KICONV_IS_ASCII(*ib)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (ob >= obtail) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(E2BIG);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = *ib++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy continue;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy oldib = ib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (! KICONV_TC_IS_BIG5_1st_BYTE(*ib)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_WITH_FLAG(1, EILSEQ);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (ibtail - ib < 2) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_WITH_FLAG(1, EINVAL);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (! KICONV_TC_IS_BIG5_2nd_BYTE(*(ib + 1))) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_WITH_FLAG(2, EILSEQ);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy big5_val = *ib++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy big5_val = (big5_val << 8) | *ib++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy sz = ptr_big5touf8(big5_val, ob, obtail, &ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (sz < 0) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ib = oldib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(E2BIG);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ob += sz;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy continue;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yyREPLACE_INVALID:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (obtail - ob < KICONV_UTF8_REPLACEMENT_CHAR_LEN) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ib = oldib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(E2BIG);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = KICONV_UTF8_REPLACEMENT_CHAR1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = KICONV_UTF8_REPLACEMENT_CHAR2;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = KICONV_UTF8_REPLACEMENT_CHAR3;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ret_val++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *inlen = ibtail - ib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *outlen = obtail - ob;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Encoding convertor from BIG5 to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconv_fr_big5(void *kcd, char **inbuf, size_t *inbytesleft, char **outbuf,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *outbytesleft, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (kiconv_fr_big5_common(kcd, inbuf, inbytesleft, outbuf,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy outbytesleft, errno, big5_to_utf8));
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * String based encoding convertor from BIG5 to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconvstr_fr_big5(char *inarray, size_t *inlen, char *outarray,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *outlen, int flag, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (kiconvstr_fr_big5_common((uchar_t *)inarray, inlen,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (uchar_t *)outarray, outlen, flag, errno,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy big5_to_utf8));
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Encoding convertor from BIG5-HKSCS to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconv_fr_big5hkscs(void *kcd, char **inbuf, size_t *inbytesleft,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy char **outbuf, size_t *outbytesleft, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return kiconv_fr_big5_common(kcd, inbuf, inbytesleft, outbuf,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy outbytesleft, errno, big5hkscs_to_utf8);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * String based encoding convertor from BIG5-HKSCS to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconvstr_fr_big5hkscs(char *inarray, size_t *inlen, char *outarray,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *outlen, int flag, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return kiconvstr_fr_big5_common((uchar_t *)inarray, inlen,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (uchar_t *)outarray, outlen, flag, errno, big5hkscs_to_utf8);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Encoding convertor from CP950-HKSCS to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconv_fr_cp950hkscs(void *kcd, char **inbuf, size_t *inbytesleft,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy char **outbuf, size_t *outbytesleft, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return kiconv_fr_big5_common(kcd, inbuf, inbytesleft, outbuf,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy outbytesleft, errno, cp950hkscs_to_utf8);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * String based encoding convertor from CP950-HKSCS to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconvstr_fr_cp950hkscs(char *inarray, size_t *inlen, char *outarray,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *outlen, int flag, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return kiconvstr_fr_big5_common((uchar_t *)inarray, inlen,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (uchar_t *)outarray, outlen, flag, errno, cp950hkscs_to_utf8);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Encoding convertor from EUC-TW to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconv_fr_euctw(void *kcd, char **inbuf, size_t *inbytesleft,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy char **outbuf, size_t *outbytesleft, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ob;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ibtail;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *obtail;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *oldib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t ret_val;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t plane_no;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy int8_t sz;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uint32_t euctw_val;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy boolean_t isplane1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /* Check on the kiconv code conversion descriptor. */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (kcd == NULL || kcd == (void *)-1) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *errno = EBADF;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return ((size_t)-1);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /* If this is a state reset request, process and return. */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (inbuf == NULL || *inbuf == NULL) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (0);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ret_val = 0;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ib = (uchar_t *)*inbuf;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ob = (uchar_t *)*outbuf;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ibtail = ib + *inbytesleft;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy obtail = ob + *outbytesleft;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy while (ib < ibtail) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (KICONV_IS_ASCII(*ib)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (ob >= obtail) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(E2BIG);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = *ib++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy continue;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Issue EILSEQ error if the first byte is not a
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * valid EUC-TW leading byte.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (! KICONV_TC_IS_EUCTW_1st_BYTE(*ib)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(EILSEQ);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy isplane1 = (*ib == KICONV_TC_EUCTW_MBYTE) ?
15d9d0b528387242011cdcc6190c9e598cfe3a07yy B_FALSE : B_TRUE;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Issue EINVAL error if input buffer has an incomplete
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * character at the end of the buffer.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (ibtail - ib < (isplane1 ? 2 : 4)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(EINVAL);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy oldib = ib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy plane_no = isplane1 ? 1 : *(ib + 1) - KICONV_TC_EUCTW_PMASK;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Issue EILSEQ error if the remaining bytes are not
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * valid EUC-TW bytes.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (! KICONV_TC_IS_VALID_EUCTW_SEQ(ib)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(EILSEQ);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (! isplane1)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ib += 2;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /* Now we have a valid EUC-TW character. */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy euctw_val = *ib++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy euctw_val = (euctw_val << 8) | *ib++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy sz = euctw_to_utf8(plane_no, euctw_val, ob, obtail, &ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (sz < 0) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ib = oldib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(E2BIG);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ob += sz;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *inbuf = (char *)ib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *inbytesleft = ibtail - ib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *outbuf = (char *)ob;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *outbytesleft = obtail - ob;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * String based encoding convertor from EUC-TW to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconvstr_fr_euctw(char *inarray, size_t *inlen, char *outarray,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *outlen, int flag, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ob;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ibtail;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *obtail;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *oldib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t ret_val;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t plane_no;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy int8_t sz;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uint32_t euctw_val;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy boolean_t isplane1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy boolean_t do_not_ignore_null;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ret_val = 0;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ib = (uchar_t *)inarray;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ob = (uchar_t *)outarray;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ibtail = ib + *inlen;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy obtail = ob + *outlen;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy do_not_ignore_null = ((flag & KICONV_IGNORE_NULL) == 0);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy while (ib < ibtail) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (*ib == '\0' && do_not_ignore_null)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy break;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (KICONV_IS_ASCII(*ib)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (ob >= obtail) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(E2BIG);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = *ib++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy continue;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy oldib = ib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (! KICONV_TC_IS_EUCTW_1st_BYTE(*ib)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_WITH_FLAG(1, EILSEQ);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy isplane1 = (*ib == KICONV_TC_EUCTW_MBYTE) ?
15d9d0b528387242011cdcc6190c9e598cfe3a07yy B_FALSE : B_TRUE;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (ibtail - ib < (isplane1 ? 2 : 4)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (flag & KICONV_REPLACE_INVALID) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ib = ibtail;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy goto REPLACE_INVALID;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(EINVAL);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy plane_no = isplane1 ? 1 : *(ib + 1) - KICONV_TC_EUCTW_PMASK;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (! KICONV_TC_IS_VALID_EUCTW_SEQ(ib)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_WITH_FLAG(isplane1 ? 2 : 4, EILSEQ);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (! isplane1)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ib += 2;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy euctw_val = *ib++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy euctw_val = (euctw_val << 8) | *ib++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy sz = euctw_to_utf8(plane_no, euctw_val, ob, obtail, &ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (sz < 0) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ib = oldib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(E2BIG);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ob += sz;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy continue;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yyREPLACE_INVALID:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (obtail - ob < KICONV_UTF8_REPLACEMENT_CHAR_LEN) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ib = oldib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_SET_ERRNO_AND_BREAK(E2BIG);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = KICONV_UTF8_REPLACEMENT_CHAR1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = KICONV_UTF8_REPLACEMENT_CHAR2;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = KICONV_UTF8_REPLACEMENT_CHAR3;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ret_val++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *inlen = ibtail - ib;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *outlen = obtail - ob;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (ret_val);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Encoding convertor from UTF-8 to BIG5.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconv_to_big5(void *kcd, char **inbuf, size_t *inbytesleft,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy char **outbuf, size_t *outbytesleft, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return kiconv_utf8_to_cck(kcd, inbuf, inbytesleft, outbuf,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy outbytesleft, errno, utf8_to_big5);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * String based encoding convertor from UTF-8 to BIG5.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconvstr_to_big5(char *inarray, size_t *inlen, char *outarray,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *outlen, int flag, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return kiconvstr_utf8_to_cck((uchar_t *)inarray, inlen,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (uchar_t *)outarray, outlen, flag, errno, utf8_to_big5);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Encoding convertor from UTF-8 to EUC-TW.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconv_to_euctw(void *kcd, char **inbuf, size_t *inbytesleft,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy char **outbuf, size_t *outbytesleft, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return kiconv_utf8_to_cck(kcd, inbuf, inbytesleft, outbuf,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy outbytesleft, errno, utf8_to_euctw);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * String based encoding convertor from UTF-8 to EUC-TW.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconvstr_to_euctw(char *inarray, size_t *inlen, char *outarray,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *outlen, int flag, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return kiconvstr_utf8_to_cck((uchar_t *)inarray, inlen,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (uchar_t *)outarray, outlen, flag, errno, utf8_to_euctw);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Encoding convertor from UTF-8 to CP950HKSCS.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconv_to_cp950hkscs(void *kcd, char **inbuf, size_t *inbytesleft,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy char **outbuf, size_t *outbytesleft, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return kiconv_utf8_to_cck(kcd, inbuf, inbytesleft, outbuf,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy outbytesleft, errno, utf8_to_cp950hkscs);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * String based encoding convertor from UTF-8 to CP950HKSCS.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconvstr_to_cp950hkscs(char *inarray, size_t *inlen, char *outarray,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *outlen, int flag, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return kiconvstr_utf8_to_cck((uchar_t *)inarray, inlen,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (uchar_t *)outarray, outlen, flag, errno, utf8_to_cp950hkscs);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Encoding convertor from UTF-8 to BIG5HKSCS(HKSCS-2004).
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconv_to_big5hkscs(void *kcd, char **inbuf, size_t *inbytesleft,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy char **outbuf, size_t *outbytesleft, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return kiconv_utf8_to_cck(kcd, inbuf, inbytesleft, outbuf,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy outbytesleft, errno, utf8_to_big5hkscs);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * String based encoding convertor from UTF-8 to BIG5HKSCS(HKSCS-2004).
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic size_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yykiconvstr_to_big5hkscs(char *inarray, size_t *inlen, char *outarray,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *outlen, int flag, int *errno)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return kiconvstr_utf8_to_cck((uchar_t *)inarray, inlen,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (uchar_t *)outarray, outlen, flag, errno, utf8_to_big5hkscs);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Common convertor from single BIG5/CP950-HKSCS character to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Return: > 0 - Converted successfully
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * = -1 - E2BIG
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yybig5_to_utf8_common(uint32_t big5_val, uchar_t *ob, uchar_t *obtail,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *ret_val, kiconv_table_array_t *table, size_t nitems)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t index;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy int8_t sz;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = kiconv_binsearch(big5_val, table, nitems);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u8 = table[index].u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy sz = u8_number_of_bytes[u8[0]];
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (obtail - ob < sz) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ret_val = (size_t)-1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (-1);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (index == 0)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (*ret_val)++; /* Non-identical conversion */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy for (index = 0; index < sz; index++)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = u8[index];
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (sz);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Convert single BIG5 character to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yybig5_to_utf8(uint32_t big5_val, uchar_t *ob, uchar_t *obtail, size_t *ret_val)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (big5_to_utf8_common(big5_val, ob, obtail, ret_val,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy kiconv_big5_utf8, KICONV_BIG5_UTF8_MAX));
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Convert single CP950-HKSCS character to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yycp950hkscs_to_utf8(uint32_t hkscs_val, uchar_t *ob, uchar_t *obtail,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *ret_val)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (big5_to_utf8_common(hkscs_val, ob, obtail, ret_val,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy kiconv_cp950hkscs_utf8, KICONV_CP950HKSCS_UTF8_MAX));
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Calculate unicode value for some CNS planes which fall in Unicode
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * UDA range.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic uint32_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yyget_unicode_from_UDA(size_t plane_no, uchar_t b1, uchar_t b2)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * CNS Plane 15 is pre-allocated, so need move Plane 16 to back 15
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * to compute the Unicode value.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (plane_no == 16)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy --plane_no;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /* 0xF0000 + (plane_no - 12) * 8836 + (b1 - 0xA1) * 94 + (b2 - 0xA1) */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (8836 * plane_no + 94 * b1 + b2 + 0xD2611);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Convert single EUC-TW character to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Return: > 0 - Converted successfully
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * = -1 - E2BIG
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yyeuctw_to_utf8(size_t plane_no, uint32_t euctw_val, uchar_t *ob,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *obtail, size_t *ret_val)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uint32_t u32;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t index;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy int8_t sz;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t udc[4];
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy switch (plane_no) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy case 1:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = kiconv_binsearch(euctw_val, kiconv_cns1_utf8,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_CNS1_UTF8_MAX);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u8 = kiconv_cns1_utf8[index].u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy break;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy case 2:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = kiconv_binsearch(euctw_val, kiconv_cns2_utf8,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_CNS2_UTF8_MAX);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u8 = kiconv_cns2_utf8[index].u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy break;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy case 3:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = kiconv_binsearch(euctw_val, kiconv_cns3_utf8,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_CNS3_UTF8_MAX);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u8 = kiconv_cns3_utf8[index].u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy break;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy case 4:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = kiconv_binsearch(euctw_val, kiconv_cns4_utf8,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_CNS4_UTF8_MAX);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u8 = kiconv_cns4_utf8[index].u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy break;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy case 5:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = kiconv_binsearch(euctw_val, kiconv_cns5_utf8,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_CNS5_UTF8_MAX);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u8 = kiconv_cns5_utf8[index].u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy break;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy case 6:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = kiconv_binsearch(euctw_val, kiconv_cns6_utf8,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_CNS6_UTF8_MAX);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u8 = kiconv_cns6_utf8[index].u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy break;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy case 7:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = kiconv_binsearch(euctw_val, kiconv_cns7_utf8,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_CNS7_UTF8_MAX);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u8 = kiconv_cns7_utf8[index].u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy break;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy case 12:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy case 13:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy case 14:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy case 16:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u32 = get_unicode_from_UDA(plane_no,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (euctw_val & 0xFF00) >> 8, euctw_val & 0xFF);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * As U+F0000 <= u32 <= U+F8A0F, so its UTF-8 sequence
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * will occupy 4 bytes.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy udc[0] = 0xF3;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy udc[1] = (uchar_t)(0x80 | (u32 & 0x03F000) >> 12);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy udc[2] = (uchar_t)(0x80 | (u32 & 0x000FC0) >> 6);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy udc[3] = (uchar_t)(0x80 | (u32 & 0x00003F));
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u8 = udc;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = 1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy break;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy case 15:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = kiconv_binsearch(euctw_val, kiconv_cns15_utf8,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_CNS15_UTF8_MAX);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u8 = kiconv_cns15_utf8[index].u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy break;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy default:
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = 0;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u8 = kiconv_cns1_utf8[index].u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy sz = u8_number_of_bytes[u8[0]];
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (obtail - ob < sz) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ret_val = (size_t)-1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (-1);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (index == 0)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (*ret_val)++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy for (index = 0; index < sz; index++)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = u8[index];
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (sz);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Convert single HKSCS character to UTF-8.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Return: > 0 - Converted successfully
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * = -1 - E2BIG
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yybig5hkscs_to_utf8(uint32_t hkscs_val, uchar_t *ob, uchar_t *obtail,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *ret_val)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t index;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy int8_t sz;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = kiconv_binsearch(hkscs_val, kiconv_hkscs_utf8,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_HKSCS_UTF8_MAX);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u8 = kiconv_hkscs_utf8[index].u8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Single HKSCS-2004 character may map to 2 Unicode
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * code points.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (u8[0] == 0xFF) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy u8 = hkscs_special_sequence[u8[1]];
15d9d0b528387242011cdcc6190c9e598cfe3a07yy sz = 4;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy } else {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy sz = u8_number_of_bytes[u8[0]];
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (obtail - ob < sz) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ret_val = (size_t)-1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (-1);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (index == 0)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (*ret_val)++; /* Non-identical conversion. */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy for (index = 0; index < sz; index++)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = u8[index];
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (sz);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Convert single UTF-8 character to EUC-TW.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Return: > 0 - Converted successfully
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * = -1 - E2BIG
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/* ARGSUSED */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yyutf8_to_euctw(uint32_t utf8, uchar_t **inbuf, uchar_t *ibtail,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ob, uchar_t *obtail, size_t *ret_val)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t index;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t plane_no;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t byte1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t byte2;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (utf8 >= KICONV_TC_UDA_UTF8_START &&
15d9d0b528387242011cdcc6190c9e598cfe3a07yy utf8 <= KICONV_TC_UDA_UTF8_END) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Calculate EUC-TW code if utf8 is in Unicode
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Private Plane 15.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = (((utf8 & 0x7000000) >> 6) | ((utf8 & 0x3F0000) >> 4) |
15d9d0b528387242011cdcc6190c9e598cfe3a07yy ((utf8 & 0x3F00) >> 2) | (utf8 & 0x3F)) -
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_TC_UDA_UCS4_START;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy plane_no = 12 + index / 8836;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy byte1 = 0xA1 + (index % 8836) / 94;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy byte2 = 0xA1 + index % 94;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /* CNS Plane 15 is pre-allocated, so place it into Plane 16. */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (plane_no == 15)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy plane_no = 16;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy } else {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uint32_t euctw_val;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = kiconv_binsearch(utf8, kiconv_utf8_euctw,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_UTF8_EUCTW_MAX);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (index == 0) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (ob >= obtail) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ret_val = (size_t)-1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (-1);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = KICONV_ASCII_REPLACEMENT_CHAR;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (*ret_val)++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (1);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy euctw_val = kiconv_utf8_euctw[index].value;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy byte1 = (euctw_val & 0xFF00) >> 8;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy byte2 = euctw_val & 0xFF;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy plane_no = euctw_val >> 16;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (obtail - ob < (plane_no == 1 ? 2 : 4)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ret_val = (size_t)-1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (-1);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (plane_no != 1) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = KICONV_TC_EUCTW_MBYTE;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = KICONV_TC_EUCTW_PMASK + plane_no;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = byte1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob = byte2;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (plane_no == 1 ? 2 : 4);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Convert single UTF-8 character to BIG5-HKSCS
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Return: > 0 - Converted successfully
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * = -1 - E2BIG
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yyutf8_to_big5hkscs(uint32_t utf8, uchar_t **inbuf, uchar_t *ibtail,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ob, uchar_t *obtail, size_t *ret_val)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t index;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy int8_t hkscslen;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uint32_t hkscscode;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy boolean_t special_sequence = B_FALSE;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = kiconv_binsearch(utf8, kiconv_utf8_hkscs,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy KICONV_UTF8_HKSCS_MAX);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy hkscscode = kiconv_utf8_hkscs[index].value;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * There are 4 special code points in HKSCS-2004 which mapped
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * to 2 UNICODE code points.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if ((int32_t)hkscscode < 0) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t special_index = (-(int32_t)hkscscode - 1) * 3;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /* Check the following 2 bytes. */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (ibtail - *inbuf >= 2 && **inbuf == 0xcc &&
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (*(*inbuf + 1) == 0x84 || *(*inbuf + 1) == 0x8c)) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy special_index += (*(*inbuf + 1) == 0x84 ? 1 : 2);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy special_sequence = B_TRUE;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy hkscscode = ucs_special_sequence[special_index];
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy hkscslen = (hkscscode <= 0xFF) ? 1 : 2;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (obtail - ob < hkscslen) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ret_val = (size_t)-1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (-1);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (index == 0)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (*ret_val)++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (hkscslen > 1)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = (uchar_t)(hkscscode >> 8);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob = (uchar_t)(hkscscode & 0xFF);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (special_sequence) { /* Advance for special sequence */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (*inbuf) += 2;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (hkscslen);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Common convertor for UTF-8 to BIG5/CP950-HKSCS.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Return: > 0 - Converted successfully
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * = -1 - E2BIG
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yyutf8_to_big5_common(uint32_t utf8, uchar_t *ob, uchar_t *obtail,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t *ret_val, kiconv_table_t *table, size_t nitems)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy size_t index;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy int8_t big5len;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uint32_t big5code;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy index = kiconv_binsearch(utf8, table, nitems);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy big5code = table[index].value;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy big5len = (big5code <= 0xFF) ? 1 : 2;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (obtail - ob < big5len) {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ret_val = (size_t)-1;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (-1);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy }
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (index == 0)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (*ret_val)++;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (big5len > 1)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob++ = (uchar_t)(big5code >> 8);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *ob = (uchar_t)(big5code & 0xFF);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (big5len);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Convert single UTF-8 character to BIG5.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/* ARGSUSED */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yyutf8_to_big5(uint32_t utf8, uchar_t **inbuf, uchar_t *ibtail,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ob, uchar_t *obtail, size_t *ret_val)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (utf8_to_big5_common(utf8, ob, obtail, ret_val,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy kiconv_utf8_big5, KICONV_UTF8_BIG5_MAX));
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Convert single UTF-8 character to CP950-HKSCS for Windows compatibility.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy/* ARGSUSED */
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic int8_t
15d9d0b528387242011cdcc6190c9e598cfe3a07yyutf8_to_cp950hkscs(uint32_t utf8, uchar_t **inbuf, uchar_t *ibtail,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy uchar_t *ob, uchar_t *obtail, size_t *ret_val)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (utf8_to_big5_common(utf8, ob, obtail, ret_val,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy kiconv_utf8_cp950hkscs, KICONV_UTF8_CP950HKSCS));
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic kiconv_ops_t kiconv_tc_ops_tbl[] = {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy "big5", "utf-8", kiconv_open_to_cck, kiconv_to_big5,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy kiconv_close_to_cck, kiconvstr_to_big5
15d9d0b528387242011cdcc6190c9e598cfe3a07yy },
15d9d0b528387242011cdcc6190c9e598cfe3a07yy {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy "utf-8", "big5", open_fr_big5, kiconv_fr_big5,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy close_fr_tc, kiconvstr_fr_big5
15d9d0b528387242011cdcc6190c9e598cfe3a07yy },
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy "big5-hkscs", "utf-8", kiconv_open_to_cck, kiconv_to_big5hkscs,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy kiconv_close_to_cck, kiconvstr_to_big5hkscs
15d9d0b528387242011cdcc6190c9e598cfe3a07yy },
15d9d0b528387242011cdcc6190c9e598cfe3a07yy {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy "utf-8", "big5-hkscs", open_fr_big5hkscs, kiconv_fr_big5hkscs,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy close_fr_tc, kiconvstr_fr_big5hkscs
15d9d0b528387242011cdcc6190c9e598cfe3a07yy },
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy "euc-tw", "utf-8", kiconv_open_to_cck, kiconv_to_euctw,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy kiconv_close_to_cck, kiconvstr_to_euctw
15d9d0b528387242011cdcc6190c9e598cfe3a07yy },
15d9d0b528387242011cdcc6190c9e598cfe3a07yy {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy "utf-8", "euc-tw", open_fr_euctw, kiconv_fr_euctw,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy close_fr_tc, kiconvstr_fr_euctw
15d9d0b528387242011cdcc6190c9e598cfe3a07yy },
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy "cp950-hkscs", "utf-8", kiconv_open_to_cck,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy kiconv_to_cp950hkscs, kiconv_close_to_cck,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy kiconvstr_to_cp950hkscs
15d9d0b528387242011cdcc6190c9e598cfe3a07yy },
15d9d0b528387242011cdcc6190c9e598cfe3a07yy {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy "utf-8", "cp950-hkscs", open_fr_cp950hkscs,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy kiconv_fr_cp950hkscs, close_fr_tc, kiconvstr_fr_cp950hkscs
15d9d0b528387242011cdcc6190c9e598cfe3a07yy },
15d9d0b528387242011cdcc6190c9e598cfe3a07yy};
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic kiconv_module_info_t kiconv_tc_info = {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy "kiconv_tc", /* module name */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy sizeof (kiconv_tc_ops_tbl) / sizeof (kiconv_tc_ops_tbl[0]),
15d9d0b528387242011cdcc6190c9e598cfe3a07yy kiconv_tc_ops_tbl,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy 0,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy NULL,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy NULL,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy 0
15d9d0b528387242011cdcc6190c9e598cfe3a07yy};
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic struct modlkiconv modlkiconv_tc = {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy &mod_kiconvops,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy "kiconv Traditional Chinese module 1.0",
15d9d0b528387242011cdcc6190c9e598cfe3a07yy &kiconv_tc_info
15d9d0b528387242011cdcc6190c9e598cfe3a07yy};
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yystatic struct modlinkage modlinkage = {
15d9d0b528387242011cdcc6190c9e598cfe3a07yy MODREV_1,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy (void *)&modlkiconv_tc,
15d9d0b528387242011cdcc6190c9e598cfe3a07yy NULL
15d9d0b528387242011cdcc6190c9e598cfe3a07yy};
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yyint
15d9d0b528387242011cdcc6190c9e598cfe3a07yy_init(void)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy int err;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy err = mod_install(&modlinkage);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (err)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy cmn_err(CE_WARN, "kiconv_tc: failed to load kernel module");
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (err);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yyint
15d9d0b528387242011cdcc6190c9e598cfe3a07yy_fini(void)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy int err;
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy /*
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * If this module is being used, then, we cannot remove the module.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * The following checking will catch pretty much all usual cases.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy *
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * Any remaining will be catached by the kiconv_unregister_module()
15d9d0b528387242011cdcc6190c9e598cfe3a07yy * during mod_remove() at below.
15d9d0b528387242011cdcc6190c9e598cfe3a07yy */
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (kiconv_module_ref_count(KICONV_MODULE_ID_TC))
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (EBUSY);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy err = mod_remove(&modlinkage);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy if (err)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy cmn_err(CE_WARN, "kiconv_tc: failed to remove kernel module");
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (err);
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}
15d9d0b528387242011cdcc6190c9e598cfe3a07yy
15d9d0b528387242011cdcc6190c9e598cfe3a07yyint
15d9d0b528387242011cdcc6190c9e598cfe3a07yy_info(struct modinfo *modinfop)
15d9d0b528387242011cdcc6190c9e598cfe3a07yy{
15d9d0b528387242011cdcc6190c9e598cfe3a07yy return (mod_info(&modlinkage, modinfop));
15d9d0b528387242011cdcc6190c9e598cfe3a07yy}