summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2010-01-08 17:05:16 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2010-01-08 17:05:16 +0800
commitc414f6a2d9a941dcf267568124cf69650e7d62c1 (patch)
treea4a43def342e019acf7306b9df2660fba00e406e
parent40a8d01cadadbebbb27b1294aa7ee768d83c4e2e (diff)
uniconv: optimize the uniconv_conv
-rw-r--r--uniconv.c25
1 files changed, 10 insertions, 15 deletions
diff --git a/uniconv.c b/uniconv.c
index e73efa7..9987130 100644
--- a/uniconv.c
+++ b/uniconv.c
@@ -8,6 +8,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <assert.h>
struct _uniconv {
struct converter *from;
@@ -117,24 +118,18 @@ uniconv_conv(uniconv_t *uc,
saved_outbuf = *outbuf;
ret = UNICONV_SUCCESS;
while (*inleft) {
- size_t i = 0;
+ size_t left = 0;
const char *abuf;
const char *aoutbuf;
- /* decode a char at a time */
- for (i = 1; i <= *inleft; i++) {
- ucsbuf = &ucs4;
- abuf = *inbuf;
- ret = uc->from->decode(uc->from, &abuf, i, &ucsbuf, 1);
- if (ret < 0 && ret == UNICONV_EINVAL)
- continue;
- break;
- }
- if (ret == UNICONV_E2BIG)
- ret = UNICONV_EILSEQ;
- if (ret < 0)
+ ucsbuf = &ucs4;
+ abuf = *inbuf;
+ left = *inleft;
+ ret = uc->from->decode(uc->from, &abuf, left, &ucsbuf, 1);
+ if (ret < 0 && ret != UNICONV_E2BIG)
return ret;
+ assert (ucsbuf - &ucs4 > 0 && ucsbuf - &ucs4 <= 1);
ucs4len = ucsbuf - &ucs4;
ucsbuf = &ucs4;
aoutbuf = *outbuf;
@@ -143,8 +138,8 @@ uniconv_conv(uniconv_t *uc,
*outleft -= *outbuf - aoutbuf;
if (ret < 0)
break;
- *inleft -= i;
- (*inbuf) += i;
+ *inleft -= abuf - *inbuf;
+ (*inbuf) = abuf;
}
} else {
/* converting pending data in buffer */