diff options
author | Luo Jinghua <sunmoon1997@gmail.com> | 2010-01-08 09:03:15 +0800 |
---|---|---|
committer | Luo Jinghua <sunmoon1997@gmail.com> | 2010-01-08 09:03:15 +0800 |
commit | 38073de086b87c0589728b66cd12d2184c98a2e4 (patch) | |
tree | 12835ff8cf767365fb7452d7313a17b79376b09d | |
parent | e6912026b88e80bf93b88a41bf0af472b8a2663c (diff) |
uniconv: be compatible with iconv
-rw-r--r-- | uconv.c | 11 | ||||
-rw-r--r-- | uniconv.c | 23 | ||||
-rw-r--r-- | uniconv.h | 4 |
3 files changed, 26 insertions, 12 deletions
@@ -44,9 +44,12 @@ int main(int argc, char **argv) len = inlen = fread(inbuffer, 1, UCONV_BUFSZ, infp); while (1) { + size_t inleft = inlen; + size_t outleft = sizeof(outbuffer); + inp = inbuffer; outp = outbuffer; - ret = uniconv_conv(conv, (const char **)&inp, inlen, &outp, sizeof(outbuffer)); + ret = uniconv_conv(conv, (const char **)&inp, &inleft, &outp, &outleft); if (ret == UNICONV_EINVAL && inlen < sizeof(inbuffer)) { size_t extralen = fread(inbuffer + inlen, 1, 1, infp); if (!extralen) @@ -56,7 +59,7 @@ int main(int argc, char **argv) continue; } if (ret) { - fprintf (stderr, "Failed to convert.\n"); + fprintf (stderr, "Failed to convert: %d.\n", ret); exit(-1); break; } @@ -70,9 +73,11 @@ int main(int argc, char **argv) while (1) { char *outp; int ret; + size_t outleft; outp = outbuffer; - ret = uniconv_conv(conv, NULL, 0, &outp, sizeof(outbuffer)); + outleft = sizeof(outbuffer); + ret = uniconv_conv(conv, NULL, NULL, &outp, &outleft); if (ret < 0) { fprintf (stderr, "Failed to flush descriptor.\n"); break; @@ -89,14 +89,16 @@ uniconv_close(uniconv_t *uc) int uniconv_conv(uniconv_t *uc, const char **inbuf, - size_t inleft, + size_t *inleft, char **outbuf, - size_t outleft) + size_t *outleft) { int ret; uc_char_t local_ucs4[UNICONV_MAX_LOCAL]; uc_char_t *ucs4, *inucs4; size_t ucs4len; + const char *saved_inbuf; + const char *saved_outbuf; if (!uc) return UNICONV_EBADF; @@ -113,24 +115,31 @@ uniconv_conv(uniconv_t *uc, if (inleft < UNICONV_MAX_LOCAL) ucs4 = local_ucs4; else - ucs4 = malloc(sizeof(uc_char_t) * inleft); + ucs4 = malloc(sizeof(uc_char_t) * (*inleft)); if (!ucs4) return UNICONV_EINVAL; inucs4 = ucs4; - ucs4len = inleft; - ret = uc->from->decode(uc->from, inbuf, inleft, &inucs4, ucs4len); + ucs4len = *inleft; + saved_inbuf = *inbuf; + saved_outbuf = *outbuf; + ret = uc->from->decode(uc->from, inbuf, *inleft, &inucs4, ucs4len); + *inleft -= *inbuf - saved_inbuf; if (ret) goto error_decode; ucs4len = inucs4 - ucs4; inucs4 = ucs4; - ret = uc->to->encode(uc->to, (const ucs4_t **)&inucs4, ucs4len, outbuf, outleft); + ret = uc->to->encode(uc->to, (const ucs4_t **)&inucs4, ucs4len, + outbuf, *outleft); } else { ucs4 = NULL; /* converting pending data in buffer */ - ret = uc->to->encode(uc->to, NULL, 0, outbuf, outleft); + saved_inbuf = NULL; + saved_outbuf = *outbuf; + ret = uc->to->encode(uc->to, NULL, 0, outbuf, *outleft); } + *outleft -= *outbuf - saved_outbuf; error_decode: if (ucs4 && ucs4 != local_ucs4) @@ -56,9 +56,9 @@ extern "C" { int uniconv_conv(uniconv_t *uc, const char **inbuf, - size_t inleft, + size_t *inleft, char **outbuf, - size_t outleft); + size_t *outleft); /** * close the conversion descriptor |