diff --git a/Sming/Core/Data/CStringArray.cpp b/Sming/Core/Data/CStringArray.cpp index 8321fbeb01..cfc3630ee8 100644 --- a/Sming/Core/Data/CStringArray.cpp +++ b/Sming/Core/Data/CStringArray.cpp @@ -168,3 +168,25 @@ unsigned CStringArray::count() const } return stringCount; } + +String CStringArray::join(const String& separator) const +{ + if(isNull()) { + return nullptr; + } + unsigned len = length(); + if(len == 0) { + return ""; + } + len -= count(); // NUL separators + len += separator.length() * (stringCount - 1); + String s; + s.reserve(len); + for(auto it = begin(); it != end(); ++it) { + if(it.index() != 0) { + s += separator; + } + s += *it; + } + return s; +} diff --git a/Sming/Core/Data/CStringArray.h b/Sming/Core/Data/CStringArray.h index 5bcf331862..c4b8c74ad0 100644 --- a/Sming/Core/Data/CStringArray.h +++ b/Sming/Core/Data/CStringArray.h @@ -246,6 +246,15 @@ class CStringArray : private String */ unsigned count() const; + /** + * @brief Get contents of array as delimited string + * @param separator What to join elements with + * @retval String + * + * e.g. CStringArray(F("a\0b\0c")).join() returns "a,b,c" + */ + String join(const String& separator = ",") const; + /** * @name Iterator support (forward only) * @{ diff --git a/tests/HostTests/modules/CStringArray.cpp b/tests/HostTests/modules/CStringArray.cpp index efb7b5e3e1..61c8394099 100644 --- a/tests/HostTests/modules/CStringArray.cpp +++ b/tests/HostTests/modules/CStringArray.cpp @@ -213,6 +213,25 @@ class CStringArrayTest : public TestGroup REQUIRE(csa.back() == nullptr); REQUIRE(!csa.popBack()); } + + TEST_CASE("join") + { + CStringArray csa; + REQUIRE(!csa.join()); + + csa = ""; + REQUIRE(csa.join() == ""); + + csa.add("a"); + REQUIRE(csa.join() == "a"); + + csa.add(""); + REQUIRE(csa.join() == "a,"); + + csa.add(F("test\0again")); + REQUIRE_EQ(csa.join("}+{"), "a}+{}+{test}+{again"); + REQUIRE_EQ(csa.join(nullptr), "atestagain"); + } } };