Explorar o código

Reduce number of overloads of `deserializeJson()` and `deserializeMsgPack()` (#1820)

Benoit Blanchon %!s(int64=3) %!d(string=hai) anos
pai
achega
5abf512276

+ 35 - 0
src/ArduinoJson/Deserialization/DeserializationOptions.hpp

@@ -0,0 +1,35 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright © 2014-2022, Benoit BLANCHON
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Deserialization/Filter.hpp>
+#include <ArduinoJson/Deserialization/NestingLimit.hpp>
+
+ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
+
+template <typename TFilter>
+struct DeserializationOptions {
+  TFilter filter;
+  DeserializationOption::NestingLimit nestingLimit;
+};
+
+template <typename TFilter>
+inline DeserializationOptions<TFilter> makeDeserializationOptions(
+    TFilter filter, DeserializationOption::NestingLimit nestingLimit = {}) {
+  return {filter, nestingLimit};
+}
+
+template <typename TFilter>
+inline DeserializationOptions<TFilter> makeDeserializationOptions(
+    DeserializationOption::NestingLimit nestingLimit, TFilter filter) {
+  return {filter, nestingLimit};
+}
+
+inline DeserializationOptions<AllowAllFilter> makeDeserializationOptions(
+    DeserializationOption::NestingLimit nestingLimit = {}) {
+  return {{}, nestingLimit};
+}
+
+ARDUINOJSON_END_PRIVATE_NAMESPACE

+ 16 - 0
src/ArduinoJson/Deserialization/Reader.hpp

@@ -5,6 +5,7 @@
 #pragma once
 
 #include <ArduinoJson/Namespace.hpp>
+#include <ArduinoJson/Polyfills/utility.hpp>
 
 #include <stdlib.h>  // for size_t
 
@@ -55,3 +56,18 @@ ARDUINOJSON_END_PRIVATE_NAMESPACE
 #if ARDUINOJSON_ENABLE_STD_STREAM
 #  include <ArduinoJson/Deserialization/Readers/StdStreamReader.hpp>
 #endif
+
+ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
+
+template <typename TInput>
+Reader<typename remove_reference<TInput>::type> makeReader(TInput&& input) {
+  return Reader<typename remove_reference<TInput>::type>{
+      detail::forward<TInput>(input)};
+}
+
+template <typename TChar>
+BoundedReader<TChar*> makeReader(TChar* input, size_t inputSize) {
+  return BoundedReader<TChar*>{input, inputSize};
+}
+
+ARDUINOJSON_END_PRIVATE_NAMESPACE

+ 21 - 45
src/ArduinoJson/Deserialization/deserialize.hpp

@@ -5,9 +5,9 @@
 #pragma once
 
 #include <ArduinoJson/Deserialization/DeserializationError.hpp>
-#include <ArduinoJson/Deserialization/Filter.hpp>
-#include <ArduinoJson/Deserialization/NestingLimit.hpp>
+#include <ArduinoJson/Deserialization/DeserializationOptions.hpp>
 #include <ArduinoJson/Deserialization/Reader.hpp>
+#include <ArduinoJson/Polyfills/utility.hpp>
 #include <ArduinoJson/StringStorage/StringStorage.hpp>
 
 ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
@@ -21,57 +21,33 @@ TDeserializer<TReader, TWriter> makeDeserializer(MemoryPool* pool,
   return TDeserializer<TReader, TWriter>(pool, reader, writer);
 }
 
-// deserialize(JsonDocument&, const std::string&, NestingLimit, Filter);
-// deserialize(JsonDocument&, const String&, NestingLimit, Filter);
-// deserialize(JsonDocument&, char*, NestingLimit, Filter);
-// deserialize(JsonDocument&, const char*, NestingLimit, Filter);
-// deserialize(JsonDocument&, const __FlashStringHelper*, NestingLimit, Filter);
-template <template <typename, typename> class TDeserializer, typename TString,
-          typename TFilter>
-typename detail::enable_if<!is_array<TString>::value,
-                           DeserializationError>::type
-deserialize(JsonDocument& doc, const TString& input,
-            DeserializationOption::NestingLimit nestingLimit, TFilter filter) {
-  Reader<TString> reader(input);
-  VariantData* data = VariantAttorney::getData(doc);
-  MemoryPool* pool = VariantAttorney::getPool(doc);
+template <template <typename, typename> class TDeserializer, typename TStream,
+          typename... Args>
+DeserializationError deserialize(JsonDocument& doc, TStream&& input,
+                                 Args... args) {
+  auto reader = makeReader(detail::forward<TStream>(input));
+  auto data = VariantAttorney::getData(doc);
+  auto pool = VariantAttorney::getPool(doc);
+  auto options = makeDeserializationOptions(args...);
   doc.clear();
   return makeDeserializer<TDeserializer>(pool, reader,
                                          makeStringStorage(input, pool))
-      .parse(*data, filter, nestingLimit);
+      .parse(*data, options.filter, options.nestingLimit);
 }
-//
-// deserialize(JsonDocument&, char*, size_t, NestingLimit, Filter);
-// deserialize(JsonDocument&, const char*, size_t, NestingLimit, Filter);
-// deserialize(JsonDocument&, const __FlashStringHelper*, size_t, NL, Filter);
+
 template <template <typename, typename> class TDeserializer, typename TChar,
-          typename TFilter>
-DeserializationError deserialize(
-    JsonDocument& doc, TChar* input, size_t inputSize,
-    DeserializationOption::NestingLimit nestingLimit, TFilter filter) {
-  BoundedReader<TChar*> reader(input, inputSize);
-  VariantData* data = VariantAttorney::getData(doc);
-  MemoryPool* pool = VariantAttorney::getPool(doc);
-  doc.clear();
-  return makeDeserializer<TDeserializer>(pool, reader,
-                                         makeStringStorage(input, pool))
-      .parse(*data, filter, nestingLimit);
-}
-//
-// deserialize(JsonDocument&, std::istream&, NestingLimit, Filter);
-// deserialize(JsonDocument&, Stream&, NestingLimit, Filter);
-template <template <typename, typename> class TDeserializer, typename TStream,
-          typename TFilter>
-DeserializationError deserialize(
-    JsonDocument& doc, TStream& input,
-    DeserializationOption::NestingLimit nestingLimit, TFilter filter) {
-  Reader<TStream> reader(input);
-  VariantData* data = VariantAttorney::getData(doc);
-  MemoryPool* pool = VariantAttorney::getPool(doc);
+          typename Size, typename... Args,
+          typename = typename enable_if<is_integral<Size>::value>::type>
+DeserializationError deserialize(JsonDocument& doc, TChar* input,
+                                 Size inputSize, Args... args) {
+  auto reader = makeReader(input, size_t(inputSize));
+  auto data = VariantAttorney::getData(doc);
+  auto pool = VariantAttorney::getPool(doc);
+  auto options = makeDeserializationOptions(args...);
   doc.clear();
   return makeDeserializer<TDeserializer>(pool, reader,
                                          makeStringStorage(input, pool))
-      .parse(*data, filter, nestingLimit);
+      .parse(*data, options.filter, options.nestingLimit);
 }
 
 ARDUINOJSON_END_PRIVATE_NAMESPACE

+ 9 - 123
src/ArduinoJson/Json/JsonDeserializer.hpp

@@ -13,6 +13,7 @@
 #include <ArduinoJson/Numbers/parseNumber.hpp>
 #include <ArduinoJson/Polyfills/assert.hpp>
 #include <ArduinoJson/Polyfills/type_traits.hpp>
+#include <ArduinoJson/Polyfills/utility.hpp>
 #include <ArduinoJson/Variant/VariantData.hpp>
 
 ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
@@ -671,137 +672,22 @@ ARDUINOJSON_END_PRIVATE_NAMESPACE
 
 ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
 
-// Parses a JSON input and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/json/deserializejson/
-template <typename TString>
-DeserializationError deserializeJson(
-    JsonDocument& doc, const TString& input,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<JsonDeserializer>(doc, input, nestingLimit,
-                                       AllowAllFilter());
-}
-
-// Parses a JSON input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/json/deserializejson/
-template <typename TString>
-DeserializationError deserializeJson(
-    JsonDocument& doc, const TString& input,
-    DeserializationOption::Filter filter,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<JsonDeserializer>(doc, input, nestingLimit, filter);
-}
-
-// Parses a JSON input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/json/deserializejson/
-template <typename TString>
-DeserializationError deserializeJson(
-    JsonDocument& doc, const TString& input,
-    DeserializationOption::NestingLimit nestingLimit,
-    DeserializationOption::Filter filter) {
-  using namespace detail;
-  return deserialize<JsonDeserializer>(doc, input, nestingLimit, filter);
-}
-
-// Parses a JSON input and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/json/deserializejson/
-template <typename TStream>
-DeserializationError deserializeJson(
-    JsonDocument& doc, TStream& input,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<JsonDeserializer>(doc, input, nestingLimit,
-                                       AllowAllFilter());
-}
-
-// Parses a JSON input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/json/deserializejson/
-template <typename TStream>
-DeserializationError deserializeJson(
-    JsonDocument& doc, TStream& input, DeserializationOption::Filter filter,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<JsonDeserializer>(doc, input, nestingLimit, filter);
-}
-
-// Parses a JSON input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/json/deserializejson/
-template <typename TStream>
-DeserializationError deserializeJson(
-    JsonDocument& doc, TStream& input,
-    DeserializationOption::NestingLimit nestingLimit,
-    DeserializationOption::Filter filter) {
-  using namespace detail;
-  return deserialize<JsonDeserializer>(doc, input, nestingLimit, filter);
-}
-
-// Parses a JSON input and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/json/deserializejson/
-template <typename TChar>
-DeserializationError deserializeJson(
-    JsonDocument& doc, TChar* input,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<JsonDeserializer>(doc, input, nestingLimit,
-                                       AllowAllFilter());
-}
-
-// Parses a JSON input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/json/deserializejson/
-template <typename TChar>
-DeserializationError deserializeJson(
-    JsonDocument& doc, TChar* input, DeserializationOption::Filter filter,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<JsonDeserializer>(doc, input, nestingLimit, filter);
-}
-
-// Parses a JSON input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/json/deserializejson/
-template <typename TChar>
-DeserializationError deserializeJson(
-    JsonDocument& doc, TChar* input,
-    DeserializationOption::NestingLimit nestingLimit,
-    DeserializationOption::Filter filter) {
-  using namespace detail;
-  return deserialize<JsonDeserializer>(doc, input, nestingLimit, filter);
-}
-
-// Parses a JSON input and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/json/deserializejson/
-template <typename TChar>
-DeserializationError deserializeJson(
-    JsonDocument& doc, TChar* input, size_t inputSize,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<JsonDeserializer>(doc, input, inputSize, nestingLimit,
-                                       AllowAllFilter());
-}
-
 // Parses a JSON input, filters, and puts the result in a JsonDocument.
 // https://arduinojson.org/v6/api/json/deserializejson/
-template <typename TChar>
-DeserializationError deserializeJson(
-    JsonDocument& doc, TChar* input, size_t inputSize,
-    DeserializationOption::Filter filter,
-    DeserializationOption::NestingLimit nestingLimit =
-        DeserializationOption::NestingLimit()) {
+template <typename... Args>
+DeserializationError deserializeJson(JsonDocument& doc, Args&&... args) {
   using namespace detail;
-  return deserialize<JsonDeserializer>(doc, input, inputSize, nestingLimit,
-                                       filter);
+  return deserialize<JsonDeserializer>(doc, detail::forward<Args>(args)...);
 }
 
 // Parses a JSON input, filters, and puts the result in a JsonDocument.
 // https://arduinojson.org/v6/api/json/deserializejson/
-template <typename TChar>
-DeserializationError deserializeJson(
-    JsonDocument& doc, TChar* input, size_t inputSize,
-    DeserializationOption::NestingLimit nestingLimit,
-    DeserializationOption::Filter filter) {
+template <typename TChar, typename... Args>
+DeserializationError deserializeJson(JsonDocument& doc, TChar* input,
+                                     Args&&... args) {
   using namespace detail;
-  return deserialize<JsonDeserializer>(doc, input, inputSize, nestingLimit,
-                                       filter);
+  return deserialize<JsonDeserializer>(doc, input,
+                                       detail::forward<Args>(args)...);
 }
 
 ARDUINOJSON_END_PUBLIC_NAMESPACE

+ 8 - 122
src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp

@@ -566,134 +566,20 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
 
 // Parses a MessagePack input and puts the result in a JsonDocument.
 // https://arduinojson.org/v6/api/msgpack/deserializemsgpack/
-template <typename TString>
-DeserializationError deserializeMsgPack(
-    JsonDocument& doc, const TString& input,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
+template <typename... Args>
+DeserializationError deserializeMsgPack(JsonDocument& doc, Args&&... args) {
   using namespace detail;
-  return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
-                                          AllowAllFilter());
-}
-
-// Parses a MessagePack input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/msgpack/deserializemsgpack/
-template <typename TString>
-DeserializationError deserializeMsgPack(
-    JsonDocument& doc, const TString& input,
-    DeserializationOption::Filter filter,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
-}
-
-// Parses a MessagePack input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/msgpack/deserializemsgpack/
-template <typename TString>
-DeserializationError deserializeMsgPack(
-    JsonDocument& doc, const TString& input,
-    DeserializationOption::NestingLimit nestingLimit,
-    DeserializationOption::Filter filter) {
-  using namespace detail;
-  return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
-}
-
-// Parses a MessagePack input and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/msgpack/deserializemsgpack/
-template <typename TStream>
-DeserializationError deserializeMsgPack(
-    JsonDocument& doc, TStream& input,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
-                                          AllowAllFilter());
-}
-
-// Parses a MessagePack input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/msgpack/deserializemsgpack/
-template <typename TStream>
-DeserializationError deserializeMsgPack(
-    JsonDocument& doc, TStream& input, DeserializationOption::Filter filter,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
-}
-
-// Parses a MessagePack input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/msgpack/deserializemsgpack/
-template <typename TStream>
-DeserializationError deserializeMsgPack(
-    JsonDocument& doc, TStream& input,
-    DeserializationOption::NestingLimit nestingLimit,
-    DeserializationOption::Filter filter) {
-  using namespace detail;
-  return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
+  return deserialize<MsgPackDeserializer>(doc, detail::forward<Args>(args)...);
 }
 
 // Parses a MessagePack input and puts the result in a JsonDocument.
 // https://arduinojson.org/v6/api/msgpack/deserializemsgpack/
-template <typename TChar>
-DeserializationError deserializeMsgPack(
-    JsonDocument& doc, TChar* input,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
-                                          AllowAllFilter());
-}
-
-// Parses a MessagePack input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/msgpack/deserializemsgpack/
-template <typename TChar>
-DeserializationError deserializeMsgPack(
-    JsonDocument& doc, TChar* input, DeserializationOption::Filter filter,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
-}
-
-// Parses a MessagePack input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/msgpack/deserializemsgpack/
-template <typename TChar>
-DeserializationError deserializeMsgPack(
-    JsonDocument& doc, TChar* input,
-    DeserializationOption::NestingLimit nestingLimit,
-    DeserializationOption::Filter filter) {
-  using namespace detail;
-  return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
-}
-
-// Parses a MessagePack input and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/msgpack/deserializemsgpack/
-template <typename TChar>
-DeserializationError deserializeMsgPack(
-    JsonDocument& doc, TChar* input, size_t inputSize,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit,
-                                          AllowAllFilter());
-}
-
-// Parses a MessagePack input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/msgpack/deserializemsgpack/
-template <typename TChar>
-DeserializationError deserializeMsgPack(
-    JsonDocument& doc, TChar* input, size_t inputSize,
-    DeserializationOption::Filter filter,
-    DeserializationOption::NestingLimit nestingLimit = {}) {
-  using namespace detail;
-  return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit,
-                                          filter);
-}
-
-// Parses a MessagePack input, filters, and puts the result in a JsonDocument.
-// https://arduinojson.org/v6/api/msgpack/deserializemsgpack/
-template <typename TChar>
-DeserializationError deserializeMsgPack(
-    JsonDocument& doc, TChar* input, size_t inputSize,
-    DeserializationOption::NestingLimit nestingLimit,
-    DeserializationOption::Filter filter) {
+template <typename TChar, typename... Args>
+DeserializationError deserializeMsgPack(JsonDocument& doc, TChar* input,
+                                        Args&&... args) {
   using namespace detail;
-  return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit,
-                                          filter);
+  return deserialize<MsgPackDeserializer>(doc, input,
+                                          detail::forward<Args>(args)...);
 }
 
 ARDUINOJSON_END_PUBLIC_NAMESPACE

+ 4 - 1
src/ArduinoJson/Polyfills/type_traits/is_base_of.hpp

@@ -6,6 +6,8 @@
 
 #include <ArduinoJson/Namespace.hpp>
 
+#include "remove_reference.hpp"
+
 ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 
 // A meta-function that returns true if Derived inherits from TBase is an
@@ -18,7 +20,8 @@ class is_base_of {
 
  public:
   static const bool value =
-      sizeof(probe(reinterpret_cast<TDerived*>(0))) == sizeof(int);
+      sizeof(probe(reinterpret_cast<typename remove_reference<TDerived>::type*>(
+          0))) == sizeof(int);
 };
 
 ARDUINOJSON_END_PRIVATE_NAMESPACE

+ 16 - 0
src/ArduinoJson/Polyfills/utility.hpp

@@ -0,0 +1,16 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright © 2014-2022, Benoit BLANCHON
+// MIT License
+
+#pragma once
+
+#include "type_traits.hpp"
+
+ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
+
+template <class T>
+T&& forward(typename remove_reference<T>::type& t) noexcept {
+  return static_cast<T&&>(t);
+}
+
+ARDUINOJSON_END_PRIVATE_NAMESPACE