#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;
unsigned char *ip, ic;
char *op;
size_t ileft, oleft;
size_t retval;
if ((inbuf == NULL) || (*inbuf == NULL)) {
if (st->_st_cset != CS_0) {
if ((outbuf != NULL) && (*outbuf != NULL)
&& (outbytesleft != NULL)) {
op = (char *)*outbuf;
oleft = *outbytesleft;
if (oleft < SEQ_SBTOG0) {
errno = E2BIG;
return ((size_t)-1);
}
PUT(ESC);
PUT(SBTOG0_1);
PUT(F_X0201_RM);
*outbuf = (char *)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 (ISASC((int)ic)) {
if (cset != CS_0) {
if (oleft < SEQ_SBTOG0) {
UNGET();
errno = E2BIG;
retval = (size_t)ERR_RETURN;
goto ret;
}
PUT(ESC);
PUT(SBTOG0_1);
PUT(F_X0201_RM);
}
cset = CS_0;
if (oleft < JISW0) {
UNGET();
errno = E2BIG;
retval = (size_t)ERR_RETURN;
goto ret;
}
PUT(ic);
continue;
} else if (ISCS1((int)ic)) {
if ((int)ileft > 0) {
if (ISCS1(ic) && ISCS1(*ip)) {
if (cset != CS_1) {
if (oleft < SEQ_MBTOG0_O) {
UNGET();
errno = E2BIG;
retval =
(size_t)ERR_RETURN;
goto ret;
}
cset = CS_1;
PUT(ESC);
PUT(MBTOG0_1);
PUT(F_X0208_83_90);
}
if (oleft < JISW1) {
UNGET();
errno = E2BIG;
retval = (size_t)ERR_RETURN;
goto ret;
}
#ifdef RFC1468_MODE
if ((ic == 0xad) || (0xf5 <= ic )){
PUT((JGETA >> 8) & CMASK);
GET(ic);
PUT(JGETA & CMASK);
continue;
}
#endif
PUT(ic & CMASK);
GET(ic);
PUT(ic & CMASK);
continue;
} else {
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else {
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (ic == SS2) {
if ((int)ileft > 0) {
if (ISCS2(*ip)) {
#ifdef RFC1468_MODE
unsigned short zenkaku;
if (cset != CS_1) {
if (oleft < SEQ_MBTOG0_O) {
UNGET();
errno = E2BIG;
retval =
(size_t)ERR_RETURN;
goto ret;
}
PUT(ESC);
PUT(MBTOG0_1);
PUT(F_X0208_83_90);
cset = CS_1;
}
if (oleft < JISW1) {
UNGET();
errno = E2BIG;
retval = (size_t)ERR_RETURN;
goto ret;
}
GET(ic);
zenkaku = halfkana2zenkakuj[ic - 0xA1];
ic = (unsigned char)((zenkaku >> 8) &
CMASK);
PUT(ic);
ic = (unsigned char)(zenkaku & CMASK);
PUT(ic);
#else
if (cset != CS_2) {
if (oleft < SEQ_SBTOG0) {
UNGET();
errno = E2BIG;
retval =
(size_t)ERR_RETURN;
goto ret;
}
PUT(ESC);
PUT(SBTOG0_1);
PUT(F_X0201_KN);
cset = CS_2;
}
if (oleft < JISW2) {
UNGET();
errno = E2BIG;
retval = (size_t)ERR_RETURN;
goto ret;
}
GET(ic);
PUT(ic & CMASK);
#endif
continue;
} else {
errno = EILSEQ;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else {
UNGET();
errno = EINVAL;
retval = (size_t)ERR_RETURN;
goto ret;
}
} else if (ic == SS3) {
if (ileft >= EUCW3) {
if (ISCS3(*ip) && ISCS3(*(ip + 1))) {
#ifdef RFC1468_MODE
if (cset != CS_1) {
if (oleft < SEQ_MBTOG0_O) {
UNGET();
errno = E2BIG;
retval =
(size_t)ERR_RETURN;
goto ret;
}
cset = CS_1;
PUT(ESC);
PUT(MBTOG0_1);
PUT(F_X0208_83_90);
}
if (oleft < JISW1) {
UNGET();
errno = E2BIG;
retval = (size_t)ERR_RETURN;
goto ret;
}
ic = (unsigned char)((JGETA >> 8) &
CMASK);
PUT(ic);
ic = (unsigned char)(JGETA & CMASK);
PUT(ic);
GET(ic);
GET(ic);
#else
if (cset != CS_3) {
if (oleft < SEQ_MBTOG0) {
UNGET();
errno = E2BIG;
retval =
(size_t)ERR_RETURN;
goto ret;
}
cset = CS_3;
PUT(ESC);
PUT(MBTOG0_1);
PUT(MBTOG0_2);
PUT(F_X0212_90);
}
if (oleft < JISW3) {
UNGET();
errno = E2BIG;
retval = (size_t)ERR_RETURN;
goto ret;
}
GET(ic);
PUT(ic & CMASK);
GET(ic);
PUT(ic & CMASK);
#endif
continue;
} else {
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);
}