#include <stdlib.h>
#include <errno.h>
#include <euc.h>
#include "japanese.h"
#include "jfp_iconv_unicode.h"
#define JFP_J2U_ICONV_X0213
#include "jfp_jis_to_ucs2.h"
typedef struct {
unsigned char odd_row;
unsigned char even_row;
} sj1torow_t;
static const sj1torow_t sj1torow_x0213_p1b1[] = {
{ 1, 2 },
{ 3, 4 },
{ 5, 6 },
{ 7, 8 },
{ 9, 10 },
{ 11, 12 },
{ 13, 14 },
{ 15, 16 },
{ 17, 18 },
{ 19, 20 },
{ 21, 22 },
{ 23, 24 },
{ 25, 26 },
{ 27, 28 },
{ 29, 30 },
{ 31, 32 },
{ 33, 34 },
{ 35, 36 },
{ 37, 38 },
{ 39, 40 },
{ 41, 42 },
{ 43, 44 },
{ 45, 46 },
{ 47, 48 },
{ 49, 50 },
{ 51, 52 },
{ 53, 54 },
{ 55, 56 },
{ 57, 58 },
{ 59, 60 },
{ 61, 62 },
};
static const sj1torow_t sj1torow_x0213_p1b2[] = {
{ 63, 64 },
{ 65, 66 },
{ 67, 68 },
{ 69, 70 },
{ 71, 72 },
{ 73, 74 },
{ 75, 76 },
{ 77, 78 },
{ 79, 80 },
{ 81, 82 },
{ 83, 84 },
{ 85, 86 },
{ 87, 88 },
{ 89, 90 },
{ 91, 92 },
{ 93, 94 },
};
static const sj1torow_t sj1torow_x0213_p2[] = {
{ 1, 8 },
{ 3, 4 },
{ 5, 12 },
{ 13, 14 },
{ 15, 78 },
{ 79, 80 },
{ 81, 82 },
{ 83, 84 },
{ 85, 86 },
{ 87, 88 },
{ 89, 90 },
{ 91, 92 },
{ 93, 94 },
};
static unsigned short sjtoe16_x0213(unsigned char c1, unsigned char c2)
{
const sj1torow_t *p;
unsigned short e16;
if ((c1 >= 0x81) && (c1 <= 0x9f)) {
p = &(sj1torow_x0213_p1b1[c1 - 0x81]);
} else if ((c1 >= 0xe0) && (c1 <= 0xef)) {
p = &(sj1torow_x0213_p1b2[c1 - 0xe0]);
} else {
p = &(sj1torow_x0213_p2[c1 - 0xf0]);
}
if (c2 >= 0x9f) {
e16 = (p->even_row + 0xa0) << 8;
e16 |= (c2 - 0x9f + 0x21);
e16 |= (c1 <= 0xef) ? 0x0080 : 0x0000;
} else {
e16 = (p->odd_row + 0xa0) << 8;
e16 |= (c2 - 0x40 + 0x21);
if (c2 >= 0x80) {
e16--;
}
e16 |= (c1 <= 0xef) ? 0x0080 : 0x0000;
}
return (e16);
}
void *
_icv_open(void)
{
return (_icv_open_unicode((size_t)0));
}
void
_icv_close(void *cd)
{
_icv_close_unicode(cd);
return;
}
size_t
_icv_iconv(void *cd, char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
unsigned int u32;
unsigned short e16;
unsigned char ic1, ic2;
size_t rv = (size_t)0;
unsigned char *ip;
size_t ileft;
char *op;
size_t oleft;
if ((inbuf == NULL) || (*inbuf == NULL)) {
_icv_reset_unicode(cd);
return ((size_t)0);
}
ip = (unsigned char *)*inbuf;
ileft = *inbytesleft;
op = *outbuf;
oleft = *outbytesleft;
while (ileft != 0) {
NGET(ic1, "never fail here");
if (ISASC((int)ic1)) {
u32 = _jfp_tbl_jisx0201roman_to_ucs2[ic1];
PUTU(u32, "ASCII");
} else if (ISSJKANA(ic1)) {
u32 = _jfp_tbl_jisx0201kana_to_ucs2[ic1 - 0xa1];
PUTU(u32, "KANA");
} else if (((ic1 >= 0x81) && (ic1 <= 0x9f)) ||
((ic1 >= 0xe0) && (ic1 <= 0xef))) {
NGET(ic2, "PLANE1-2");
if (ISSJKANJI2(ic2)) {
e16 = sjtoe16_x0213(ic1, ic2);
u32 = (unsigned int)_jfp_tbl_jisx0208_to_ucs2[
((e16 >> 8) - 0xa1) * 94
+ ((e16 & 0xff) - 0xa1)];
if (IFHISUR(u32)) {
u32 = _jfp_lookup_x0213_nonbmp(
e16, u32);
PUTU(u32, "PLANE1->NONBMP");
} else if (u32 == 0xffff) {
unsigned int u32_2;
u32 = _jfp_lookup_x0213_compose(
e16, &u32_2);
PUTU(u32, "PLANE1->CP1");
PUTU(u32_2, "PLANE1->CP2");
} else {
PUTU(u32, "PLANE1->BMP");
}
} else {
RETERROR(EILSEQ, "PLANE1-2")
}
} else if ((ic1 >= 0xf0) && (ic1 <= 0xfc)) {
NGET(ic2, "PLANE2-2");
if (ISSJKANJI2(ic2)) {
e16 = sjtoe16_x0213(ic1, ic2);
u32 = (unsigned int)_jfp_tbl_jisx0213p2_to_ucs2[
((e16 >> 8) - 0xa1) * 94
+ ((e16 & 0xff) - 0x21)];
if (IFHISUR(u32)) {
u32 = _jfp_lookup_x0213_nonbmp(
e16, u32);
PUTU(u32, "PLANE2->NONBMP");
} else {
PUTU(u32, "PLANE2->BMP");
}
} else {
RETERROR(EILSEQ, "PLANE2-2")
}
} else {
RETERROR(EILSEQ, "EILSEQ at 1st")
}
*inbuf = (char *)ip;
*inbytesleft = ileft;
*outbuf = op;
*outbytesleft = oleft;
}
ret:
DEBUGPRINTERROR
return ((rv == (size_t)-1) ? rv : *inbytesleft);
}