#include "config.h"
+#include <assert.h>
#include <string.h>
#include <ccan/mem/mem.h>
return NULL;
}
#endif
+
+void *mempbrkm(const void *data_, size_t len, const void *accept_, size_t accept_len)
+{
+ const char *data = data_, *accept = accept_;
+ size_t i, j;
+
+ for (i = 0; i < len; i++)
+ for (j = 0; j < accept_len; j++)
+ if (accept[j] == data[i])
+ return (void *)&data[i];
+ return NULL;
+}
+
+void *memcchr(void const *data, int c, size_t data_len)
+{
+ char const *p = data;
+ size_t i;
+
+ for (i = 0; i < data_len; i++)
+ if (p[i] != c)
+ return (void *)&p[i];
+
+ return NULL;
+}
+
+#define MEMSWAP_TMP_SIZE 256
+
+void memswap(void *a, void *b, size_t n)
+{
+ char *ap = a;
+ char *bp = b;
+ char tmp[MEMSWAP_TMP_SIZE];
+
+ assert(!memoverlaps(a, n, b, n));
+
+ while (n) {
+ size_t m = n > MEMSWAP_TMP_SIZE ? MEMSWAP_TMP_SIZE : n;
+
+ memcpy(tmp, bp, m);
+ memcpy(bp, ap, m);
+ memcpy(ap, tmp, m);
+
+ ap += m;
+ bp += m;
+ n -= m;
+ }
+}
+
+bool memeqzero(const void *data, size_t length)
+{
+ const unsigned char *p = data;
+ size_t len;
+
+ /* Check first 16 bytes manually */
+ for (len = 0; len < 16; len++) {
+ if (!length)
+ return true;
+ if (*p)
+ return false;
+ p++;
+ length--;
+ }
+
+ /* Now we know that's zero, memcmp with self. */
+ return memcmp(data, p, length) == 0;
+}
+
+void memtaint(void *data, size_t len)
+{
+ /* Using 16 bytes is a bit quicker than 4 */
+ const unsigned tainter[]
+ = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef };
+ char *p = data;
+
+ while (len >= sizeof(tainter)) {
+ memcpy(p, tainter, sizeof(tainter));
+ p += sizeof(tainter);
+ len -= sizeof(tainter);
+ }
+ memcpy(p, tainter, len);
+
+#if HAVE_VALGRIND_MEMCHECK_H
+ VALGRIND_MAKE_MEM_UNDEFINED(data, len);
+#endif
+}