#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <euc.h>
#include "japanese.h"
struct _icv_state {
int _st_cset;
int _st_cset_sav;
};
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 = st->_st_cset_sav = 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 *op;
char *ip, ic;
size_t ileft, oleft;
size_t retval;
#ifdef RFC1468_MODE
unsigned short zenkaku;
#endif
if ((inbuf == NULL) || (*inbuf == NULL)) {
st->_st_cset_sav = st->_st_cset = CS_0;
return ((size_t)0);
}
cset = st->_st_cset;
ip = *inbuf;
op = (unsigned char *)*outbuf;
ileft = *inbytesleft;
oleft = *outbytesleft;
while ((int)ileft > 0) {
GET(ic);
if (stat == ST_INIT) {
goto text;
}
if (stat == ST_ESC) {
if (ic == MBTOG0_1) {
if ((int)ileft > 0) {
stat = ST_MBTOG0_1;
continue;
} else {
UNGET();
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (ic == SBTOG0_1) {
if ((int)ileft > 0) {
stat = ST_SBTOG0;
continue;
} else {
UNGET();
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (ic == X208REV_1) {
if ((int)ileft > 0) {
stat = ST_208REV_1;
continue;
} else {
UNGET();
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else {
UNGET();
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (stat == ST_MBTOG0_1) {
if ((ic == F_X0208_83_90) || (ic == F_X0208_78)) {
stat = ST_INIT;
st->_st_cset_sav = cset = CS_1;
continue;
} else if (ic == MBTOG0_2) {
if ((int)ileft > 0) {
stat = ST_MBTOG0_2;
continue;
} else {
UNGET();
UNGET();
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (ic == F_X0212_90) {
stat = ST_INIT;
st->_st_cset_sav = cset = CS_3;
continue;
} else {
UNGET();
UNGET();
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (stat == ST_MBTOG0_2) {
if ((ic == F_X0208_83_90) || (ic == F_X0208_78)) {
stat = ST_INIT;
st->_st_cset_sav = cset = CS_1;
continue;
} else if (ic == F_X0212_90) {
stat = ST_INIT;
st->_st_cset_sav = cset = CS_3;
continue;
} else {
UNGET();
UNGET();
UNGET();
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (stat == ST_SBTOG0) {
if ((ic == F_ASCII) ||
(ic == F_X0201_RM) ||
(ic == F_ISO646)) {
stat = ST_INIT;
st->_st_cset_sav = cset = CS_0;
continue;
} else if (ic == F_X0201_KN) {
stat = ST_INIT;
st->_st_cset_sav = cset = CS_2;
continue;
} else {
UNGET();
UNGET();
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (stat == ST_208REV_1) {
if (ic == X208REV_2) {
if ((int)ileft > 0) {
stat = ST_208REV_2;
continue;
} else {
UNGET();
UNGET();
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else {
UNGET();
UNGET();
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (stat == ST_208REV_2) {
if (ic == ESC) {
if ((int)ileft > 0) {
stat = ST_REV_AFT_ESC;
continue;
} else {
UNGET();
UNGET();
UNGET();
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else {
UNGET();
UNGET();
UNGET();
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (stat == ST_REV_AFT_ESC) {
if (ic == MBTOG0_1) {
if ((int)ileft > 0) {
stat = ST_REV_AFT_MBTOG0_1;
continue;
} else {
UNGET();
UNGET();
UNGET();
UNGET();
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else {
UNGET();
UNGET();
UNGET();
UNGET();
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (stat == ST_REV_AFT_MBTOG0_1) {
if (ic == F_X0208_83_90) {
stat = ST_INIT;
st->_st_cset_sav = cset = CS_1;
continue;
} else if (ic == MBTOG0_2) {
if ((int)ileft > 0) {
stat = ST_REV_AFT_MBTOG0_2;
continue;
} else {
UNGET();
UNGET();
UNGET();
UNGET();
UNGET();
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else {
UNGET();
UNGET();
UNGET();
UNGET();
UNGET();
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (stat == ST_REV_AFT_MBTOG0_2) {
if (ic == F_X0208_83_90) {
stat = ST_INIT;
st->_st_cset_sav = cset = CS_1;
continue;
} else {
UNGET();
UNGET();
UNGET();
UNGET();
UNGET();
UNGET();
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
}
text:
if (ic == ESC) {
if ((int)ileft > 0) {
stat = ST_ESC;
continue;
} else {
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (ic == SO) {
cset = CS_2;
stat = ST_INIT;
continue;
} else if (ic == SI) {
cset = st->_st_cset_sav;
stat = ST_INIT;
continue;
} else if (!(ic & CMSB)) {
if (cset == CS_0) {
CHECK2BIG(EUCW0, 1);
PUT(ic);
continue;
} else if (cset == CS_1) {
if ((int)ileft > 0) {
CHECK2BIG(EUCW1, 1);
if ((ic < 0x21) || (ic == 0x7f)) {
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
} else if ((*ip < 0x21) || (*ip ==
0x7f)) {
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
#ifdef RFC1468_MODE
if ((ic == 0x2d) || (0x75 <= ic )){
PUT((EGETA >> 8) & 0xff);
GET(ic);
PUT(EGETA & 0xff);
continue;
}
#endif
PUT(ic | CMSB);
GET(ic);
PUT(ic | CMSB);
stat = ST_INIT;
continue;
} else {
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (cset == CS_2) {
if (!ISSJKANA((ic | CMSB))) {
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
#ifdef RFC1468_MODE
CHECK2BIG(EUCW1, 1);
zenkaku = halfkana2zenkakue[(ic - 0x21)];
ic = (unsigned char)((zenkaku >> 8) & 0xFF);
PUT(ic);
ic = (unsigned char)(zenkaku & 0xFF);
PUT(ic);
#else
CHECK2BIG(EUCW2 + SEQ_SS, 1);
PUT(SS2);
PUT(ic | CMSB);
#endif
continue;
} else if (cset == CS_3) {
if ((int)ileft > 0) {
if ((ic < 0x21) || (ic == 0x7f)) {
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
} else if ((*ip < 0x21) || (*ip ==
0x7f)) {
UNGET();
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
#ifdef RFC1468_MODE
CHECK2BIG(EUCW1, 1);
PUT((EGETA >> 8) | CMSB);
GET(ic);
PUT((EGETA & CMASK) | CMSB);
#else
CHECK2BIG(EUCW3 + SEQ_SS, 1);
PUT(SS3);
PUT(ic | CMSB);
GET(ic);
PUT(ic | CMSB);
#endif
stat = ST_INIT;
continue;
} 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 = ip;
*inbytesleft = ileft;
*outbuf = (char *)op;
*outbytesleft = oleft;
st->_st_cset = cset;
return (retval);
}