forked from bblanchon/ArduinoJson
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