Example #1
0
 /* Detect whether the character used to fill mask is in X */
#define DETECTCHAR(X,MASK) (DETECTNULL(X^MASK))
#endif /* OPTIMIZED_FOR_SIZE */
static char *
strchr (const char *s, int c)
{
  char pc = (char) c;
#ifndef OPTIMIZED_FOR_SIZE
  unsigned long *ps, mask = 0;
  size_t i;

  /* If s is unaligned, punt into the byte search loop.  This should be
     rare.  */
  if (!UNALIGNED (s))
    {
      ps = (unsigned long *) s;
      for (i = 0; i < sizeof (unsigned long); i++)
        mask =
          ((mask << CHAR_BIT) + ((unsigned char) pc & ~(~0 << CHAR_BIT)));
      /* Move ps a block at a time. */
      while (!DETECTNULL (*ps) && !DETECTCHAR (*ps, mask))
        ps++;
      /* Pick up any residual with a byte searcher.  */
      s = (char *) ps;
    }
#endif
  /* The normal byte-search loop.  */
  while (*s && *s != pc)
    s++;
  return *s == pc ? (char *) s : 0;
}
Example #2
0
/**
 * memchr - Find a character in an area of memory.
 * @s: The memory area
 * @c: The byte to search for
 * @n: The size of the area.
 *
 * returns the address of the first occurrence of @c, or %NULL
 * if @c is not found
 */
void *memchr(const void *s, int c, size_t n)
{
	const unsigned char *src = (const unsigned char *) s;
	unsigned char d = c;

#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
	unsigned long *asrc;
	unsigned long  mask;
	int i;

	while (UNALIGNED(src)) {
		if (!n--)
			return NULL;
		if (*src == d)
			return (void *) src;
		src++;
	}

	if (!TOO_SMALL(n)) {
		/* If we get this far, we know that length is large and src is
		   word-aligned. */
		/* The fast code reads the source one word at a time and only
		   performs the bytewise search on word-sized segments if they
		   contain the search character, which is detected by XORing
		   the word-sized segment with a word-sized block of the search
		   character and then detecting for the presence of NUL in the
		   result.  */
		asrc = (unsigned long *) src;
		mask = d << 8 | d;
		mask = mask << 16 | mask;
		for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
			mask = (mask << i) | mask;

		while (n >= LBLOCKSIZE) {
			if (DETECTCHAR(*asrc, mask))
				break;
			n -= LBLOCKSIZE;
			asrc++;
		}

		/* If there are fewer than LBLOCKSIZE characters left,
		   then we resort to the bytewise loop.  */

		src = (unsigned char *) asrc;
	}

#endif /* not PREFER_SIZE_OVER_SPEED */

	while (n--) {
		if (*src == d)
			return (void *) src;
		src++;
	}

	return NULL;
}
Example #3
0
/* Detect whether the character used to fill mask is in X */
#define DETECTCHAR(X,MASK) (DETECTNULL(X^MASK))
#endif /* OPTIMIZED_FOR_SIZE */
static char *
strchr (const char *s, int c)
{
  char pc = (char) c;
#ifndef OPTIMIZED_FOR_SIZE
  const unsigned long *ps;
  unsigned long mask = 0;
  size_t i;

  /* Special case for finding \0. */
  if (c == '\0')
    {
      while (UNALIGNED (s))
	{
	  if (*s == '\0')
	    return (char *) s;
	  ++s;
	}
      /* Operate a word at a time.  */
      ps = (const unsigned long *) s;
      while (!DETECTNULL (*ps))
	++ps;
      /* Found the end of the string.  */
      s = (const char *) ps;
      while (*s != '\0')
	++s;
      return (char *) s;
    }
  /* All other bytes.  Align the pointer, then search a long at a time.  */
  while (UNALIGNED (s))
    {
      if (*s == '\0' || *s == pc)
	return *s ? (char *) s : 0;
      ++s;
    }
  ps = (const unsigned long *) s;
  for (i = 0; i < sizeof (unsigned long); ++i)
    mask = ((mask << CHAR_BIT) + ((unsigned char) pc & ~(~0 << CHAR_BIT)));
  /* Move ps a block at a time.  */
  while (!DETECTNULL (*ps) && !DETECTCHAR (*ps, mask))
    ++ps;
  /* Pick up any residual with a byte searcher.  */
  s = (const char *) ps;
#endif                          /* OPTIMIZED_FOR_SIZE */
  /* The normal byte-search loop.  */
  while (*s && *s != pc)
    ++s;
  return *s == pc ? (char *) s : 0;
}
Example #4
0
File: strchr.c Project: bloq/ora
char *strchr(const char *s1, int i)
{
  const unsigned char *s = (const unsigned char *)s1;
  unsigned char c = i;

#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
  unsigned long mask,j;
  unsigned long *aligned_addr;

  /* Special case for finding 0.  */
  if (!c)
    {
      while (UNALIGNED (s))
        {
          if (!*s)
            return (char *) s;
          s++;
        }
      /* Operate a word at a time.  */
      aligned_addr = (unsigned long *) s;
      while (!DETECTNULL (*aligned_addr))
        aligned_addr++;
      /* Found the end of string.  */
      s = (const unsigned char *) aligned_addr;
      while (*s)
        s++;
      return (char *) s;
    }

  /* All other bytes.  Align the pointer, then search a long at a time.  */
  while (UNALIGNED (s))
    {
      if (!*s)
        return NULL;
      if (*s == c)
        return (char *) s;
      s++;
    }

  mask = c;
  for (j = 8; j < LBLOCKSIZE * 8; j <<= 1)
    mask = (mask << j) | mask;

  aligned_addr = (unsigned long *) s;
  while (!DETECTNULL (*aligned_addr) && !DETECTCHAR (*aligned_addr, mask))
    aligned_addr++;

  /* The block of bytes currently pointed to by aligned_addr
     contains either a null or the target char, or both.  We
     catch it using the bytewise search.  */

  s = (unsigned char *) aligned_addr;

#endif /* not PREFER_SIZE_OVER_SPEED */

  while (*s && *s != c)
    s++;
  if (*s == c)
    return (char *)s;
  return NULL;
}