/*-
 * Copyright (c) 1999,2000
 *	Konstantin Chuguev.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Konstantin Chuguev
 *	and its contributors.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	iconv (Charset Conversion Library) v1.0
 */

#define ICONV_INTERNAL
#include "iconv.h"

#include <stdlib.h>	/* free, malloc */
#include <string.h>

#define	CESTOSTATE(ces)		((iconv_ces_euc_state_t *)(ces)->data)
#define	MODTOCCS(mod)		((struct iconv_ccs_desc *)(mod)->im_desc->imd_data)


typedef struct {
	int nccs;
	const struct iconv_module *ccs[1];
} iconv_ces_euc_state_t;

API_DECLARE_NONSTD(apr_status_t)
apr_iconv_euc_open(struct iconv_ces *ces, apr_pool_t *ctx)
{
	struct iconv_module *depmod = ces->mod->im_deplist;
	iconv_ces_euc_state_t *state;
	apr_size_t stsz;
	int i;

	stsz = sizeof(iconv_ces_euc_state_t) +
	    sizeof(struct iconv_module *) * (ces->mod->im_depcnt - 1);
	state = (iconv_ces_euc_state_t *)malloc(stsz);
	if (state == NULL)
		return APR_ENOMEM;
	memset(state, 0, stsz);
	state->nccs = ces->mod->im_depcnt;
	for (i = ces->mod->im_depcnt; i; i--, depmod = depmod->im_next)
		state->ccs[i - 1] = depmod;
	ces->data = state;
	return APR_SUCCESS;
}

API_DECLARE_NONSTD(apr_status_t)
apr_iconv_euc_close(struct iconv_ces *ces)
{
	free(CESTOSTATE(ces));
	return APR_SUCCESS;
}

#define is_7_14bit(data) ((data)->nbits & 7)
#define is_7bit(data) ((data)->nbits & 1)

API_DECLARE_NONSTD(apr_ssize_t)
apr_iconv_euc_convert_from_ucs(struct iconv_ces *ces, ucs_t in,
	unsigned char **outbuf, apr_size_t *outbytesleft)
{
	iconv_ces_euc_state_t *euc_state = CESTOSTATE(ces);
	const iconv_ces_euc_ccs_t *ccsattr;
	const struct iconv_ccs_desc *ccs;
	ucs_t res;
	apr_size_t bytes;
	int i;

	if (in == UCS_CHAR_NONE)
		return 1;	/* No state reinitialization for table charsets */
	if (iconv_char32bit(in))
		return -1;

	for (i = 0; i < euc_state->nccs; i++) {
		ccs = MODTOCCS(euc_state->ccs[i]);
		res = ICONV_CCS_CONVERT_FROM_UCS(ccs, in);
		if (res == UCS_CHAR_INVALID)
			continue;
		ccsattr = euc_state->ccs[i]->im_depdata;
		if (i) {
			if (is_7_14bit(ccs))
				res |= is_7bit(ccs) ? 0x80 : 0x8080;
			else if (!(res & 0x8080))
				continue;
		} else if (res & 0x8080)
			continue;
		bytes = (res & 0xFF00 ? 2 : 1) + ccsattr->prefixlen;
		if (*outbytesleft < bytes)
			return 0;	/* No space in the output buffer */
		if (ccsattr->prefixlen) {
			memcpy(*outbuf, ccsattr->prefix, ccsattr->prefixlen);
			(*outbuf) += ccsattr->prefixlen;
		}
		if (res & 0xFF00)
			*(*outbuf)++ = (unsigned char)(res >> 8);
		*(*outbuf)++ = (unsigned char)res;
		*outbytesleft -= bytes;
		return 1;
	}
	return -1;	/* No character in output charset */
}

static ucs_t
cvt2ucs(const struct iconv_ccs_desc *ccs, const unsigned char *inbuf,
	apr_size_t inbytesleft, int hi_plane, const unsigned char **bufptr)
{
	apr_size_t bytes = ccs->nbits > 8 ? 2 : 1;
	ucs_t ch = *(const unsigned char *)inbuf++;

	if (inbytesleft < bytes)
		return UCS_CHAR_NONE;	/* Not enough bytes in the input buffer */
	if (bytes == 2)
		ch = (ch << 8) | *(const unsigned char *)inbuf++;
	*bufptr = inbuf;
	if (hi_plane) {
		if (!(ch & 0x8080))
			return UCS_CHAR_INVALID;
		if (is_7_14bit(ccs))
			ch &= 0x7F7F;
	} else if (ch & 0x8080)
		return UCS_CHAR_INVALID;
	return ICONV_CCS_CONVERT_TO_UCS(ccs, ch);
}

API_DECLARE_NONSTD(ucs_t)
apr_iconv_euc_convert_to_ucs(struct iconv_ces *ces,
	const unsigned char **inbuf, apr_size_t *inbytesleft)
{
	iconv_ces_euc_state_t *euc_state = CESTOSTATE(ces);
	const iconv_ces_euc_ccs_t *ccsattr;
	const struct iconv_module *ccsmod;
	ucs_t res = UCS_CHAR_INVALID;
	const unsigned char *ptr;
        int i;

	if (**inbuf & 0x80) {
		for (i = 1; i < euc_state->nccs; i++) {
			ccsmod = euc_state->ccs[i];
			ccsattr = ccsmod->im_depdata;
			if (ccsattr->prefixlen + 1 > *inbytesleft)
				return UCS_CHAR_NONE;
			if (ccsattr->prefixlen &&
			    memcmp(*inbuf, ccsattr->prefix, ccsattr->prefixlen) != 0)
				continue;
			res = cvt2ucs(MODTOCCS(ccsmod), *inbuf + ccsattr->prefixlen,
			    *inbytesleft - ccsattr->prefixlen, 1, &ptr);
			if (res != UCS_CHAR_INVALID)
				break;
		}
		if (res == UCS_CHAR_INVALID)
			ptr = *inbuf + 1;
	} else
		res = cvt2ucs(MODTOCCS(euc_state->ccs[0]), *inbuf, *inbytesleft, 0, &ptr);
	if (res == UCS_CHAR_NONE)
		return res;	/* Not enough bytes in the input buffer */
	*inbytesleft -= ptr - *inbuf;
	*inbuf = ptr;
	return res;
}
