A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 117 lines 2.8 kB view raw
1/* 2FUNCTION 3 <<memchr>>---search for character in memory 4 5INDEX 6 memchr 7 8ANSI_SYNOPSIS 9 #include <string.h> 10 void * memchr(const void *<[s1]>, int <[c]>, size_t <[n]>); 11 12TRAD_SYNOPSIS 13 #include <string.h> 14 void * memchr(<[s1]>, <[c]>, <[n]>); 15 void *<[string]>; 16 int *<[c]>; 17 size_t *<[n]>; 18 19DESCRIPTION 20 This function scans the first <[n]> bytes of the memory pointed 21 to by <[s1]> for the character <[c]> (converted to a char). 22 23RETURNS 24 Returns a pointer to the matching byte, or a null pointer if 25 <[c]> does not occur in <[s1]>. 26 27PORTABILITY 28<<memchr>> is ANSI C. 29 30<<memchr>> requires no supporting OS subroutines. 31 32QUICKREF 33 memchr ansi pure 34*/ 35 36#include <string.h> 37#include <limits.h> 38#include "_ansi.h" /* for _DEFUN */ 39 40/* Nonzero if X is not aligned on a "long" boundary. */ 41#define ROCKBOX_UNALIGNED(X) ((long)X & (sizeof (long) - 1)) 42 43/* How many bytes are loaded each iteration of the word copy loop. */ 44#define LBLOCKSIZE (sizeof (long)) 45 46#if LONG_MAX == 2147483647L 47#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) 48#else 49#if LONG_MAX == 9223372036854775807L 50/* Nonzero if X (a long int) contains a NULL byte. */ 51#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080) 52#else 53#error long int is not a 32bit or 64bit type. 54#endif 55#endif 56 57/* DETECTCHAR returns nonzero if (long)X contains the byte used 58 to fill (long)MASK. */ 59#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK)) 60 61void * 62_DEFUN (memchr, (s1, i, n), 63 _CONST void *s1 _AND 64 int i _AND size_t n) 65{ 66 _CONST unsigned char *s = (_CONST unsigned char *)s1; 67#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) 68 unsigned char c = (unsigned char)i; 69 70 while (n-- > 0) 71 { 72 if (*s == c) 73 { 74 return (void *)s; 75 } 76 s++; 77 } 78 79 return NULL; 80#else 81 unsigned char c = (unsigned char)i; 82 unsigned long mask,j; 83 unsigned long *aligned_addr; 84 85 if (!ROCKBOX_UNALIGNED (s)) 86 { 87 mask = 0; 88 for (j = 0; j < LBLOCKSIZE; j++) 89 mask = (mask << 8) | c; 90 91 aligned_addr = (unsigned long*)s; 92 while ((!DETECTCHAR (*aligned_addr, mask)) && (n>LBLOCKSIZE)) 93 { 94 aligned_addr++; 95 n -= LBLOCKSIZE; 96 } 97 98 /* The block of bytes currently pointed to by aligned_addr 99 may contain the target character or there may be less than 100 LBLOCKSIZE bytes left to search. We check the last few 101 bytes using the bytewise search. */ 102 103 s = (unsigned char*)aligned_addr; 104 } 105 106 while (n-- > 0) 107 { 108 if (*s == c) 109 { 110 return (void *)s; 111 } 112 s++; 113 } 114 115 return NULL; 116#endif /* not PREFER_SIZE_OVER_SPEED */ 117}