I managed to clean up a large part of the code I'm planning to share via github but encountered a weird issue with length, my test string is "Testing, testing, 123" which gives me a length of 21 for the src parameter, the problem is that somehow the calculation from bytes converted results in 128, here's the problem area:
Code:
tok.src = mcc_iconv_tok_mem( tok.src, srcm->addr, srcm->size );
tok.dst = mcc_iconv_tok_mem( tok.dst, dstm->addr, dstm->size );
while ( (ret = mcc_iconv( &tok )) == ENOMEM ) {
ret = mcc_vecsize(dstv,dstm->size + MCC_BUFSIZ,sizeof(mcc_ch8_t));
if ( ret != EXIT_SUCCESS ) break;
tok.dst = mcc_iconv_tok_mem( tok.dst, dstm->addr, dstm->size );
}
mcc_getall_done:
#if 0
/* Least ideal, assumes total success */
dstv->use += srcv->use;
#elif 1
/* Slow (uses a loop with subcall) so not ideal, highest accuracy though, currently in use to verify everything else works correctly */
dstv->use = mcc_ch8len((mcc_ch8_t*)(dstm->addr));
#else
/* Should work yet somehow reults in bigger than expected length */
dstv->use += (tok.dst.done / sizeof(mcc_ch8_t));
#endif
And just in case, the mcc_iconv* functions:
Code:
MCC_ICONV_TOK mcc_iconv_new_tok( iconv_t cd ) {
MCC_ICONV_TOK tok = {0};
tok.cd = cd;
return tok;
}
MCC_ICONV_MEM mcc_iconv_tok_mem(
MCC_ICONV_MEM prv, void *src, size_t size )
{
MCC_ICONV_MEM mem = {0};
char *ptr = (char*)src;
mem.addr = &(ptr[prv.done]);
mem.left = size - prv.done;
mem.done = prv.done;
mem.size = size;
return mem;
}
int mcc_iconv( MCC_ICONV_TOK *tok ) {
int ret = EXIT_SUCCESS;
errno = ret;
if ( !tok->dst.addr || !tok->dst.left )
return ENOMEM;
if ( !tok->src.addr || !tok->src.left ) {
(void)memset( tok->dst.addr, 0, tok->dst.left );
tok->dst.left = 0;
tok->dst.done = tok->dst.size - tok->dst.left;
return EXIT_SUCCESS;
}
while ( iconv( tok->cd,
&(tok->src.addr), &(tok->src.left),
&(tok->dst.addr), &(tok->dst.left)) ) {
/* Must allow room for 21bit UTF character (4 characters)*/
if ( tok->dst.left < sizeof(mcc_utf_t) ) {
ret = ENOMEM;
break;
}
if ( errno != ret ) {
ret = errno;
errno = EXIT_SUCCESS;
break;
}
}
tok->src.done = tok->src.size - tok->src.left;
tok->dst.done = tok->dst.size - tok->dst.left;
return ret;
}