summaryrefslogtreecommitdiff
path: root/uniconv.c
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2010-01-07 23:00:22 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2010-01-07 23:00:22 +0800
commit8e2d99abd7bb55112898bd90e3affb660b4915a0 (patch)
treeca216b6fde912109edadafe8ebefa0cbefaf306d /uniconv.c
parent601fa11a8eba8d032c1491f79d0974f24fba7613 (diff)
uniconv: try to improve the interface
Diffstat (limited to 'uniconv.c')
-rw-r--r--uniconv.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/uniconv.c b/uniconv.c
index 30c0f54..bbbdb2b 100644
--- a/uniconv.c
+++ b/uniconv.c
@@ -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;
}