Added support for custom writer classes (closes #1088)

This commit is contained in:
Benoit Blanchon
2019-09-13 14:06:41 +02:00
parent 2078871f36
commit 498a2e4c1e
9 changed files with 133 additions and 30 deletions

View File

@ -4,7 +4,9 @@
#pragma once
#include <ArduinoJson/Configuration.hpp>
#include <ArduinoJson/Polyfills/type_traits.hpp>
#include <ArduinoJson/Serialization/WriterSelector.hpp>
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
#include <WString.h>
@ -79,4 +81,11 @@ class DynamicStringWriter<std::basic_string<char, TCharTraits, TAllocator> > {
string_type *_str;
};
#endif
template <typename TDestination>
struct WriterSelector<
TDestination,
typename enable_if<IsWriteableString<TDestination>::value>::type> {
typedef DynamicStringWriter<TDestination> writer_type;
};
} // namespace ARDUINOJSON_NAMESPACE

View 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

View File

@ -5,8 +5,7 @@
#pragma once
#include <ArduinoJson/Configuration.hpp>
#if ARDUINOJSON_ENABLE_STD_STREAM
#include <ArduinoJson/Serialization/WriterSelector.hpp>
#include <ostream>
@ -33,6 +32,11 @@ class StreamWriter {
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

View 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

View File

@ -4,6 +4,7 @@
#pragma once
#include <ArduinoJson/Configuration.hpp>
#include <ArduinoJson/Serialization/DynamicStringWriter.hpp>
#include <ArduinoJson/Serialization/StaticStringWriter.hpp>
@ -11,30 +12,26 @@
#include <ArduinoJson/Serialization/StreamWriter.hpp>
#endif
#if ARDUINOJSON_ENABLE_ARDUINO_PRINT
#include <ArduinoJson/Serialization/PrintWriter.hpp>
#endif
namespace ARDUINOJSON_NAMESPACE {
template <template <typename> class TSerializer, typename TSource,
typename TDestination>
size_t doSerialize(const TSource &source, TDestination &destination) {
TSerializer<TDestination> serializer(destination);
typename TWriter>
size_t doSerialize(const TSource &source, TWriter &writer) {
TSerializer<TWriter> serializer(writer);
source.accept(serializer);
return serializer.bytesWritten();
}
#if ARDUINOJSON_ENABLE_STD_STREAM
template <template <typename> class TSerializer, typename TSource>
size_t serialize(const TSource &source, std::ostream &destination) {
StreamWriter writer(destination);
template <template <typename> class TSerializer, typename TSource,
typename TDestination>
size_t serialize(const TSource &source, TDestination &destination) {
typename WriterSelector<TDestination>::writer_type writer(destination);
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>
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);
}
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