wsutil: Add a memrchr implementation
Use the system memrchr if found, otherwise use a very basic non optimized implementation
This commit is contained in:
parent
6c424b610d
commit
0cec46bb25
|
@ -104,6 +104,7 @@ if(UNIX)
|
|||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
|
||||
check_symbol_exists("memmem" "string.h" HAVE_MEMMEM)
|
||||
check_symbol_exists("memrchr" "string.h" HAVE_MEMRCHR)
|
||||
check_symbol_exists("strerrorname_np" "string.h" HAVE_STRERRORNAME_NP)
|
||||
check_symbol_exists("strptime" "time.h" HAVE_STRPTIME)
|
||||
check_symbol_exists("vasprintf" "stdio.h" HAVE_VASPRINTF)
|
||||
|
|
|
@ -280,6 +280,9 @@
|
|||
/* Define if you have the 'memmem' function. */
|
||||
#cmakedefine HAVE_MEMMEM 1
|
||||
|
||||
/* Define if you have the 'memrchr' function. */
|
||||
#cmakedefine HAVE_MEMRCHR 1
|
||||
|
||||
/* Define if you have the 'strerrorname_np' function. */
|
||||
#cmakedefine HAVE_STRERRORNAME_NP 1
|
||||
|
||||
|
|
|
@ -490,6 +490,7 @@ libwsutil.so.0 libwsutil0 #MINVER#
|
|||
ws_memmem@Base 3.7.0
|
||||
ws_mempbrk_compile@Base 1.99.4
|
||||
ws_mempbrk_exec@Base 1.99.4
|
||||
ws_memrchr@Base 4.3.0rc0
|
||||
ws_optarg@Base 3.5.1
|
||||
ws_opterr@Base 3.5.1
|
||||
ws_optind@Base 3.5.1
|
||||
|
|
|
@ -339,6 +339,36 @@ ws_ascii_strcasestr(const char *haystack, const char *needle)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the last occurrence of ch in the n bytes of haystack.
|
||||
* If not found or n is 0, return NULL. */
|
||||
const uint8_t *
|
||||
ws_memrchr(const void *_haystack, int ch, size_t n)
|
||||
{
|
||||
#ifdef HAVE_MEMRCHR
|
||||
return memrchr(_haystack, ch, n);
|
||||
#else
|
||||
/* A generic implementation. This could be optimized considerably,
|
||||
* e.g. by fetching a word at a time.
|
||||
*/
|
||||
if (n == 0) {
|
||||
return NULL;
|
||||
}
|
||||
const uint8_t *haystack = _haystack;
|
||||
const uint8_t *p;
|
||||
uint8_t c = (uint8_t)ch;
|
||||
|
||||
const uint8_t *const end = haystack + n - 1;
|
||||
|
||||
for (p = end; p >= haystack; --p) {
|
||||
if (*p == c) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#endif /* HAVE_MEMRCHR */
|
||||
}
|
||||
|
||||
#define FORMAT_SIZE_UNIT_MASK 0x00ff
|
||||
#define FORMAT_SIZE_PFX_MASK 0xff00
|
||||
|
||||
|
|
|
@ -182,6 +182,17 @@ bool isdigit_string(const unsigned char *str);
|
|||
WS_DLL_PUBLIC
|
||||
const char *ws_ascii_strcasestr(const char *haystack, const char *needle);
|
||||
|
||||
/** Like the memchr() function, except it scans backwards from the end.
|
||||
*
|
||||
* @param haystack Pointer to the bytes of memory to search
|
||||
* @param ch The character to search
|
||||
* @param n The length of bytes to search from the end
|
||||
* @return A pointer to the last occurrence of "ch" in "haystack".
|
||||
* If "ch" isn't found or "n" is 0, returns NULL.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
const uint8_t *ws_memrchr(const void *haystack, int ch, size_t n);
|
||||
|
||||
WS_DLL_PUBLIC
|
||||
char *ws_escape_string(wmem_allocator_t *alloc, const char *string, bool add_quotes);
|
||||
|
||||
|
|
Loading…
Reference in New Issue