diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-10-07 11:19:00 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-10-07 11:19:00 +0100 |
commit | e0eda4422521a57230d3b1d84152bc6218932d28 (patch) | |
tree | 609b5bf57c71f0a1d5fe8bfed6523344ec2584c6 /src/libutil/fstring.c | |
parent | 4e7e96c138779a2db2cdc8e688ec291abfac36df (diff) | |
download | rspamd-e0eda4422521a57230d3b1d84152bc6218932d28.tar.gz rspamd-e0eda4422521a57230d3b1d84152bc6218932d28.zip |
Add fixed strings comparision routines.
Diffstat (limited to 'src/libutil/fstring.c')
-rw-r--r-- | src/libutil/fstring.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/libutil/fstring.c b/src/libutil/fstring.c index 6a1304423..a03121f42 100644 --- a/src/libutil/fstring.c +++ b/src/libutil/fstring.c @@ -238,3 +238,78 @@ rspamd_fstring_equal (const rspamd_fstring_t *s1, return FALSE; } + +extern const guchar lc_map[256]; + +gint +rspamd_fstring_casecmp (const rspamd_fstring_t *s1, + const rspamd_fstring_t *s2) +{ + gint ret = 0; + gsize leftover = s1->len % 4; + guint fp, i; + const uint8_t *s, *d; + guchar c1, c2, c3, c4; + union { + guchar c[4]; + guint32 n; + } cmp1, cmp2; + + g_assert (s1 != NULL && s2 != NULL); + + if (s1->len == s2->len) { + leftover = s1->len % 4; + s = (const uint8_t *) s1->str; + d = (const uint8_t *) s2->str; + fp = s1->len - leftover; + + for (i = 0; i != fp; i += 4) { + c1 = s[i], c2 = s[i + 1], c3 = s[i + 2], c4 = s[i + 3]; + cmp1.c[0] = lc_map[c1]; + cmp1.c[1] = lc_map[c2]; + cmp1.c[2] = lc_map[c3]; + cmp1.c[3] = lc_map[c4]; + + c1 = d[i], c2 = d[i + 1], c3 = d[i + 2], c4 = d[i + 3]; + cmp2.c[0] = lc_map[c1]; + cmp2.c[1] = lc_map[c2]; + cmp2.c[2] = lc_map[c3]; + cmp2.c[3] = lc_map[c4]; + + if (cmp1.n != cmp2.n) { + return cmp1.n - cmp2.n; + } + + s += 4; + d += 4; + } + + while (leftover > 0) { + if (g_ascii_tolower (*s) != g_ascii_tolower (*d)) { + return (*s) - (*d); + } + + leftover --; + s ++; + d ++; + } + } + else { + ret = s1->len - s2->len; + } + + return ret; +} + +gint +rspamd_fstring_cmp (const rspamd_fstring_t *s1, + const rspamd_fstring_t *s2) +{ + g_assert (s1 != NULL && s2 != NULL); + + if (s1->len == s2->len) { + return memcmp (s1->str, s2->str, s1->len); + } + + return s1->len - s2->len; +}
\ No newline at end of file |