#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <euc.h>
#include "japanese.h"
#include "jfp_iconv_unicode.h"
#ifdef RFC1468_MODE
#define JFP_U2E_ICONV_RFC1468
#else
#define JFP_U2E_ICONV
#endif
#include "jfp_ucs2_to_euc16.h"
#define DEF_SINGLE '?'
struct _icv_state {
int _st_cset;
};
void *
_icv_open(void)
{
struct _icv_state *st;
if ((st = (struct _icv_state *)
malloc(sizeof (struct _icv_state))) == NULL)
return ((void *)-1);
st->_st_cset = CS_0;
return (st);
}
void
_icv_close(void *cd)
{
if (cd == NULL) {
errno = EBADF;
} else {
free(cd);
}
return;
}
size_t
_icv_iconv(void *cd, char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
unsigned char ic;
size_t rv = (size_t)0;
unsigned int ucs4;
unsigned short euc16;
struct _icv_state *st = (struct _icv_state *)cd;
int cset;
unsigned char *ip;
size_t ileft;
char *op;
size_t oleft;
if ((inbuf == NULL) || (*inbuf == NULL)) {
if (st->_st_cset != CS_0) {
if ((outbuf != NULL) && (*outbuf != NULL)
&& (outbytesleft != NULL)) {
op = (char *)*outbuf;
oleft = *outbytesleft;
NPUT(ESC, "RESET-SEQ-ESC");
NPUT(SBTOG0_1, "RESET-SEQ-1");
NPUT(F_X0201_RM, "RESET-SEQ-2");
*outbuf = (char *)op;
*outbytesleft = oleft;
}
st->_st_cset = CS_0;
}
return ((size_t)0);
}
cset = st->_st_cset;
ip = (unsigned char *)*inbuf;
ileft = *inbytesleft;
op = *outbuf;
oleft = *outbytesleft;
while (ileft != 0) {
if (utf8_ucs(&ucs4, &ip, &ileft) == (size_t)-1) {
rv = (size_t)-1;
goto ret;
}
if (ucs4 > 0xffff) {
if (cset != CS_0) {
NPUT(ESC, "CS0-SEQ-ESC");
NPUT(SBTOG0_1, "CS0-SEQ-1");
NPUT(F_X0201_RM, "CS0-SEQ-2");
cset = CS_0;
}
ic = (unsigned char)DEF_SINGLE;
NPUT(ic, "DEF for non-BMP(replaced)");
} else {
euc16 = _jfp_ucs2_to_euc16((unsigned short)ucs4);
switch (euc16 & 0x8080) {
case 0x0000:
if (cset != CS_0) {
NPUT(ESC, "CS0-SEQ-ESC");
NPUT(SBTOG0_1, "CS0-SEQ-1");
NPUT(F_X0201_RM, "CS0-SEQ-2");
cset = CS_0;
}
ic = (unsigned char)euc16;
NPUT(ic, "CS0-1");
break;
case 0x8080:
if (cset != CS_1) {
NPUT(ESC, "CS1-SEQ-ESC");
NPUT(MBTOG0_1, "CS1-SEQ-1");
NPUT(F_X0208_83_90, "CS1-SEQ-2");
cset = CS_1;
}
ic = (unsigned char)((euc16 >> 8) & CMASK);
NPUT(ic, "CS1-1");
ic = (unsigned char)(euc16 & CMASK);
NPUT(ic, "CS1-2");
break;
case 0x0080:
#ifdef RFC1468_MODE
if (cset != CS_1) {
NPUT(ESC, "CS2-SEQ-ESC(fullsized)");
NPUT(MBTOG0_1, "CS2-SEQ-1(fullsized)");
NPUT(F_X0208_83_90,
"CS2-SEQ-2(fullsized)");
cset = CS_1;
}
euc16 = halfkana2zenkakuj[euc16 - 0xa1];
ic = (unsigned char)((euc16 >> 8) & CMASK);
NPUT(ic, "CS2-1(fullsized)");
ic = (unsigned char)(euc16 & CMASK);
NPUT(ic, "CS2-2(fullsized)");
#else
if (cset != CS_2) {
NPUT(ESC, "CS2-SEQ-ESC");
NPUT(SBTOG0_1, "CS2-SEQ-1");
NPUT(F_X0201_KN, "CS2-SEQ-2");
cset = CS_2;
}
ic = (unsigned char)euc16;
NPUT(ic & CMASK, "CS2-1");
#endif
break;
case 0x8000:
if (cset != CS_3) {
NPUT(ESC, "CS3-SEQ-ESC");
NPUT(MBTOG0_1, "CS3-SEQ-1");
NPUT(MBTOG0_2, "CS3-SEQ-2");
NPUT(F_X0212_90, "CS3-SEQ-3");
cset = CS_3;
}
ic = (unsigned char)((euc16 >> 8) & CMASK);
NPUT(ic, "CS3-1");
ic = (unsigned char)(euc16 & CMASK);
NPUT(ic, "CS3-2");
break;
}
}
*inbuf = (char *)ip;
*inbytesleft = ileft;
*outbuf = op;
*outbytesleft = oleft;
st->_st_cset = cset;
}
ret:
#if defined(DEBUG)
if (rv == (size_t)-1) {
fprintf(stderr, "DEBUG: errno=%d: %s\n", errno, debugmsg);
}
#endif
return ((rv == (size_t)-1) ? rv : *inbytesleft);
}