string: introduce memchr_inv
Directly taken from Linux Kernel. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
bdfd6a629c
commit
b445152396
|
@ -106,6 +106,8 @@ extern char * skip_spaces(const char *);
|
||||||
|
|
||||||
extern char *strim(char *);
|
extern char *strim(char *);
|
||||||
|
|
||||||
|
void *memchr_inv(const void *start, int c, size_t bytes);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
59
lib/string.c
59
lib/string.c
|
@ -666,3 +666,62 @@ char *strim(char *s)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(strim);
|
EXPORT_SYMBOL(strim);
|
||||||
|
|
||||||
|
static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
|
||||||
|
{
|
||||||
|
while (bytes) {
|
||||||
|
if (*start != value)
|
||||||
|
return (void *)start;
|
||||||
|
start++;
|
||||||
|
bytes--;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* memchr_inv - Find an unmatching character in an area of memory.
|
||||||
|
* @start: The memory area
|
||||||
|
* @c: Find a character other than c
|
||||||
|
* @bytes: The size of the area.
|
||||||
|
*
|
||||||
|
* returns the address of the first character other than @c, or %NULL
|
||||||
|
* if the whole buffer contains just @c.
|
||||||
|
*/
|
||||||
|
void *memchr_inv(const void *start, int c, size_t bytes)
|
||||||
|
{
|
||||||
|
u8 value = c;
|
||||||
|
u64 value64;
|
||||||
|
unsigned int words, prefix;
|
||||||
|
|
||||||
|
if (bytes <= 16)
|
||||||
|
return check_bytes8(start, value, bytes);
|
||||||
|
|
||||||
|
value64 = value;
|
||||||
|
value64 |= value64 << 8;
|
||||||
|
value64 |= value64 << 16;
|
||||||
|
value64 |= value64 << 32;
|
||||||
|
|
||||||
|
prefix = (unsigned long)start % 8;
|
||||||
|
if (prefix) {
|
||||||
|
u8 *r;
|
||||||
|
|
||||||
|
prefix = 8 - prefix;
|
||||||
|
r = check_bytes8(start, value, prefix);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
start += prefix;
|
||||||
|
bytes -= prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
words = bytes / 8;
|
||||||
|
|
||||||
|
while (words) {
|
||||||
|
if (*(u64 *)start != value64)
|
||||||
|
return check_bytes8(start, value, 8);
|
||||||
|
start += 8;
|
||||||
|
words--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return check_bytes8(start, value, bytes % 8);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(memchr_inv);
|
||||||
|
|
Loading…
Reference in New Issue