1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
/* fast memchr -- Copyright (C) 2003 Thomas M. Ogrisegg <tom@hi-tek.fnord.at> */
#include <string.h>
#include "dietfeatures.h"
#include "dietstring.h"
#if __WORDSIZE == 64
# define MB 0x7efefefefefefeff
#else
# define MB 0x7efefeff
#endif
void *
memchr (const void *s, int c, size_t n)
{
const unsigned char *pc = (unsigned char *) s;
#ifdef WANT_SMALLER_STRING_ROUTINES
for (;n--;pc++) if (*pc == c) return ((void *) pc);
return (NULL);
#else
unsigned long l, lb, lt;
int tmp;
if ((tmp = STRALIGN(s)) || n < sizeof(unsigned long)) {
if (n < sizeof(unsigned long)) tmp = n;
for (; tmp-- && n--; pc++)
if (*pc == c)
return ((char *) pc);
if (n == (size_t) - 1)
return (NULL);
}
lb = c | c << 8;
lb |= lb << 16;
#if __WORDSIZE == 64
lb |= lb << 32;
#endif
while (n >= sizeof(unsigned long)) {
l = *(unsigned long *) pc;
lt = l ^ lb;
if ((((lt + MB) ^ ~lt) & ~MB)) {
while (l && (l & 0xff) != (unsigned long) c) l >>= 8, pc++;
if (l) return ((char *) pc);
} else
pc += sizeof(unsigned long);
n -= sizeof(unsigned long);
}
for (; n--; pc++) if (*pc == c) return ((char *) pc);
return (NULL);
#endif
}
|