mem.c (2600B)
1 /* CC0 (Public domain) - see LICENSE file for details */ 2 3 #include "config.h" 4 5 #include <assert.h> 6 #include <string.h> 7 #include "mem.h" 8 9 #if !HAVE_MEMMEM 10 void *memmem(const void *haystack, size_t haystacklen, 11 const void *needle, size_t needlelen) 12 { 13 const char *p; 14 15 if (needlelen > haystacklen) 16 return NULL; 17 18 p = haystack; 19 20 for (p = haystack; 21 (p + needlelen) <= ((const char *)haystack + haystacklen); 22 p++) 23 if (memcmp(p, needle, needlelen) == 0) 24 return (void *)p; 25 26 return NULL; 27 } 28 #endif 29 30 #if !HAVE_MEMRCHR 31 void *memrchr(const void *s, int c, size_t n) 32 { 33 unsigned char *p = (unsigned char *)s; 34 35 while (n) { 36 if (p[n-1] == c) 37 return p + n - 1; 38 n--; 39 } 40 41 return NULL; 42 } 43 #endif 44 45 void *mempbrkm(const void *data_, size_t len, const void *accept_, size_t accept_len) 46 { 47 const char *data = data_, *accept = accept_; 48 size_t i, j; 49 50 for (i = 0; i < len; i++) 51 for (j = 0; j < accept_len; j++) 52 if (accept[j] == data[i]) 53 return (void *)&data[i]; 54 return NULL; 55 } 56 57 void *memcchr(void const *data, int c, size_t data_len) 58 { 59 char const *p = data; 60 size_t i; 61 62 for (i = 0; i < data_len; i++) 63 if (p[i] != c) 64 return (void *)&p[i]; 65 66 return NULL; 67 } 68 69 #define MEMSWAP_TMP_SIZE 256 70 71 void memswap(void *a, void *b, size_t n) 72 { 73 char *ap = a; 74 char *bp = b; 75 char tmp[MEMSWAP_TMP_SIZE]; 76 77 assert(!memoverlaps(a, n, b, n)); 78 79 while (n) { 80 size_t m = n > MEMSWAP_TMP_SIZE ? MEMSWAP_TMP_SIZE : n; 81 82 memcpy(tmp, bp, m); 83 memcpy(bp, ap, m); 84 memcpy(ap, tmp, m); 85 86 ap += m; 87 bp += m; 88 n -= m; 89 } 90 } 91 92 bool memeqzero(const void *data, size_t length) 93 { 94 const unsigned char *p = data; 95 size_t len; 96 97 /* Check first 16 bytes manually */ 98 for (len = 0; len < 16; len++) { 99 if (!length) 100 return true; 101 if (*p) 102 return false; 103 p++; 104 length--; 105 } 106 107 /* Now we know that's zero, memcmp with self. */ 108 return memcmp(data, p, length) == 0; 109 } 110 111 void memtaint(void *data, size_t len) 112 { 113 /* Using 16 bytes is a bit quicker than 4 */ 114 const unsigned tainter[] 115 = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }; 116 char *p = data; 117 118 while (len >= sizeof(tainter)) { 119 memcpy(p, tainter, sizeof(tainter)); 120 p += sizeof(tainter); 121 len -= sizeof(tainter); 122 } 123 memcpy(p, tainter, len); 124 125 #if HAVE_VALGRIND_MEMCHECK_H 126 VALGRIND_MAKE_MEM_UNDEFINED(data, len); 127 #endif 128 }