From: Willy Tarreau Date: Fri, 19 Oct 2012 13:18:06 +0000 (+0200) Subject: MINOR: chunk: provide string compare functions X-Git-Tag: v1.5-dev13~135 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad8f8e8ffb9bc619ad2e4c0783bcd744486df127;p=thirdparty%2Fhaproxy.git MINOR: chunk: provide string compare functions 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. --- diff --git a/include/common/chunk.h b/include/common/chunk.h index 75eb030573..00437d5ddb 100644 --- a/include/common/chunk.h +++ b/include/common/chunk.h @@ -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) { diff --git a/src/chunk.c b/src/chunk.c index a4cbb7d2cf..5b1552c5dc 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -124,6 +124,55 @@ int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc) return dst->len; } +/* Compares the string in chunk with the string in 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 with the string in + * 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: