mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 08:42:39 +01:00 
			
		
		
		
	Removed Print class and converted printTo() to a template method (issue #276)
				
					
				
			This commit is contained in:
		| @@ -9,6 +9,8 @@ HEAD | |||||||
| * Renamed `JsonArray::removeAt(size_t)` into `remove(size_t)` | * Renamed `JsonArray::removeAt(size_t)` into `remove(size_t)` | ||||||
| * Renamed folder `include/` to `src/` | * Renamed folder `include/` to `src/` | ||||||
| * Fixed warnings `floating constant exceeds range of float`and `floating constant truncated to zero` (issue #483) | * Fixed warnings `floating constant exceeds range of float`and `floating constant truncated to zero` (issue #483) | ||||||
|  | * Removed `Print` class and converted `printTo()` to a template method (issue #276) | ||||||
|  | * Removed example `IndentedPrintExample.ino` | ||||||
|  |  | ||||||
| v5.8.4 | v5.8.4 | ||||||
| ------ | ------ | ||||||
|   | |||||||
| @@ -1,35 +0,0 @@ | |||||||
| // Copyright Benoit Blanchon 2014-2017 |  | ||||||
| // MIT License |  | ||||||
| // |  | ||||||
| // Arduino JSON library |  | ||||||
| // https://bblanchon.github.io/ArduinoJson/ |  | ||||||
| // If you like this project, please add a star! |  | ||||||
|  |  | ||||||
| #include <ArduinoJson.h> |  | ||||||
|  |  | ||||||
| using namespace ArduinoJson::Internals; |  | ||||||
|  |  | ||||||
| void setup() { |  | ||||||
|   Serial.begin(9600); |  | ||||||
|   while (!Serial) { |  | ||||||
|     // wait serial port initialization |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   IndentedPrint serial(Serial); |  | ||||||
|   serial.setTabSize(4); |  | ||||||
|  |  | ||||||
|   serial.println("This is at indentation 0"); |  | ||||||
|   serial.indent(); |  | ||||||
|   serial.println("This is at indentation 1"); |  | ||||||
|   serial.println("This is also at indentation 1"); |  | ||||||
|   serial.indent(); |  | ||||||
|   serial.println("This is at indentation 2"); |  | ||||||
|  |  | ||||||
|   serial.unindent(); |  | ||||||
|   serial.unindent(); |  | ||||||
|   serial.println("This is back at indentation 0"); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void loop() { |  | ||||||
|   // not used in this example |  | ||||||
| } |  | ||||||
| @@ -7,8 +7,6 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "../Print.hpp" |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -40,8 +40,8 @@ class JsonObject; | |||||||
| // - a string (const char*) | // - a string (const char*) | ||||||
| // - a reference to a JsonArray or JsonObject | // - a reference to a JsonArray or JsonObject | ||||||
| class JsonVariant : public JsonVariantBase<JsonVariant> { | class JsonVariant : public JsonVariantBase<JsonVariant> { | ||||||
|   friend void Internals::JsonSerializer::serialize(const JsonVariant &, |   template <typename Print> | ||||||
|                                                    JsonWriter &); |   friend class Internals::JsonSerializer; | ||||||
|  |  | ||||||
|  public: |  public: | ||||||
|   // Creates an uninitialized JsonVariant |   // Creates an uninitialized JsonVariant | ||||||
|   | |||||||
| @@ -1,44 +0,0 @@ | |||||||
| // Copyright Benoit Blanchon 2014-2017 |  | ||||||
| // MIT License |  | ||||||
| // |  | ||||||
| // Arduino JSON library |  | ||||||
| // https://bblanchon.github.io/ArduinoJson/ |  | ||||||
| // If you like this project, please add a star! |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #ifndef ARDUINO |  | ||||||
|  |  | ||||||
| #include <stddef.h> |  | ||||||
| #include <stdint.h> |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { |  | ||||||
| // This class reproduces Arduino's Print class |  | ||||||
| class Print { |  | ||||||
|  public: |  | ||||||
|   virtual ~Print() {} |  | ||||||
|  |  | ||||||
|   virtual size_t write(uint8_t) = 0; |  | ||||||
|  |  | ||||||
|   size_t print(const char* s) { |  | ||||||
|     size_t n = 0; |  | ||||||
|     while (*s) { |  | ||||||
|       n += write(static_cast<uint8_t>(*s++)); |  | ||||||
|     } |  | ||||||
|     return n; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   size_t println() { |  | ||||||
|     size_t n = 0; |  | ||||||
|     n += write('\r'); |  | ||||||
|     n += write('\n'); |  | ||||||
|     return n; |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #else |  | ||||||
|  |  | ||||||
| #include <Print.h> |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
| @@ -7,17 +7,19 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "../Print.hpp" |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
|  |  | ||||||
| // A dummy Print implementation used in JsonPrintable::measureLength() | // A dummy Print implementation used in JsonPrintable::measureLength() | ||||||
| class DummyPrint : public Print { | class DummyPrint { | ||||||
|  public: |  public: | ||||||
|   virtual size_t write(uint8_t) { |   size_t print(char) { | ||||||
|     return 1; |     return 1; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   size_t print(const char* s) { | ||||||
|  |     return strlen(s); | ||||||
|  |   } | ||||||
| }; | }; | ||||||
| } | } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "../Print.hpp" |  | ||||||
| #include "../StringTraits/StringTraits.hpp" | #include "../StringTraits/StringTraits.hpp" | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| @@ -15,15 +14,21 @@ namespace Internals { | |||||||
|  |  | ||||||
| // A Print implementation that allows to write in a String | // A Print implementation that allows to write in a String | ||||||
| template <typename TString> | template <typename TString> | ||||||
| class DynamicStringBuilder : public Print { | class DynamicStringBuilder { | ||||||
|  public: |  public: | ||||||
|   DynamicStringBuilder(TString &str) : _str(str) {} |   DynamicStringBuilder(TString &str) : _str(str) {} | ||||||
|  |  | ||||||
|   virtual size_t write(uint8_t c) { |   size_t print(char c) { | ||||||
|     StringTraits<TString>::append(_str, static_cast<char>(c)); |     StringTraits<TString>::append(_str, c); | ||||||
|     return 1; |     return 1; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   size_t print(const char *s) { | ||||||
|  |     size_t initialLen = _str.length(); | ||||||
|  |     StringTraits<TString>::append(_str, s); | ||||||
|  |     return _str.length() - initialLen; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   DynamicStringBuilder &operator=(const DynamicStringBuilder &); |   DynamicStringBuilder &operator=(const DynamicStringBuilder &); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,15 +7,14 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "../Print.hpp" |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
|  |  | ||||||
| // Decorator on top of Print to allow indented output. | // Decorator on top of Print to allow indented output. | ||||||
| // This class is used by JsonPrintable::prettyPrintTo() but can also be used | // This class is used by JsonPrintable::prettyPrintTo() but can also be used | ||||||
| // for your own purpose, like logging. | // for your own purpose, like logging. | ||||||
| class IndentedPrint : public Print { | template <typename Print> | ||||||
|  | class IndentedPrint { | ||||||
|  public: |  public: | ||||||
|   explicit IndentedPrint(Print &p) : sink(&p) { |   explicit IndentedPrint(Print &p) : sink(&p) { | ||||||
|     level = 0; |     level = 0; | ||||||
| @@ -23,14 +22,21 @@ class IndentedPrint : public Print { | |||||||
|     isNewLine = true; |     isNewLine = true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   virtual size_t write(uint8_t c) { |   size_t print(char c) { | ||||||
|     size_t n = 0; |     size_t n = 0; | ||||||
|     if (isNewLine) n += writeTabs(); |     if (isNewLine) n += writeTabs(); | ||||||
|     n += sink->write(c); |     n += sink->print(c); | ||||||
|     isNewLine = c == '\n'; |     isNewLine = c == '\n'; | ||||||
|     return n; |     return n; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   size_t print(const char *s) { | ||||||
|  |     // TODO: optimize | ||||||
|  |     size_t n = 0; | ||||||
|  |     while (*s) n += print(*s++); | ||||||
|  |     return n; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // Adds one level of indentation |   // Adds one level of indentation | ||||||
|   void indent() { |   void indent() { | ||||||
|     if (level < MAX_LEVEL) level++; |     if (level < MAX_LEVEL) level++; | ||||||
| @@ -54,7 +60,7 @@ class IndentedPrint : public Print { | |||||||
|  |  | ||||||
|   size_t writeTabs() { |   size_t writeTabs() { | ||||||
|     size_t n = 0; |     size_t n = 0; | ||||||
|     for (int i = 0; i < level * tabSize; i++) n += sink->write(' '); |     for (int i = 0; i < level * tabSize; i++) n += sink->print(' '); | ||||||
|     return n; |     return n; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -31,9 +31,12 @@ namespace Internals { | |||||||
| template <typename T> | template <typename T> | ||||||
| class JsonPrintable { | class JsonPrintable { | ||||||
|  public: |  public: | ||||||
|   size_t printTo(Print &print) const { |   template <typename Print> | ||||||
|     JsonWriter writer(print); |   typename TypeTraits::EnableIf<!TypeTraits::IsString<Print>::value, | ||||||
|     JsonSerializer::serialize(downcast(), writer); |                                 size_t>::type | ||||||
|  |   printTo(Print &print) const { | ||||||
|  |     JsonWriter<Print> writer(print); | ||||||
|  |     JsonSerializer<JsonWriter<Print> >::serialize(downcast(), writer); | ||||||
|     return writer.bytesWritten(); |     return writer.bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -62,8 +65,9 @@ class JsonPrintable { | |||||||
|     return printTo(sb); |     return printTo(sb); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   size_t prettyPrintTo(IndentedPrint &print) const { |   template <typename Print> | ||||||
|     Prettyfier p(print); |   size_t prettyPrintTo(IndentedPrint<Print> &print) const { | ||||||
|  |     Prettyfier<Print> p(print); | ||||||
|     return printTo(p); |     return printTo(p); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -77,8 +81,11 @@ class JsonPrintable { | |||||||
|     return prettyPrintTo(buffer, N); |     return prettyPrintTo(buffer, N); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   size_t prettyPrintTo(Print &print) const { |   template <typename Print> | ||||||
|     IndentedPrint indentedPrint = IndentedPrint(print); |   typename TypeTraits::EnableIf<!TypeTraits::IsString<Print>::value, | ||||||
|  |                                 size_t>::type | ||||||
|  |   prettyPrintTo(Print &print) const { | ||||||
|  |     IndentedPrint<Print> indentedPrint(print); | ||||||
|     return prettyPrintTo(indentedPrint); |     return prettyPrintTo(indentedPrint); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -20,14 +20,15 @@ class JsonVariant; | |||||||
|  |  | ||||||
| namespace Internals { | namespace Internals { | ||||||
|  |  | ||||||
|  | template <typename Writer> | ||||||
| class JsonSerializer { | class JsonSerializer { | ||||||
|  public: |  public: | ||||||
|   static void serialize(const JsonArray &, JsonWriter &); |   static void serialize(const JsonArray &, Writer &); | ||||||
|   static void serialize(const JsonArraySubscript &, JsonWriter &); |   static void serialize(const JsonArraySubscript &, Writer &); | ||||||
|   static void serialize(const JsonObject &, JsonWriter &); |   static void serialize(const JsonObject &, Writer &); | ||||||
|   template <typename TKey> |   template <typename TKey> | ||||||
|   static void serialize(const JsonObjectSubscript<TKey> &, JsonWriter &); |   static void serialize(const JsonObjectSubscript<TKey> &, Writer &); | ||||||
|   static void serialize(const JsonVariant &, JsonWriter &); |   static void serialize(const JsonVariant &, Writer &); | ||||||
| }; | }; | ||||||
| } | } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -14,8 +14,9 @@ | |||||||
| #include "../JsonVariant.hpp" | #include "../JsonVariant.hpp" | ||||||
| #include "JsonSerializer.hpp" | #include "JsonSerializer.hpp" | ||||||
|  |  | ||||||
| inline void ArduinoJson::Internals::JsonSerializer::serialize( | template <typename Writer> | ||||||
|     const JsonArray& array, JsonWriter& writer) { | inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize( | ||||||
|  |     const JsonArray& array, Writer& writer) { | ||||||
|   writer.beginArray(); |   writer.beginArray(); | ||||||
|  |  | ||||||
|   JsonArray::const_iterator it = array.begin(); |   JsonArray::const_iterator it = array.begin(); | ||||||
| @@ -31,13 +32,15 @@ inline void ArduinoJson::Internals::JsonSerializer::serialize( | |||||||
|   writer.endArray(); |   writer.endArray(); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline void ArduinoJson::Internals::JsonSerializer::serialize( | template <typename Writer> | ||||||
|     const JsonArraySubscript& arraySubscript, JsonWriter& writer) { | inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize( | ||||||
|  |     const JsonArraySubscript& arraySubscript, Writer& writer) { | ||||||
|   serialize(arraySubscript.as<JsonVariant>(), writer); |   serialize(arraySubscript.as<JsonVariant>(), writer); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline void ArduinoJson::Internals::JsonSerializer::serialize( | template <typename Writer> | ||||||
|     const JsonObject& object, JsonWriter& writer) { | inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize( | ||||||
|  |     const JsonObject& object, Writer& writer) { | ||||||
|   writer.beginObject(); |   writer.beginObject(); | ||||||
|  |  | ||||||
|   JsonObject::const_iterator it = object.begin(); |   JsonObject::const_iterator it = object.begin(); | ||||||
| @@ -55,14 +58,16 @@ inline void ArduinoJson::Internals::JsonSerializer::serialize( | |||||||
|   writer.endObject(); |   writer.endObject(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | template <typename Writer> | ||||||
| template <typename TKey> | template <typename TKey> | ||||||
| inline void ArduinoJson::Internals::JsonSerializer::serialize( | inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize( | ||||||
|     const JsonObjectSubscript<TKey>& objectSubscript, JsonWriter& writer) { |     const JsonObjectSubscript<TKey>& objectSubscript, Writer& writer) { | ||||||
|   serialize(objectSubscript.template as<JsonVariant>(), writer); |   serialize(objectSubscript.template as<JsonVariant>(), writer); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline void ArduinoJson::Internals::JsonSerializer::serialize( | template <typename Writer> | ||||||
|     const JsonVariant& variant, JsonWriter& writer) { | inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize( | ||||||
|  |     const JsonVariant& variant, Writer& writer) { | ||||||
|   switch (variant._type) { |   switch (variant._type) { | ||||||
|     case JSON_UNDEFINED: |     case JSON_UNDEFINED: | ||||||
|       return; |       return; | ||||||
|   | |||||||
| @@ -7,13 +7,13 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
|  | #include <stdint.h> | ||||||
| #include "../Data/Encoding.hpp" | #include "../Data/Encoding.hpp" | ||||||
| #include "../Data/JsonFloat.hpp" | #include "../Data/JsonFloat.hpp" | ||||||
| #include "../Data/JsonInteger.hpp" | #include "../Data/JsonInteger.hpp" | ||||||
| #include "../Polyfills/attributes.hpp" | #include "../Polyfills/attributes.hpp" | ||||||
| #include "../Polyfills/math.hpp" | #include "../Polyfills/math.hpp" | ||||||
| #include "../Polyfills/normalize.hpp" | #include "../Polyfills/normalize.hpp" | ||||||
| #include "../Print.hpp" |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
| @@ -25,6 +25,7 @@ namespace Internals { | |||||||
| // - JsonVariant::writeTo() | // - JsonVariant::writeTo() | ||||||
| // Its derived by PrettyJsonWriter that overrides some members to add | // Its derived by PrettyJsonWriter that overrides some members to add | ||||||
| // indentation. | // indentation. | ||||||
|  | template <typename Print> | ||||||
| class JsonWriter { | class JsonWriter { | ||||||
|  public: |  public: | ||||||
|   explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {} |   explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {} | ||||||
| @@ -150,7 +151,7 @@ class JsonWriter { | |||||||
|     _length += _sink.print(s); |     _length += _sink.print(s); | ||||||
|   } |   } | ||||||
|   void writeRaw(char c) { |   void writeRaw(char c) { | ||||||
|     _length += _sink.write(c); |     _length += _sink.print(c); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   | |||||||
| @@ -13,19 +13,27 @@ namespace ArduinoJson { | |||||||
| namespace Internals { | namespace Internals { | ||||||
|  |  | ||||||
| // Converts a compact JSON string into an indented one. | // Converts a compact JSON string into an indented one. | ||||||
| class Prettyfier : public Print { | template <typename Print> | ||||||
|  | class Prettyfier { | ||||||
|  public: |  public: | ||||||
|   explicit Prettyfier(IndentedPrint& p) : _sink(p) { |   explicit Prettyfier(IndentedPrint<Print>& p) : _sink(p) { | ||||||
|     _previousChar = 0; |     _previousChar = 0; | ||||||
|     _inString = false; |     _inString = false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   virtual size_t write(uint8_t c) { |   size_t print(char c) { | ||||||
|     size_t n = _inString ? handleStringChar(c) : handleMarkupChar(c); |     size_t n = _inString ? handleStringChar(c) : handleMarkupChar(c); | ||||||
|     _previousChar = c; |     _previousChar = c; | ||||||
|     return n; |     return n; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   size_t print(const char* s) { | ||||||
|  |     // TODO: optimize | ||||||
|  |     size_t n = 0; | ||||||
|  |     while (*s) n += print(*s++); | ||||||
|  |     return n; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   Prettyfier& operator=(const Prettyfier&);  // cannot be assigned |   Prettyfier& operator=(const Prettyfier&);  // cannot be assigned | ||||||
|  |  | ||||||
| @@ -33,15 +41,15 @@ class Prettyfier : public Print { | |||||||
|     return _previousChar == '{' || _previousChar == '['; |     return _previousChar == '{' || _previousChar == '['; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   size_t handleStringChar(uint8_t c) { |   size_t handleStringChar(char c) { | ||||||
|     bool isQuote = c == '"' && _previousChar != '\\'; |     bool isQuote = c == '"' && _previousChar != '\\'; | ||||||
|  |  | ||||||
|     if (isQuote) _inString = false; |     if (isQuote) _inString = false; | ||||||
|  |  | ||||||
|     return _sink.write(c); |     return _sink.print(c); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   size_t handleMarkupChar(uint8_t c) { |   size_t handleMarkupChar(char c) { | ||||||
|     switch (c) { |     switch (c) { | ||||||
|       case '{': |       case '{': | ||||||
|       case '[': |       case '[': | ||||||
| @@ -65,31 +73,29 @@ class Prettyfier : public Print { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   size_t writeBlockClose(uint8_t c) { |   size_t writeBlockClose(char c) { | ||||||
|     size_t n = 0; |     size_t n = 0; | ||||||
|     n += unindentIfNeeded(); |     n += unindentIfNeeded(); | ||||||
|     n += _sink.write(c); |     n += _sink.print(c); | ||||||
|     return n; |     return n; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   size_t writeBlockOpen(uint8_t c) { |   size_t writeBlockOpen(char c) { | ||||||
|     size_t n = 0; |     size_t n = 0; | ||||||
|     n += indentIfNeeded(); |     n += indentIfNeeded(); | ||||||
|     n += _sink.write(c); |     n += _sink.print(c); | ||||||
|     return n; |     return n; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   size_t writeColon() { |   size_t writeColon() { | ||||||
|     size_t n = 0; |     size_t n = 0; | ||||||
|     n += _sink.write(':'); |     n += _sink.print(": "); | ||||||
|     n += _sink.write(' '); |  | ||||||
|     return n; |     return n; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   size_t writeComma() { |   size_t writeComma() { | ||||||
|     size_t n = 0; |     size_t n = 0; | ||||||
|     n += _sink.write(','); |     n += _sink.print(",\r\n"); | ||||||
|     n += _sink.println(); |  | ||||||
|     return n; |     return n; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -97,14 +103,14 @@ class Prettyfier : public Print { | |||||||
|     _inString = true; |     _inString = true; | ||||||
|     size_t n = 0; |     size_t n = 0; | ||||||
|     n += indentIfNeeded(); |     n += indentIfNeeded(); | ||||||
|     n += _sink.write('"'); |     n += _sink.print('"'); | ||||||
|     return n; |     return n; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   size_t writeNormalChar(uint8_t c) { |   size_t writeNormalChar(char c) { | ||||||
|     size_t n = 0; |     size_t n = 0; | ||||||
|     n += indentIfNeeded(); |     n += indentIfNeeded(); | ||||||
|     n += _sink.write(c); |     n += _sink.print(c); | ||||||
|     return n; |     return n; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -112,18 +118,18 @@ class Prettyfier : public Print { | |||||||
|     if (!inEmptyBlock()) return 0; |     if (!inEmptyBlock()) return 0; | ||||||
|  |  | ||||||
|     _sink.indent(); |     _sink.indent(); | ||||||
|     return _sink.println(); |     return _sink.print("\r\n"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   size_t unindentIfNeeded() { |   size_t unindentIfNeeded() { | ||||||
|     if (inEmptyBlock()) return 0; |     if (inEmptyBlock()) return 0; | ||||||
|  |  | ||||||
|     _sink.unindent(); |     _sink.unindent(); | ||||||
|     return _sink.println(); |     return _sink.print("\r\n"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   uint8_t _previousChar; |   char _previousChar; | ||||||
|   IndentedPrint& _sink; |   IndentedPrint<Print>& _sink; | ||||||
|   bool _inString; |   bool _inString; | ||||||
| }; | }; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,31 +7,33 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "../Print.hpp" |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
|  |  | ||||||
| // A Print implementation that allows to write in a char[] | // A Print implementation that allows to write in a char[] | ||||||
| class StaticStringBuilder : public Print { | class StaticStringBuilder { | ||||||
|  public: |  public: | ||||||
|   StaticStringBuilder(char *buf, size_t size) |   StaticStringBuilder(char *buf, size_t size) : end(buf + size - 1), p(buf) { | ||||||
|       : buffer(buf), capacity(size - 1), length(0) { |     *p = '\0'; | ||||||
|     buffer[0] = '\0'; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   virtual size_t write(uint8_t c) { |   size_t print(char c) { | ||||||
|     if (length >= capacity) return 0; |     if (p >= end) return 0; | ||||||
|  |     *p++ = c; | ||||||
|     buffer[length++] = c; |     *p = '\0'; | ||||||
|     buffer[length] = '\0'; |  | ||||||
|     return 1; |     return 1; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   size_t print(const char *s) { | ||||||
|  |     char *begin = p; | ||||||
|  |     while (p < end && *s) *p++ = *s++; | ||||||
|  |     *p = '\0'; | ||||||
|  |     return p - begin; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   char *buffer; |   char *end; | ||||||
|   size_t capacity; |   char *p; | ||||||
|   size_t length; |  | ||||||
| }; | }; | ||||||
| } | } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -11,22 +11,25 @@ | |||||||
|  |  | ||||||
| #if ARDUINOJSON_ENABLE_STD_STREAM | #if ARDUINOJSON_ENABLE_STD_STREAM | ||||||
|  |  | ||||||
| #include "../Print.hpp" |  | ||||||
|  |  | ||||||
| #include <ostream> | #include <ostream> | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
|  |  | ||||||
| class StreamPrintAdapter : public Print { | class StreamPrintAdapter { | ||||||
|  public: |  public: | ||||||
|   explicit StreamPrintAdapter(std::ostream& os) : _os(os) {} |   explicit StreamPrintAdapter(std::ostream& os) : _os(os) {} | ||||||
|  |  | ||||||
|   virtual size_t write(uint8_t c) { |   size_t print(char c) { | ||||||
|     _os << static_cast<char>(c); |     _os << c; | ||||||
|     return 1; |     return 1; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   size_t print(const char* s) { | ||||||
|  |     _os << s; | ||||||
|  |     return strlen(s); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   // cannot be assigned |   // cannot be assigned | ||||||
|   StreamPrintAdapter& operator=(const StreamPrintAdapter&); |   StreamPrintAdapter& operator=(const StreamPrintAdapter&); | ||||||
|   | |||||||
| @@ -43,6 +43,10 @@ struct StdStringTraits { | |||||||
|     str += c; |     str += c; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static void append(TString& str, const char* s) { | ||||||
|  |     str += s; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static const bool has_append = true; |   static const bool has_append = true; | ||||||
|   static const bool has_equals = true; |   static const bool has_equals = true; | ||||||
|   static const bool should_duplicate = true; |   static const bool should_duplicate = true; | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ using namespace ArduinoJson::Internals; | |||||||
| void check(const std::string& expected, double input, uint8_t digits = 2) { | void check(const std::string& expected, double input, uint8_t digits = 2) { | ||||||
|   char output[1024]; |   char output[1024]; | ||||||
|   StaticStringBuilder sb(output, sizeof(output)); |   StaticStringBuilder sb(output, sizeof(output)); | ||||||
|   JsonWriter writer(sb); |   JsonWriter<StaticStringBuilder> writer(sb); | ||||||
|   writer.writeFloat(input, digits); |   writer.writeFloat(input, digits); | ||||||
|   REQUIRE(output == expected); |   REQUIRE(output == expected); | ||||||
|   REQUIRE(writer.bytesWritten() == expected.size()); |   REQUIRE(writer.bytesWritten() == expected.size()); | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ using namespace ArduinoJson::Internals; | |||||||
| void check(const char* input, std::string expected) { | void check(const char* input, std::string expected) { | ||||||
|   char output[1024]; |   char output[1024]; | ||||||
|   StaticStringBuilder sb(output, sizeof(output)); |   StaticStringBuilder sb(output, sizeof(output)); | ||||||
|   JsonWriter writer(sb); |   JsonWriter<StaticStringBuilder> writer(sb); | ||||||
|   writer.writeString(input); |   writer.writeString(input); | ||||||
|   REQUIRE(expected == output); |   REQUIRE(expected == output); | ||||||
|   REQUIRE(writer.bytesWritten() == expected.size()); |   REQUIRE(writer.bytesWritten() == expected.size()); | ||||||
|   | |||||||
| @@ -10,20 +10,12 @@ | |||||||
|  |  | ||||||
| using namespace ArduinoJson::Internals; | using namespace ArduinoJson::Internals; | ||||||
|  |  | ||||||
| TEST_CASE("StringBuilder") { | template <typename StringBuilder, typename String> | ||||||
|   char output[20]; | void common_tests(StringBuilder& sb, const String& output) { | ||||||
|   StaticStringBuilder sb(output, sizeof(output)); |  | ||||||
|  |  | ||||||
|   SECTION("InitialState") { |   SECTION("InitialState") { | ||||||
|     REQUIRE(std::string("") == output); |     REQUIRE(std::string("") == output); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("OverCapacity") { |  | ||||||
|     REQUIRE(19 == sb.print("ABCDEFGHIJKLMNOPQRSTUVWXYZ")); |  | ||||||
|     REQUIRE(0 == sb.print("ABC")); |  | ||||||
|     REQUIRE(std::string("ABCDEFGHIJKLMNOPQRS") == output); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   SECTION("EmptyString") { |   SECTION("EmptyString") { | ||||||
|     REQUIRE(0 == sb.print("")); |     REQUIRE(0 == sb.print("")); | ||||||
|     REQUIRE(std::string("") == output); |     REQUIRE(std::string("") == output); | ||||||
| @@ -40,3 +32,22 @@ TEST_CASE("StringBuilder") { | |||||||
|     REQUIRE(std::string("ABCDEFGH") == output); |     REQUIRE(std::string("ABCDEFGH") == output); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | TEST_CASE("StaticStringBuilder") { | ||||||
|  |   char output[20]; | ||||||
|  |   StaticStringBuilder sb(output, sizeof(output)); | ||||||
|  |  | ||||||
|  |   common_tests(sb, static_cast<const char*>(output)); | ||||||
|  |  | ||||||
|  |   SECTION("OverCapacity") { | ||||||
|  |     REQUIRE(19 == sb.print("ABCDEFGHIJKLMNOPQRSTUVWXYZ")); | ||||||
|  |     REQUIRE(0 == sb.print("ABC")); | ||||||
|  |     REQUIRE(std::string("ABCDEFGHIJKLMNOPQRS") == output); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST_CASE("DynamicStringBuilder") { | ||||||
|  |   std::string output; | ||||||
|  |   DynamicStringBuilder<std::string> sb(output); | ||||||
|  |   common_tests(sb, output); | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user