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)13void* 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