summaryrefslogtreecommitdiffstats
path: root/source3/lib/charcnv.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2003-09-05 21:30:50 +0000
committerJeremy Allison <jra@samba.org>2003-09-05 21:30:50 +0000
commit966b0fc7c96b1dba63fa755312a2be64e18ff471 (patch)
tree93eed4b8880005b154cb5346e20bc5fdc2a2cd31 /source3/lib/charcnv.c
parent94f59f54921174fc156fade575ca114d331b1bd8 (diff)
downloadsamba-966b0fc7c96b1dba63fa755312a2be64e18ff471.tar.gz
samba-966b0fc7c96b1dba63fa755312a2be64e18ff471.tar.xz
samba-966b0fc7c96b1dba63fa755312a2be64e18ff471.zip
More cachegrind tuning, plus fix an error message.
Jeremy. (This used to be commit 8cb9ec5d533085d40fc6bfe4ca9647d80bf41ac7)
Diffstat (limited to 'source3/lib/charcnv.c')
-rw-r--r--source3/lib/charcnv.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index ceb9d57fc71..5a922e226ce 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -511,22 +511,43 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
char *strdup_upper(const char *s)
{
- size_t size;
- wpstring buffer;
pstring out_buffer;
-
- size = convert_string(CH_UNIX, CH_UCS2, s, -1, buffer, sizeof(buffer));
- if (size == -1) {
- return NULL;
+ const unsigned char *p = (const unsigned char *)s;
+ unsigned char *q = (unsigned char *)out_buffer;
+
+ /* this is quite a common operation, so we want it to be
+ fast. We optimise for the ascii case, knowing that all our
+ supported multi-byte character sets are ascii-compatible
+ (ie. they match for the first 128 chars) */
+
+ while (1) {
+ if (*p & 0x80)
+ break;
+ *q++ = toupper(*p);
+ if (!*p)
+ break;
+ p++;
+ if (p - ( const unsigned char *)s >= sizeof(pstring))
+ break;
}
- strupper_w(buffer);
+ if (*p) {
+ /* MB case. */
+ size_t size;
+ wpstring buffer;
+ size = convert_string(CH_UNIX, CH_UCS2, s, -1, buffer, sizeof(buffer));
+ if (size == -1) {
+ return NULL;
+ }
+
+ strupper_w(buffer);
- size = convert_string(CH_UCS2, CH_UNIX, buffer, sizeof(buffer), out_buffer, sizeof(out_buffer));
- if (size == -1) {
- return NULL;
+ size = convert_string(CH_UCS2, CH_UNIX, buffer, sizeof(buffer), out_buffer, sizeof(out_buffer));
+ if (size == -1) {
+ return NULL;
+ }
}
-
+
return strdup(out_buffer);
}