diff options
author | Andrew Tridgell <tridge@samba.org> | 2011-04-28 10:50:06 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2011-04-28 03:24:06 +0200 |
commit | d17f4352fe2493be433a21e2f47453968aafdc4d (patch) | |
tree | c30bf8163f5f5bfc3d2da2a4d0f1c4f6d48a72aa | |
parent | eee1ff2fb56f46fb3c6aa7dfe51583e3b489fb5d (diff) | |
download | samba-d17f4352fe2493be433a21e2f47453968aafdc4d.tar.gz samba-d17f4352fe2493be433a21e2f47453968aafdc4d.tar.bz2 samba-d17f4352fe2493be433a21e2f47453968aafdc4d.zip |
lib/util/charset Make fast path from UTF16 to '8 bit' charsets clearer
This breaks the fast path into handling for -1 and handling for
specified lenghts, avoding branch operations on each character.
Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
Signed-off-by: Andrew Tridgell <tridge@samba.org>
-rw-r--r-- | lib/util/charset/convert_string.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/lib/util/charset/convert_string.c b/lib/util/charset/convert_string.c index 41a0c75c10..8243e63a72 100644 --- a/lib/util/charset/convert_string.c +++ b/lib/util/charset/convert_string.c @@ -178,28 +178,29 @@ bool convert_string_error_handle(struct smb_iconv_handle *ic, size_t slen = srclen; size_t dlen = destlen; unsigned char lastp = '\0'; + bool ret; - /* If all characters are ascii, fast path here. */ - while (((slen == (size_t)-1) || (slen >= 1)) && dlen) { - if (slen >= 2 && ((lastp = *p) <= 0x7f) && (p[1] == 0)) { + if (slen == (size_t)-1) { + while (dlen && + ((lastp = *p) <= 0x7f) && (p[1] == 0)) { *q++ = *p; - if (slen != (size_t)-1) { - slen -= 2; - } p += 2; dlen--; retval++; if (!lastp) break; - } else { -#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS - goto general_case; -#else - bool ret = convert_string_internal(ic, from, to, p, slen, q, dlen, converted_size); - *converted_size += retval; - return ret; -#endif } + if (lastp != 0) goto slow_path; + } else { + while (slen >= 2 && dlen && + (*p <= 0x7f) && (p[1] == 0)) { + *q++ = *p; + slen -= 2; + p += 2; + dlen--; + retval++; + } + if (slen != 0) goto slow_path; } *converted_size = retval; @@ -213,6 +214,19 @@ bool convert_string_error_handle(struct smb_iconv_handle *ic, } } return true; + + slow_path: + /* come here when we hit a character we can't deal + * with in the fast path + */ +#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS + goto general_case; +#else + ret = convert_string_internal(ic, from, to, p, slen, q, dlen, converted_size); + *converted_size += retval; + return ret; +#endif + } else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) { const unsigned char *p = (const unsigned char *)src; unsigned char *q = (unsigned char *)dest; |