/* See LICENSE file for copyright and license details. */ #include "common.h" void * libautomata_execute_kmp_automaton(const void *haystack, size_t length, LIBAUTOMATA_KMP_AUTOMATON *automaton) { const void *pattern = (void *)&automaton->next[automaton->length + 1U]; size_t i = 0; #define INTRINSIC(TYPE)\ (((const TYPE *)pattern)[automaton->position] == ((const TYPE *)haystack)[i]) #define MEMCMP(WIDTH)\ (!memcmp(&((const char *)pattern)[automaton->position * automaton->elemsize],\ &((const char *)haystack)[i * automaton->elemsize],\ automaton->elemsize)) #define IMPLEMENT(EQ, EQ_PARAM)\ while (i < length) {\ while (automaton->position != SIZE_MAX && !(EQ(EQ_PARAM)))\ automaton->position = automaton->next[automaton->position];\ i++;\ if (++automaton->position == automaton->length)\ goto found;\ }\ return NULL switch (automaton->elemsize) { case sizeof(uint8_t): IMPLEMENT(INTRINSIC, uint8_t); case sizeof(uint16_t): IMPLEMENT(INTRINSIC, uint16_t); case sizeof(uint32_t): IMPLEMENT(INTRINSIC, uint32_t); case sizeof(uint64_t): IMPLEMENT(INTRINSIC, uint64_t); default: IMPLEMENT(MEMCMP, elemsize); } found: automaton->position = automaton->next[automaton->position]; return &(*(char **)(void *)&haystack)[i]; }