summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
authorArno Töll <arno@debian.org>2013-10-15 20:19:04 +0200
committerArno Töll <arno@debian.org>2013-10-15 20:19:04 +0200
commit1380410981681f011377225708e9c530330fd5a0 (patch)
tree7dd371bc4cac8910130e4ee0f4508bc519f1778d /src/buffer.c
parent5b23e76990e58208a01c2a5362362575bc12b397 (diff)
downloadlighttpd-upstream.tar.gz
Imported Upstream version 1.4.33upstream/1.4.33upstream
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c75
1 files changed, 29 insertions, 46 deletions
diff --git a/src/buffer.c b/src/buffer.c
index cff44fe..eea7041 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -7,6 +7,11 @@
#include <assert.h>
#include <ctype.h>
+#if defined HAVE_STDINT_H
+# include <stdint.h>
+#elif defined HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
static const char hex_chars[] = "0123456789abcdef";
@@ -533,60 +538,38 @@ int buffer_is_equal_string(buffer *a, const char *s, size_t b_len) {
return buffer_is_equal(a, &b);
}
-/* simple-assumption:
- *
- * most parts are equal and doing a case conversion needs time
- *
- */
-int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len) {
- size_t ndx = 0, max_ndx;
- size_t *al, *bl;
- size_t mask = sizeof(*al) - 1;
-
- al = (size_t *)a;
- bl = (size_t *)b;
+/* buffer_is_equal_caseless_string(b, CONST_STR_LEN("value")) */
+int buffer_is_equal_caseless_string(buffer *a, const char *s, size_t b_len) {
+ if (a->used != b_len + 1) return 0;
- /* is the alignment correct ? */
- if ( ((size_t)al & mask) == 0 &&
- ((size_t)bl & mask) == 0 ) {
-
- max_ndx = ((a_len < b_len) ? a_len : b_len) & ~mask;
-
- for (; ndx < max_ndx; ndx += sizeof(*al)) {
- if (*al != *bl) break;
- al++; bl++;
-
- }
-
- }
-
- a = (char *)al;
- b = (char *)bl;
-
- max_ndx = ((a_len < b_len) ? a_len : b_len);
+ return (0 == strcasecmp(a->ptr, s));
+}
- for (; ndx < max_ndx; ndx++) {
- int a1 = *a++, b1 = *b++;
+int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len) {
+ size_t const len = (a_len < b_len) ? a_len : b_len;
+ size_t i;
- if (a1 != b1) {
- /* always lowercase for transitive results */
- if (a1 >= 'A' && a1 <= 'Z') a1 |= 32;
- if (b1 >= 'A' && b1 <= 'Z') b1 |= 32;
+ for (i = 0; i < len; ++i) {
+ unsigned char ca = a[i], cb = b[i];
+ if (ca == cb) continue;
+
+ /* always lowercase for transitive results */
+#if 1
+ if (ca >= 'A' && ca <= 'Z') ca |= 32;
+ if (cb >= 'A' && cb <= 'Z') cb |= 32;
+#else
+ /* try to produce code without branching (jumps) */
+ ca |= ((unsigned char)(ca - (unsigned char)'A') <= (unsigned char)('Z' - 'A')) ? 32 : 0;
+ cb |= ((unsigned char)(cb - (unsigned char)'A') <= (unsigned char)('Z' - 'A')) ? 32 : 0;
+#endif
- if ((a1 - b1) != 0) return (a1 - b1);
- }
+ if (ca == cb) continue;
+ return ca - cb;
}
-
- /* all chars are the same, and the length match too
- *
- * they are the same */
if (a_len == b_len) return 0;
-
- /* if a is shorter then b, then b is larger */
- return (a_len - b_len);
+ return a_len - b_len;
}
-
/**
* check if the rightmost bytes of the string are equal.
*