#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <euc.h>
#include "japanese.h"
struct _icv_state {
int _st_cset;
};
void *
_icv_open()
{
struct _icv_state *st;
if ((st = (struct _icv_state *)malloc(sizeof (struct _icv_state)))
== NULL)
return ((void *)ERR_RETURN);
st->_st_cset = CS_0;
return (st);
}
void
_icv_close(struct _icv_state *st)
{
free(st);
}
size_t
_icv_iconv(struct _icv_state *st, char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
int cset;
int stat = ST_INIT;
unsigned char *ip, ic;
char *op;
size_t ileft, oleft;
size_t retval;
if ((inbuf == NULL) || (*inbuf == NULL)) {
if ((st->_st_cset == CS_1) || (st->_st_cset == CS_3)) {
if ((outbuf != NULL) && (*outbuf != NULL)
&& (outbytesleft != NULL)) {
op = *outbuf;
oleft = *outbytesleft;
if (oleft < SEQ_SBTOG0) {
errno = E2BIG;
return ((size_t)-1);
}
PUT(ESC);
PUT(SBTOG0_1);
PUT(F_X0201_RM);
*outbuf = op;
*outbytesleft = oleft;
}
st->_st_cset = CS_0;
} else if (st->_st_cset == CS_2) {
if ((outbuf != NULL) && (*outbuf != NULL)
&& (outbytesleft != NULL)) {
op = *outbuf;
oleft = *outbytesleft;
if (oleft < SEQ_SOSI) {
errno = E2BIG;
return ((size_t)-1);
}
PUT(SI);
*outbuf = op;
*outbytesleft = oleft;
}
st->_st_cset = CS_0;
}
return ((size_t)0);
}
cset = st->_st_cset;
ip = (unsigned char *)*inbuf;
op = *outbuf;
ileft = *inbytesleft;
oleft = *outbytesleft;
while ((int)ileft > 0) {
GET(ic);
if ((stat == ST_INCS1) || (stat == ST_INCS3)) {
ic = sjtojis2[ic];
PUT(ic);
stat = ST_INIT;
continue;
} else if (ISASC((int)ic)) {
if ((cset == CS_1) || (cset == CS_3)) {
CHECK2BIG(SEQ_SBTOG0,1);
PUT(ESC);
PUT(SBTOG0_1);
PUT(F_X0201_RM);
} else if (cset == CS_2) {
CHECK2BIG(SEQ_SOSI,1);
PUT(SI);
}
cset = CS_0;
CHECK2BIG(JISW0,1);
PUT(ic);
continue;
} else if (ISSJKANA(ic)) {
if ((cset == CS_1) || (cset == CS_3)) {
CHECK2BIG(SEQ_SBTOG0,1);
cset = CS_0;
PUT(ESC);
PUT(SBTOG0_1);
PUT(F_X0201_RM);
}
if (cset != CS_2) {
CHECK2BIG(SEQ_SOSI,1);
cset = CS_2;
PUT(SO);
}
CHECK2BIG(JISW2,1);
stat = ST_INIT;
PUT(ic & CMASK);
continue;
} else if (ISSJKANJI1(ic)) {
if ((int)ileft > 0) {
if (ISSJKANJI2(*ip)) {
if (cset == CS_2) {
cset = CS_0;
PUT(SI);
}
if (cset != CS_1) {
CHECK2BIG(SEQ_MBTOG0_O,1);
cset = CS_1;
PUT(ESC);
PUT(MBTOG0_1);
PUT(F_X0208_83_90);
}
CHECK2BIG(JISW1,1);
stat = ST_INCS1;
ic = sjtojis1[(ic - 0x80)];
if (*ip >= 0x9f) {
ic++;
}
PUT(ic);
continue;
} else {
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else {
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (ISSJSUPKANJI1(ic)) {
if ((int)ileft > 0) {
if (ISSJKANJI2(*ip)) {
if (cset == CS_2) {
cset = CS_0;
PUT(SI);
}
if (cset != CS_3) {
CHECK2BIG(SEQ_MBTOG0,1);
cset = CS_3;
PUT(ESC);
PUT(MBTOG0_1);
PUT(MBTOG0_2);
PUT(F_X0212_90);
}
CHECK2BIG(JISW3,1);
stat = ST_INCS3;
ic = sjtojis1[(ic - 0x80)];
if (*ip >= 0x9f) {
ic++;
}
PUT(ic);
continue;
} else {
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else {
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (ISSJIBM(ic) ||
ISSJNECIBM(ic)) {
if ((int)ileft > 0) {
if (ISSJKANJI2(*ip)) {
unsigned short dest;
dest = (ic << 8);
GET(ic);
dest += ic;
if (cset == CS_2) {
cset = CS_0;
PUT(SI);
}
if ((0xed40 <= dest) &&
(dest <= 0xeffc)) {
REMAP_NEC(dest);
if (dest == 0xffff) {
goto ill_ibm;
}
}
if ((cset != CS_1) &&
((dest == 0xfa54) ||
(dest == 0xfa5b))) {
CHECK2BIG(SEQ_MBTOG0_O,2);
cset = CS_1;
PUT(ESC);
PUT(MBTOG0_1);
PUT(F_X0208_83_90);
CHECK2BIG(JISW1,2);
if (dest == 0xfa54) {
PUT(0x22);
PUT(0x4c);
} else {
PUT(0x22);
PUT(0x68);
}
continue;
}
if (cset != CS_3) {
CHECK2BIG(SEQ_MBTOG0,2);
cset = CS_3;
PUT(ESC);
PUT(MBTOG0_1);
PUT(MBTOG0_2);
PUT(F_X0212_90);
}
CHECK2BIG(JISW3,2);
dest = dest - 0xfa40 -
(((dest>>8) - 0xfa) * 0x40);
dest = sjtoibmext[dest];
if (dest == 0xffff) {
ill_ibm:
UNGET();
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
PUT(((dest>>8) & 0x7f));
PUT(dest & 0x7f);
continue;
} else {
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else {
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if ((0xeb <= ic) && (ic <= 0xec)) {
if ((int)ileft > 0) {
if (ISSJKANJI2(*ip)) {
if (cset == CS_2) {
cset = CS_0;
PUT(SI);
}
if (cset != CS_1) {
CHECK2BIG(SEQ_MBTOG0_O,1);
cset = CS_1;
PUT(ESC);
PUT(MBTOG0_1);
PUT(F_X0208_83_90);
}
CHECK2BIG(JISW1,1);
GET(ic);
PUT((JGETA>>8) & CMASK);
PUT(JGETA & CMASK);
continue;
} else {
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else {
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else {
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
}
retval = ileft;
ret:
*inbuf = (char *)ip;
*inbytesleft = ileft;
*outbuf = op;
*outbytesleft = oleft;
st->_st_cset = cset;
return (retval);
}