summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2011-04-28 10:50:06 +1000
committerAndrew Bartlett <abartlet@samba.org>2011-04-28 03:24:06 +0200
commitd17f4352fe2493be433a21e2f47453968aafdc4d (patch)
treec30bf8163f5f5bfc3d2da2a4d0f1c4f6d48a72aa
parenteee1ff2fb56f46fb3c6aa7dfe51583e3b489fb5d (diff)
downloadsamba-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.c42
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;