summaryrefslogtreecommitdiff
path: root/src/helper/binarybuffer.c
diff options
context:
space:
mode:
authorZachary T Welch <zw@superlucidity.net>2009-11-14 10:27:34 -0800
committerZachary T Welch <zw@superlucidity.net>2009-11-16 00:46:33 -0800
commite4ee891759b08d3edb258b34f00b4ae8e3298d06 (patch)
treeeb7d4b3636fc25753fa48cbe643e2760a8fafe64 /src/helper/binarybuffer.c
parentd50caa97d17187ed96746cc1527e5dbf57d4a81a (diff)
downloadopenocd+libswd-e4ee891759b08d3edb258b34f00b4ae8e3298d06.tar.gz
openocd+libswd-e4ee891759b08d3edb258b34f00b4ae8e3298d06.tar.bz2
openocd+libswd-e4ee891759b08d3edb258b34f00b4ae8e3298d06.tar.xz
openocd+libswd-e4ee891759b08d3edb258b34f00b4ae8e3298d06.zip
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.
Diffstat (limited to 'src/helper/binarybuffer.c')
-rw-r--r--src/helper/binarybuffer.c73
1 files changed, 37 insertions, 36 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++)