mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 08:42:39 +01:00 
			
		
		
		
	serializeMsgPack(doc, p, n) doesn't add terminator anymore (fixes #1545)
This commit is contained in:
		| @@ -16,6 +16,8 @@ HEAD | ||||
| * Simplified `JsonVariant::as<T>()` to always return `T` (see below) | ||||
| * Updated folders list in `.mbedignore` (PR #1515 by @AGlass0fMilk) | ||||
| * Fixed member-call-on-null-pointer in `getMember()` when array is empty | ||||
| * `serializeMsgPack(doc, buffer, size)` doesn't add null-terminator anymore (issue #1545) | ||||
| * `serializeJson(doc, buffer, size)` adds null-terminator only if there is enough room | ||||
|  | ||||
| > ### BREAKING CHANGES | ||||
| > | ||||
|   | ||||
| @@ -8,12 +8,15 @@ | ||||
|  | ||||
| static void checkObject(const JsonObject obj, const std::string &expected) { | ||||
|   char actual[256]; | ||||
|   memset(actual, '!', sizeof(actual)); | ||||
|  | ||||
|   size_t actualLen = serializeJson(obj, actual); | ||||
|   size_t measuredLen = measureJson(obj); | ||||
|  | ||||
|   REQUIRE(expected == actual); | ||||
|   REQUIRE(expected.size() == actualLen); | ||||
|   REQUIRE(expected.size() == measuredLen); | ||||
|   REQUIRE(expected.size() == actualLen); | ||||
|   REQUIRE(actual[actualLen] == 0);  // serializeJson() adds a null terminator | ||||
|   REQUIRE(expected == actual); | ||||
| } | ||||
|  | ||||
| TEST_CASE("serializeJson(JsonObject)") { | ||||
|   | ||||
| @@ -39,15 +39,15 @@ void common_tests(StringWriter& sb, const String& output) { | ||||
| } | ||||
|  | ||||
| TEST_CASE("StaticStringWriter") { | ||||
|   char output[20]; | ||||
|   char output[20] = {0}; | ||||
|   StaticStringWriter sb(output, sizeof(output)); | ||||
|  | ||||
|   common_tests(sb, static_cast<const char*>(output)); | ||||
|  | ||||
|   SECTION("OverCapacity") { | ||||
|     REQUIRE(19 == print(sb, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")); | ||||
|     REQUIRE(20 == print(sb, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")); | ||||
|     REQUIRE(0 == print(sb, "ABC")); | ||||
|     REQUIRE(std::string("ABCDEFGHIJKLMNOPQRS") == output); | ||||
|     REQUIRE("ABCDEFGHIJKLMNOPQRST" == std::string(output, 20)); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -29,19 +29,31 @@ TEST_CASE("serialize MsgPack to various destination types") { | ||||
|     REQUIRE(expected_length == len); | ||||
|     } */ | ||||
|  | ||||
|   SECTION("char[]") { | ||||
|   SECTION("char[] larger than needed") { | ||||
|     char result[64]; | ||||
|     memset(result, 42, sizeof(result)); | ||||
|     size_t len = serializeMsgPack(object, result); | ||||
|  | ||||
|     REQUIRE(std::string(expected_result) == result); | ||||
|     REQUIRE(expected_length == len); | ||||
|     REQUIRE(std::string(expected_result, len) == std::string(result, len)); | ||||
|     REQUIRE(result[len] == 42); | ||||
|   } | ||||
|  | ||||
|   SECTION("char[] of the right size") {  // #1545 | ||||
|     char result[13]; | ||||
|     size_t len = serializeMsgPack(object, result); | ||||
|  | ||||
|     REQUIRE(expected_length == len); | ||||
|     REQUIRE(std::string(expected_result, len) == std::string(result, len)); | ||||
|   } | ||||
|  | ||||
|   SECTION("char*") { | ||||
|     char result[64]; | ||||
|     memset(result, 42, sizeof(result)); | ||||
|     size_t len = serializeMsgPack(object, result, 64); | ||||
|  | ||||
|     REQUIRE(std::string(expected_result) == result); | ||||
|     REQUIRE(expected_length == len); | ||||
|     REQUIRE(std::string(expected_result, len) == std::string(result, len)); | ||||
|     REQUIRE(result[len] == 42); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -13,7 +13,7 @@ using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
| template <typename T> | ||||
| void checkWriteInteger(T value, std::string expected) { | ||||
|   char output[1024]; | ||||
|   char output[64] = {0}; | ||||
|   StaticStringWriter sb(output, sizeof(output)); | ||||
|   TextFormatter<StaticStringWriter> writer(sb); | ||||
|   writer.writeInteger<T>(value); | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
| void check(const char* input, std::string expected) { | ||||
|   char output[1024]; | ||||
|   char output[64] = {0}; | ||||
|   StaticStringWriter sb(output, sizeof(output)); | ||||
|   TextFormatter<StaticStringWriter> writer(sb); | ||||
|   writer.writeString(input); | ||||
|   | ||||
| @@ -14,6 +14,8 @@ namespace ARDUINOJSON_NAMESPACE { | ||||
| template <typename TWriter> | ||||
| class JsonSerializer : public Visitor<size_t> { | ||||
|  public: | ||||
|   static const bool producesText = true; | ||||
|  | ||||
|   JsonSerializer(TWriter writer) : _formatter(writer) {} | ||||
|  | ||||
|   FORCE_INLINE size_t visitArray(const CollectionData &array) { | ||||
|   | ||||
| @@ -16,7 +16,7 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> { | ||||
|   typedef JsonSerializer<TWriter> base; | ||||
|  | ||||
|  public: | ||||
|   PrettyJsonSerializer(TWriter &writer) : base(writer), _nesting(0) {} | ||||
|   PrettyJsonSerializer(TWriter writer) : base(writer), _nesting(0) {} | ||||
|  | ||||
|   size_t visitArray(const CollectionData &array) { | ||||
|     VariantSlot *slot = array.head(); | ||||
|   | ||||
| @@ -17,6 +17,8 @@ namespace ARDUINOJSON_NAMESPACE { | ||||
| template <typename TWriter> | ||||
| class MsgPackSerializer : public Visitor<size_t> { | ||||
|  public: | ||||
|   static const bool producesText = false; | ||||
|  | ||||
|   MsgPackSerializer(TWriter writer) : _writer(writer) {} | ||||
|  | ||||
|   template <typename T> | ||||
|   | ||||
| @@ -8,18 +8,14 @@ | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| // A Print implementation that allows to write in a char[] | ||||
| class StaticStringWriter { | ||||
|  public: | ||||
|   StaticStringWriter(char *buf, size_t size) : end(buf + size - 1), p(buf) { | ||||
|     *p = '\0'; | ||||
|   } | ||||
|   StaticStringWriter(char *buf, size_t size) : end(buf + size), p(buf) {} | ||||
|  | ||||
|   size_t write(uint8_t c) { | ||||
|     if (p >= end) | ||||
|       return 0; | ||||
|     *p++ = static_cast<char>(c); | ||||
|     *p = '\0'; | ||||
|     return 1; | ||||
|   } | ||||
|  | ||||
| @@ -29,7 +25,6 @@ class StaticStringWriter { | ||||
|       *p++ = static_cast<char>(*s++); | ||||
|       n--; | ||||
|     } | ||||
|     *p = '\0'; | ||||
|     return size_t(p - begin); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -23,11 +23,23 @@ size_t serialize(const TSource &source, TDestination &destination) { | ||||
| } | ||||
|  | ||||
| template <template <typename> class TSerializer, typename TSource> | ||||
| size_t serialize(const TSource &source, void *buffer, size_t bufferSize) { | ||||
| typename enable_if<!TSerializer<StaticStringWriter>::producesText, size_t>::type | ||||
| serialize(const TSource &source, void *buffer, size_t bufferSize) { | ||||
|   StaticStringWriter writer(reinterpret_cast<char *>(buffer), bufferSize); | ||||
|   return doSerialize<TSerializer>(source, writer); | ||||
| } | ||||
|  | ||||
| template <template <typename> class TSerializer, typename TSource> | ||||
| typename enable_if<TSerializer<StaticStringWriter>::producesText, size_t>::type | ||||
| serialize(const TSource &source, void *buffer, size_t bufferSize) { | ||||
|   StaticStringWriter writer(reinterpret_cast<char *>(buffer), bufferSize); | ||||
|   size_t n = doSerialize<TSerializer>(source, writer); | ||||
|   // add null-terminator for text output (not counted in the size) | ||||
|   if (n < bufferSize) | ||||
|     reinterpret_cast<char *>(buffer)[n] = 0; | ||||
|   return n; | ||||
| } | ||||
|  | ||||
| template <template <typename> class TSerializer, typename TSource, | ||||
|           typename TChar, size_t N> | ||||
| #if defined _MSC_VER && _MSC_VER < 1900 | ||||
| @@ -36,8 +48,7 @@ typename enable_if<sizeof(remove_reference<TChar>::type) == 1, size_t>::type | ||||
| typename enable_if<sizeof(TChar) == 1, size_t>::type | ||||
| #endif | ||||
| serialize(const TSource &source, TChar (&buffer)[N]) { | ||||
|   StaticStringWriter writer(reinterpret_cast<char *>(buffer), N); | ||||
|   return doSerialize<TSerializer>(source, writer); | ||||
|   return serialize<TSerializer>(source, buffer, N); | ||||
| } | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
		Reference in New Issue
	
	Block a user