summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2010-01-08 09:03:15 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2010-01-08 09:03:15 +0800
commit38073de086b87c0589728b66cd12d2184c98a2e4 (patch)
tree12835ff8cf767365fb7452d7313a17b79376b09d
parente6912026b88e80bf93b88a41bf0af472b8a2663c (diff)
uniconv: be compatible with iconv
-rw-r--r--uconv.c11
-rw-r--r--uniconv.c23
-rw-r--r--uniconv.h4
3 files changed, 26 insertions, 12 deletions
diff --git a/uconv.c b/uconv.c
index bd7905e..57f28e1 100644
--- a/uconv.c
+++ b/uconv.c
@@ -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;
diff --git a/uniconv.c b/uniconv.c
index cb6fea2..8b3ad04 100644
--- a/uniconv.c
+++ b/uniconv.c
@@ -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)
diff --git a/uniconv.h b/uniconv.h
index b90096e..714882c 100644
--- a/uniconv.h
+++ b/uniconv.h
@@ -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