damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

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 }