From af6954c224131cb0f1912e2297e66b1751a24df7 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 31 Jul 2023 18:37:35 +0200 Subject: [PATCH] `serializeXxx()` sets `std::string` and `String` instead of appending --- CHANGELOG.md | 1 + extras/tests/Helpers/api/String.h | 14 ++++++++++---- extras/tests/JsonSerializer/std_string.cpp | 10 +++++----- extras/tests/Misc/StringWriter.cpp | 2 +- .../Serialization/Writers/ArduinoStringWriter.hpp | 6 ++++-- .../Serialization/Writers/StdStringWriter.hpp | 4 +++- 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83d614b2..931365c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,3 +26,4 @@ HEAD * Remove `JsonDocument::garbageCollect()` * Add `deserializeJson(JsonVariant, ...)` and `deserializeMsgPack(JsonVariant, ...)` (#1226) * Call `shrinkToFit()` in `deserializeJson()` and `deserializeMsgPack()` +* `serializeJson()` and `serializeMsgPack()` replace the content of `std::string` and `String` instead of appending to it diff --git a/extras/tests/Helpers/api/String.h b/extras/tests/Helpers/api/String.h index 560fed94..64b93a75 100644 --- a/extras/tests/Helpers/api/String.h +++ b/extras/tests/Helpers/api/String.h @@ -9,8 +9,11 @@ // Reproduces Arduino's String class class String { public: - String() : maxCapacity_(1024) {} - explicit String(const char* s) : str_(s), maxCapacity_(1024) {} + String() = default; + String(const char* s) { + if (s) + str_.assign(s); + } void limitCapacityTo(size_t maxCapacity) { maxCapacity_ = maxCapacity; @@ -33,7 +36,10 @@ class String { } String& operator=(const char* s) { - str_.assign(s); + if (s) + str_.assign(s); + else + str_.clear(); return *this; } @@ -59,7 +65,7 @@ class String { private: std::string str_; - size_t maxCapacity_; + size_t maxCapacity_ = 1024; }; class StringSumHelper : public ::String {}; diff --git a/extras/tests/JsonSerializer/std_string.cpp b/extras/tests/JsonSerializer/std_string.cpp index f25deb20..fa33c60f 100644 --- a/extras/tests/JsonSerializer/std_string.cpp +++ b/extras/tests/JsonSerializer/std_string.cpp @@ -12,14 +12,14 @@ TEST_CASE("serialize JsonArray to std::string") { array.add(2); SECTION("serializeJson()") { - std::string json; + std::string json = "erase me"; serializeJson(array, json); REQUIRE("[4,2]" == json); } SECTION("serializeJsonPretty") { - std::string json; + std::string json = "erase me"; serializeJsonPretty(array, json); REQUIRE("[\r\n 4,\r\n 2\r\n]" == json); @@ -32,14 +32,14 @@ TEST_CASE("serialize JsonObject to std::string") { obj["key"] = "value"; SECTION("object") { - std::string json; + std::string json = "erase me"; serializeJson(doc, json); REQUIRE("{\"key\":\"value\"}" == json); } SECTION("serializeJsonPretty") { - std::string json; + std::string json = "erase me"; serializeJsonPretty(doc, json); REQUIRE("{\r\n \"key\": \"value\"\r\n}" == json); @@ -50,7 +50,7 @@ TEST_CASE("serialize an std::string containing a NUL") { JsonDocument doc; doc.set(std::string("hello\0world", 11)); - std::string json; + std::string json = "erase me"; serializeJson(doc, json); CHECK("\"hello\\u0000world\"" == json); } diff --git a/extras/tests/Misc/StringWriter.cpp b/extras/tests/Misc/StringWriter.cpp index 4fc5c774..d7cec9d0 100644 --- a/extras/tests/Misc/StringWriter.cpp +++ b/extras/tests/Misc/StringWriter.cpp @@ -141,7 +141,7 @@ TEST_CASE("Writer") { TEST_CASE("serializeJson(doc, String)") { JsonDocument doc; doc["hello"] = "world"; - ::String output; + ::String output = "erase me"; SECTION("sufficient capacity") { serializeJson(doc, output); diff --git a/src/ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp b/src/ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp index c6432487..7381b414 100644 --- a/src/ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp +++ b/src/ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp @@ -13,8 +13,10 @@ class Writer<::String, void> { static const size_t bufferCapacity = ARDUINOJSON_STRING_BUFFER_SIZE; public: - explicit Writer(::String& str) : destination_(&str) { - size_ = 0; + explicit Writer(::String& str) : destination_(&str), size_(0) { + // clear the string but don't use "" to avoid useless allocation + // https://cpp4arduino.com/2018/11/21/eight-tips-to-use-the-string-class-efficiently.html + str = static_cast(0); } ~Writer() { diff --git a/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp b/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp index 1f8afaa8..8dc079d5 100644 --- a/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp +++ b/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp @@ -24,7 +24,9 @@ template class Writer::value>::type> { public: - Writer(TDestination& str) : str_(&str) {} + Writer(TDestination& str) : str_(&str) { + str.clear(); + } size_t write(uint8_t c) { str_->push_back(static_cast(c));