forked from bblanchon/ArduinoJson
Added support for custom writer classes (closes #1088)
This commit is contained in:
@ -1,6 +1,11 @@
|
|||||||
ArduinoJson: change log
|
ArduinoJson: change log
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
|
HEAD
|
||||||
|
----
|
||||||
|
|
||||||
|
* Added support for custom writer classes (issue #1088)
|
||||||
|
|
||||||
v6.12.0 (2019-09-05)
|
v6.12.0 (2019-09-05)
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
# MIT License
|
# MIT License
|
||||||
|
|
||||||
add_executable(JsonSerializerTests
|
add_executable(JsonSerializerTests
|
||||||
|
CustomWriter.cpp
|
||||||
JsonArray.cpp
|
JsonArray.cpp
|
||||||
JsonArrayPretty.cpp
|
JsonArrayPretty.cpp
|
||||||
JsonObject.cpp
|
JsonObject.cpp
|
||||||
|
41
extras/tests/JsonSerializer/CustomWriter.cpp
Normal file
41
extras/tests/JsonSerializer/CustomWriter.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2019
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
struct CustomWriter {
|
||||||
|
std::string str;
|
||||||
|
|
||||||
|
size_t write(uint8_t c) {
|
||||||
|
str.append(1, static_cast<char>(c));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t write(const uint8_t *s, size_t n) {
|
||||||
|
str.append(reinterpret_cast<const char *>(s), n);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_CASE("CustomWriter") {
|
||||||
|
DynamicJsonDocument doc(4096);
|
||||||
|
JsonArray array = doc.to<JsonArray>();
|
||||||
|
array.add(4);
|
||||||
|
array.add(2);
|
||||||
|
|
||||||
|
SECTION("serializeJson()") {
|
||||||
|
CustomWriter writer;
|
||||||
|
serializeJson(array, writer);
|
||||||
|
|
||||||
|
REQUIRE("[4,2]" == writer.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("serializeJsonPretty") {
|
||||||
|
CustomWriter writer;
|
||||||
|
serializeJsonPretty(array, writer);
|
||||||
|
|
||||||
|
REQUIRE("[\r\n 4,\r\n 2\r\n]" == writer.str);
|
||||||
|
}
|
||||||
|
}
|
@ -2,10 +2,10 @@
|
|||||||
# Copyright Benoit Blanchon 2014-2019
|
# Copyright Benoit Blanchon 2014-2019
|
||||||
# MIT License
|
# MIT License
|
||||||
|
|
||||||
add_executable(JsonWriterTests
|
add_executable(TextFormatterTests
|
||||||
writeFloat.cpp
|
writeFloat.cpp
|
||||||
writeString.cpp
|
writeString.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(JsonWriterTests catch)
|
target_link_libraries(TextFormatterTests catch)
|
||||||
add_test(TextFormatter JsonWriterTests)
|
add_test(TextFormatter TextFormatterTests)
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
|
#include <ArduinoJson/Serialization/WriterSelector.hpp>
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||||
#include <WString.h>
|
#include <WString.h>
|
||||||
@ -79,4 +81,11 @@ class DynamicStringWriter<std::basic_string<char, TCharTraits, TAllocator> > {
|
|||||||
string_type *_str;
|
string_type *_str;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <typename TDestination>
|
||||||
|
struct WriterSelector<
|
||||||
|
TDestination,
|
||||||
|
typename enable_if<IsWriteableString<TDestination>::value>::type> {
|
||||||
|
typedef DynamicStringWriter<TDestination> writer_type;
|
||||||
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
37
src/ArduinoJson/Serialization/PrintWriter.hpp
Normal file
37
src/ArduinoJson/Serialization/PrintWriter.hpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2019
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
|
#include <ArduinoJson/Serialization/WriterSelector.hpp>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
class PrintWriter {
|
||||||
|
public:
|
||||||
|
explicit PrintWriter(Print& print) : _print(print) {}
|
||||||
|
|
||||||
|
size_t write(uint8_t c) {
|
||||||
|
return _print.write(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t write(const uint8_t* s, size_t n) {
|
||||||
|
return _print.write(s, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// cannot be assigned
|
||||||
|
PrintWriter& operator=(const PrintWriter&);
|
||||||
|
|
||||||
|
Print& _print;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TDestination>
|
||||||
|
struct WriterSelector<
|
||||||
|
TDestination,
|
||||||
|
typename enable_if<is_base_of<Print, TDestination>::value>::type> {
|
||||||
|
typedef PrintWriter writer_type;
|
||||||
|
};
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
@ -5,8 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
|
#include <ArduinoJson/Serialization/WriterSelector.hpp>
|
||||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
@ -33,6 +32,11 @@ class StreamWriter {
|
|||||||
|
|
||||||
std::ostream& _os;
|
std::ostream& _os;
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
|
||||||
|
|
||||||
#endif // ARDUINOJSON_ENABLE_STD_STREAM
|
template <typename TDestination>
|
||||||
|
struct WriterSelector<
|
||||||
|
TDestination,
|
||||||
|
typename enable_if<is_base_of<std::ostream, TDestination>::value>::type> {
|
||||||
|
typedef StreamWriter writer_type;
|
||||||
|
};
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
17
src/ArduinoJson/Serialization/WriterSelector.hpp
Normal file
17
src/ArduinoJson/Serialization/WriterSelector.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2019
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <typename TDestination, typename Enable = void>
|
||||||
|
struct WriterSelector {
|
||||||
|
// by default, assume destination implements the Writer concept
|
||||||
|
typedef TDestination& writer_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include <ArduinoJson/Serialization/DynamicStringWriter.hpp>
|
#include <ArduinoJson/Serialization/DynamicStringWriter.hpp>
|
||||||
#include <ArduinoJson/Serialization/StaticStringWriter.hpp>
|
#include <ArduinoJson/Serialization/StaticStringWriter.hpp>
|
||||||
|
|
||||||
@ -11,30 +12,26 @@
|
|||||||
#include <ArduinoJson/Serialization/StreamWriter.hpp>
|
#include <ArduinoJson/Serialization/StreamWriter.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ARDUINOJSON_ENABLE_ARDUINO_PRINT
|
||||||
|
#include <ArduinoJson/Serialization/PrintWriter.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <template <typename> class TSerializer, typename TSource,
|
template <template <typename> class TSerializer, typename TSource,
|
||||||
typename TDestination>
|
typename TWriter>
|
||||||
size_t doSerialize(const TSource &source, TDestination &destination) {
|
size_t doSerialize(const TSource &source, TWriter &writer) {
|
||||||
TSerializer<TDestination> serializer(destination);
|
TSerializer<TWriter> serializer(writer);
|
||||||
source.accept(serializer);
|
source.accept(serializer);
|
||||||
return serializer.bytesWritten();
|
return serializer.bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
template <template <typename> class TSerializer, typename TSource,
|
||||||
template <template <typename> class TSerializer, typename TSource>
|
typename TDestination>
|
||||||
size_t serialize(const TSource &source, std::ostream &destination) {
|
size_t serialize(const TSource &source, TDestination &destination) {
|
||||||
StreamWriter writer(destination);
|
typename WriterSelector<TDestination>::writer_type writer(destination);
|
||||||
return doSerialize<TSerializer>(source, writer);
|
return doSerialize<TSerializer>(source, writer);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_ARDUINO_PRINT
|
|
||||||
template <template <typename> class TSerializer, typename TSource>
|
|
||||||
size_t serialize(const TSource &source, Print &destination) {
|
|
||||||
return doSerialize<TSerializer>(source, destination);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <template <typename> class TSerializer, typename TSource>
|
template <template <typename> class TSerializer, typename TSource>
|
||||||
size_t serialize(const TSource &source, char *buffer, size_t bufferSize) {
|
size_t serialize(const TSource &source, char *buffer, size_t bufferSize) {
|
||||||
@ -48,12 +45,4 @@ size_t serialize(const TSource &source, char (&buffer)[N]) {
|
|||||||
return doSerialize<TSerializer>(source, writer);
|
return doSerialize<TSerializer>(source, writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <typename> class TSerializer, typename TSource,
|
|
||||||
typename TString>
|
|
||||||
typename enable_if<IsWriteableString<TString>::value, size_t>::type serialize(
|
|
||||||
const TSource &source, TString &str) {
|
|
||||||
DynamicStringWriter<TString> writer(str);
|
|
||||||
return doSerialize<TSerializer>(source, writer);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
Reference in New Issue
Block a user