#include <stdlib.h>
#include <errno.h>
#include "ktable.h"
#include "nbyte_utf.h"
void* _icv_open()
{
_conv_desc* cd = (_conv_desc*)malloc(sizeof(_conv_desc));
if (cd == (_conv_desc*)NULL)
{
errno = ENOMEM;
return((void*)-1);
}
cd->cur_stat = 1;
cd->hbuf[1] = cd->hbuf[2] = cd->hbuf[3] = cd->hbuf[4] = '\0';
cd->cur_act = 0;
return((void*)cd);
}
void _icv_close(_conv_desc* cd)
{
if (!cd)
errno = EBADF;
else
free((void*)cd);
}
size_t _icv_iconv(_conv_desc* cd, char** inbuf, size_t* inbufleft,
char** outbuf, size_t* outbufleft)
{
size_t ret_val = 0;
unsigned char* ib;
unsigned char* ob;
unsigned char* ibtail;
unsigned char* obtail;
if (!cd)
{
errno = EBADF;
return((size_t)-1);
}
if (!inbuf || !(*inbuf))
{
cd->cur_stat = 1;
cd->hbuf[1] = cd->hbuf[2] = cd->hbuf[3] = cd->hbuf[4] = '\0';
cd->cur_act = 0;
return((size_t)0);
}
ib = (unsigned char*)*inbuf;
ob = (unsigned char*)*outbuf;
ibtail = ib + *inbufleft;
obtail = ob + *outbufleft;
while (ib < ibtail)
{
int cur_input, action, state;
unsigned long ci, v, cf;
char result;
int input_conv(char);
unsigned short make_johap_code(int, char*);
extern char _johap_to_utf8(unsigned long*, unsigned long*,
unsigned long*, unsigned short);
cur_input = input_conv(*ib);
action = next_act[cd->cur_stat][cur_input];
state = next_stat[cd->cur_stat][cur_input];
if (action == 4)
{
if (ob >= obtail)
{
errno = E2BIG;
ret_val = (size_t)-1;
break;
}
*ob++ = *ib;
}
else if (action >= 5 && action <= 8)
cd->hbuf[action - 4] = *ib;
else if (action == 9)
{
ADD_CONVERTED_CODE(0, 0);
cd->hbuf[1] = *ib;
}
else if (action == 10)
{
ADD_CONVERTED_CODE(0, 0);
cd->hbuf[2] = *ib;
ADD_CONVERTED_CODE(0, 0);
}
else if (action == 11 || action == 12)
{
ADD_CONVERTED_CODE(0, 0);
}
else if (action == 13)
{
ADD_CONVERTED_CODE(0, 1);
*ob++ = *ib;
}
else if (action == 14)
{
register char c1 = cd->hbuf[2], c2 = *ib;
if (c1 == 'l' && c2 == 'b')
cd->hbuf[2] = 'm';
else if (c1 == 'l' && c2 == 'c')
cd->hbuf[2] = 'n';
else if (c1 == 'l' && c2 == '|')
cd->hbuf[2] = 'o';
else if (c1 == 's' && c2 == 'f')
cd->hbuf[2] = 't';
else if (c1 == 's' && c2 == 'g')
cd->hbuf[2] = 'u';
else if (c1 == 's' && c2 == '|')
cd->hbuf[2] = 'v';
else if (c1 == 'z' && c2 == '|')
cd->hbuf[2] = '{';
else
cd->hbuf[2] = *ib;
}
else if (action == 15)
{
cd->hbuf[2] = *ib;
ADD_CONVERTED_CODE(0, 0);
}
else if (action == 16)
{
ADD_CONVERTED_CODE(0, 0);
}
else if (action == 17)
{
ADD_CONVERTED_CODE(1, 0);
cd->hbuf[2] = *ib;
}
cd->cur_act = action;
cd->cur_stat = state;
ib++;
}
*inbuf = (char*)ib;
*inbufleft = ibtail - ib;
*outbuf = (char*)ob;
*outbufleft = obtail - ob;
return(ret_val);
}
int input_conv(char c)
{
switch (c)
{
case 'H':
case 'S':
case 'Y':
return(1);
case 'A':
return(2);
case 'D':
return(3);
case 'I':
return(4);
case 'R':
return(5);
case 'B':
case 'G':
case 'V':
case 'W':
case 'Z':
case '[':
return(6);
case 'U':
return(7);
case 'X':
return(8);
case '^':
return(9);
case 'Q':
case ']':
case '\\':
return(10);
case 'k':
case 'd':
case 'e':
case 'j':
case 'r':
case 'w':
return(11);
case 'b':
case 'c':
return(12);
case 'f':
case 'g':
return(13);
case '|':
return(14);
case 'l':
return(15);
case 's':
return(16);
case 'z':
return(17);
case '\016':
return(18);
case '\017':
case '\024':
return(19);
default:
return(20);
}
}
unsigned short make_johap_code(int n, char* temp)
{
register unsigned short code = 0;
char save ='\0';
if (n == 1)
{
if (temp[4] == '\0')
{
save = temp[3];
temp[3] = '\0';
}
else
{
save = temp[4];
temp[4] = '\0';
}
}
code = (temp[1] >= 'A' && temp[1] <= '^') ?
(unsigned short)X32_19[temp[1] - '@']
: (unsigned short)9;
code = (code << 5) | (unsigned short)((temp[2] >= 'b' &&
temp[2] <= '|') ? X32_21[temp[2] - '`']
: 1);
code = (code << 5) | (unsigned short)((temp[3] >= 'A' &&
temp[3] <= '^') ? X32_28[temp[3] - '@']
: 1);
if (temp[4] >= 'A')
{
if (temp[3] == 'A' && temp[4] == 'U')
code += 2;
else if (temp[3] == 'D' && temp[4] == 'X')
code++;
else if (temp[3] == 'D' && temp[4] == '^')
code += 2;
else if (temp[3] == 'I' && temp[4] == 'A')
code++;
else if (temp[3] == 'I' && temp[4] == 'Q')
code += 2;
else if (temp[3] == 'I' && temp[4] == 'R')
code += 3;
else if (temp[3] == 'I' && temp[4] == 'U')
code += 4;
else if (temp[3] == 'I' && temp[4] == '\\')
code += 5;
else if (temp[3] == 'I' && temp[4] == ']')
code += 6;
else if (temp[3] == 'I' && temp[4] == '^')
code += 7;
else if (temp[3] == 'R' && temp[4] == 'U')
code++;
else if (temp[3] == 'U' && temp[4] == 'U')
code++;
}
temp[1] = (n == 1) ? save : '\0';
temp[2] = temp[3] = temp[4] = '\0';
return(code | 0x8000);
}