diff --git a/extras/tests/Helpers/api/String.h b/extras/tests/Helpers/api/String.h index 96b05e30..3ffb291c 100644 --- a/extras/tests/Helpers/api/String.h +++ b/extras/tests/Helpers/api/String.h @@ -37,6 +37,12 @@ class String { return *this; } + char operator[](unsigned int index) const { + if (index >= _str.size()) + return 0; + return _str[index]; + } + friend std::ostream& operator<<(std::ostream& lhs, const ::String& rhs) { lhs << rhs._str; return lhs; diff --git a/src/ArduinoJson/Memory/MemoryPool.hpp b/src/ArduinoJson/Memory/MemoryPool.hpp index c7fa33b7..e0d69cb4 100644 --- a/src/ArduinoJson/Memory/MemoryPool.hpp +++ b/src/ArduinoJson/Memory/MemoryPool.hpp @@ -166,9 +166,21 @@ class MemoryPool { #if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION template - const char* findString(const TAdaptedString& str) { - for (char* next = _begin; next < _left; ++next) { - if (str.compare(next) == 0) + static bool stringEquals(const char* p, size_t n, const TAdaptedString& s) { + if (p[n]) // check terminator first + return false; + for (size_t i = 0; i < n; i++) { + if (p[i] != s[i]) + return false; + } + return true; + } + + template + const char* findString(const TAdaptedString& str) const { + size_t n = str.size(); + for (char* next = _begin; next + n < _left; ++next) { + if (stringEquals(next, n, str)) return next; // jump to next terminator diff --git a/src/ArduinoJson/Strings/Adapters/ArduinoStringAdapter.hpp b/src/ArduinoJson/Strings/Adapters/ArduinoStringAdapter.hpp index 3d520406..7203bf82 100644 --- a/src/ArduinoJson/Strings/Adapters/ArduinoStringAdapter.hpp +++ b/src/ArduinoJson/Strings/Adapters/ArduinoStringAdapter.hpp @@ -32,6 +32,11 @@ class StringAdapter< ::String> { return safe_strcmp(me, other); } + char operator[](size_t i) const { + ARDUINOJSON_ASSERT(_str != 0); + return _str->operator[](static_cast(i)); + } + size_t size() const { return _str->length(); } diff --git a/src/ArduinoJson/Strings/Adapters/ConstRamStringAdapter.hpp b/src/ArduinoJson/Strings/Adapters/ConstRamStringAdapter.hpp index b4a696e2..760dc1f0 100644 --- a/src/ArduinoJson/Strings/Adapters/ConstRamStringAdapter.hpp +++ b/src/ArduinoJson/Strings/Adapters/ConstRamStringAdapter.hpp @@ -7,6 +7,7 @@ #include // size_t #include // strcmp +#include #include #include #include @@ -32,6 +33,12 @@ class StringAdapter { return strlen(_str); } + char operator[](size_t i) const { + ARDUINOJSON_ASSERT(_str != 0); + ARDUINOJSON_ASSERT(i <= size()); + return _str[i]; + } + const char* data() const { return _str; } diff --git a/src/ArduinoJson/Strings/Adapters/FlashStringAdapter.hpp b/src/ArduinoJson/Strings/Adapters/FlashStringAdapter.hpp index 3a958181..c0aa2969 100644 --- a/src/ArduinoJson/Strings/Adapters/FlashStringAdapter.hpp +++ b/src/ArduinoJson/Strings/Adapters/FlashStringAdapter.hpp @@ -39,6 +39,13 @@ class StringAdapter { return strlen_P(reinterpret_cast(_str)); } + char operator[](size_t i) const { + ARDUINOJSON_ASSERT(_str != 0); + ARDUINOJSON_ASSERT(i <= size()); + return static_cast( + pgm_read_byte(reinterpret_cast(_str) + i)); + } + typedef storage_policies::store_by_copy storage_policy; private: diff --git a/src/ArduinoJson/Strings/Adapters/SizedFlashStringAdapter.hpp b/src/ArduinoJson/Strings/Adapters/SizedFlashStringAdapter.hpp index b2d012fc..90950628 100644 --- a/src/ArduinoJson/Strings/Adapters/SizedFlashStringAdapter.hpp +++ b/src/ArduinoJson/Strings/Adapters/SizedFlashStringAdapter.hpp @@ -34,6 +34,14 @@ class StringAdapter { memcpy_P(p, reinterpret_cast(_str), n); } + // TODO: not covered by the tests + char operator[](size_t i) const { + ARDUINOJSON_ASSERT(_str != 0); + ARDUINOJSON_ASSERT(i <= _size); + return static_cast( + pgm_read_byte(reinterpret_cast(_str) + i)); + } + size_t size() const { return _size; } diff --git a/src/ArduinoJson/Strings/Adapters/SizedRamStringAdapter.hpp b/src/ArduinoJson/Strings/Adapters/SizedRamStringAdapter.hpp index a18d5ab9..f219a453 100644 --- a/src/ArduinoJson/Strings/Adapters/SizedRamStringAdapter.hpp +++ b/src/ArduinoJson/Strings/Adapters/SizedRamStringAdapter.hpp @@ -33,6 +33,12 @@ class StringAdapter { return _size; } + char operator[](size_t i) const { + ARDUINOJSON_ASSERT(_str != 0); + ARDUINOJSON_ASSERT(i <= _size); + return _str[i]; + } + typedef storage_policies::store_by_copy storage_policy; private: diff --git a/src/ArduinoJson/Strings/Adapters/StdStringAdapter.hpp b/src/ArduinoJson/Strings/Adapters/StdStringAdapter.hpp index 4d2d32c5..346616f6 100644 --- a/src/ArduinoJson/Strings/Adapters/StdStringAdapter.hpp +++ b/src/ArduinoJson/Strings/Adapters/StdStringAdapter.hpp @@ -33,6 +33,11 @@ class StringAdapter > { return _str->compare(other); } + char operator[](size_t i) const { + ARDUINOJSON_ASSERT(i <= size()); + return _str->operator[](i); + } + size_t size() const { return _str->size(); } diff --git a/src/ArduinoJson/Strings/Adapters/StringViewAdapter.hpp b/src/ArduinoJson/Strings/Adapters/StringViewAdapter.hpp index 787f7c21..3d5e10c9 100644 --- a/src/ArduinoJson/Strings/Adapters/StringViewAdapter.hpp +++ b/src/ArduinoJson/Strings/Adapters/StringViewAdapter.hpp @@ -31,6 +31,11 @@ class StringAdapter { return _str.compare(other); } + char operator[](size_t i) const { + ARDUINOJSON_ASSERT(i <= size()); + return _str[i]; + } + size_t size() const { return _str.size(); }