diff --git a/src/util/FFlist.h b/src/util/FFlist.h index 0ec1f2899..d1eee05ad 100644 --- a/src/util/FFlist.h +++ b/src/util/FFlist.h @@ -29,12 +29,13 @@ void ffListDestroy(FFlist* list); static inline void ffListInit(FFlist* list, uint32_t elementSize) { + assert(elementSize > 0); ffListInitA(list, elementSize, 0); } static inline void* ffListGet(const FFlist* list, uint32_t index) { - assert(list->capacity > 0); + assert(list->capacity > index); return list->data + (index * list->elementSize); } diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index 1b152ae44..b302bce0a 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -363,42 +363,6 @@ void ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c) ffStrbufSubstrAfter(strbuf, index); } -bool ffStrbufStartsWithIgnCaseS(const FFstrbuf* strbuf, const char* start) -{ - for(uint32_t i = 0; start[i] != '\0'; i++) - { - if(i >= strbuf->length) - return false; - - if(tolower(strbuf->chars[i]) != tolower(start[i])) - return false; - } - return true; -} - -bool ffStrbufStartsWithIgnCase(const FFstrbuf* strbuf, const FFstrbuf* start) -{ - if (start->length > strbuf->length) - return false; - return ffStrbufStartsWithIgnCaseS(strbuf, start->chars); -} - -bool ffStrbufEndsWithC(const FFstrbuf* strbuf, char c) -{ - return strbuf->length == 0 ? false : - strbuf->chars[strbuf->length - 1] == c; -} - -bool ffStrbufEndsWithS(const FFstrbuf* strbuf, const char* end) -{ - uint32_t endLength = (uint32_t) strlen(end); - - if(endLength > strbuf->length) - return false; - - return memcmp(strbuf->chars + strbuf->length - endLength, end, endLength) == 0; -} - uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c) { uint32_t result = 0; @@ -411,26 +375,11 @@ uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c) return result; } -static bool testEndsWithIgnCaseS(const FFstrbuf* strbuf, const char* end, uint32_t* endLength) -{ - *endLength = (uint32_t) strlen(end); - - if(*endLength > strbuf->length) - return false; - - for(uint32_t i = 0; i < *endLength; ++i) - { - if(tolower(strbuf->chars[strbuf->length - *endLength + i]) != tolower(end[i])) - return false; - } - - return true; -} bool ffStrbufRemoveIgnCaseEndS(FFstrbuf* strbuf, const char* end) { - uint32_t endLength; - if(testEndsWithIgnCaseS(strbuf, end, &endLength)) + uint32_t endLength = (uint32_t) strlen(end); + if(ffStrbufEndsWithIgnCaseNS(strbuf, endLength, end)) { ffStrbufSubstrBefore(strbuf, strbuf->length - endLength); return true; diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 84db2f060..23f2e48f1 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -70,12 +70,6 @@ void ffStrbufSubstrAfterFirstC(FFstrbuf* strbuf, char c); void ffStrbufSubstrAfterFirstS(FFstrbuf* strbuf, const char* str); void ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c); -bool ffStrbufStartsWithIgnCase(const FFstrbuf* strbuf, const FFstrbuf* start); -bool ffStrbufStartsWithIgnCaseS(const FFstrbuf* strbuf, const char* start); - -bool ffStrbufEndsWithC(const FFstrbuf* strbuf, char c); -bool ffStrbufEndsWithS(const FFstrbuf* strbuf, const char* end); - FF_C_NODISCARD uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c); bool ffStrbufRemoveIgnCaseEndS(FFstrbuf* strbuf, const char* end); @@ -110,9 +104,20 @@ static inline void ffStrbufSetS(FFstrbuf* strbuf, const char* value) ffStrbufAppendNS(strbuf, (uint32_t) strlen(value), value); } -static inline void ffStrbufInitS(FFstrbuf* strbuf, const char* str) +static inline void ffStrbufInit(FFstrbuf* strbuf) { ffStrbufInitA(strbuf, 0); +} + +static inline void ffStrbufInitNS(FFstrbuf* strbuf, uint32_t length, const char* str) +{ + ffStrbufInit(strbuf); + ffStrbufAppendNS(strbuf, length, str); +} + +static inline void ffStrbufInitS(FFstrbuf* strbuf, const char* str) +{ + ffStrbufInit(strbuf); ffStrbufAppendS(strbuf, str); } @@ -124,11 +129,6 @@ static inline void ffStrbufAppend(FFstrbuf* strbuf, const FFstrbuf* value) ffStrbufAppendNS(strbuf, value->length, value->chars); } -static inline void ffStrbufInit(FFstrbuf* strbuf) -{ - ffStrbufInitA(strbuf, 0); -} - static inline void ffStrbufPrependS(FFstrbuf* strbuf, const char* value) { if(value == NULL) @@ -199,4 +199,62 @@ static inline FF_C_NODISCARD bool ffStrbufStartsWith(const FFstrbuf* strbuf, con { return ffStrbufStartsWithSN(strbuf, start->chars, start->length); } + +static inline FF_C_NODISCARD bool ffStrbufStartsWithIgnCaseNS(const FFstrbuf* strbuf, uint32_t length, const char* start) +{ + if(length > strbuf->length) + return false; + return strncasecmp(strbuf->chars, start, length) == 0; +} + +static inline FF_C_NODISCARD bool ffStrbufStartsWithIgnCaseS(const FFstrbuf* strbuf, const char* start) +{ + return ffStrbufStartsWithIgnCaseNS(strbuf, (uint32_t) strlen(start), start); +} + +static inline FF_C_NODISCARD bool ffStrbufStartsWithIgnCase(const FFstrbuf* strbuf, const FFstrbuf* start) +{ + return ffStrbufStartsWithIgnCaseNS(strbuf, start->length, start->chars); +} + +static inline FF_C_NODISCARD bool ffStrbufEndsWithC(const FFstrbuf* strbuf, char c) +{ + return strbuf->length == 0 ? false : + strbuf->chars[strbuf->length - 1] == c; +} + +static inline FF_C_NODISCARD bool ffStrbufEndsWithNS(const FFstrbuf* strbuf, uint32_t endLength, const char* end) +{ + if(endLength > strbuf->length) + return false; + + return memcmp(strbuf->chars + strbuf->length - endLength, end, endLength) == 0; +} + +static inline FF_C_NODISCARD bool ffStrbufEndsWithS(const FFstrbuf* strbuf, const char* end) +{ + return ffStrbufEndsWithNS(strbuf, (uint32_t) strlen(end), end); +} + +static inline FF_C_NODISCARD bool ffStrbufEndsWith(const FFstrbuf* strbuf, const FFstrbuf* end) +{ + return ffStrbufEndsWithNS(strbuf, end->length, end->chars); +} + +static inline FF_C_NODISCARD bool ffStrbufEndsWithIgnCaseNS(const FFstrbuf* strbuf, uint32_t endLength, const char* end) +{ + if(endLength > strbuf->length) + return false; + return strcasecmp(strbuf->chars + strbuf->length - endLength, end) == 0; +} + +static inline FF_C_NODISCARD bool ffStrbufEndsWithIgnCaseS(const FFstrbuf* strbuf, const char* end) +{ + return ffStrbufEndsWithIgnCaseNS(strbuf, (uint32_t) strlen(end), end); +} + +static inline FF_C_NODISCARD bool ffStrbufEndsWithIgnCase(const FFstrbuf* strbuf, const FFstrbuf* end) +{ + return ffStrbufEndsWithIgnCaseNS(strbuf, end->length, end->chars); +} #endif diff --git a/tests/strbuf.c b/tests/strbuf.c index da26e50e7..403da59d5 100644 --- a/tests/strbuf.c +++ b/tests/strbuf.c @@ -156,6 +156,21 @@ int main(int argc, char** argv) VERIFY(ffStrbufNextIndexS(&strbuf, 1, "1") == 3); VERIFY(ffStrbufNextIndexS(&strbuf, 4, "1") == 5); + //ignCase + ffStrbufSetS(&strbuf, "AbCdEfG"); + + VERIFY(ffStrbufIgnCaseCompS(&strbuf, "aBcDeFg") == 0); + VERIFY(ffStrbufStartsWithIgnCaseS(&strbuf, "ABCD")); + VERIFY(ffStrbufEndsWithIgnCaseS(&strbuf, "defg")); + VERIFY(!ffStrbufStartsWithIgnCaseS(&strbuf, "aBcDeFgH")); + VERIFY(!ffStrbufEndsWithIgnCaseS(&strbuf, "0aBcDeFg")); + + //ensure + ffStrbufEnsureEndsWithC(&strbuf, '^'); + VERIFY(ffStrbufCompS(&strbuf, "^aBcDeFg")); + ffStrbufEnsureEndsWithC(&strbuf, '$'); + VERIFY(ffStrbufCompS(&strbuf, "^aBcDeFg$")); + //Destroy ffStrbufDestroy(&strbuf);