#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/isa_defs.h>
#include "common_defs.h"
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;
uchar_t *ib;
uchar_t *ob;
uchar_t *ibtail;
uchar_t *obtail;
uchar_t *ib_copy;
uint_t u4;
uint_t first_byte;
signed char sz;
signed char obsz;
if (! cd || cd != (int *)MAGIC_NUMBER) {
errno = EBADF;
return((size_t)-1);
}
if (!inbuf || !(*inbuf))
return((size_t)0);
ib = (uchar_t *)*inbuf;
ob = (uchar_t *)*outbuf;
ibtail = ib + *inbufleft;
obtail = ob + *outbufleft;
while (ib < ibtail) {
sz = number_of_bytes_in_utf8_char[*ib];
if (sz == ICV_TYPE_ILLEGAL_CHAR) {
errno = EILSEQ;
ret_val = (size_t)-1;
break;
}
obsz = sz;
if ((ibtail - ib) < sz) {
errno = EINVAL;
ret_val = (size_t)-1;
break;
}
ib_copy = ib;
first_byte = *ib_copy++;
u4 = first_byte & (uint_t)masks_tbl[sz];
for (; sz > 1; sz--) {
if (first_byte) {
if (((uchar_t)*ib_copy) <
valid_min_2nd_byte[first_byte] ||
((uchar_t)*ib_copy) >
valid_max_2nd_byte[first_byte]) {
errno = EILSEQ;
ret_val = (size_t)-1;
goto ILLEGAL_CHAR_ERR;
}
first_byte = 0;
} else if (((uint_t)*ib_copy) < 0x80 ||
((uint_t)*ib_copy) > 0xbf) {
errno = EILSEQ;
ret_val = (size_t)-1;
goto ILLEGAL_CHAR_ERR;
}
u4 = (u4 << ICV_UTF8_BIT_SHIFT) |
(((uint_t)*ib_copy) & ICV_UTF8_BIT_MASK);
ib_copy++;
}
if ((u4 & 0xffff) == 0x00fffe || (u4 & 0xffff) == 0x00ffff ||
(u4 >= 0x00fdd0 && u4 <= 0x00fdef) || u4 > 0x10fffd) {
errno = EILSEQ;
ret_val = (size_t)-1;
goto ILLEGAL_CHAR_ERR;
}
if ((obtail - ob) < obsz) {
errno = E2BIG;
ret_val = (size_t)-1;
break;
}
for (; obsz >= 1; obsz--)
*ob++ = *ib++;
}
ILLEGAL_CHAR_ERR:
*inbuf = (char *)ib;
*inbufleft = ibtail - ib;
*outbuf = (char *)ob;
*outbufleft = obtail - ob;
return(ret_val);
}