From e4ee891759b08d3edb258b34f00b4ae8e3298d06 Mon Sep 17 00:00:00 2001 From: Zachary T Welch Date: Sat, 14 Nov 2009 10:27:34 -0800 Subject: improve buf_cmp and buf_cmp_mask helpers Rewrite buf_cmp to use memcpy for bulk of comparison. Add static helper to perform comparison of trailing byte, which uses another static helper to perform a maksed comparison. The masked comparison helper is used by the buf_cmp_mask to simplify its loop. Improve types to use void *, unsigned, and return bool. --- src/helper/binarybuffer.c | 73 ++++++++++++++++++++++++----------------------- src/helper/binarybuffer.h | 6 ++-- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c index 0def9485..865d3a37 100644 --- a/src/helper/binarybuffer.c +++ b/src/helper/binarybuffer.c @@ -65,52 +65,53 @@ uint8_t* buf_cpy(const uint8_t *from, uint8_t *to, int size) return to; } -int buf_cmp(const uint8_t *buf1, const uint8_t *buf2, int size) +static bool buf_cmp_masked(uint8_t a, uint8_t b, uint8_t m) { - if (!buf1 || !buf2) - return 1; + return (a & m) != (b & m); +} +static bool buf_cmp_trailing(uint8_t a, uint8_t b, uint8_t m, unsigned trailing) +{ + uint8_t mask = (1 << trailing) - 1; + return buf_cmp_masked(a, b, mask & m); +} - for (unsigned i = 0, num_bytes = CEIL(size, 8); i < num_bytes; i++) - { - /* last byte */ - /* mask out bits that don't really belong to the buffer if size isn't a multiple of 8 bits */ - if ((size % 8) && (i == num_bytes -1)) - { - if ((buf1[i] & ((1 << (size % 8)) - 1)) != (buf2[i] & ((1 << (size % 8)) - 1))) - return 1; - } - else - { - if (buf1[i] != buf2[i]) - return 1; - } - } +bool buf_cmp(const void *_buf1, const void *_buf2, unsigned size) +{ + if (!_buf1 || !_buf2) + return _buf1 != _buf2; - return 0; + unsigned last = size / 8; + if (memcmp(_buf1, _buf2, last) != 0) + return false; + + unsigned trailing = size % 8; + if (!trailing) + return false; + + const uint8_t *buf1 = _buf1, *buf2 = _buf2; + return buf_cmp_trailing(buf1[last], buf2[last], 0xff, trailing); } -int buf_cmp_mask(const uint8_t *buf1, const uint8_t *buf2, const uint8_t *mask, int size) +bool buf_cmp_mask(const void *_buf1, const void *_buf2, + const void *_mask, unsigned size) { - for (unsigned i = 0, num_bytes = CEIL(size, 8); i < num_bytes; i++) + if (!_buf1 || !_buf2) + return _buf1 != _buf2 || _buf1 != _mask; + + const uint8_t *buf1 = _buf1, *buf2 = _buf2, *mask = _mask; + unsigned last = size / 8; + for (unsigned i = 0; i < last; i++) { - /* last byte */ - /* mask out bits that don't really belong to the buffer if size isn't a multiple of 8 bits */ - if ((size % 8) && (i == num_bytes -1)) - { - if ((buf1[i] & ((1 << (size % 8)) - 1) & mask[i]) != - (buf2[i] & ((1 << (size % 8)) - 1) & mask[i])) - return 1; - } - else - { - if ((buf1[i] & mask[i]) != (buf2[i] & mask[i])) - return 1; - } + if (buf_cmp_masked(buf1[i], buf2[i], mask[i])) + return true; } - - return 0; + unsigned trailing = size % 8; + if (!trailing) + return false; + return buf_cmp_trailing(buf1[last], buf2[last], mask[last], trailing); } + uint8_t* buf_set_ones(uint8_t *buf, int count) { for (unsigned i = 0, num_bytes = CEIL(count, 8); i < num_bytes; i++) diff --git a/src/helper/binarybuffer.h b/src/helper/binarybuffer.h index 49050074..a51c2e57 100644 --- a/src/helper/binarybuffer.h +++ b/src/helper/binarybuffer.h @@ -70,9 +70,9 @@ static inline uint32_t buf_get_u32(const uint8_t* buffer, /// flip_u32 inverts the bit order inside a 32-bit word (31..0 -> 0..31) uint32_t flip_u32(uint32_t value, unsigned int num); -int buf_cmp(const uint8_t *buf1, const uint8_t *buf2, int size); -int buf_cmp_mask(const uint8_t *buf1, const uint8_t *buf2, - const uint8_t *mask, int size); +bool buf_cmp(const void *buf1, const void *buf2, unsigned size); +bool buf_cmp_mask(const void *buf1, const void *buf2, + const void *mask, unsigned size); uint8_t* buf_cpy(const uint8_t *from, uint8_t *to, int size); uint8_t* buf_set_ones(uint8_t *buf, int count); -- cgit v1.2.3