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 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