From d1415e32565fd7a61249bc6fedbc6916e6592438 Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Sat, 23 Apr 2011 17:48:23 -0400 Subject: [PATCH] Unroll the loop in encode_utf8() --- eglib/src/giconv.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/eglib/src/giconv.c b/eglib/src/giconv.c index 7a413c08d07..f509fb59a6b 100644 --- a/eglib/src/giconv.c +++ b/eglib/src/giconv.c @@ -559,49 +559,50 @@ static int encode_utf8 (gunichar c, char **outbytes, size_t *outbytesleft) { size_t outleft = *outbytesleft; - char *outptr = *outbytes; - size_t len, i; - int base; + unsigned char *outptr; + int base, n; if (c < 128UL) { base = 0; - len = 1; + n = 1; } else if (c < 2048UL) { base = 192; - len = 2; + n = 2; } else if (c < 65536UL) { base = 224; - len = 3; + n = 3; } else if (c < 2097152UL) { base = 240; - len = 4; + n = 4; } else if (c < 67108864UL) { - base = 248; - len = 5; + base = 248; + n = 5; } else if (c < 2147483648UL) { base = 252; - len = 6; + n = 6; } else { errno = EINVAL; return -1; } - if (outleft < len) { + if (outleft < n) { errno = E2BIG; return -1; } - for (i = len - 1; i > 0; i--) { - /* mask off 6 bits worth and add 128 */ - outptr[i] = 128 + (c & 0x3f); - c >>= 6; - } + outptr = (unsigned char *) *outbytes; - /* first character has a different base */ - outptr[0] = base + c; + switch (n) { + case 6: outptr[5] = (c & 0x3f) | 0x80; c >>= 6; + case 5: outptr[4] = (c & 0x3f) | 0x80; c >>= 6; + case 4: outptr[3] = (c & 0x3f) | 0x80; c >>= 6; + case 3: outptr[2] = (c & 0x3f) | 0x80; c >>= 6; + case 2: outptr[1] = (c & 0x3f) | 0x80; c >>= 6; + case 1: outptr[0] = c | base; + } - *outbytesleft = outleft - len; - *outbytes = outptr + len; + *outbytes = (char *) outptr + n; + *outbytesleft = outleft - n; return 0; } -- 2.25.1