Skip to content

Commit

Permalink
Rationalise string comparison methods
Browse files Browse the repository at this point in the history
  • Loading branch information
mikee47 committed Apr 6, 2024
1 parent 5059948 commit 72e81a2
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 48 deletions.
47 changes: 26 additions & 21 deletions src/String.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -58,25 +70,18 @@ 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()) {
return false;
}
// @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
44 changes: 17 additions & 27 deletions src/include/FlashString/String.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,30 +197,32 @@ class String : public Object<String, char>
* @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 <typename T> 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 <typename T> bool operator==(const T& str) const
{
return !equals(str);
return equals(str);
}

bool operator!=(const String& str) const
template <typename T> bool operator!=(const T& str) const
{
return !equals(str);
}
Expand All @@ -229,19 +231,7 @@ class String : public Object<String, char>

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 */

Expand Down

0 comments on commit 72e81a2

Please sign in to comment.