]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: chunk: provide string compare functions
authorWilly Tarreau <w@1wt.eu>
Fri, 19 Oct 2012 13:18:06 +0000 (15:18 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 19 Oct 2012 13:18:06 +0000 (15:18 +0200)
It's sometimes needed to be able to compare a zero-terminated string with a
chunk, so we now have two functions to do that, one strcmp() equivalent and
one strcasecmp() equivalent.

include/common/chunk.h
src/chunk.c

index 75eb0305732c83c708aa9e7dafef8f1c5e731e10..00437d5ddbc1a7fd0d7c017711c3048a29d79539 100644 (file)
@@ -42,6 +42,8 @@ int chunk_printf(struct chunk *chk, const char *fmt, ...)
 
 int chunk_htmlencode(struct chunk *dst, struct chunk *src);
 int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc);
+int chunk_strcmp(const struct chunk *chk, const char *str);
+int chunk_strcasecmp(const struct chunk *chk, const char *str);
 
 static inline void chunk_init(struct chunk *chk, char *str, size_t size)
 {
index a4cbb7d2cf17b3cc9a76149abfb5658963b8e9fe..5b1552c5dce9bb588abab9a7b9254bb1646406ba 100644 (file)
@@ -124,6 +124,55 @@ int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc)
        return dst->len;
 }
 
+/* Compares the string in chunk <chk> with the string in <str> which must be
+ * zero-terminated. Return is the same as with strcmp(). Neither is allowed
+ * to be null.
+ */
+int chunk_strcmp(const struct chunk *chk, const char *str)
+{
+       const char *s1 = chk->str;
+       int len = chk->len;
+       int diff = 0;
+
+       do {
+               if (--len < 0)
+                       break;
+               diff = (unsigned char)*(s1++) - (unsigned char)*(str++);
+       } while (!diff);
+       return diff;
+}
+
+/* Case-insensitively compares the string in chunk <chk> with the string in
+ * <str> which must be zero-terminated. Return is the same as with strcmp().
+ * Neither is allowed to be null.
+ */
+int chunk_strcasecmp(const struct chunk *chk, const char *str)
+{
+       const char *s1 = chk->str;
+       int len = chk->len;
+       int diff = 0;
+
+       do {
+               if (--len < 0)
+                       break;
+               diff = (unsigned char)*s1 - (unsigned char)*str;
+               if (unlikely(diff)) {
+                       unsigned int l = (unsigned char)*s1;
+                       unsigned int r = (unsigned char)*str;
+
+                       l -= 'a';
+                       r -= 'a';
+
+                       if (likely(l <= (unsigned char)'z' - 'a'))
+                               l -= 'a' - 'A';
+                       if (likely(r <= (unsigned char)'z' - 'a'))
+                               r -= 'a' - 'A';
+                       diff = l - r;
+               }
+               s1++; str++;
+       } while (!diff);
+       return diff;
+}
 
 /*
  * Local variables: