1 #include <string.h>
2 
3 #include <limits.h>
4 #include <zircon/compiler.h>
5 #include <stdint.h>
6 
7 #define SS (sizeof(size_t))
8 #define ALIGN (sizeof(size_t) - 1)
9 #define ONES ((size_t)-1 / UCHAR_MAX)
10 #define HIGHS (ONES * (UCHAR_MAX / 2 + 1))
11 #define HASZERO(x) (((x)-ONES) & ~(x)&HIGHS)
12 
memchr(const void * src,int c,size_t n)13 void* memchr(const void* src, int c, size_t n) {
14     const unsigned char* s = src;
15     c = (unsigned char)c;
16     for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--)
17         ;
18     if (n && *s != c) {
19         const size_t* w = (const void*)s;
20 #if !__has_feature(address_sanitizer)
21         // This reads past the end of the string, which is usually OK since
22         // it won't cross a page boundary.  But under ASan, even one byte
23         // past the actual end is diagnosed.
24         size_t k = ONES * c;
25         while (n >= SS && !HASZERO(*w ^ k)) {
26             ++w;
27             n -= SS;
28         }
29 #endif
30         for (s = (const void*)w; n && *s != c; s++, n--)
31             ;
32     }
33     return n ? (void*)s : 0;
34 }
35