#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <euc.h>
#define JFP_ICONV_STATELESS
#include "japanese.h"
static unsigned short lookuptbl(unsigned short);
void *
_icv_open(void)
{
return (_icv_open_stateless());
}
void
_icv_close(void *cd)
{
_icv_close_stateless(cd);
return;
}
size_t
_icv_iconv(void *cd, char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
int stat;
unsigned char *ip, ic, *op;
size_t ileft, oleft;
size_t retval;
stat = ST_INIT;
if ((inbuf == NULL) || (*inbuf == NULL)) {
return ((size_t)0);
}
ip = (unsigned char *)*inbuf;
op = (unsigned char *)*outbuf;
ileft = *inbytesleft;
oleft = *outbytesleft;
while ((int)ileft > 0) {
GET(ic);
if (stat == ST_INCS2) {
PUT(ic);
stat = ST_INIT;
continue;
}
if (ISASC((int)ic)) {
if (oleft < SJISW0) {
UNGET();
errno = E2BIG;
retval = (size_t)ERR_RETURN;
goto ret;
}
PUT(ic);
continue;
}
if (ISCS1(ic)) {
if ((int)ileft > 0) {
if (ISCS1(*ip)) {
int even_ku;
if (oleft < SJISW1) {
UNGET();
errno = E2BIG;
retval = (size_t)ERR_RETURN;
goto ret;
}
ic &= 0x7f;
PUT(jis208tosj1[ic]);
if ((ic % 2) == 0)
even_ku = TRUE;
else
even_ku = FALSE;
GET(ic);
ic &= 0x7f;
if (even_ku)
ic += 0x80;
PUT(jistosj2[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 (ic == SS2) {
if ((int)ileft > 0) {
if (ISCS2(*ip)) {
if (oleft < SJISW2) {
UNGET();
errno = E2BIG;
retval = (size_t)ERR_RETURN;
goto ret;
}
stat = ST_INCS2;
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 (ic == SS3) {
unsigned short dest;
if (ileft >= EUCW3) {
if (ISCS3(*ip) && ISCS3(*(ip + 1))) {
if (oleft < SJISW1) {
UNGET();
errno = E2BIG;
retval = (size_t)ERR_RETURN;
goto ret;
}
if (*ip < 0xf5) {
GET(ic);
dest = (ic << 8);
GET(ic);
dest += ic;
dest = lookuptbl(dest);
if (dest == 0xffff) {
UNGET();
UNGET();
errno = E2BIG;
retval =
(size_t)ERR_RETURN;
goto ret;
} else {
PUT((dest >> 8) &
0xff);
PUT(dest & 0xff);
}
continue;
} else {
unsigned char c1, c2;
GET(c1);
GET(c2);
c1 &= 0x7f;
c2 &= 0x7f;
if ((c1 % 2) == 0)
c2 += 0x80;
c1 = jis212tosj1[c1];
c2 = jistosj2[c2];
if ((c1 != 0xff) &&
(c2 != 0xff)) {
PUT(c1);
PUT(c2);
continue;
}
PUT((PGETA >> 8) & 0xff);
PUT(PGETA & 0xff);
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 = (char *)op;
*outbytesleft = oleft;
return (retval);
}
static unsigned short
lookuptbl(unsigned short dest)
{
unsigned short tmp;
int i;
int sz = (sizeof (sjtoibmext) / sizeof (sjtoibmext[0]));
for (i = 0; i < sz; i++) {
tmp = sjtoibmext[i];
if (tmp == dest)
return ((i + 0xfa40 + ((i / 0xc0) * 0x40)));
}
return (PGETA);
}