diff --git a/src/String.cpp b/src/String.cpp index fa39d77..a24a748 100644 --- a/src/String.cpp +++ b/src/String.cpp @@ -23,32 +23,44 @@ namespace FSTR { -bool String::equals(const char* cstr, size_t len) const +bool String::equals(const char* cstr, size_t clen, bool ignoreCase) const { // Unlikely we'd want an empty flash string, but check anyway if(cstr == nullptr) { return length() == 0; } - // Don't use strcmp as our data may contain nuls - if(len == 0) { - len = strlen(cstr); - } - if(len != length()) { + auto len = length(); + if(clen != len) { return false; } LOAD_FSTR(buf, *this); + if(ignoreCase) { + return memicmp(buf, cstr, len) == 0; + } return memcmp(buf, cstr, len) == 0; } -bool String::equals(const String& str) const +bool String::equals(const char* cstr, bool ignoreCase) const +{ + return equals(cstr, cstr ? strlen(cstr) : 0, ignoreCase); +} + +bool String::equals(const String& str, bool ignoreCase) const { - if(data() == str.data()) { + auto dataptr = data(); + auto strdata = str.data(); + if(dataptr == strdata) { return true; } - if(length() != str.length()) { + auto len = length(); + if(len != str.length()) { return false; } - return memcmp_aligned(data(), str.data(), length()) == 0; + if(ignoreCase) { + LOAD_FSTR(buf, *this); + return memicmp(dataptr, buf, len) == 0; + } + return memcmp_aligned(dataptr, strdata, len) == 0; } /* Wiring String support */ @@ -58,7 +70,7 @@ String::operator WString() const return isNull() ? WString() : WString(data(), length()); } -bool String::equals(const WString& str) const +bool String::equals(const WString& str, bool ignoreCase) const { auto len = str.length(); if(len != length()) { @@ -66,17 +78,10 @@ bool String::equals(const WString& str) const } // @todo optimise memcmp_P then we won't need to load entire String into RAM first LOAD_FSTR(buf, *this); - return memcmp(buf, str.c_str(), len) == 0; -} - -bool String::equalsIgnoreCase(const WString& str) const -{ - auto len = str.length(); - if(len != length()) { - return false; + if(ignoreCase) { + return memicmp(buf, str.c_str(), len) == 0; } - LOAD_FSTR(buf, *this); - return memicmp(buf, str.c_str(), len) == 0; + return memcmp(buf, str.c_str(), len) == 0; } } // namespace FSTR diff --git a/src/include/FlashString/String.hpp b/src/include/FlashString/String.hpp index 481720c..bda834c 100644 --- a/src/include/FlashString/String.hpp +++ b/src/include/FlashString/String.hpp @@ -197,30 +197,32 @@ class String : public Object * @retval bool true if strings are identical * @note loads string into a stack buffer for the comparison, no heap required */ - bool equals(const char* cstr, size_t len = 0) const; + bool equals(const char* cstr, size_t len, bool ignoreCase = false) const; - /** @brief Check for equality with another String - * @param str - * @retval bool true if strings are identical - */ - bool equals(const String& str) const; - - bool operator==(const char* str) const + bool equalsIgnoreCase(const char* cstr, size_t len) const { - return equals(str); + return equals(cstr, len, true); } - bool operator==(const String& str) const + bool equals(const char* cstr, bool ignoreCase = false) const; + + template bool equalsIgnoreCase(const T& str) const { - return equals(str); + return equals(str, true); } - bool operator!=(const char* str) const + /** @brief Check for equality with another String + * @param str + * @retval bool true if strings are identical + */ + bool equals(const String& str, bool ignoreCase = false) const; + + template bool operator==(const T& str) const { - return !equals(str); + return equals(str); } - bool operator!=(const String& str) const + template bool operator!=(const T& str) const { return !equals(str); } @@ -229,19 +231,7 @@ class String : public Object operator WString() const; - bool equals(const WString& str) const; - - bool equalsIgnoreCase(const WString& str) const; - - bool operator==(const WString& str) const - { - return equals(str); - } - - bool operator!=(const WString& str) const - { - return !equals(str); - } + bool equals(const WString& str, bool ignoreCase = false) const; /* Arduino Print support */