diff options
Diffstat (limited to 'prism/memchr.c')
| -rw-r--r-- | prism/memchr.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/prism/memchr.c b/prism/memchr.c new file mode 100644 index 0000000000..900e6245b7 --- /dev/null +++ b/prism/memchr.c @@ -0,0 +1,37 @@ +#include "prism/internal/memchr.h" + +#include <stdbool.h> +#include <stdint.h> +#include <string.h> + +#define TRAILING_BYTE_MINIMUM 0x40 + +/** + * We need to roll our own memchr to handle cases where the encoding changes and + * we need to search for a character in a buffer that could be the trailing byte + * of a multibyte character. + */ +const void * +pm_memchr(const void *memory, int character, size_t number, bool encoding_changed, const pm_encoding_t *encoding) { + if (encoding_changed && encoding->multibyte && character >= TRAILING_BYTE_MINIMUM) { + const uint8_t *source = (const uint8_t *) memory; + size_t index = 0; + + while (index < number) { + if (source[index] == character) { + return (void *) (source + index); + } + + size_t width = encoding->char_width(source + index, (ptrdiff_t) (number - index)); + if (width == 0) { + return NULL; + } + + index += width; + } + + return NULL; + } else { + return memchr(memory, character, number); + } +} |
