#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;
#ifdef RFC1468_MODE
unsigned short zenkaku;
#endif
if ((inbuf == NULL) || (*inbuf == NULL)) {
if (st->_st_cset != CS_0) {
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;
}
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) {
CHECK2BIG(SEQ_SBTOG0,1);
PUT(ESC);
PUT(SBTOG0_1);
PUT(F_X0201_RM);
}
cset = CS_0;
CHECK2BIG(JISW0,1);
PUT(ic);
continue;
} else if (ISSJKANA(ic)) {
#ifdef RFC1468_MODE
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);
zenkaku = halfkana2zenkakuj[ic - 0xA1];
ic = (unsigned char)((zenkaku >> 8) & CMASK);
PUT(ic);
ic = (unsigned char)(zenkaku & CMASK);
PUT(ic);
#else
if (cset != CS_2) {
CHECK2BIG(SEQ_SBTOG0,1);
cset = CS_2;
PUT(ESC);
PUT(SBTOG0_1);
PUT(F_X0201_KN);
}
CHECK2BIG(JISW2,1);
PUT(ic & CMASK);
#endif
continue;
} else if (ISSJKANJI1(ic)) {
if ((int)ileft > 0) {
if (ISSJKANJI2(*ip)) {
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);
#ifdef RFC1468_MODE
if ((ic == 0x87) || (0xed <= ic )){
PUT((JGETA >> 8) & CMASK);
GET(ic);
PUT(JGETA & CMASK);
continue;
}
#endif
ic = sjtojis1[(ic - 0x80)];
if (*ip >= 0x9f) {
ic++;
}
PUT(ic);
GET(ic);
ic = sjtojis2[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)) {
#ifdef RFC1468_MODE
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);
ic = (unsigned char)((JGETA >> 8) &
CMASK);
PUT(ic);
ic = (unsigned char)(JGETA & CMASK);
PUT(ic);
GET(ic);
#else
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);
ic = sjtojis1[(ic - 0x80)];
if (*ip >= 0x9f) {
ic++;
}
PUT(ic);
GET(ic);
ic = sjtojis2[ic];
PUT(ic);
#endif
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 ((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_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);
}