diff options
author | Luo Jinghua <sunmoon1997@gmail.com> | 2010-01-07 23:00:22 +0800 |
---|---|---|
committer | Luo Jinghua <sunmoon1997@gmail.com> | 2010-01-07 23:00:22 +0800 |
commit | 8e2d99abd7bb55112898bd90e3affb660b4915a0 (patch) | |
tree | ca216b6fde912109edadafe8ebefa0cbefaf306d /uniconv.c | |
parent | 601fa11a8eba8d032c1491f79d0974f24fba7613 (diff) |
uniconv: try to improve the interface
Diffstat (limited to 'uniconv.c')
-rw-r--r-- | uniconv.c | 50 |
1 files changed, 30 insertions, 20 deletions
@@ -101,28 +101,38 @@ uniconv_conv(uniconv_t *uc, if (!uc) return UNICONV_EBADF; - if (!inbuf || !outbuf) - return UNICONV_EINVAL; - - if (inleft < UNICONV_MAX_LOCAL) - ucs4 = local_ucs4; - else - 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); - if (ret) - goto error_decode; - - ucs4len = inucs4 - ucs4; - inucs4 = ucs4; - ret = uc->to->encode(uc->to, (const ucs4_t **)&inucs4, ucs4len, outbuf, outleft); + /* reset converter */ + if (!inbuf && !outbuf) { + converter_reset(uc->from); + converter_reset(uc->to); + return UNICONV_SUCCESS; + } + + /* converting/pushing input data */ + if (inbuf) { + if (inleft < UNICONV_MAX_LOCAL) + ucs4 = local_ucs4; + else + 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); + if (ret) + goto error_decode; + + ucs4len = inucs4 - ucs4; + inucs4 = ucs4; + ret = uc->to->encode(uc->to, (const ucs4_t **)&inucs4, ucs4len, outbuf, outleft); + } else { + /* converting pending data in buffer */ + ret = uc->to->encode(uc->to, NULL, 0, outbuf, outleft); + } error_decode: - if (ucs4 != local_ucs4) + if (ucs4 && ucs4 != local_ucs4) free (ucs4); return ret; } |