#include <errno.h>
#include "ktable.h"
#include "hangulcode.h"
static unsigned short _wansung_to_johap92(unsigned short code);
void* _icv_open()
{
return((void*)MAGIC_NUMBER);
}
void _icv_close(int* cd)
{
if (!cd || cd != (int*)MAGIC_NUMBER)
errno = EBADF;
}
size_t _icv_iconv(int* 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 || cd != (int*)MAGIC_NUMBER)
{
errno = EBADF;
return((size_t)-1);
}
if (!inbuf || !(*inbuf))
{
return((size_t)0);
}
ib = (unsigned char*)*inbuf;
ob = (unsigned char*)*outbuf;
ibtail = ib + *inbufleft;
obtail = ob + *outbufleft;
while (ib < ibtail)
{
if (!(*ib & 0x80))
{
if (ob >= obtail)
{
errno = E2BIG;
ret_val = (size_t)-1;
break;
}
*ob++ = *ib++;
}
else
{
unsigned short code;
if ((ibtail - ib) < 2)
{
errno = EINVAL;
ret_val = (size_t)-1;
break;
}
if ((obtail - ob) < 2)
{
errno = E2BIG;
ret_val = (size_t)-1;
break;
}
code = _wansung_to_johap92((unsigned short)(*ib)<<8 |
(unsigned short)(*(ib + 1)));
if (code != FAILED && code != ILLEGAL_SEQ)
{
*ob++ = (unsigned char)(code >> 8);
*ob++ = (unsigned char)(code & 0xFF);
}
else
{
*ob++ = NON_IDENTICAL;
*ob++ = NON_IDENTICAL;
}
ib += 2;
}
}
*inbuf = (char*)ib;
*inbufleft = ibtail - ib;
*outbuf = (char*)ob;
*outbufleft = obtail - ob;
return(ret_val);
}
static unsigned short _wansung_to_johap92(unsigned short code)
{
register unsigned short jc, jc2;
register short h, i, l;
short ci, v, cf;
short disp;
long cfbit;
if ((unsigned short)(code & 0xFF) < 0xA1)
return(ILLEGAL_SEQ);
if (code >= 0xB0A1 && code <= 0xC8FE)
{
for (h = CI_CNT, l = 0; ; )
{
ci = (l + h) / 2;
if (l >= h)
break;
if (code < cmp_srchtbl[ci][0])
h = ci - 1;
else if (code < cmp_srchtbl[ci + 1][0])
break;
else
l = ci + 1;
}
for (v = 1; ; )
{
if (code < cmp_srchtbl[ci][v])
{
while (!cmp_srchtbl[ci][--v])
;
break;
}
else if (v == V_CNT)
break;
v++;
}
disp = code - cmp_srchtbl[ci][v];
if (((short)(cmp_srchtbl[ci][v] & BYTE_MASK) + disp) > 0xfe)
disp -= SKIP;
for (cfbit = cmp_bitmap[ci][v], i = -1, cf = -1; i < disp; cf++)
{
if (cfbit & BIT_MASK)
i++;
cfbit >>= 1;
}
if (cf == -1)
return(FAILED);
code = ci + 2;
code = (code << 5) | (v + (v + 1) / 6 * 2 + 3);
return((code << 5) | (cf + cf / 18) | 0x8000);
}
else if (code >= 0xA1A1 && code <= 0xACFE)
{
jc = (((unsigned short)(code - 0xA100) >> 1) + 0xD900) & 0xFF00;
jc2 = code & 0xFF;
if ((unsigned short)(code >> 8) % 2)
return(jc | (jc2 - ((jc2 > 0xEE) ? 0x5E : 0x70)));
return(jc | jc2);
}
else if (code >= 0xCAA1 && code <= 0xFDFE)
{
jc = (((unsigned short)(code - 0xCA00) >> 1) + 0xE000) & 0xFF00;
jc2 = code & 0xFF;
if ((unsigned short)(code >> 8) % 2)
return(jc | jc2);
return(jc | (jc2 - ((jc2 > 0xEE) ? 0x5E : 0x70)));
}
else if ((code >= 0xC9A1 && code <= 0xC9FE) ||
(code >= 0xFEA1 && code <= 0xFEFE))
{
if ((code & 0xFF00) == 0xFE00)
return(0xD800 | (code & 0xFF));
code = code & 0xFF;
return(0xD800 | (code - ((code > 0xEE) ? 0x5E : 0x70)));
}
return(FAILED);
}