Update ArduinoJSON, esp-nimble-cpp, Arduino Core, ESP-IDF (#448)
* ArduinoJSON 7.1.0 * Update nimble and arduino core * Update nuki_ble
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
#include "ArduinoJson/Array/ElementProxy.hpp"
|
||||
#include "ArduinoJson/Array/Utilities.hpp"
|
||||
#include "ArduinoJson/Collection/CollectionImpl.hpp"
|
||||
#include "ArduinoJson/Memory/ResourceManagerImpl.hpp"
|
||||
#include "ArduinoJson/Memory/VariantPoolImpl.hpp"
|
||||
#include "ArduinoJson/Object/MemberProxy.hpp"
|
||||
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
||||
@@ -47,7 +48,9 @@
|
||||
#include "ArduinoJson/Json/JsonDeserializer.hpp"
|
||||
#include "ArduinoJson/Json/JsonSerializer.hpp"
|
||||
#include "ArduinoJson/Json/PrettyJsonSerializer.hpp"
|
||||
#include "ArduinoJson/MsgPack/MsgPackBinary.hpp"
|
||||
#include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp"
|
||||
#include "ArduinoJson/MsgPack/MsgPackExtension.hpp"
|
||||
#include "ArduinoJson/MsgPack/MsgPackSerializer.hpp"
|
||||
|
||||
#include "ArduinoJson/compatibility.hpp"
|
||||
|
||||
@@ -20,6 +20,17 @@ class ArrayData : public CollectionData {
|
||||
return array->addElement(resources);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool addValue(T&& value, ResourceManager* resources);
|
||||
|
||||
template <typename T>
|
||||
static bool addValue(ArrayData* array, T&& value,
|
||||
ResourceManager* resources) {
|
||||
if (!array)
|
||||
return false;
|
||||
return array->addValue(value, resources);
|
||||
}
|
||||
|
||||
VariantData* getOrAddElement(size_t index, ResourceManager* resources);
|
||||
|
||||
VariantData* getElement(size_t index, const ResourceManager* resources) const;
|
||||
|
||||
@@ -47,4 +47,19 @@ inline void ArrayData::removeElement(size_t index, ResourceManager* resources) {
|
||||
remove(at(index, resources), resources);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool ArrayData::addValue(T&& value, ResourceManager* resources) {
|
||||
ARDUINOJSON_ASSERT(resources != nullptr);
|
||||
auto slot = resources->allocSlot();
|
||||
if (!slot)
|
||||
return false;
|
||||
JsonVariant variant(slot->data(), resources);
|
||||
if (!variant.set(detail::forward<T>(value))) {
|
||||
resources->freeSlot(slot);
|
||||
return false;
|
||||
}
|
||||
addSlot(slot, resources);
|
||||
return true;
|
||||
}
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -44,8 +44,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// Returns a reference to the new element.
|
||||
// https://arduinojson.org/v7/api/jsonarray/add/
|
||||
template <typename T>
|
||||
typename detail::enable_if<!detail::is_same<T, JsonVariant>::value, T>::type
|
||||
add() const {
|
||||
detail::enable_if_t<!detail::is_same<T, JsonVariant>::value, T> add() const {
|
||||
return add<JsonVariant>().to<T>();
|
||||
}
|
||||
|
||||
@@ -53,8 +52,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// Returns a reference to the new element.
|
||||
// https://arduinojson.org/v7/api/jsonarray/add/
|
||||
template <typename T>
|
||||
typename detail::enable_if<detail::is_same<T, JsonVariant>::value, T>::type
|
||||
add() const {
|
||||
detail::enable_if_t<detail::is_same<T, JsonVariant>::value, T> add() const {
|
||||
return JsonVariant(detail::ArrayData::addElement(data_, resources_),
|
||||
resources_);
|
||||
}
|
||||
@@ -63,14 +61,14 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// https://arduinojson.org/v7/api/jsonarray/add/
|
||||
template <typename T>
|
||||
bool add(const T& value) const {
|
||||
return add<JsonVariant>().set(value);
|
||||
return detail::ArrayData::addValue(data_, value, resources_);
|
||||
}
|
||||
|
||||
// Appends a value to the array.
|
||||
// https://arduinojson.org/v7/api/jsonarray/add/
|
||||
template <typename T>
|
||||
bool add(T* value) const {
|
||||
return add<JsonVariant>().set(value);
|
||||
return detail::ArrayData::addValue(data_, value, resources_);
|
||||
}
|
||||
|
||||
// Returns an iterator to the first element of the array.
|
||||
@@ -114,6 +112,15 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
detail::ArrayData::removeElement(data_, index, resources_);
|
||||
}
|
||||
|
||||
// Removes the element at the specified index.
|
||||
// https://arduinojson.org/v7/api/jsonarray/remove/
|
||||
template <typename TVariant>
|
||||
detail::enable_if_t<detail::IsVariant<TVariant>::value> remove(
|
||||
TVariant variant) const {
|
||||
if (variant.template is<size_t>())
|
||||
remove(variant.template as<size_t>());
|
||||
}
|
||||
|
||||
// Removes all the elements of the array.
|
||||
// https://arduinojson.org/v7/api/jsonarray/clear/
|
||||
void clear() const {
|
||||
@@ -122,8 +129,23 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
|
||||
// Gets or sets the element at the specified index.
|
||||
// https://arduinojson.org/v7/api/jsonarray/subscript/
|
||||
detail::ElementProxy<JsonArray> operator[](size_t index) const {
|
||||
return {*this, index};
|
||||
template <typename T>
|
||||
detail::enable_if_t<detail::is_integral<T>::value,
|
||||
detail::ElementProxy<JsonArray>>
|
||||
operator[](T index) const {
|
||||
return {*this, size_t(index)};
|
||||
}
|
||||
|
||||
// Gets or sets the element at the specified index.
|
||||
// https://arduinojson.org/v7/api/jsonarray/subscript/
|
||||
template <typename TVariant>
|
||||
detail::enable_if_t<detail::IsVariant<TVariant>::value,
|
||||
detail::ElementProxy<JsonArray>>
|
||||
operator[](const TVariant& variant) const {
|
||||
if (variant.template is<size_t>())
|
||||
return operator[](variant.template as<size_t>());
|
||||
else
|
||||
return {*this, size_t(-1)};
|
||||
}
|
||||
|
||||
operator JsonVariantConst() const {
|
||||
|
||||
@@ -36,7 +36,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
}
|
||||
|
||||
// Creates an unbound reference.
|
||||
JsonArrayConst() : data_(0) {}
|
||||
JsonArrayConst() : data_(0), resources_(0) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonArrayConst(const detail::ArrayData* data,
|
||||
@@ -45,9 +45,23 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
|
||||
// Returns the element at the specified index.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/subscript/
|
||||
JsonVariantConst operator[](size_t index) const {
|
||||
template <typename T>
|
||||
detail::enable_if_t<detail::is_integral<T>::value, JsonVariantConst>
|
||||
operator[](T index) const {
|
||||
return JsonVariantConst(
|
||||
detail::ArrayData::getElement(data_, index, resources_), resources_);
|
||||
detail::ArrayData::getElement(data_, size_t(index), resources_),
|
||||
resources_);
|
||||
}
|
||||
|
||||
// Returns the element at the specified index.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/subscript/
|
||||
template <typename TVariant>
|
||||
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
|
||||
operator[](const TVariant& variant) const {
|
||||
if (variant.template is<size_t>())
|
||||
return operator[](variant.template as<size_t>());
|
||||
else
|
||||
return JsonVariantConst();
|
||||
}
|
||||
|
||||
operator JsonVariantConst() const {
|
||||
|
||||
@@ -12,16 +12,16 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
|
||||
// Copies a value to a JsonVariant.
|
||||
// This is a degenerated form of copyArray() to stop the recursion.
|
||||
template <typename T>
|
||||
inline typename detail::enable_if<!detail::is_array<T>::value, bool>::type
|
||||
copyArray(const T& src, JsonVariant dst) {
|
||||
inline detail::enable_if_t<!detail::is_array<T>::value, bool> copyArray(
|
||||
const T& src, JsonVariant dst) {
|
||||
return dst.set(src);
|
||||
}
|
||||
|
||||
// Copies values from an array to a JsonArray or a JsonVariant.
|
||||
// https://arduinojson.org/v7/api/misc/copyarray/
|
||||
template <typename T, size_t N, typename TDestination>
|
||||
inline typename detail::enable_if<
|
||||
!detail::is_base_of<JsonDocument, TDestination>::value, bool>::type
|
||||
inline detail::enable_if_t<
|
||||
!detail::is_base_of<JsonDocument, TDestination>::value, bool>
|
||||
copyArray(T (&src)[N], const TDestination& dst) {
|
||||
return copyArray(src, N, dst);
|
||||
}
|
||||
@@ -29,8 +29,8 @@ copyArray(T (&src)[N], const TDestination& dst) {
|
||||
// Copies values from an array to a JsonArray or a JsonVariant.
|
||||
// https://arduinojson.org/v7/api/misc/copyarray/
|
||||
template <typename T, typename TDestination>
|
||||
inline typename detail::enable_if<
|
||||
!detail::is_base_of<JsonDocument, TDestination>::value, bool>::type
|
||||
inline detail::enable_if_t<
|
||||
!detail::is_base_of<JsonDocument, TDestination>::value, bool>
|
||||
copyArray(const T* src, size_t len, const TDestination& dst) {
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
@@ -63,8 +63,8 @@ inline bool copyArray(const T* src, size_t len, JsonDocument& dst) {
|
||||
// Copies a value from a JsonVariant.
|
||||
// This is a degenerated form of copyArray() to stop the recursion.
|
||||
template <typename T>
|
||||
inline typename detail::enable_if<!detail::is_array<T>::value, size_t>::type
|
||||
copyArray(JsonVariantConst src, T& dst) {
|
||||
inline detail::enable_if_t<!detail::is_array<T>::value, size_t> copyArray(
|
||||
JsonVariantConst src, T& dst) {
|
||||
dst = src.as<T>();
|
||||
return 1;
|
||||
}
|
||||
@@ -103,10 +103,9 @@ inline size_t copyArray(JsonVariantConst src, char (&dst)[N]) {
|
||||
// Copies values from a JsonDocument to an array.
|
||||
// https://arduinojson.org/v7/api/misc/copyarray/
|
||||
template <typename TSource, typename T>
|
||||
inline typename detail::enable_if<
|
||||
detail::is_array<T>::value &&
|
||||
detail::is_base_of<JsonDocument, TSource>::value,
|
||||
size_t>::type
|
||||
inline detail::enable_if_t<detail::is_array<T>::value &&
|
||||
detail::is_base_of<JsonDocument, TSource>::value,
|
||||
size_t>
|
||||
copyArray(const TSource& src, T& dst) {
|
||||
return copyArray(src.template as<JsonArrayConst>(), dst);
|
||||
}
|
||||
|
||||
@@ -111,12 +111,13 @@ class CollectionData {
|
||||
return head_;
|
||||
}
|
||||
|
||||
void addSlot(SlotWithId slot, ResourceManager* resources);
|
||||
|
||||
protected:
|
||||
iterator addSlot(ResourceManager*);
|
||||
|
||||
private:
|
||||
SlotWithId getPreviousSlot(VariantSlot*, const ResourceManager*) const;
|
||||
void releaseSlot(SlotWithId, ResourceManager*);
|
||||
};
|
||||
|
||||
inline const VariantData* collectionToVariant(
|
||||
|
||||
@@ -63,13 +63,25 @@ inline CollectionData::iterator CollectionData::addSlot(
|
||||
return iterator(slot, slot.id());
|
||||
}
|
||||
|
||||
inline void CollectionData::addSlot(SlotWithId slot,
|
||||
ResourceManager* resources) {
|
||||
if (tail_ != NULL_SLOT) {
|
||||
auto tail = resources->getSlot(tail_);
|
||||
tail->setNext(slot.id());
|
||||
tail_ = slot.id();
|
||||
} else {
|
||||
head_ = slot.id();
|
||||
tail_ = slot.id();
|
||||
}
|
||||
}
|
||||
|
||||
inline void CollectionData::clear(ResourceManager* resources) {
|
||||
auto next = head_;
|
||||
while (next != NULL_SLOT) {
|
||||
auto currId = next;
|
||||
auto slot = resources->getSlot(next);
|
||||
next = slot->next();
|
||||
releaseSlot(SlotWithId(slot, currId), resources);
|
||||
resources->freeSlot(SlotWithId(slot, currId));
|
||||
}
|
||||
|
||||
head_ = NULL_SLOT;
|
||||
@@ -102,7 +114,7 @@ inline void CollectionData::remove(iterator it, ResourceManager* resources) {
|
||||
head_ = next;
|
||||
if (next == NULL_SLOT)
|
||||
tail_ = prev.id();
|
||||
releaseSlot({it.slot_, it.currentId_}, resources);
|
||||
resources->freeSlot({it.slot_, it.currentId_});
|
||||
}
|
||||
|
||||
inline size_t CollectionData::nesting(const ResourceManager* resources) const {
|
||||
@@ -122,12 +134,4 @@ inline size_t CollectionData::size(const ResourceManager* resources) const {
|
||||
return count;
|
||||
}
|
||||
|
||||
inline void CollectionData::releaseSlot(SlotWithId slot,
|
||||
ResourceManager* resources) {
|
||||
if (slot->ownsKey())
|
||||
resources->dereferenceString(slot->key());
|
||||
slot->data()->setNull(resources);
|
||||
resources->freeSlot(slot);
|
||||
}
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -93,11 +93,14 @@
|
||||
// https://arduinojson.org/v7/config/slot_id_size/
|
||||
#ifndef ARDUINOJSON_SLOT_ID_SIZE
|
||||
# if ARDUINOJSON_SIZEOF_POINTER <= 2
|
||||
# define ARDUINOJSON_SLOT_ID_SIZE 1 // up to 255 slots
|
||||
// 8-bit and 16-bit archs => up to 255 slots
|
||||
# define ARDUINOJSON_SLOT_ID_SIZE 1
|
||||
# elif ARDUINOJSON_SIZEOF_POINTER == 4
|
||||
# define ARDUINOJSON_SLOT_ID_SIZE 2 // up to 65535 slots
|
||||
// 32-bit arch => up to 65535 slots
|
||||
# define ARDUINOJSON_SLOT_ID_SIZE 2
|
||||
# else
|
||||
# define ARDUINOJSON_SLOT_ID_SIZE 4 // up to 4294967295 slots
|
||||
// 64-bit arch => up to 4294967295 slots
|
||||
# define ARDUINOJSON_SLOT_ID_SIZE 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -62,9 +62,8 @@ ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
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)};
|
||||
Reader<remove_reference_t<TInput>> makeReader(TInput&& input) {
|
||||
return Reader<remove_reference_t<TInput>>{detail::forward<TInput>(input)};
|
||||
}
|
||||
|
||||
template <typename TChar>
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource,
|
||||
typename enable_if<is_base_of<Stream, TSource>::value>::type> {
|
||||
struct Reader<TSource, enable_if_t<is_base_of<Stream, TSource>::value>> {
|
||||
public:
|
||||
explicit Reader(Stream& stream) : stream_(&stream) {}
|
||||
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource,
|
||||
typename enable_if<is_base_of<::String, TSource>::value>::type>
|
||||
struct Reader<TSource, enable_if_t<is_base_of<::String, TSource>::value>>
|
||||
: BoundedReader<const char*> {
|
||||
explicit Reader(const ::String& s)
|
||||
: BoundedReader<const char*>(s.c_str(), s.length()) {}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename TIterator>
|
||||
@@ -29,13 +31,8 @@ class IteratorReader {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct void_ {
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource, typename void_<typename TSource::const_iterator>::type>
|
||||
struct Reader<TSource, void_t<typename TSource::const_iterator>>
|
||||
: IteratorReader<typename TSource::const_iterator> {
|
||||
explicit Reader(const TSource& source)
|
||||
: IteratorReader<typename TSource::const_iterator>(source.begin(),
|
||||
|
||||
@@ -19,8 +19,7 @@ template <typename T>
|
||||
struct IsCharOrVoid<const T> : IsCharOrVoid<T> {};
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource*,
|
||||
typename enable_if<IsCharOrVoid<TSource>::value>::type> {
|
||||
struct Reader<TSource*, enable_if_t<IsCharOrVoid<TSource>::value>> {
|
||||
const char* ptr_;
|
||||
|
||||
public:
|
||||
@@ -39,8 +38,7 @@ struct Reader<TSource*,
|
||||
};
|
||||
|
||||
template <typename TSource>
|
||||
struct BoundedReader<TSource*,
|
||||
typename enable_if<IsCharOrVoid<TSource>::value>::type>
|
||||
struct BoundedReader<TSource*, enable_if_t<IsCharOrVoid<TSource>::value>>
|
||||
: public IteratorReader<const char*> {
|
||||
public:
|
||||
explicit BoundedReader(const void* ptr, size_t len)
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource, typename enable_if<
|
||||
is_base_of<std::istream, TSource>::value>::type> {
|
||||
struct Reader<TSource, enable_if_t<is_base_of<std::istream, TSource>::value>> {
|
||||
public:
|
||||
explicit Reader(std::istream& stream) : stream_(&stream) {}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename TVariant>
|
||||
struct Reader<TVariant, typename enable_if<IsVariant<TVariant>::value>::type>
|
||||
struct Reader<TVariant, enable_if_t<IsVariant<TVariant>::value>>
|
||||
: Reader<char*, void> {
|
||||
explicit Reader(const TVariant& x)
|
||||
: Reader<char*, void>(x.template as<const char*>()) {}
|
||||
|
||||
@@ -29,10 +29,9 @@ struct is_deserialize_destination : false_type {};
|
||||
|
||||
template <class T>
|
||||
struct is_deserialize_destination<
|
||||
T, typename enable_if<is_same<decltype(VariantAttorney::getResourceManager(
|
||||
detail::declval<T&>())),
|
||||
ResourceManager*>::value>::type> : true_type {
|
||||
};
|
||||
T, enable_if_t<is_same<decltype(VariantAttorney::getResourceManager(
|
||||
detail::declval<T&>())),
|
||||
ResourceManager*>::value>> : true_type {};
|
||||
|
||||
template <typename TDestination>
|
||||
inline void shrinkJsonDocument(TDestination&) {
|
||||
@@ -62,8 +61,8 @@ DeserializationError doDeserialize(TDestination&& dst, TReader reader,
|
||||
|
||||
template <template <typename> class TDeserializer, typename TDestination,
|
||||
typename TStream, typename... Args,
|
||||
typename = typename enable_if< // issue #1897
|
||||
!is_integral<typename first_or_void<Args...>::type>::value>::type>
|
||||
typename = enable_if_t< // issue #1897
|
||||
!is_integral<typename first_or_void<Args...>::type>::value>>
|
||||
DeserializationError deserialize(TDestination&& dst, TStream&& input,
|
||||
Args... args) {
|
||||
return doDeserialize<TDeserializer>(
|
||||
@@ -73,7 +72,7 @@ DeserializationError deserialize(TDestination&& dst, TStream&& input,
|
||||
|
||||
template <template <typename> class TDeserializer, typename TDestination,
|
||||
typename TChar, typename Size, typename... Args,
|
||||
typename = typename enable_if<is_integral<Size>::value>::type>
|
||||
typename = enable_if_t<is_integral<Size>::value>>
|
||||
DeserializationError deserialize(TDestination&& dst, TChar* input,
|
||||
Size inputSize, Args... args) {
|
||||
return doDeserialize<TDeserializer>(dst, makeReader(input, size_t(inputSize)),
|
||||
|
||||
@@ -37,15 +37,13 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
|
||||
// Construct from variant, array, or object
|
||||
template <typename T>
|
||||
JsonDocument(const T& src,
|
||||
Allocator* alloc = detail::DefaultAllocator::instance(),
|
||||
typename detail::enable_if<
|
||||
detail::is_same<T, JsonVariant>::value ||
|
||||
detail::is_same<T, JsonVariantConst>::value ||
|
||||
detail::is_same<T, JsonArray>::value ||
|
||||
detail::is_same<T, JsonArrayConst>::value ||
|
||||
detail::is_same<T, JsonObject>::value ||
|
||||
detail::is_same<T, JsonObjectConst>::value>::type* = 0)
|
||||
JsonDocument(
|
||||
const T& src, Allocator* alloc = detail::DefaultAllocator::instance(),
|
||||
detail::enable_if_t<detail::IsVariant<T>::value ||
|
||||
detail::is_same<T, JsonArray>::value ||
|
||||
detail::is_same<T, JsonArrayConst>::value ||
|
||||
detail::is_same<T, JsonObject>::value ||
|
||||
detail::is_same<T, JsonObjectConst>::value>* = 0)
|
||||
: JsonDocument(alloc) {
|
||||
set(src);
|
||||
}
|
||||
@@ -139,9 +137,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
// Replaces the root with the specified value.
|
||||
// https://arduinojson.org/v7/api/jsondocument/set/
|
||||
template <typename T>
|
||||
typename detail::enable_if<!detail::is_base_of<JsonDocument, T>::value,
|
||||
bool>::type
|
||||
set(const T& src) {
|
||||
detail::enable_if_t<!detail::is_base_of<JsonDocument, T>::value, bool> set(
|
||||
const T& src) {
|
||||
return to<JsonVariant>().set(src);
|
||||
}
|
||||
|
||||
@@ -163,15 +160,24 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
// Returns true if the root object contains the specified key.
|
||||
// https://arduinojson.org/v7/api/jsondocument/containskey/
|
||||
template <typename TString>
|
||||
bool containsKey(const TString& key) const {
|
||||
detail::enable_if_t<detail::IsString<TString>::value, bool> containsKey(
|
||||
const TString& key) const {
|
||||
return data_.getMember(detail::adaptString(key), &resources_) != 0;
|
||||
}
|
||||
|
||||
// Returns true if the root object contains the specified key.
|
||||
// https://arduinojson.org/v7/api/jsondocument/containskey/
|
||||
template <typename TVariant>
|
||||
detail::enable_if_t<detail::IsVariant<TVariant>::value, bool> containsKey(
|
||||
const TVariant& key) const {
|
||||
return containsKey(key.template as<const char*>());
|
||||
}
|
||||
|
||||
// Gets or sets a root object's member.
|
||||
// https://arduinojson.org/v7/api/jsondocument/subscript/
|
||||
template <typename TString>
|
||||
typename detail::enable_if<detail::IsString<TString>::value,
|
||||
detail::MemberProxy<JsonDocument&, TString>>::type
|
||||
detail::enable_if_t<detail::IsString<TString>::value,
|
||||
detail::MemberProxy<JsonDocument&, TString>>
|
||||
operator[](const TString& key) {
|
||||
return {*this, key};
|
||||
}
|
||||
@@ -179,8 +185,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
// Gets or sets a root object's member.
|
||||
// https://arduinojson.org/v7/api/jsondocument/subscript/
|
||||
template <typename TChar>
|
||||
typename detail::enable_if<detail::IsString<TChar*>::value,
|
||||
detail::MemberProxy<JsonDocument&, TChar*>>::type
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value,
|
||||
detail::MemberProxy<JsonDocument&, TChar*>>
|
||||
operator[](TChar* key) {
|
||||
return {*this, key};
|
||||
}
|
||||
@@ -188,8 +194,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
// Gets a root object's member.
|
||||
// https://arduinojson.org/v7/api/jsondocument/subscript/
|
||||
template <typename TString>
|
||||
typename detail::enable_if<detail::IsString<TString>::value,
|
||||
JsonVariantConst>::type
|
||||
detail::enable_if_t<detail::IsString<TString>::value, JsonVariantConst>
|
||||
operator[](const TString& key) const {
|
||||
return JsonVariantConst(
|
||||
data_.getMember(detail::adaptString(key), &resources_), &resources_);
|
||||
@@ -198,8 +203,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
// Gets a root object's member.
|
||||
// https://arduinojson.org/v7/api/jsondocument/subscript/
|
||||
template <typename TChar>
|
||||
typename detail::enable_if<detail::IsString<TChar*>::value,
|
||||
JsonVariantConst>::type
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value, JsonVariantConst>
|
||||
operator[](TChar* key) const {
|
||||
return JsonVariantConst(
|
||||
data_.getMember(detail::adaptString(key), &resources_), &resources_);
|
||||
@@ -207,8 +211,11 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
|
||||
// Gets or sets a root array's element.
|
||||
// https://arduinojson.org/v7/api/jsondocument/subscript/
|
||||
detail::ElementProxy<JsonDocument&> operator[](size_t index) {
|
||||
return {*this, index};
|
||||
template <typename T>
|
||||
detail::enable_if_t<detail::is_integral<T>::value,
|
||||
detail::ElementProxy<JsonDocument&>>
|
||||
operator[](T index) {
|
||||
return {*this, size_t(index)};
|
||||
}
|
||||
|
||||
// Gets a root array's member.
|
||||
@@ -217,12 +224,23 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
return JsonVariantConst(data_.getElement(index, &resources_), &resources_);
|
||||
}
|
||||
|
||||
// Gets or sets a root object's member.
|
||||
// https://arduinojson.org/v7/api/jsondocument/subscript/
|
||||
template <typename TVariant>
|
||||
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
|
||||
operator[](const TVariant& key) const {
|
||||
if (key.template is<const char*>())
|
||||
return operator[](key.template as<const char*>());
|
||||
if (key.template is<size_t>())
|
||||
return operator[](key.template as<size_t>());
|
||||
return {};
|
||||
}
|
||||
|
||||
// Appends a new (empty) element to the root array.
|
||||
// Returns a reference to the new element.
|
||||
// https://arduinojson.org/v7/api/jsondocument/add/
|
||||
template <typename T>
|
||||
typename detail::enable_if<!detail::is_same<T, JsonVariant>::value, T>::type
|
||||
add() {
|
||||
detail::enable_if_t<!detail::is_same<T, JsonVariant>::value, T> add() {
|
||||
return add<JsonVariant>().to<T>();
|
||||
}
|
||||
|
||||
@@ -230,8 +248,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
// Returns a reference to the new element.
|
||||
// https://arduinojson.org/v7/api/jsondocument/add/
|
||||
template <typename T>
|
||||
typename detail::enable_if<detail::is_same<T, JsonVariant>::value, T>::type
|
||||
add() {
|
||||
detail::enable_if_t<detail::is_same<T, JsonVariant>::value, T> add() {
|
||||
return JsonVariant(data_.addElement(&resources_), &resources_);
|
||||
}
|
||||
|
||||
@@ -239,27 +256,28 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
// https://arduinojson.org/v7/api/jsondocument/add/
|
||||
template <typename TValue>
|
||||
bool add(const TValue& value) {
|
||||
return add<JsonVariant>().set(value);
|
||||
return data_.addValue(value, &resources_);
|
||||
}
|
||||
|
||||
// Appends a value to the root array.
|
||||
// https://arduinojson.org/v7/api/jsondocument/add/
|
||||
template <typename TChar>
|
||||
bool add(TChar* value) {
|
||||
return add<JsonVariant>().set(value);
|
||||
return data_.addValue(value, &resources_);
|
||||
}
|
||||
|
||||
// Removes an element of the root array.
|
||||
// https://arduinojson.org/v7/api/jsondocument/remove/
|
||||
void remove(size_t index) {
|
||||
detail::VariantData::removeElement(getData(), index, getResourceManager());
|
||||
template <typename T>
|
||||
detail::enable_if_t<detail::is_integral<T>::value> remove(T index) {
|
||||
detail::VariantData::removeElement(getData(), size_t(index),
|
||||
getResourceManager());
|
||||
}
|
||||
|
||||
// Removes a member of the root object.
|
||||
// https://arduinojson.org/v7/api/jsondocument/remove/
|
||||
template <typename TChar>
|
||||
typename detail::enable_if<detail::IsString<TChar*>::value>::type remove(
|
||||
TChar* key) {
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value> remove(TChar* key) {
|
||||
detail::VariantData::removeMember(getData(), detail::adaptString(key),
|
||||
getResourceManager());
|
||||
}
|
||||
@@ -267,13 +285,23 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
// Removes a member of the root object.
|
||||
// https://arduinojson.org/v7/api/jsondocument/remove/
|
||||
template <typename TString>
|
||||
|
||||
typename detail::enable_if<detail::IsString<TString>::value>::type remove(
|
||||
detail::enable_if_t<detail::IsString<TString>::value> remove(
|
||||
const TString& key) {
|
||||
detail::VariantData::removeMember(getData(), detail::adaptString(key),
|
||||
getResourceManager());
|
||||
}
|
||||
|
||||
// Removes a member of the root object or an element of the root array.
|
||||
// https://arduinojson.org/v7/api/jsondocument/remove/
|
||||
template <typename TVariant>
|
||||
detail::enable_if_t<detail::IsVariant<TVariant>::value> remove(
|
||||
const TVariant& key) {
|
||||
if (key.template is<const char*>())
|
||||
remove(key.template as<const char*>());
|
||||
if (key.template is<size_t>())
|
||||
remove(key.template as<size_t>());
|
||||
}
|
||||
|
||||
operator JsonVariant() {
|
||||
return getVariant();
|
||||
}
|
||||
|
||||
@@ -671,9 +671,8 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
|
||||
// Parses a JSON input, filters, and puts the result in a JsonDocument.
|
||||
// https://arduinojson.org/v7/api/json/deserializejson/
|
||||
template <typename TDestination, typename... Args>
|
||||
typename detail::enable_if<
|
||||
detail::is_deserialize_destination<TDestination>::value,
|
||||
DeserializationError>::type
|
||||
detail::enable_if_t<detail::is_deserialize_destination<TDestination>::value,
|
||||
DeserializationError>
|
||||
deserializeJson(TDestination&& dst, Args&&... args) {
|
||||
using namespace detail;
|
||||
return deserialize<JsonDeserializer>(detail::forward<TDestination>(dst),
|
||||
@@ -683,9 +682,8 @@ deserializeJson(TDestination&& dst, Args&&... args) {
|
||||
// Parses a JSON input, filters, and puts the result in a JsonDocument.
|
||||
// https://arduinojson.org/v7/api/json/deserializejson/
|
||||
template <typename TDestination, typename TChar, typename... Args>
|
||||
typename detail::enable_if<
|
||||
detail::is_deserialize_destination<TDestination>::value,
|
||||
DeserializationError>::type
|
||||
detail::enable_if_t<detail::is_deserialize_destination<TDestination>::value,
|
||||
DeserializationError>
|
||||
deserializeJson(TDestination&& dst, TChar* input, Args&&... args) {
|
||||
using namespace detail;
|
||||
return deserialize<JsonDeserializer>(detail::forward<TDestination>(dst),
|
||||
|
||||
@@ -150,8 +150,8 @@ inline size_t measureJson(JsonVariantConst source) {
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
template <typename T>
|
||||
inline typename detail::enable_if<
|
||||
detail::is_convertible<T, JsonVariantConst>::value, std::ostream&>::type
|
||||
inline detail::enable_if_t<detail::is_convertible<T, JsonVariantConst>::value,
|
||||
std::ostream&>
|
||||
operator<<(std::ostream& os, const T& source) {
|
||||
serializeJson(source, os);
|
||||
return os;
|
||||
|
||||
@@ -100,8 +100,8 @@ class TextFormatter {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<is_signed<T>::value>::type writeInteger(T value) {
|
||||
typedef typename make_unsigned<T>::type unsigned_type;
|
||||
enable_if_t<is_signed<T>::value> writeInteger(T value) {
|
||||
typedef make_unsigned_t<T> unsigned_type;
|
||||
unsigned_type unsigned_value;
|
||||
if (value < 0) {
|
||||
writeRaw('-');
|
||||
@@ -113,7 +113,7 @@ class TextFormatter {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<is_unsigned<T>::value>::type writeInteger(T value) {
|
||||
enable_if_t<is_unsigned<T>::value> writeInteger(T value) {
|
||||
char buffer[22];
|
||||
char* end = buffer + sizeof(buffer);
|
||||
char* begin = end;
|
||||
|
||||
@@ -56,9 +56,7 @@ class ResourceManager {
|
||||
return p;
|
||||
}
|
||||
|
||||
void freeSlot(SlotWithId id) {
|
||||
variantPools_.freeSlot(id);
|
||||
}
|
||||
void freeSlot(SlotWithId slot);
|
||||
|
||||
VariantSlot* getSlot(SlotId id) const {
|
||||
return variantPools_.getSlot(id);
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
inline void ResourceManager::freeSlot(SlotWithId slot) {
|
||||
if (slot->ownsKey())
|
||||
dereferenceString(slot->key());
|
||||
slot->data()->setNull(this);
|
||||
variantPools_.freeSlot(slot);
|
||||
}
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
67
lib/ArduinoJson/src/ArduinoJson/Memory/StringBuffer.hpp
Normal file
67
lib/ArduinoJson/src/ArduinoJson/Memory/StringBuffer.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
class StringBuffer {
|
||||
public:
|
||||
StringBuffer(ResourceManager* resources) : resources_(resources) {}
|
||||
|
||||
~StringBuffer() {
|
||||
if (node_)
|
||||
resources_->destroyString(node_);
|
||||
}
|
||||
|
||||
char* reserve(size_t capacity) {
|
||||
if (node_ && capacity > node_->length) {
|
||||
// existing buffer is too small, we need to reallocate
|
||||
resources_->destroyString(node_);
|
||||
node_ = nullptr;
|
||||
}
|
||||
if (!node_)
|
||||
node_ = resources_->createString(capacity);
|
||||
if (!node_)
|
||||
return nullptr;
|
||||
size_ = capacity;
|
||||
node_->data[capacity] = 0; // null-terminate the string
|
||||
return node_->data;
|
||||
}
|
||||
|
||||
StringNode* save() {
|
||||
ARDUINOJSON_ASSERT(node_ != nullptr);
|
||||
node_->data[size_] = 0;
|
||||
auto node = resources_->getString(adaptString(node_->data, size_));
|
||||
if (node) {
|
||||
node->references++;
|
||||
return node;
|
||||
}
|
||||
|
||||
if (node_->length != size_) {
|
||||
node = resources_->resizeString(node_, size_);
|
||||
ARDUINOJSON_ASSERT(node != nullptr); // realloc to smaller can't fail
|
||||
} else {
|
||||
node = node_;
|
||||
}
|
||||
node_ = nullptr;
|
||||
resources_->saveString(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
JsonString str() const {
|
||||
ARDUINOJSON_ASSERT(node_ != nullptr);
|
||||
|
||||
return JsonString(node_->data, node_->length, JsonString::Copied);
|
||||
}
|
||||
|
||||
private:
|
||||
ResourceManager* resources_;
|
||||
StringNode* node_ = nullptr;
|
||||
size_t size_ = 0;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
@@ -17,9 +17,9 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
struct StringNode {
|
||||
// Use the same type as SlotId to store the reference count
|
||||
// (there can never be more references than slots)
|
||||
using references_type = uint_t<ARDUINOJSON_SLOT_ID_SIZE * 8>::type;
|
||||
using references_type = uint_t<ARDUINOJSON_SLOT_ID_SIZE * 8>;
|
||||
|
||||
using length_type = uint_t<ARDUINOJSON_STRING_LENGTH_SIZE * 8>::type;
|
||||
using length_type = uint_t<ARDUINOJSON_STRING_LENGTH_SIZE * 8>;
|
||||
|
||||
struct StringNode* next;
|
||||
references_type references;
|
||||
@@ -35,8 +35,10 @@ struct StringNode {
|
||||
static StringNode* create(size_t length, Allocator* allocator) {
|
||||
if (length > maxLength)
|
||||
return nullptr;
|
||||
auto node = reinterpret_cast<StringNode*>(
|
||||
allocator->allocate(sizeForLength(length)));
|
||||
auto size = sizeForLength(length);
|
||||
if (size < length) // integer overflow
|
||||
return nullptr; // (not testable on 64-bit)
|
||||
auto node = reinterpret_cast<StringNode*>(allocator->allocate(size));
|
||||
if (node) {
|
||||
node->length = length_type(length);
|
||||
node->references = 1;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
class VariantSlot;
|
||||
using SlotId = uint_t<ARDUINOJSON_SLOT_ID_SIZE * 8>::type;
|
||||
using SlotId = uint_t<ARDUINOJSON_SLOT_ID_SIZE * 8>;
|
||||
using SlotCount = SlotId;
|
||||
const SlotId NULL_SLOT = SlotId(-1);
|
||||
|
||||
|
||||
97
lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackBinary.hpp
Normal file
97
lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackBinary.hpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Variant/Converter.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
|
||||
|
||||
class MsgPackBinary {
|
||||
public:
|
||||
MsgPackBinary() : data_(nullptr), size_(0) {}
|
||||
explicit MsgPackBinary(const void* c, size_t size) : data_(c), size_(size) {}
|
||||
|
||||
const void* data() const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return size_;
|
||||
}
|
||||
|
||||
private:
|
||||
const void* data_;
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<MsgPackBinary> : private detail::VariantAttorney {
|
||||
static void toJson(MsgPackBinary src, JsonVariant dst) {
|
||||
auto data = VariantAttorney::getData(dst);
|
||||
if (!data)
|
||||
return;
|
||||
auto resources = getResourceManager(dst);
|
||||
if (src.data()) {
|
||||
size_t headerSize = src.size() >= 0x10000 ? 5
|
||||
: src.size() >= 0x100 ? 3
|
||||
: 2;
|
||||
auto str = resources->createString(src.size() + headerSize);
|
||||
if (str) {
|
||||
resources->saveString(str);
|
||||
auto ptr = reinterpret_cast<uint8_t*>(str->data);
|
||||
switch (headerSize) {
|
||||
case 2:
|
||||
ptr[0] = uint8_t(0xc4);
|
||||
ptr[1] = uint8_t(src.size() & 0xff);
|
||||
break;
|
||||
case 3:
|
||||
ptr[0] = uint8_t(0xc5);
|
||||
ptr[1] = uint8_t(src.size() >> 8 & 0xff);
|
||||
ptr[2] = uint8_t(src.size() & 0xff);
|
||||
break;
|
||||
case 5:
|
||||
ptr[0] = uint8_t(0xc6);
|
||||
ptr[1] = uint8_t(src.size() >> 24 & 0xff);
|
||||
ptr[2] = uint8_t(src.size() >> 16 & 0xff);
|
||||
ptr[3] = uint8_t(src.size() >> 8 & 0xff);
|
||||
ptr[4] = uint8_t(src.size() & 0xff);
|
||||
break;
|
||||
default:
|
||||
ARDUINOJSON_ASSERT(false);
|
||||
}
|
||||
memcpy(ptr + headerSize, src.data(), src.size());
|
||||
data->setRawString(str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
data->setNull();
|
||||
}
|
||||
|
||||
static MsgPackBinary fromJson(JsonVariantConst src) {
|
||||
auto data = getData(src);
|
||||
if (!data)
|
||||
return {};
|
||||
auto rawstr = data->asRawString();
|
||||
auto p = reinterpret_cast<const uint8_t*>(rawstr.c_str());
|
||||
auto n = rawstr.size();
|
||||
if (n >= 2 && p[0] == 0xc4) { // bin 8
|
||||
size_t size = p[1];
|
||||
if (size + 2 == n)
|
||||
return MsgPackBinary(p + 2, size);
|
||||
} else if (n >= 3 && p[0] == 0xc5) { // bin 16
|
||||
size_t size = size_t(p[1] << 8) | p[2];
|
||||
if (size + 3 == n)
|
||||
return MsgPackBinary(p + 3, size);
|
||||
} else if (n >= 5 && p[0] == 0xc6) { // bin 32
|
||||
size_t size =
|
||||
size_t(p[1] << 24) | size_t(p[2] << 16) | size_t(p[3] << 8) | p[4];
|
||||
if (size + 5 == n)
|
||||
return MsgPackBinary(p + 5, size);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
static bool checkJson(JsonVariantConst src) {
|
||||
return fromJson(src).data() != nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PUBLIC_NAMESPACE
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
#include <ArduinoJson/Deserialization/deserialize.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/MsgPack/endianess.hpp>
|
||||
#include <ArduinoJson/Memory/StringBuffer.hpp>
|
||||
#include <ArduinoJson/MsgPack/endianness.hpp>
|
||||
#include <ArduinoJson/MsgPack/ieee754.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
@@ -19,7 +20,7 @@ class MsgPackDeserializer {
|
||||
MsgPackDeserializer(ResourceManager* resources, TReader reader)
|
||||
: resources_(resources),
|
||||
reader_(reader),
|
||||
stringBuilder_(resources),
|
||||
stringBuffer_(resources),
|
||||
foundSomething_(false) {}
|
||||
|
||||
template <typename TFilter>
|
||||
@@ -37,11 +38,13 @@ class MsgPackDeserializer {
|
||||
DeserializationOption::NestingLimit nestingLimit) {
|
||||
DeserializationError::Code err;
|
||||
|
||||
uint8_t code = 0; // TODO: why do we need to initialize this variable?
|
||||
err = readByte(code);
|
||||
uint8_t header[5];
|
||||
err = readBytes(header, 1);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
const uint8_t& code = header[0];
|
||||
|
||||
foundSomething_ = true;
|
||||
|
||||
bool allowValue = filter.allowValue();
|
||||
@@ -51,6 +54,14 @@ class MsgPackDeserializer {
|
||||
ARDUINOJSON_ASSERT(variant != 0);
|
||||
}
|
||||
|
||||
if (code >= 0xcc && code <= 0xd3) {
|
||||
auto width = uint8_t(1U << ((code - 0xcc) % 4));
|
||||
if (allowValue)
|
||||
return readInteger(variant, width, code >= 0xd0);
|
||||
else
|
||||
return skipBytes(width);
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
case 0xc0:
|
||||
// already null
|
||||
@@ -60,33 +71,11 @@ class MsgPackDeserializer {
|
||||
return DeserializationError::InvalidInput;
|
||||
|
||||
case 0xc2:
|
||||
if (allowValue)
|
||||
variant->setBoolean(false);
|
||||
return DeserializationError::Ok;
|
||||
|
||||
case 0xc3:
|
||||
if (allowValue)
|
||||
variant->setBoolean(true);
|
||||
variant->setBoolean(code == 0xc3);
|
||||
return DeserializationError::Ok;
|
||||
|
||||
case 0xc4: // bin 8 (not supported)
|
||||
return skipString<uint8_t>();
|
||||
|
||||
case 0xc5: // bin 16 (not supported)
|
||||
return skipString<uint16_t>();
|
||||
|
||||
case 0xc6: // bin 32 (not supported)
|
||||
return skipString<uint32_t>();
|
||||
|
||||
case 0xc7: // ext 8 (not supported)
|
||||
return skipExt<uint8_t>();
|
||||
|
||||
case 0xc8: // ext 16 (not supported)
|
||||
return skipExt<uint16_t>();
|
||||
|
||||
case 0xc9: // ext 32 (not supported)
|
||||
return skipExt<uint32_t>();
|
||||
|
||||
case 0xca:
|
||||
if (allowValue)
|
||||
return readFloat<float>(variant);
|
||||
@@ -98,128 +87,97 @@ class MsgPackDeserializer {
|
||||
return readDouble<double>(variant);
|
||||
else
|
||||
return skipBytes(8);
|
||||
}
|
||||
|
||||
case 0xcc:
|
||||
if (allowValue)
|
||||
return readInteger<uint8_t>(variant);
|
||||
else
|
||||
return skipBytes(1);
|
||||
if (code <= 0x7f || code >= 0xe0) { // fixint
|
||||
if (allowValue)
|
||||
variant->setInteger(static_cast<int8_t>(code));
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
case 0xcd:
|
||||
if (allowValue)
|
||||
return readInteger<uint16_t>(variant);
|
||||
else
|
||||
return skipBytes(2);
|
||||
uint8_t sizeBytes = 0;
|
||||
size_t size = 0;
|
||||
bool isExtension = code >= 0xc7 && code <= 0xc9;
|
||||
|
||||
case 0xce:
|
||||
if (allowValue)
|
||||
return readInteger<uint32_t>(variant);
|
||||
else
|
||||
return skipBytes(4);
|
||||
switch (code) {
|
||||
case 0xc4: // bin 8
|
||||
case 0xc7: // ext 8
|
||||
case 0xd9: // str 8
|
||||
sizeBytes = 1;
|
||||
break;
|
||||
|
||||
case 0xcf:
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
if (allowValue)
|
||||
return readInteger<uint64_t>(variant);
|
||||
else
|
||||
return skipBytes(8);
|
||||
#else
|
||||
return skipBytes(8); // not supported
|
||||
#endif
|
||||
case 0xc5: // bin 16
|
||||
case 0xc8: // ext 16
|
||||
case 0xda: // str 16
|
||||
case 0xdc: // array 16
|
||||
case 0xde: // map 16
|
||||
sizeBytes = 2;
|
||||
break;
|
||||
|
||||
case 0xd0:
|
||||
if (allowValue)
|
||||
return readInteger<int8_t>(variant);
|
||||
else
|
||||
return skipBytes(1);
|
||||
case 0xc6: // bin 32
|
||||
case 0xc9: // ext 32
|
||||
case 0xdb: // str 32
|
||||
case 0xdd: // array 32
|
||||
case 0xdf: // map 32
|
||||
sizeBytes = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xd1:
|
||||
if (allowValue)
|
||||
return readInteger<int16_t>(variant);
|
||||
else
|
||||
return skipBytes(2);
|
||||
|
||||
case 0xd2:
|
||||
if (allowValue)
|
||||
return readInteger<int32_t>(variant);
|
||||
else
|
||||
return skipBytes(4);
|
||||
|
||||
case 0xd3:
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
if (allowValue)
|
||||
return readInteger<int64_t>(variant);
|
||||
else
|
||||
return skipBytes(8); // not supported
|
||||
#else
|
||||
return skipBytes(8);
|
||||
#endif
|
||||
|
||||
case 0xd4: // fixext 1 (not supported)
|
||||
return skipBytes(2);
|
||||
|
||||
case 0xd5: // fixext 2 (not supported)
|
||||
return skipBytes(3);
|
||||
|
||||
case 0xd6: // fixext 4 (not supported)
|
||||
return skipBytes(5);
|
||||
|
||||
case 0xd7: // fixext 8 (not supported)
|
||||
return skipBytes(9);
|
||||
|
||||
case 0xd8: // fixext 16 (not supported)
|
||||
return skipBytes(17);
|
||||
|
||||
case 0xd9:
|
||||
if (allowValue)
|
||||
return readString<uint8_t>(variant);
|
||||
else
|
||||
return skipString<uint8_t>();
|
||||
|
||||
case 0xda:
|
||||
if (allowValue)
|
||||
return readString<uint16_t>(variant);
|
||||
else
|
||||
return skipString<uint16_t>();
|
||||
|
||||
case 0xdb:
|
||||
if (allowValue)
|
||||
return readString<uint32_t>(variant);
|
||||
else
|
||||
return skipString<uint32_t>();
|
||||
|
||||
case 0xdc:
|
||||
return readArray<uint16_t>(variant, filter, nestingLimit);
|
||||
|
||||
case 0xdd:
|
||||
return readArray<uint32_t>(variant, filter, nestingLimit);
|
||||
|
||||
case 0xde:
|
||||
return readObject<uint16_t>(variant, filter, nestingLimit);
|
||||
|
||||
case 0xdf:
|
||||
return readObject<uint32_t>(variant, filter, nestingLimit);
|
||||
if (code >= 0xd4 && code <= 0xd8) { // fixext
|
||||
size = size_t(1) << (code - 0xd4);
|
||||
isExtension = true;
|
||||
}
|
||||
|
||||
switch (code & 0xf0) {
|
||||
case 0x80:
|
||||
return readObject(variant, code & 0x0F, filter, nestingLimit);
|
||||
|
||||
case 0x90:
|
||||
return readArray(variant, code & 0x0F, filter, nestingLimit);
|
||||
case 0x90: // fixarray
|
||||
case 0x80: // fixmap
|
||||
size = code & 0x0F;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((code & 0xe0) == 0xa0) {
|
||||
switch (code & 0xe0) {
|
||||
case 0xa0: // fixstr
|
||||
size = code & 0x1f;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sizeBytes) {
|
||||
err = readBytes(header + 1, sizeBytes);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
uint32_t size32 = 0;
|
||||
for (uint8_t i = 0; i < sizeBytes; i++)
|
||||
size32 = (size32 << 8) | header[i + 1];
|
||||
|
||||
size = size_t(size32);
|
||||
if (size < size32) // integer overflow
|
||||
return DeserializationError::NoMemory; // (not testable on 32/64-bit)
|
||||
}
|
||||
|
||||
// array 16, 32 and fixarray
|
||||
if (code == 0xdc || code == 0xdd || (code & 0xf0) == 0x90)
|
||||
return readArray(variant, size, filter, nestingLimit);
|
||||
|
||||
// map 16, 32 and fixmap
|
||||
if (code == 0xde || code == 0xdf || (code & 0xf0) == 0x80)
|
||||
return readObject(variant, size, filter, nestingLimit);
|
||||
|
||||
// str 8, 16, 32 and fixstr
|
||||
if (code == 0xd9 || code == 0xda || code == 0xdb || (code & 0xe0) == 0xa0) {
|
||||
if (allowValue)
|
||||
return readString(variant, code & 0x1f);
|
||||
return readString(variant, size);
|
||||
else
|
||||
return skipBytes(code & 0x1f);
|
||||
return skipBytes(size);
|
||||
}
|
||||
|
||||
if (isExtension)
|
||||
size++; // to include the type
|
||||
|
||||
if (allowValue)
|
||||
variant->setInteger(static_cast<int8_t>(code));
|
||||
|
||||
return DeserializationError::Ok;
|
||||
return readRawString(variant, header, uint8_t(1 + sizeBytes), size);
|
||||
else
|
||||
return skipBytes(size);
|
||||
}
|
||||
|
||||
DeserializationError::Code readByte(uint8_t& value) {
|
||||
@@ -230,7 +188,7 @@ class MsgPackDeserializer {
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
DeserializationError::Code readBytes(uint8_t* p, size_t n) {
|
||||
DeserializationError::Code readBytes(void* p, size_t n) {
|
||||
if (reader_.readBytes(reinterpret_cast<char*>(p), n) == n)
|
||||
return DeserializationError::Ok;
|
||||
return DeserializationError::IncompleteInput;
|
||||
@@ -238,7 +196,7 @@ class MsgPackDeserializer {
|
||||
|
||||
template <typename T>
|
||||
DeserializationError::Code readBytes(T& value) {
|
||||
return readBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
|
||||
return readBytes(&value, sizeof(value));
|
||||
}
|
||||
|
||||
DeserializationError::Code skipBytes(size_t n) {
|
||||
@@ -249,36 +207,45 @@ class MsgPackDeserializer {
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DeserializationError::Code readInteger(T& value) {
|
||||
DeserializationError::Code err;
|
||||
DeserializationError::Code readInteger(VariantData* variant, uint8_t width,
|
||||
bool isSigned) {
|
||||
uint8_t buffer[8];
|
||||
|
||||
err = readBytes(value);
|
||||
auto err = readBytes(buffer, width);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
fixEndianess(value);
|
||||
union {
|
||||
int64_t signedValue;
|
||||
uint64_t unsignedValue;
|
||||
};
|
||||
|
||||
if (isSigned)
|
||||
signedValue = static_cast<int8_t>(buffer[0]); // propagate sign bit
|
||||
else
|
||||
unsignedValue = static_cast<uint8_t>(buffer[0]);
|
||||
|
||||
for (uint8_t i = 1; i < width; i++)
|
||||
unsignedValue = (unsignedValue << 8) | buffer[i];
|
||||
|
||||
if (isSigned) {
|
||||
auto truncatedValue = static_cast<JsonInteger>(signedValue);
|
||||
if (truncatedValue == signedValue)
|
||||
variant->setInteger(truncatedValue);
|
||||
// else set null on overflow
|
||||
} else {
|
||||
auto truncatedValue = static_cast<JsonUInt>(unsignedValue);
|
||||
if (truncatedValue == unsignedValue)
|
||||
variant->setInteger(truncatedValue);
|
||||
// else set null on overflow
|
||||
}
|
||||
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DeserializationError::Code readInteger(VariantData* variant) {
|
||||
DeserializationError::Code err;
|
||||
T value;
|
||||
|
||||
err = readInteger(value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
variant->setInteger(value);
|
||||
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 4, DeserializationError::Code>::type
|
||||
readFloat(VariantData* variant) {
|
||||
enable_if_t<sizeof(T) == 4, DeserializationError::Code> readFloat(
|
||||
VariantData* variant) {
|
||||
DeserializationError::Code err;
|
||||
T value;
|
||||
|
||||
@@ -286,15 +253,15 @@ class MsgPackDeserializer {
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
fixEndianess(value);
|
||||
fixEndianness(value);
|
||||
variant->setFloat(value);
|
||||
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 8, DeserializationError::Code>::type
|
||||
readDouble(VariantData* variant) {
|
||||
enable_if_t<sizeof(T) == 8, DeserializationError::Code> readDouble(
|
||||
VariantData* variant) {
|
||||
DeserializationError::Code err;
|
||||
T value;
|
||||
|
||||
@@ -302,15 +269,15 @@ class MsgPackDeserializer {
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
fixEndianess(value);
|
||||
fixEndianness(value);
|
||||
variant->setFloat(value);
|
||||
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 4, DeserializationError::Code>::type
|
||||
readDouble(VariantData* variant) {
|
||||
enable_if_t<sizeof(T) == 4, DeserializationError::Code> readDouble(
|
||||
VariantData* variant) {
|
||||
DeserializationError::Code err;
|
||||
uint8_t i[8]; // input is 8 bytes
|
||||
T value; // output is 4 bytes
|
||||
@@ -321,48 +288,12 @@ class MsgPackDeserializer {
|
||||
return err;
|
||||
|
||||
doubleToFloat(i, o);
|
||||
fixEndianess(value);
|
||||
fixEndianness(value);
|
||||
variant->setFloat(value);
|
||||
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DeserializationError::Code readString(VariantData* variant) {
|
||||
DeserializationError::Code err;
|
||||
T size;
|
||||
|
||||
err = readInteger(size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return readString(variant, size);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DeserializationError::Code readString() {
|
||||
DeserializationError::Code err;
|
||||
T size;
|
||||
|
||||
err = readInteger(size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return readString(size);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DeserializationError::Code skipString() {
|
||||
DeserializationError::Code err;
|
||||
T size;
|
||||
|
||||
err = readInteger(size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return skipBytes(size);
|
||||
}
|
||||
|
||||
DeserializationError::Code readString(VariantData* variant, size_t n) {
|
||||
DeserializationError::Code err;
|
||||
|
||||
@@ -370,42 +301,37 @@ class MsgPackDeserializer {
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
variant->setOwnedString(stringBuilder_.save());
|
||||
variant->setOwnedString(stringBuffer_.save());
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
DeserializationError::Code readString(size_t n) {
|
||||
DeserializationError::Code err;
|
||||
|
||||
stringBuilder_.startString();
|
||||
for (; n; --n) {
|
||||
uint8_t c;
|
||||
|
||||
err = readBytes(c);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
stringBuilder_.append(static_cast<char>(c));
|
||||
}
|
||||
|
||||
if (!stringBuilder_.isValid())
|
||||
char* p = stringBuffer_.reserve(n);
|
||||
if (!p)
|
||||
return DeserializationError::NoMemory;
|
||||
|
||||
return DeserializationError::Ok;
|
||||
return readBytes(p, n);
|
||||
}
|
||||
|
||||
template <typename TSize, typename TFilter>
|
||||
DeserializationError::Code readArray(
|
||||
VariantData* variant, TFilter filter,
|
||||
DeserializationOption::NestingLimit nestingLimit) {
|
||||
DeserializationError::Code err;
|
||||
TSize size;
|
||||
DeserializationError::Code readRawString(VariantData* variant,
|
||||
const void* header,
|
||||
uint8_t headerSize, size_t n) {
|
||||
auto totalSize = size_t(headerSize + n);
|
||||
if (totalSize < n) // integer overflow
|
||||
return DeserializationError::NoMemory; // (not testable on 64-bit)
|
||||
|
||||
err = readInteger(size);
|
||||
char* p = stringBuffer_.reserve(totalSize);
|
||||
if (!p)
|
||||
return DeserializationError::NoMemory;
|
||||
|
||||
memcpy(p, header, headerSize);
|
||||
|
||||
auto err = readBytes(p + headerSize, n);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return readArray(variant, size, filter, nestingLimit);
|
||||
variant->setRawString(stringBuffer_.save());
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename TFilter>
|
||||
@@ -449,20 +375,6 @@ class MsgPackDeserializer {
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename TSize, typename TFilter>
|
||||
DeserializationError::Code readObject(
|
||||
VariantData* variant, TFilter filter,
|
||||
DeserializationOption::NestingLimit nestingLimit) {
|
||||
DeserializationError::Code err;
|
||||
TSize size;
|
||||
|
||||
err = readInteger(size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return readObject(variant, size, filter, nestingLimit);
|
||||
}
|
||||
|
||||
template <typename TFilter>
|
||||
DeserializationError::Code readObject(
|
||||
VariantData* variant, size_t n, TFilter filter,
|
||||
@@ -485,7 +397,7 @@ class MsgPackDeserializer {
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
JsonString key = stringBuilder_.str();
|
||||
JsonString key = stringBuffer_.str();
|
||||
TFilter memberFilter = filter[key.c_str()];
|
||||
VariantData* member;
|
||||
|
||||
@@ -493,7 +405,7 @@ class MsgPackDeserializer {
|
||||
ARDUINOJSON_ASSERT(object != 0);
|
||||
|
||||
// Save key in memory pool.
|
||||
auto savedKey = stringBuilder_.save();
|
||||
auto savedKey = stringBuffer_.save();
|
||||
|
||||
member = object->addMember(savedKey, resources_);
|
||||
if (!member)
|
||||
@@ -521,36 +433,24 @@ class MsgPackDeserializer {
|
||||
if ((code & 0xe0) == 0xa0)
|
||||
return readString(code & 0x1f);
|
||||
|
||||
switch (code) {
|
||||
case 0xd9:
|
||||
return readString<uint8_t>();
|
||||
|
||||
case 0xda:
|
||||
return readString<uint16_t>();
|
||||
|
||||
case 0xdb:
|
||||
return readString<uint32_t>();
|
||||
|
||||
default:
|
||||
return DeserializationError::InvalidInput;
|
||||
if (code >= 0xd9 && code <= 0xdb) {
|
||||
uint8_t sizeBytes = uint8_t(1U << (code - 0xd9));
|
||||
uint32_t size = 0;
|
||||
for (uint8_t i = 0; i < sizeBytes; i++) {
|
||||
err = readByte(code);
|
||||
if (err)
|
||||
return err;
|
||||
size = (size << 8) | code;
|
||||
}
|
||||
return readString(size);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DeserializationError::Code skipExt() {
|
||||
DeserializationError::Code err;
|
||||
T size;
|
||||
|
||||
err = readInteger(size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return skipBytes(size + 1U);
|
||||
return DeserializationError::InvalidInput;
|
||||
}
|
||||
|
||||
ResourceManager* resources_;
|
||||
TReader reader_;
|
||||
StringBuilder stringBuilder_;
|
||||
StringBuffer stringBuffer_;
|
||||
bool foundSomething_;
|
||||
};
|
||||
|
||||
@@ -561,9 +461,8 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
|
||||
// Parses a MessagePack input and puts the result in a JsonDocument.
|
||||
// https://arduinojson.org/v7/api/msgpack/deserializemsgpack/
|
||||
template <typename TDestination, typename... Args>
|
||||
typename detail::enable_if<
|
||||
detail::is_deserialize_destination<TDestination>::value,
|
||||
DeserializationError>::type
|
||||
detail::enable_if_t<detail::is_deserialize_destination<TDestination>::value,
|
||||
DeserializationError>
|
||||
deserializeMsgPack(TDestination&& dst, Args&&... args) {
|
||||
using namespace detail;
|
||||
return deserialize<MsgPackDeserializer>(detail::forward<TDestination>(dst),
|
||||
@@ -573,9 +472,8 @@ deserializeMsgPack(TDestination&& dst, Args&&... args) {
|
||||
// Parses a MessagePack input and puts the result in a JsonDocument.
|
||||
// https://arduinojson.org/v7/api/msgpack/deserializemsgpack/
|
||||
template <typename TDestination, typename TChar, typename... Args>
|
||||
typename detail::enable_if<
|
||||
detail::is_deserialize_destination<TDestination>::value,
|
||||
DeserializationError>::type
|
||||
detail::enable_if_t<detail::is_deserialize_destination<TDestination>::value,
|
||||
DeserializationError>
|
||||
deserializeMsgPack(TDestination&& dst, TChar* input, Args&&... args) {
|
||||
using namespace detail;
|
||||
return deserialize<MsgPackDeserializer>(detail::forward<TDestination>(dst),
|
||||
|
||||
120
lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackExtension.hpp
Normal file
120
lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackExtension.hpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Variant/Converter.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
|
||||
|
||||
class MsgPackExtension {
|
||||
public:
|
||||
MsgPackExtension() : data_(nullptr), size_(0), type_(0) {}
|
||||
explicit MsgPackExtension(int8_t type, const void* data, size_t size)
|
||||
: data_(data), size_(size), type_(type) {}
|
||||
|
||||
int8_t type() const {
|
||||
return type_;
|
||||
}
|
||||
|
||||
const void* data() const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return size_;
|
||||
}
|
||||
|
||||
private:
|
||||
const void* data_;
|
||||
size_t size_;
|
||||
int8_t type_;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<MsgPackExtension> : private detail::VariantAttorney {
|
||||
static void toJson(MsgPackExtension src, JsonVariant dst) {
|
||||
auto data = VariantAttorney::getData(dst);
|
||||
if (!data)
|
||||
return;
|
||||
auto resources = getResourceManager(dst);
|
||||
if (src.data()) {
|
||||
uint8_t format, sizeBytes;
|
||||
if (src.size() >= 0x10000) {
|
||||
format = 0xc9; // ext 32
|
||||
sizeBytes = 4;
|
||||
} else if (src.size() >= 0x100) {
|
||||
format = 0xc8; // ext 16
|
||||
sizeBytes = 2;
|
||||
} else if (src.size() == 16) {
|
||||
format = 0xd8; // fixext 16
|
||||
sizeBytes = 0;
|
||||
} else if (src.size() == 8) {
|
||||
format = 0xd7; // fixext 8
|
||||
sizeBytes = 0;
|
||||
} else if (src.size() == 4) {
|
||||
format = 0xd6; // fixext 4
|
||||
sizeBytes = 0;
|
||||
} else if (src.size() == 2) {
|
||||
format = 0xd5; // fixext 2
|
||||
sizeBytes = 0;
|
||||
} else if (src.size() == 1) {
|
||||
format = 0xd4; // fixext 1
|
||||
sizeBytes = 0;
|
||||
} else {
|
||||
format = 0xc7; // ext 8
|
||||
sizeBytes = 1;
|
||||
}
|
||||
|
||||
auto str = resources->createString(src.size() + 2 + sizeBytes);
|
||||
if (str) {
|
||||
resources->saveString(str);
|
||||
auto ptr = reinterpret_cast<uint8_t*>(str->data);
|
||||
*ptr++ = uint8_t(format);
|
||||
for (uint8_t i = 0; i < sizeBytes; i++)
|
||||
*ptr++ = uint8_t(src.size() >> (sizeBytes - i - 1) * 8 & 0xff);
|
||||
*ptr++ = uint8_t(src.type());
|
||||
memcpy(ptr, src.data(), src.size());
|
||||
data->setRawString(str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
data->setNull();
|
||||
}
|
||||
|
||||
static MsgPackExtension fromJson(JsonVariantConst src) {
|
||||
auto data = getData(src);
|
||||
if (!data)
|
||||
return {};
|
||||
auto rawstr = data->asRawString();
|
||||
if (rawstr.size() == 0)
|
||||
return {};
|
||||
auto p = reinterpret_cast<const uint8_t*>(rawstr.c_str());
|
||||
|
||||
size_t payloadSize = 0;
|
||||
uint8_t headerSize = 0;
|
||||
|
||||
const uint8_t& code = p[0];
|
||||
|
||||
if (code >= 0xd4 && code <= 0xd8) { // fixext 1
|
||||
headerSize = 2;
|
||||
payloadSize = size_t(1) << (code - 0xd4);
|
||||
}
|
||||
|
||||
if (code >= 0xc7 && code <= 0xc9) {
|
||||
uint8_t sizeBytes = uint8_t(1 << (code - 0xc7));
|
||||
for (uint8_t i = 0; i < sizeBytes; i++)
|
||||
payloadSize = (payloadSize << 8) | p[1 + i];
|
||||
headerSize = uint8_t(2 + sizeBytes);
|
||||
}
|
||||
|
||||
if (rawstr.size() == headerSize + payloadSize)
|
||||
return MsgPackExtension(int8_t(p[headerSize - 1]), p + headerSize,
|
||||
payloadSize);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
static bool checkJson(JsonVariantConst src) {
|
||||
return fromJson(src).data() != nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PUBLIC_NAMESPACE
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/MsgPack/endianess.hpp>
|
||||
#include <ArduinoJson/MsgPack/endianness.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Serialization/CountingDecorator.hpp>
|
||||
@@ -23,9 +23,8 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
|
||||
: writer_(writer), resources_(resources) {}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<is_floating_point<T>::value && sizeof(T) == 4,
|
||||
size_t>::type
|
||||
visit(T value32) {
|
||||
enable_if_t<is_floating_point<T>::value && sizeof(T) == 4, size_t> visit(
|
||||
T value32) {
|
||||
if (canConvertNumber<JsonInteger>(value32)) {
|
||||
JsonInteger truncatedValue = JsonInteger(value32);
|
||||
if (value32 == T(truncatedValue))
|
||||
@@ -38,8 +37,8 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
|
||||
|
||||
template <typename T>
|
||||
ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
|
||||
typename enable_if<is_floating_point<T>::value && sizeof(T) == 8,
|
||||
size_t>::type visit(T value64) {
|
||||
enable_if_t<is_floating_point<T>::value && sizeof(T) == 8, size_t> visit(
|
||||
T value64) {
|
||||
float value32 = float(value64);
|
||||
if (value32 == value64)
|
||||
return visit(value32);
|
||||
@@ -206,7 +205,7 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
|
||||
|
||||
template <typename T>
|
||||
void writeInteger(T value) {
|
||||
fixEndianess(value);
|
||||
fixEndianness(value);
|
||||
writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
|
||||
}
|
||||
|
||||
|
||||
@@ -15,32 +15,32 @@ inline void swapBytes(uint8_t& a, uint8_t& b) {
|
||||
b = t;
|
||||
}
|
||||
|
||||
inline void fixEndianess(uint8_t* p, integral_constant<size_t, 8>) {
|
||||
inline void fixEndianness(uint8_t* p, integral_constant<size_t, 8>) {
|
||||
swapBytes(p[0], p[7]);
|
||||
swapBytes(p[1], p[6]);
|
||||
swapBytes(p[2], p[5]);
|
||||
swapBytes(p[3], p[4]);
|
||||
}
|
||||
|
||||
inline void fixEndianess(uint8_t* p, integral_constant<size_t, 4>) {
|
||||
inline void fixEndianness(uint8_t* p, integral_constant<size_t, 4>) {
|
||||
swapBytes(p[0], p[3]);
|
||||
swapBytes(p[1], p[2]);
|
||||
}
|
||||
|
||||
inline void fixEndianess(uint8_t* p, integral_constant<size_t, 2>) {
|
||||
inline void fixEndianness(uint8_t* p, integral_constant<size_t, 2>) {
|
||||
swapBytes(p[0], p[1]);
|
||||
}
|
||||
|
||||
inline void fixEndianess(uint8_t*, integral_constant<size_t, 1>) {}
|
||||
inline void fixEndianness(uint8_t*, integral_constant<size_t, 1>) {}
|
||||
|
||||
template <typename T>
|
||||
inline void fixEndianess(T& value) {
|
||||
fixEndianess(reinterpret_cast<uint8_t*>(&value),
|
||||
integral_constant<size_t, sizeof(T)>());
|
||||
inline void fixEndianness(T& value) {
|
||||
fixEndianness(reinterpret_cast<uint8_t*>(&value),
|
||||
integral_constant<size_t, sizeof(T)>());
|
||||
}
|
||||
#else
|
||||
template <typename T>
|
||||
inline void fixEndianess(T&) {}
|
||||
inline void fixEndianness(T&) {}
|
||||
#endif
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
@@ -10,16 +10,16 @@
|
||||
|
||||
#ifndef ARDUINOJSON_VERSION_NAMESPACE
|
||||
|
||||
# define ARDUINOJSON_VERSION_NAMESPACE \
|
||||
ARDUINOJSON_CONCAT4(ARDUINOJSON_VERSION_MACRO, \
|
||||
ARDUINOJSON_BIN2ALPHA(ARDUINOJSON_ENABLE_PROGMEM, \
|
||||
ARDUINOJSON_USE_LONG_LONG, \
|
||||
ARDUINOJSON_USE_DOUBLE, 1), \
|
||||
ARDUINOJSON_BIN2ALPHA(ARDUINOJSON_ENABLE_NAN, \
|
||||
ARDUINOJSON_ENABLE_INFINITY, \
|
||||
ARDUINOJSON_ENABLE_COMMENTS, \
|
||||
ARDUINOJSON_DECODE_UNICODE), \
|
||||
ARDUINOJSON_SLOT_ID_SIZE)
|
||||
# define ARDUINOJSON_VERSION_NAMESPACE \
|
||||
ARDUINOJSON_CONCAT5( \
|
||||
ARDUINOJSON_VERSION_MACRO, \
|
||||
ARDUINOJSON_BIN2ALPHA(ARDUINOJSON_ENABLE_PROGMEM, \
|
||||
ARDUINOJSON_USE_LONG_LONG, \
|
||||
ARDUINOJSON_USE_DOUBLE, 1), \
|
||||
ARDUINOJSON_BIN2ALPHA( \
|
||||
ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \
|
||||
ARDUINOJSON_ENABLE_COMMENTS, ARDUINOJSON_DECODE_UNICODE), \
|
||||
ARDUINOJSON_SLOT_ID_SIZE, ARDUINOJSON_STRING_LENGTH_SIZE)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -77,17 +77,17 @@ struct FloatTraits<T, 8 /*64bits*/> {
|
||||
|
||||
template <typename TOut> // int64_t
|
||||
static T highest_for(
|
||||
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TOut) == 8,
|
||||
signed>::type* = 0) {
|
||||
enable_if_t<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TOut) == 8,
|
||||
signed>* = 0) {
|
||||
return forge(0x43DFFFFFFFFFFFFF); // 9.2233720368547748e+18
|
||||
}
|
||||
|
||||
template <typename TOut> // uint64_t
|
||||
static T highest_for(
|
||||
typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value &&
|
||||
sizeof(TOut) == 8,
|
||||
unsigned>::type* = 0) {
|
||||
enable_if_t<is_integral<TOut>::value && is_unsigned<TOut>::value &&
|
||||
sizeof(TOut) == 8,
|
||||
unsigned>* = 0) {
|
||||
return forge(0x43EFFFFFFFFFFFFF); // 1.8446744073709549568e+19
|
||||
}
|
||||
|
||||
@@ -157,33 +157,33 @@ struct FloatTraits<T, 4 /*32bits*/> {
|
||||
|
||||
template <typename TOut> // int32_t
|
||||
static T highest_for(
|
||||
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TOut) == 4,
|
||||
signed>::type* = 0) {
|
||||
enable_if_t<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TOut) == 4,
|
||||
signed>* = 0) {
|
||||
return forge(0x4EFFFFFF); // 2.14748352E9
|
||||
}
|
||||
|
||||
template <typename TOut> // uint32_t
|
||||
static T highest_for(
|
||||
typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value &&
|
||||
sizeof(TOut) == 4,
|
||||
unsigned>::type* = 0) {
|
||||
enable_if_t<is_integral<TOut>::value && is_unsigned<TOut>::value &&
|
||||
sizeof(TOut) == 4,
|
||||
unsigned>* = 0) {
|
||||
return forge(0x4F7FFFFF); // 4.29496704E9
|
||||
}
|
||||
|
||||
template <typename TOut> // int64_t
|
||||
static T highest_for(
|
||||
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TOut) == 8,
|
||||
signed>::type* = 0) {
|
||||
enable_if_t<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TOut) == 8,
|
||||
signed>* = 0) {
|
||||
return forge(0x5EFFFFFF); // 9.22337148709896192E18
|
||||
}
|
||||
|
||||
template <typename TOut> // uint64_t
|
||||
static T highest_for(
|
||||
typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value &&
|
||||
sizeof(TOut) == 8,
|
||||
unsigned>::type* = 0) {
|
||||
enable_if_t<is_integral<TOut>::value && is_unsigned<TOut>::value &&
|
||||
sizeof(TOut) == 8,
|
||||
unsigned>* = 0) {
|
||||
return forge(0x5F7FFFFF); // 1.844674297419792384E19
|
||||
}
|
||||
|
||||
|
||||
@@ -32,34 +32,34 @@ CompareResult arithmeticCompare(const T& lhs, const T& rhs) {
|
||||
template <typename T1, typename T2>
|
||||
CompareResult arithmeticCompare(
|
||||
const T1& lhs, const T2& rhs,
|
||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
sizeof(T1) < sizeof(T2)>::type* = 0) {
|
||||
enable_if_t<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
sizeof(T1) < sizeof(T2)>* = 0) {
|
||||
return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
CompareResult arithmeticCompare(
|
||||
const T1& lhs, const T2& rhs,
|
||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
sizeof(T2) < sizeof(T1)>::type* = 0) {
|
||||
enable_if_t<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
sizeof(T2) < sizeof(T1)>* = 0) {
|
||||
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
CompareResult arithmeticCompare(
|
||||
const T1& lhs, const T2& rhs,
|
||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
is_signed<T1>::value == is_signed<T2>::value &&
|
||||
sizeof(T2) == sizeof(T1)>::type* = 0) {
|
||||
enable_if_t<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
is_signed<T1>::value == is_signed<T2>::value &&
|
||||
sizeof(T2) == sizeof(T1)>* = 0) {
|
||||
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
CompareResult arithmeticCompare(
|
||||
const T1& lhs, const T2& rhs,
|
||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
is_unsigned<T1>::value && is_signed<T2>::value &&
|
||||
sizeof(T2) == sizeof(T1)>::type* = 0) {
|
||||
enable_if_t<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
is_unsigned<T1>::value && is_signed<T2>::value &&
|
||||
sizeof(T2) == sizeof(T1)>* = 0) {
|
||||
if (rhs < 0)
|
||||
return COMPARE_RESULT_GREATER;
|
||||
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
|
||||
@@ -68,9 +68,9 @@ CompareResult arithmeticCompare(
|
||||
template <typename T1, typename T2>
|
||||
CompareResult arithmeticCompare(
|
||||
const T1& lhs, const T2& rhs,
|
||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
is_signed<T1>::value && is_unsigned<T2>::value &&
|
||||
sizeof(T2) == sizeof(T1)>::type* = 0) {
|
||||
enable_if_t<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
is_signed<T1>::value && is_unsigned<T2>::value &&
|
||||
sizeof(T2) == sizeof(T1)>* = 0) {
|
||||
if (lhs < 0)
|
||||
return COMPARE_RESULT_LESS;
|
||||
return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
|
||||
@@ -79,23 +79,21 @@ CompareResult arithmeticCompare(
|
||||
template <typename T1, typename T2>
|
||||
CompareResult arithmeticCompare(
|
||||
const T1& lhs, const T2& rhs,
|
||||
typename enable_if<is_floating_point<T1>::value ||
|
||||
is_floating_point<T2>::value>::type* = 0) {
|
||||
enable_if_t<is_floating_point<T1>::value || is_floating_point<T2>::value>* =
|
||||
0) {
|
||||
return arithmeticCompare<double>(static_cast<double>(lhs),
|
||||
static_cast<double>(rhs));
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
CompareResult arithmeticCompareNegateLeft(
|
||||
JsonUInt, const T2&,
|
||||
typename enable_if<is_unsigned<T2>::value>::type* = 0) {
|
||||
JsonUInt, const T2&, enable_if_t<is_unsigned<T2>::value>* = 0) {
|
||||
return COMPARE_RESULT_LESS;
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
CompareResult arithmeticCompareNegateLeft(
|
||||
JsonUInt lhs, const T2& rhs,
|
||||
typename enable_if<is_signed<T2>::value>::type* = 0) {
|
||||
JsonUInt lhs, const T2& rhs, enable_if_t<is_signed<T2>::value>* = 0) {
|
||||
if (rhs > 0)
|
||||
return COMPARE_RESULT_LESS;
|
||||
return arithmeticCompare(-rhs, static_cast<T2>(lhs));
|
||||
@@ -103,15 +101,13 @@ CompareResult arithmeticCompareNegateLeft(
|
||||
|
||||
template <typename T1>
|
||||
CompareResult arithmeticCompareNegateRight(
|
||||
const T1&, JsonUInt,
|
||||
typename enable_if<is_unsigned<T1>::value>::type* = 0) {
|
||||
const T1&, JsonUInt, enable_if_t<is_unsigned<T1>::value>* = 0) {
|
||||
return COMPARE_RESULT_GREATER;
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
CompareResult arithmeticCompareNegateRight(
|
||||
const T1& lhs, JsonUInt rhs,
|
||||
typename enable_if<is_signed<T1>::value>::type* = 0) {
|
||||
const T1& lhs, JsonUInt rhs, enable_if_t<is_signed<T1>::value>* = 0) {
|
||||
if (lhs > 0)
|
||||
return COMPARE_RESULT_GREATER;
|
||||
return arithmeticCompare(static_cast<T1>(rhs), -lhs);
|
||||
|
||||
@@ -22,18 +22,18 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
// uint32 -> int32
|
||||
// uint64 -> int32
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TIn>::value && is_unsigned<TIn>::value &&
|
||||
is_integral<TOut>::value && sizeof(TOut) <= sizeof(TIn),
|
||||
bool>::type
|
||||
enable_if_t<is_integral<TIn>::value && is_unsigned<TIn>::value &&
|
||||
is_integral<TOut>::value && sizeof(TOut) <= sizeof(TIn),
|
||||
bool>
|
||||
canConvertNumber(TIn value) {
|
||||
return value <= TIn(numeric_limits<TOut>::highest());
|
||||
}
|
||||
|
||||
// uint32 -> int64
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TIn>::value && is_unsigned<TIn>::value &&
|
||||
is_integral<TOut>::value && sizeof(TIn) < sizeof(TOut),
|
||||
bool>::type
|
||||
enable_if_t<is_integral<TIn>::value && is_unsigned<TIn>::value &&
|
||||
is_integral<TOut>::value && sizeof(TIn) < sizeof(TOut),
|
||||
bool>
|
||||
canConvertNumber(TIn) {
|
||||
return true;
|
||||
}
|
||||
@@ -41,18 +41,17 @@ canConvertNumber(TIn) {
|
||||
// uint32 -> float
|
||||
// int32 -> float
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TIn>::value && is_floating_point<TOut>::value,
|
||||
bool>::type
|
||||
enable_if_t<is_integral<TIn>::value && is_floating_point<TOut>::value, bool>
|
||||
canConvertNumber(TIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// int64 -> int32
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
|
||||
is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TOut) < sizeof(TIn),
|
||||
bool>::type
|
||||
enable_if_t<is_integral<TIn>::value && is_signed<TIn>::value &&
|
||||
is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TOut) < sizeof(TIn),
|
||||
bool>
|
||||
canConvertNumber(TIn value) {
|
||||
return value >= TIn(numeric_limits<TOut>::lowest()) &&
|
||||
value <= TIn(numeric_limits<TOut>::highest());
|
||||
@@ -61,10 +60,10 @@ canConvertNumber(TIn value) {
|
||||
// int32 -> int32
|
||||
// int32 -> int64
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
|
||||
is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TIn) <= sizeof(TOut),
|
||||
bool>::type
|
||||
enable_if_t<is_integral<TIn>::value && is_signed<TIn>::value &&
|
||||
is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TIn) <= sizeof(TOut),
|
||||
bool>
|
||||
canConvertNumber(TIn) {
|
||||
return true;
|
||||
}
|
||||
@@ -72,10 +71,10 @@ canConvertNumber(TIn) {
|
||||
// int32 -> uint32
|
||||
// int32 -> uint64
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
|
||||
is_integral<TOut>::value && is_unsigned<TOut>::value &&
|
||||
sizeof(TOut) >= sizeof(TIn),
|
||||
bool>::type
|
||||
enable_if_t<is_integral<TIn>::value && is_signed<TIn>::value &&
|
||||
is_integral<TOut>::value && is_unsigned<TOut>::value &&
|
||||
sizeof(TOut) >= sizeof(TIn),
|
||||
bool>
|
||||
canConvertNumber(TIn value) {
|
||||
if (value < 0)
|
||||
return false;
|
||||
@@ -84,10 +83,10 @@ canConvertNumber(TIn value) {
|
||||
|
||||
// int32 -> uint16
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
|
||||
is_integral<TOut>::value && is_unsigned<TOut>::value &&
|
||||
sizeof(TOut) < sizeof(TIn),
|
||||
bool>::type
|
||||
enable_if_t<is_integral<TIn>::value && is_signed<TIn>::value &&
|
||||
is_integral<TOut>::value && is_unsigned<TOut>::value &&
|
||||
sizeof(TOut) < sizeof(TIn),
|
||||
bool>
|
||||
canConvertNumber(TIn value) {
|
||||
if (value < 0)
|
||||
return false;
|
||||
@@ -97,9 +96,9 @@ canConvertNumber(TIn value) {
|
||||
// float32 -> int16
|
||||
// float64 -> int32
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_floating_point<TIn>::value && is_integral<TOut>::value &&
|
||||
sizeof(TOut) < sizeof(TIn),
|
||||
bool>::type
|
||||
enable_if_t<is_floating_point<TIn>::value && is_integral<TOut>::value &&
|
||||
sizeof(TOut) < sizeof(TIn),
|
||||
bool>
|
||||
canConvertNumber(TIn value) {
|
||||
return value >= numeric_limits<TOut>::lowest() &&
|
||||
value <= numeric_limits<TOut>::highest();
|
||||
@@ -112,9 +111,9 @@ canConvertNumber(TIn value) {
|
||||
// float64 -> int64
|
||||
// float64 -> uint64
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_floating_point<TIn>::value && is_integral<TOut>::value &&
|
||||
sizeof(TOut) >= sizeof(TIn),
|
||||
bool>::type
|
||||
enable_if_t<is_floating_point<TIn>::value && is_integral<TOut>::value &&
|
||||
sizeof(TOut) >= sizeof(TIn),
|
||||
bool>
|
||||
canConvertNumber(TIn value) {
|
||||
// Avoid error "9.22337e+18 is outside the range of representable values of
|
||||
// type 'long'"
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename A, typename B>
|
||||
struct choose_largest : conditional<(sizeof(A) > sizeof(B)), A, B> {};
|
||||
using largest_type = conditional_t<(sizeof(A) > sizeof(B)), A, B>;
|
||||
|
||||
inline bool parseNumber(const char* s, VariantData& result) {
|
||||
typedef FloatTraits<JsonFloat> traits;
|
||||
typedef choose_largest<traits::mantissa_type, JsonUInt>::type mantissa_t;
|
||||
typedef largest_type<traits::mantissa_type, JsonUInt> mantissa_t;
|
||||
typedef traits::exponent_type exponent_t;
|
||||
|
||||
ARDUINOJSON_ASSERT(s != 0);
|
||||
|
||||
@@ -102,9 +102,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// Gets or sets the member with specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobject/subscript/
|
||||
template <typename TString>
|
||||
|
||||
typename detail::enable_if<detail::IsString<TString>::value,
|
||||
detail::MemberProxy<JsonObject, TString>>::type
|
||||
detail::enable_if_t<detail::IsString<TString>::value,
|
||||
detail::MemberProxy<JsonObject, TString>>
|
||||
operator[](const TString& key) const {
|
||||
return {*this, key};
|
||||
}
|
||||
@@ -112,13 +111,24 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// Gets or sets the member with specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobject/subscript/
|
||||
template <typename TChar>
|
||||
|
||||
typename detail::enable_if<detail::IsString<TChar*>::value,
|
||||
detail::MemberProxy<JsonObject, TChar*>>::type
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value,
|
||||
detail::MemberProxy<JsonObject, TChar*>>
|
||||
operator[](TChar* key) const {
|
||||
return {*this, key};
|
||||
}
|
||||
|
||||
// Gets or sets the member with specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobject/subscript/
|
||||
template <typename TVariant>
|
||||
detail::enable_if_t<detail::IsVariant<TVariant>::value,
|
||||
detail::MemberProxy<JsonObject, const char*>>
|
||||
operator[](const TVariant& key) const {
|
||||
if (key.template is<const char*>())
|
||||
return {*this, key.template as<const char*>()};
|
||||
else
|
||||
return {*this, nullptr};
|
||||
}
|
||||
|
||||
// Removes the member at the specified iterator.
|
||||
// https://arduinojson.org/v7/api/jsonobject/remove/
|
||||
FORCE_INLINE void remove(iterator it) const {
|
||||
@@ -128,11 +138,21 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// Removes the member with the specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobject/remove/
|
||||
template <typename TString>
|
||||
FORCE_INLINE void remove(const TString& key) const {
|
||||
detail::enable_if_t<detail::IsString<TString>::value> remove(
|
||||
const TString& key) const {
|
||||
detail::ObjectData::removeMember(data_, detail::adaptString(key),
|
||||
resources_);
|
||||
}
|
||||
|
||||
// Removes the member with the specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobject/remove/
|
||||
template <typename TVariant>
|
||||
detail::enable_if_t<detail::IsVariant<TVariant>::value> remove(
|
||||
const TVariant& key) const {
|
||||
if (key.template is<const char*>())
|
||||
remove(key.template as<const char*>());
|
||||
}
|
||||
|
||||
// Removes the member with the specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobject/remove/
|
||||
template <typename TChar>
|
||||
@@ -144,9 +164,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// Returns true if the object contains the specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobject/containskey/
|
||||
template <typename TString>
|
||||
|
||||
typename detail::enable_if<detail::IsString<TString>::value, bool>::type
|
||||
containsKey(const TString& key) const {
|
||||
detail::enable_if_t<detail::IsString<TString>::value, bool> containsKey(
|
||||
const TString& key) const {
|
||||
return detail::ObjectData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
}
|
||||
@@ -154,13 +173,20 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// Returns true if the object contains the specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobject/containskey/
|
||||
template <typename TChar>
|
||||
|
||||
typename detail::enable_if<detail::IsString<TChar*>::value, bool>::type
|
||||
containsKey(TChar* key) const {
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value, bool> containsKey(
|
||||
TChar* key) const {
|
||||
return detail::ObjectData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
}
|
||||
|
||||
// Returns true if the object contains the specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobject/containskey/
|
||||
template <typename TVariant>
|
||||
detail::enable_if_t<detail::IsVariant<TVariant>::value, bool> containsKey(
|
||||
const TVariant& key) const {
|
||||
return containsKey(key.template as<const char*>());
|
||||
}
|
||||
|
||||
// DEPRECATED: use obj[key].to<JsonArray>() instead
|
||||
template <typename TChar>
|
||||
ARDUINOJSON_DEPRECATED("use obj[key].to<JsonArray>() instead")
|
||||
|
||||
@@ -19,7 +19,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
typedef JsonObjectConstIterator iterator;
|
||||
|
||||
// Creates an unbound reference.
|
||||
JsonObjectConst() : data_(0) {}
|
||||
JsonObjectConst() : data_(0), resources_(0) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonObjectConst(const detail::ObjectData* data,
|
||||
@@ -71,7 +71,8 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
// Returns true if the object contains the specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/containskey/
|
||||
template <typename TString>
|
||||
bool containsKey(const TString& key) const {
|
||||
detail::enable_if_t<detail::IsString<TString>::value, bool> containsKey(
|
||||
const TString& key) const {
|
||||
return detail::ObjectData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
}
|
||||
@@ -84,11 +85,18 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
resources_) != 0;
|
||||
}
|
||||
|
||||
// Returns true if the object contains the specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/containskey/
|
||||
template <typename TVariant>
|
||||
detail::enable_if_t<detail::IsVariant<TVariant>::value, bool> containsKey(
|
||||
const TVariant& key) const {
|
||||
return containsKey(key.template as<const char*>());
|
||||
}
|
||||
|
||||
// Gets the member with specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/subscript/
|
||||
template <typename TString>
|
||||
typename detail::enable_if<detail::IsString<TString>::value,
|
||||
JsonVariantConst>::type
|
||||
detail::enable_if_t<detail::IsString<TString>::value, JsonVariantConst>
|
||||
operator[](const TString& key) const {
|
||||
return JsonVariantConst(detail::ObjectData::getMember(
|
||||
data_, detail::adaptString(key), resources_),
|
||||
@@ -98,14 +106,24 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
// Gets the member with specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/subscript/
|
||||
template <typename TChar>
|
||||
typename detail::enable_if<detail::IsString<TChar*>::value,
|
||||
JsonVariantConst>::type
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value, JsonVariantConst>
|
||||
operator[](TChar* key) const {
|
||||
return JsonVariantConst(detail::ObjectData::getMember(
|
||||
data_, detail::adaptString(key), resources_),
|
||||
resources_);
|
||||
}
|
||||
|
||||
// Gets the member with specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/subscript/
|
||||
template <typename TVariant>
|
||||
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
|
||||
operator[](const TVariant& key) const {
|
||||
if (key.template is<const char*>())
|
||||
return operator[](key.template as<const char*>());
|
||||
else
|
||||
return JsonVariantConst();
|
||||
}
|
||||
|
||||
// DEPRECATED: always returns zero
|
||||
ARDUINOJSON_DEPRECATED("always returns zero")
|
||||
size_t memoryUsage() const {
|
||||
|
||||
@@ -11,21 +11,24 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <int Bits>
|
||||
struct uint_t;
|
||||
struct uint_;
|
||||
|
||||
template <>
|
||||
struct uint_t<8> {
|
||||
struct uint_<8> {
|
||||
typedef uint8_t type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct uint_t<16> {
|
||||
struct uint_<16> {
|
||||
typedef uint16_t type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct uint_t<32> {
|
||||
struct uint_<32> {
|
||||
typedef uint32_t type;
|
||||
};
|
||||
|
||||
template <int Bits>
|
||||
using uint_t = typename uint_<Bits>::type;
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -18,7 +18,7 @@ template <typename T, typename Enable = void>
|
||||
struct numeric_limits;
|
||||
|
||||
template <typename T>
|
||||
struct numeric_limits<T, typename enable_if<is_unsigned<T>::value>::type> {
|
||||
struct numeric_limits<T, enable_if_t<is_unsigned<T>::value>> {
|
||||
static constexpr T lowest() {
|
||||
return 0;
|
||||
}
|
||||
@@ -29,7 +29,7 @@ struct numeric_limits<T, typename enable_if<is_unsigned<T>::value>::type> {
|
||||
|
||||
template <typename T>
|
||||
struct numeric_limits<
|
||||
T, typename enable_if<is_integral<T>::value && is_signed<T>::value>::type> {
|
||||
T, enable_if_t<is_integral<T>::value && is_signed<T>::value>> {
|
||||
static constexpr T lowest() {
|
||||
return T(T(1) << (sizeof(T) * 8 - 1));
|
||||
}
|
||||
|
||||
@@ -6,8 +6,12 @@
|
||||
|
||||
#define ARDUINOJSON_CONCAT_(A, B) A##B
|
||||
#define ARDUINOJSON_CONCAT2(A, B) ARDUINOJSON_CONCAT_(A, B)
|
||||
#define ARDUINOJSON_CONCAT3(A, B, C) \
|
||||
ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT2(A, B), C)
|
||||
#define ARDUINOJSON_CONCAT4(A, B, C, D) \
|
||||
ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT2(A, B), ARDUINOJSON_CONCAT2(C, D))
|
||||
ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT3(A, B, C), D)
|
||||
#define ARDUINOJSON_CONCAT5(A, B, C, D, E) \
|
||||
ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT4(A, B, C, D), E)
|
||||
|
||||
#define ARDUINOJSON_BIN2ALPHA_0000() A
|
||||
#define ARDUINOJSON_BIN2ALPHA_0001() B
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "type_traits/conditional.hpp"
|
||||
#include "type_traits/enable_if.hpp"
|
||||
#include "type_traits/function_traits.hpp"
|
||||
#include "type_traits/integral_constant.hpp"
|
||||
#include "type_traits/is_array.hpp"
|
||||
#include "type_traits/is_base_of.hpp"
|
||||
@@ -20,6 +21,6 @@
|
||||
#include "type_traits/is_signed.hpp"
|
||||
#include "type_traits/is_unsigned.hpp"
|
||||
#include "type_traits/make_unsigned.hpp"
|
||||
#include "type_traits/make_void.hpp"
|
||||
#include "type_traits/remove_const.hpp"
|
||||
#include "type_traits/remove_reference.hpp"
|
||||
#include "type_traits/void_t.hpp"
|
||||
|
||||
@@ -18,4 +18,8 @@ struct conditional<false, TrueType, FalseType> {
|
||||
typedef FalseType type;
|
||||
};
|
||||
|
||||
template <bool Condition, class TrueType, class FalseType>
|
||||
using conditional_t =
|
||||
typename conditional<Condition, TrueType, FalseType>::type;
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -17,4 +17,7 @@ struct enable_if<true, T> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <bool Condition, typename T = void>
|
||||
using enable_if_t = typename enable_if<Condition, T>::type;
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename Sig>
|
||||
struct function_traits;
|
||||
|
||||
template <typename ReturnType, typename Arg1>
|
||||
struct function_traits<ReturnType (*)(Arg1)> {
|
||||
using return_type = ReturnType;
|
||||
using arg1_type = Arg1;
|
||||
};
|
||||
|
||||
template <typename ReturnType, typename Arg1, typename Arg2>
|
||||
struct function_traits<ReturnType (*)(Arg1, Arg2)> {
|
||||
using return_type = ReturnType;
|
||||
using arg1_type = Arg1;
|
||||
using arg2_type = Arg2;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
@@ -20,8 +20,8 @@ class is_base_of {
|
||||
|
||||
public:
|
||||
static const bool value =
|
||||
sizeof(probe(reinterpret_cast<typename remove_reference<TDerived>::type*>(
|
||||
0))) == sizeof(int);
|
||||
sizeof(probe(reinterpret_cast<remove_reference_t<TDerived>*>(0))) ==
|
||||
sizeof(int);
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -14,7 +14,7 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename T>
|
||||
struct is_enum {
|
||||
static const bool value = is_convertible<T, int>::value &&
|
||||
static const bool value = is_convertible<T, long long>::value &&
|
||||
!is_class<T>::value && !is_integral<T>::value &&
|
||||
!is_floating_point<T>::value;
|
||||
};
|
||||
|
||||
@@ -12,9 +12,8 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <class T>
|
||||
struct is_floating_point
|
||||
: integral_constant<
|
||||
bool, //
|
||||
is_same<float, typename remove_cv<T>::type>::value ||
|
||||
is_same<double, typename remove_cv<T>::type>::value> {};
|
||||
: integral_constant<bool, //
|
||||
is_same<float, remove_cv_t<T>>::value ||
|
||||
is_same<double, remove_cv_t<T>>::value> {};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -15,18 +15,18 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
// clang-format off
|
||||
template <typename T>
|
||||
struct is_integral : integral_constant<bool,
|
||||
is_same<typename remove_cv<T>::type, signed char>::value ||
|
||||
is_same<typename remove_cv<T>::type, unsigned char>::value ||
|
||||
is_same<typename remove_cv<T>::type, signed short>::value ||
|
||||
is_same<typename remove_cv<T>::type, unsigned short>::value ||
|
||||
is_same<typename remove_cv<T>::type, signed int>::value ||
|
||||
is_same<typename remove_cv<T>::type, unsigned int>::value ||
|
||||
is_same<typename remove_cv<T>::type, signed long>::value ||
|
||||
is_same<typename remove_cv<T>::type, unsigned long>::value ||
|
||||
is_same<typename remove_cv<T>::type, signed long long>::value ||
|
||||
is_same<typename remove_cv<T>::type, unsigned long long>::value ||
|
||||
is_same<typename remove_cv<T>::type, char>::value ||
|
||||
is_same<typename remove_cv<T>::type, bool>::value> {};
|
||||
is_same<remove_cv_t<T>, signed char>::value ||
|
||||
is_same<remove_cv_t<T>, unsigned char>::value ||
|
||||
is_same<remove_cv_t<T>, signed short>::value ||
|
||||
is_same<remove_cv_t<T>, unsigned short>::value ||
|
||||
is_same<remove_cv_t<T>, signed int>::value ||
|
||||
is_same<remove_cv_t<T>, unsigned int>::value ||
|
||||
is_same<remove_cv_t<T>, signed long>::value ||
|
||||
is_same<remove_cv_t<T>, unsigned long>::value ||
|
||||
is_same<remove_cv_t<T>, signed long long>::value ||
|
||||
is_same<remove_cv_t<T>, unsigned long long>::value ||
|
||||
is_same<remove_cv_t<T>, char>::value ||
|
||||
is_same<remove_cv_t<T>, bool>::value> {};
|
||||
// clang-format on
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -13,14 +13,14 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
// clang-format off
|
||||
template <typename T>
|
||||
struct is_signed : integral_constant<bool,
|
||||
is_same<typename remove_cv<T>::type, char>::value ||
|
||||
is_same<typename remove_cv<T>::type, signed char>::value ||
|
||||
is_same<typename remove_cv<T>::type, signed short>::value ||
|
||||
is_same<typename remove_cv<T>::type, signed int>::value ||
|
||||
is_same<typename remove_cv<T>::type, signed long>::value ||
|
||||
is_same<typename remove_cv<T>::type, signed long long>::value ||
|
||||
is_same<typename remove_cv<T>::type, float>::value ||
|
||||
is_same<typename remove_cv<T>::type, double>::value> {};
|
||||
is_same<remove_cv_t<T>, char>::value ||
|
||||
is_same<remove_cv_t<T>, signed char>::value ||
|
||||
is_same<remove_cv_t<T>, signed short>::value ||
|
||||
is_same<remove_cv_t<T>, signed int>::value ||
|
||||
is_same<remove_cv_t<T>, signed long>::value ||
|
||||
is_same<remove_cv_t<T>, signed long long>::value ||
|
||||
is_same<remove_cv_t<T>, float>::value ||
|
||||
is_same<remove_cv_t<T>, double>::value> {};
|
||||
// clang-format on
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -13,12 +13,12 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
// clang-format off
|
||||
template <typename T>
|
||||
struct is_unsigned : integral_constant<bool,
|
||||
is_same<typename remove_cv<T>::type, unsigned char>::value ||
|
||||
is_same<typename remove_cv<T>::type, unsigned short>::value ||
|
||||
is_same<typename remove_cv<T>::type, unsigned int>::value ||
|
||||
is_same<typename remove_cv<T>::type, unsigned long>::value ||
|
||||
is_same<typename remove_cv<T>::type, unsigned long long>::value ||
|
||||
is_same<typename remove_cv<T>::type, bool>::value> {};
|
||||
is_same<remove_cv_t<T>, unsigned char>::value ||
|
||||
is_same<remove_cv_t<T>, unsigned short>::value ||
|
||||
is_same<remove_cv_t<T>, unsigned int>::value ||
|
||||
is_same<remove_cv_t<T>, unsigned long>::value ||
|
||||
is_same<remove_cv_t<T>, unsigned long long>::value ||
|
||||
is_same<remove_cv_t<T>, bool>::value> {};
|
||||
// clang-format on
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -38,4 +38,7 @@ struct make_unsigned<signed long long> : type_identity<unsigned long long> {};
|
||||
template <>
|
||||
struct make_unsigned<unsigned long long> : type_identity<unsigned long long> {};
|
||||
|
||||
template <typename T>
|
||||
using make_unsigned_t = typename make_unsigned<T>::type;
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <class = void>
|
||||
struct make_void {
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
@@ -18,4 +18,7 @@ struct remove_const<const T> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using remove_const_t = typename remove_const<T>::type;
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -25,4 +25,7 @@ struct remove_cv<const volatile T> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using remove_cv_t = typename remove_cv<T>::type;
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -18,4 +18,7 @@ struct remove_reference<T&> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using remove_reference_t = typename remove_reference<T>::type;
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename...>
|
||||
struct make_void {
|
||||
using type = void;
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
using void_t = typename make_void<Args...>::type;
|
||||
// NOTE: using void_t = void; doesn't work on GCC 4.8
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
@@ -11,13 +11,13 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
using nullptr_t = decltype(nullptr);
|
||||
|
||||
template <class T>
|
||||
T&& forward(typename remove_reference<T>::type& t) noexcept {
|
||||
T&& forward(remove_reference_t<T>& t) noexcept {
|
||||
return static_cast<T&&>(t);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename remove_reference<T>::type&& move(T&& t) {
|
||||
return static_cast<typename remove_reference<T>::type&&>(t);
|
||||
remove_reference_t<T>&& move(T&& t) {
|
||||
return static_cast<remove_reference_t<T>&&>(t);
|
||||
}
|
||||
|
||||
// Polyfull for std::swap
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename TDestination>
|
||||
class Writer<
|
||||
TDestination,
|
||||
typename enable_if<is_base_of<::Print, TDestination>::value>::type> {
|
||||
class Writer<TDestination,
|
||||
enable_if_t<is_base_of<::Print, TDestination>::value>> {
|
||||
public:
|
||||
explicit Writer(::Print& print) : print_(&print) {}
|
||||
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename TDestination>
|
||||
class Writer<
|
||||
TDestination,
|
||||
typename enable_if<is_base_of<std::ostream, TDestination>::value>::type> {
|
||||
class Writer<TDestination,
|
||||
enable_if_t<is_base_of<std::ostream, TDestination>::value>> {
|
||||
public:
|
||||
explicit Writer(std::ostream& os) : os_(&os) {}
|
||||
|
||||
|
||||
@@ -14,13 +14,12 @@ struct is_std_string : false_type {};
|
||||
|
||||
template <class T>
|
||||
struct is_std_string<
|
||||
T, typename enable_if<is_same<void, decltype(T().push_back('a'))>::value &&
|
||||
is_same<T&, decltype(T().append(""))>::value>::type>
|
||||
: true_type {};
|
||||
T, enable_if_t<is_same<void, decltype(T().push_back('a'))>::value &&
|
||||
is_same<T&, decltype(T().append(""))>::value>> : true_type {
|
||||
};
|
||||
|
||||
template <typename TDestination>
|
||||
class Writer<TDestination,
|
||||
typename enable_if<is_std_string<TDestination>::value>::type> {
|
||||
class Writer<TDestination, enable_if_t<is_std_string<TDestination>::value>> {
|
||||
public:
|
||||
Writer(TDestination& str) : str_(&str) {
|
||||
str.clear();
|
||||
|
||||
@@ -23,17 +23,15 @@ size_t serialize(ArduinoJson::JsonVariantConst source,
|
||||
}
|
||||
|
||||
template <template <typename> class TSerializer>
|
||||
typename enable_if<!TSerializer<StaticStringWriter>::producesText, size_t>::type
|
||||
serialize(ArduinoJson::JsonVariantConst source, void* buffer,
|
||||
size_t bufferSize) {
|
||||
enable_if_t<!TSerializer<StaticStringWriter>::producesText, size_t> serialize(
|
||||
ArduinoJson::JsonVariantConst source, void* buffer, size_t bufferSize) {
|
||||
StaticStringWriter writer(reinterpret_cast<char*>(buffer), bufferSize);
|
||||
return doSerialize<TSerializer>(source, writer);
|
||||
}
|
||||
|
||||
template <template <typename> class TSerializer>
|
||||
typename enable_if<TSerializer<StaticStringWriter>::producesText, size_t>::type
|
||||
serialize(ArduinoJson::JsonVariantConst source, void* buffer,
|
||||
size_t bufferSize) {
|
||||
enable_if_t<TSerializer<StaticStringWriter>::producesText, size_t> serialize(
|
||||
ArduinoJson::JsonVariantConst source, void* buffer, size_t bufferSize) {
|
||||
StaticStringWriter writer(reinterpret_cast<char*>(buffer), bufferSize);
|
||||
size_t n = doSerialize<TSerializer>(source, writer);
|
||||
// add null-terminator for text output (not counted in the size)
|
||||
@@ -43,7 +41,7 @@ serialize(ArduinoJson::JsonVariantConst source, void* buffer,
|
||||
}
|
||||
|
||||
template <template <typename> class TSerializer, typename TChar, size_t N>
|
||||
typename enable_if<IsChar<TChar>::value, size_t>::type serialize(
|
||||
enable_if_t<IsChar<TChar>::value, size_t> serialize(
|
||||
ArduinoJson::JsonVariantConst source, TChar (&buffer)[N]) {
|
||||
return serialize<TSerializer>(source, buffer, N);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ class ZeroTerminatedRamString {
|
||||
};
|
||||
|
||||
template <typename TChar>
|
||||
struct StringAdapter<TChar*, typename enable_if<IsChar<TChar>::value>::type> {
|
||||
struct StringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
|
||||
typedef ZeroTerminatedRamString AdaptedString;
|
||||
|
||||
static AdaptedString adapt(const TChar* p) {
|
||||
@@ -71,7 +71,7 @@ struct StringAdapter<TChar*, typename enable_if<IsChar<TChar>::value>::type> {
|
||||
};
|
||||
|
||||
template <typename TChar, size_t N>
|
||||
struct StringAdapter<TChar[N], typename enable_if<IsChar<TChar>::value>::type> {
|
||||
struct StringAdapter<TChar[N], enable_if_t<IsChar<TChar>::value>> {
|
||||
typedef ZeroTerminatedRamString AdaptedString;
|
||||
|
||||
static AdaptedString adapt(const TChar* p) {
|
||||
@@ -131,8 +131,7 @@ class SizedRamString {
|
||||
};
|
||||
|
||||
template <typename TChar>
|
||||
struct SizedStringAdapter<TChar*,
|
||||
typename enable_if<IsChar<TChar>::value>::type> {
|
||||
struct SizedStringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
|
||||
typedef SizedRamString AdaptedString;
|
||||
|
||||
static AdaptedString adapt(const TChar* p, size_t n) {
|
||||
|
||||
@@ -13,9 +13,8 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
template <typename T>
|
||||
struct StringAdapter<
|
||||
T,
|
||||
typename enable_if<
|
||||
(string_traits<T>::has_cstr || string_traits<T>::has_data) &&
|
||||
(string_traits<T>::has_length || string_traits<T>::has_size)>::type> {
|
||||
enable_if_t<(string_traits<T>::has_cstr || string_traits<T>::has_data) &&
|
||||
(string_traits<T>::has_length || string_traits<T>::has_size)>> {
|
||||
typedef SizedRamString AdaptedString;
|
||||
|
||||
static AdaptedString adapt(const T& s) {
|
||||
@@ -24,26 +23,24 @@ struct StringAdapter<
|
||||
|
||||
private:
|
||||
template <typename U>
|
||||
static typename enable_if<string_traits<U>::has_size, size_t>::type get_size(
|
||||
const U& s) {
|
||||
static enable_if_t<string_traits<U>::has_size, size_t> get_size(const U& s) {
|
||||
return s.size();
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
static typename enable_if<!string_traits<U>::has_size, size_t>::type get_size(
|
||||
const U& s) {
|
||||
static enable_if_t<!string_traits<U>::has_size, size_t> get_size(const U& s) {
|
||||
return s.length();
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
static typename enable_if<string_traits<U>::has_data, const char*>::type
|
||||
get_data(const U& s) {
|
||||
static enable_if_t<string_traits<U>::has_data, const char*> get_data(
|
||||
const U& s) {
|
||||
return s.data();
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
static typename enable_if<!string_traits<U>::has_data, const char*>::type
|
||||
get_data(const U& s) {
|
||||
static enable_if_t<!string_traits<U>::has_data, const char*> get_data(
|
||||
const U& s) {
|
||||
return s.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,8 +13,7 @@ template <typename T, typename Enable = void>
|
||||
struct IsString : false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct IsString<
|
||||
T, typename make_void<typename StringAdapter<T>::AdaptedString>::type>
|
||||
struct IsString<T, void_t<typename StringAdapter<T>::AdaptedString>>
|
||||
: true_type {};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename TAdaptedString1, typename TAdaptedString2>
|
||||
typename enable_if<TAdaptedString1::typeSortKey <= TAdaptedString2::typeSortKey,
|
||||
int>::type
|
||||
enable_if_t<TAdaptedString1::typeSortKey <= TAdaptedString2::typeSortKey, int>
|
||||
stringCompare(TAdaptedString1 s1, TAdaptedString2 s2) {
|
||||
ARDUINOJSON_ASSERT(!s1.isNull());
|
||||
ARDUINOJSON_ASSERT(!s2.isNull());
|
||||
@@ -36,15 +35,13 @@ stringCompare(TAdaptedString1 s1, TAdaptedString2 s2) {
|
||||
}
|
||||
|
||||
template <typename TAdaptedString1, typename TAdaptedString2>
|
||||
typename enable_if<
|
||||
(TAdaptedString1::typeSortKey > TAdaptedString2::typeSortKey), int>::type
|
||||
enable_if_t<(TAdaptedString1::typeSortKey > TAdaptedString2::typeSortKey), int>
|
||||
stringCompare(TAdaptedString1 s1, TAdaptedString2 s2) {
|
||||
return -stringCompare(s2, s1);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString1, typename TAdaptedString2>
|
||||
typename enable_if<TAdaptedString1::typeSortKey <= TAdaptedString2::typeSortKey,
|
||||
bool>::type
|
||||
enable_if_t<TAdaptedString1::typeSortKey <= TAdaptedString2::typeSortKey, bool>
|
||||
stringEquals(TAdaptedString1 s1, TAdaptedString2 s2) {
|
||||
ARDUINOJSON_ASSERT(!s1.isNull());
|
||||
ARDUINOJSON_ASSERT(!s2.isNull());
|
||||
@@ -60,8 +57,7 @@ stringEquals(TAdaptedString1 s1, TAdaptedString2 s2) {
|
||||
}
|
||||
|
||||
template <typename TAdaptedString1, typename TAdaptedString2>
|
||||
typename enable_if<
|
||||
(TAdaptedString1::typeSortKey > TAdaptedString2::typeSortKey), bool>::type
|
||||
enable_if_t<(TAdaptedString1::typeSortKey > TAdaptedString2::typeSortKey), bool>
|
||||
stringEquals(TAdaptedString1 s1, TAdaptedString2 s2) {
|
||||
return stringEquals(s2, s1);
|
||||
}
|
||||
|
||||
@@ -19,10 +19,8 @@ template <class T, class = void>
|
||||
struct has_cstr : false_type {};
|
||||
|
||||
template <class T>
|
||||
struct has_cstr<T,
|
||||
typename enable_if<is_same<decltype(declval<const T>().c_str()),
|
||||
const char*>::value>::type>
|
||||
: true_type {};
|
||||
struct has_cstr<T, enable_if_t<is_same<decltype(declval<const T>().c_str()),
|
||||
const char*>::value>> : true_type {};
|
||||
|
||||
// const char* data() const
|
||||
// - std::string
|
||||
@@ -33,12 +31,10 @@ template <class T, class = void>
|
||||
struct has_data : false_type {};
|
||||
|
||||
template <class T>
|
||||
struct has_data<T,
|
||||
typename enable_if<is_same<decltype(declval<const T>().data()),
|
||||
const char*>::value>::type>
|
||||
: true_type {};
|
||||
struct has_data<T, enable_if_t<is_same<decltype(declval<const T>().data()),
|
||||
const char*>::value>> : true_type {};
|
||||
|
||||
// size_t length() const
|
||||
// unsigned int length() const
|
||||
// - String
|
||||
|
||||
template <class T, class = void>
|
||||
@@ -46,8 +42,7 @@ struct has_length : false_type {};
|
||||
|
||||
template <class T>
|
||||
struct has_length<
|
||||
T, typename enable_if<
|
||||
is_same<decltype(declval<const T>().length()), size_t>::value>::type>
|
||||
T, enable_if_t<is_unsigned<decltype(declval<const T>().length())>::value>>
|
||||
: true_type {};
|
||||
|
||||
// size_t size() const
|
||||
@@ -60,8 +55,7 @@ struct has_size : false_type {};
|
||||
|
||||
template <class T>
|
||||
struct has_size<
|
||||
T, typename enable_if<
|
||||
is_same<decltype(declval<const T>().size()), size_t>::value>::type>
|
||||
T, enable_if_t<is_same<decltype(declval<const T>().size()), size_t>::value>>
|
||||
: true_type {};
|
||||
|
||||
} // namespace string_traits_impl
|
||||
|
||||
@@ -20,7 +20,4 @@ template <typename T1, typename T2>
|
||||
class InvalidConversion; // Error here? See https://arduinojson.org/v7/invalid-conversion/
|
||||
// clang-format on
|
||||
|
||||
template <typename T>
|
||||
struct ConverterNeedsWriteableRef;
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -54,16 +54,17 @@ struct Converter {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Converter<
|
||||
T, typename detail::enable_if<detail::is_integral<T>::value &&
|
||||
!detail::is_same<bool, T>::value &&
|
||||
!detail::is_same<char, T>::value>::type>
|
||||
struct Converter<T, detail::enable_if_t<detail::is_integral<T>::value &&
|
||||
!detail::is_same<bool, T>::value &&
|
||||
!detail::is_same<char, T>::value>>
|
||||
: private detail::VariantAttorney {
|
||||
static void toJson(T src, JsonVariant dst) {
|
||||
static bool toJson(T src, JsonVariant dst) {
|
||||
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
|
||||
auto data = getData(dst);
|
||||
if (data)
|
||||
data->setInteger(src, getResourceManager(dst));
|
||||
if (!data)
|
||||
return false;
|
||||
data->setInteger(src, getResourceManager(dst));
|
||||
return true;
|
||||
}
|
||||
|
||||
static T fromJson(JsonVariantConst src) {
|
||||
@@ -79,10 +80,10 @@ struct Converter<
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Converter<T, typename detail::enable_if<detail::is_enum<T>::value>::type>
|
||||
struct Converter<T, detail::enable_if_t<detail::is_enum<T>::value>>
|
||||
: private detail::VariantAttorney {
|
||||
static void toJson(T src, JsonVariant dst) {
|
||||
dst.set(static_cast<JsonInteger>(src));
|
||||
static bool toJson(T src, JsonVariant dst) {
|
||||
return dst.set(static_cast<JsonInteger>(src));
|
||||
}
|
||||
|
||||
static T fromJson(JsonVariantConst src) {
|
||||
@@ -98,10 +99,12 @@ struct Converter<T, typename detail::enable_if<detail::is_enum<T>::value>::type>
|
||||
|
||||
template <>
|
||||
struct Converter<bool> : private detail::VariantAttorney {
|
||||
static void toJson(bool src, JsonVariant dst) {
|
||||
static bool toJson(bool src, JsonVariant dst) {
|
||||
auto data = getData(dst);
|
||||
if (data)
|
||||
data->setBoolean(src, getResourceManager(dst));
|
||||
if (!data)
|
||||
return false;
|
||||
data->setBoolean(src, getResourceManager(dst));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool fromJson(JsonVariantConst src) {
|
||||
@@ -116,13 +119,14 @@ struct Converter<bool> : private detail::VariantAttorney {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Converter<
|
||||
T, typename detail::enable_if<detail::is_floating_point<T>::value>::type>
|
||||
struct Converter<T, detail::enable_if_t<detail::is_floating_point<T>::value>>
|
||||
: private detail::VariantAttorney {
|
||||
static void toJson(T src, JsonVariant dst) {
|
||||
static bool toJson(T src, JsonVariant dst) {
|
||||
auto data = getData(dst);
|
||||
if (data)
|
||||
data->setFloat(static_cast<JsonFloat>(src), getResourceManager(dst));
|
||||
if (!data)
|
||||
return false;
|
||||
data->setFloat(static_cast<JsonFloat>(src), getResourceManager(dst));
|
||||
return true;
|
||||
}
|
||||
|
||||
static T fromJson(JsonVariantConst src) {
|
||||
@@ -173,8 +177,8 @@ struct Converter<JsonString> : private detail::VariantAttorney {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline typename detail::enable_if<detail::IsString<T>::value>::type
|
||||
convertToJson(const T& src, JsonVariant dst) {
|
||||
inline detail::enable_if_t<detail::IsString<T>::value> convertToJson(
|
||||
const T& src, JsonVariant dst) {
|
||||
using namespace detail;
|
||||
auto data = VariantAttorney::getData(dst);
|
||||
auto resources = VariantAttorney::getResourceManager(dst);
|
||||
@@ -305,19 +309,6 @@ inline bool canConvertFromJson(JsonVariantConst src, const std::string_view&) {
|
||||
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct ConverterNeedsWriteableRef {
|
||||
protected: // <- to avoid GCC's "all member functions in class are private"
|
||||
static int probe(T (*f)(ArduinoJson::JsonVariant));
|
||||
static char probe(T (*f)(ArduinoJson::JsonVariantConst));
|
||||
|
||||
public:
|
||||
static const bool value =
|
||||
sizeof(probe(Converter<T>::fromJson)) == sizeof(int);
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <>
|
||||
struct Converter<JsonArrayConst> : private detail::VariantAttorney {
|
||||
static void toJson(JsonArrayConst src, JsonVariant dst) {
|
||||
@@ -354,13 +345,6 @@ struct Converter<JsonArray> : private detail::VariantAttorney {
|
||||
return JsonArray(data != 0 ? data->asArray() : 0, resources);
|
||||
}
|
||||
|
||||
static detail::InvalidConversion<JsonVariantConst, JsonArray> fromJson(
|
||||
JsonVariantConst);
|
||||
|
||||
static bool checkJson(JsonVariantConst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool checkJson(JsonVariant src) {
|
||||
auto data = getData(src);
|
||||
return data && data->isArray();
|
||||
@@ -403,13 +387,6 @@ struct Converter<JsonObject> : private detail::VariantAttorney {
|
||||
return JsonObject(data != 0 ? data->asObject() : 0, resources);
|
||||
}
|
||||
|
||||
static detail::InvalidConversion<JsonVariantConst, JsonObject> fromJson(
|
||||
JsonVariantConst);
|
||||
|
||||
static bool checkJson(JsonVariantConst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool checkJson(JsonVariant src) {
|
||||
auto data = getData(src);
|
||||
return data && data->isObject();
|
||||
|
||||
@@ -53,17 +53,10 @@ struct Converter<JsonVariant> : private detail::VariantAttorney {
|
||||
return src;
|
||||
}
|
||||
|
||||
static detail::InvalidConversion<JsonVariantConst, JsonVariant> fromJson(
|
||||
JsonVariantConst);
|
||||
|
||||
static bool checkJson(JsonVariant src) {
|
||||
auto data = getData(src);
|
||||
return !!data;
|
||||
}
|
||||
|
||||
static bool checkJson(JsonVariantConst) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
|
||||
@@ -27,6 +27,12 @@ class JsonVariantConst : public detail::VariantTag,
|
||||
public detail::VariantOperators<JsonVariantConst> {
|
||||
friend class detail::VariantAttorney;
|
||||
|
||||
template <typename T>
|
||||
using ConversionSupported =
|
||||
detail::is_same<typename detail::function_traits<
|
||||
decltype(&Converter<T>::fromJson)>::arg1_type,
|
||||
JsonVariantConst>;
|
||||
|
||||
public:
|
||||
// Creates an unbound reference.
|
||||
JsonVariantConst() : data_(nullptr), resources_(nullptr) {}
|
||||
@@ -61,24 +67,31 @@ class JsonVariantConst : public detail::VariantTag,
|
||||
|
||||
// Casts the value to the specified type.
|
||||
// https://arduinojson.org/v7/api/jsonvariantconst/as/
|
||||
template <typename T>
|
||||
typename detail::enable_if<!detail::is_same<T, char*>::value &&
|
||||
!detail::is_same<T, char>::value,
|
||||
T>::type
|
||||
as() const {
|
||||
template <typename T,
|
||||
detail::enable_if_t<ConversionSupported<T>::value, bool> = true>
|
||||
T as() const {
|
||||
return Converter<T>::fromJson(*this);
|
||||
}
|
||||
|
||||
// Invalid conversion. Will not compile.
|
||||
template <typename T,
|
||||
detail::enable_if_t<!ConversionSupported<T>::value, bool> = true>
|
||||
detail::InvalidConversion<JsonVariantConst, T> as() const;
|
||||
|
||||
// Returns true if the value is of the specified type.
|
||||
// https://arduinojson.org/v7/api/jsonvariantconst/is/
|
||||
template <typename T>
|
||||
typename detail::enable_if<!detail::is_same<T, char*>::value &&
|
||||
!detail::is_same<T, char>::value,
|
||||
bool>::type
|
||||
is() const {
|
||||
detail::enable_if_t<ConversionSupported<T>::value, bool> is() const {
|
||||
return Converter<T>::checkJson(*this);
|
||||
}
|
||||
|
||||
// Always returns false for the unsupported types.
|
||||
// https://arduinojson.org/v7/api/jsonvariantconst/is/
|
||||
template <typename T>
|
||||
detail::enable_if_t<!ConversionSupported<T>::value, bool> is() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
operator T() const {
|
||||
return as<T>();
|
||||
@@ -86,16 +99,18 @@ class JsonVariantConst : public detail::VariantTag,
|
||||
|
||||
// Gets array's element at specified index.
|
||||
// https://arduinojson.org/v7/api/jsonvariantconst/subscript/
|
||||
JsonVariantConst operator[](size_t index) const {
|
||||
template <typename T>
|
||||
detail::enable_if_t<detail::is_integral<T>::value, JsonVariantConst>
|
||||
operator[](T index) const {
|
||||
return JsonVariantConst(
|
||||
detail::VariantData::getElement(data_, index, resources_), resources_);
|
||||
detail::VariantData::getElement(data_, size_t(index), resources_),
|
||||
resources_);
|
||||
}
|
||||
|
||||
// Gets object's member with specified key.
|
||||
// https://arduinojson.org/v7/api/jsonvariantconst/subscript/
|
||||
template <typename TString>
|
||||
typename detail::enable_if<detail::IsString<TString>::value,
|
||||
JsonVariantConst>::type
|
||||
detail::enable_if_t<detail::IsString<TString>::value, JsonVariantConst>
|
||||
operator[](const TString& key) const {
|
||||
return JsonVariantConst(detail::VariantData::getMember(
|
||||
data_, detail::adaptString(key), resources_),
|
||||
@@ -105,20 +120,30 @@ class JsonVariantConst : public detail::VariantTag,
|
||||
// Gets object's member with specified key.
|
||||
// https://arduinojson.org/v7/api/jsonvariantconst/subscript/
|
||||
template <typename TChar>
|
||||
typename detail::enable_if<detail::IsString<TChar*>::value,
|
||||
JsonVariantConst>::type
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value, JsonVariantConst>
|
||||
operator[](TChar* key) const {
|
||||
return JsonVariantConst(detail::VariantData::getMember(
|
||||
data_, detail::adaptString(key), resources_),
|
||||
resources_);
|
||||
}
|
||||
|
||||
// Gets object's member with specified key or the array's element at the
|
||||
// specified index.
|
||||
// https://arduinojson.org/v7/api/jsonvariantconst/subscript/
|
||||
template <typename TVariant>
|
||||
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
|
||||
operator[](const TVariant& key) const {
|
||||
if (key.template is<size_t>())
|
||||
return operator[](key.template as<size_t>());
|
||||
else
|
||||
return operator[](key.template as<const char*>());
|
||||
}
|
||||
|
||||
// Returns true if tge object contains the specified key.
|
||||
// https://arduinojson.org/v7/api/jsonvariantconst/containskey/
|
||||
template <typename TString>
|
||||
|
||||
typename detail::enable_if<detail::IsString<TString>::value, bool>::type
|
||||
containsKey(const TString& key) const {
|
||||
detail::enable_if_t<detail::IsString<TString>::value, bool> containsKey(
|
||||
const TString& key) const {
|
||||
return detail::VariantData::getMember(getData(), detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
}
|
||||
@@ -126,13 +151,18 @@ class JsonVariantConst : public detail::VariantTag,
|
||||
// Returns true if tge object contains the specified key.
|
||||
// https://arduinojson.org/v7/api/jsonvariantconst/containskey/
|
||||
template <typename TChar>
|
||||
|
||||
typename detail::enable_if<detail::IsString<TChar*>::value, bool>::type
|
||||
containsKey(TChar* key) const {
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value, bool> containsKey(
|
||||
TChar* key) const {
|
||||
return detail::VariantData::getMember(getData(), detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
}
|
||||
|
||||
template <typename TVariant>
|
||||
detail::enable_if_t<detail::IsVariant<TVariant>::value, bool> containsKey(
|
||||
const TVariant& key) const {
|
||||
return containsKey(key.template as<const char*>());
|
||||
}
|
||||
|
||||
// DEPRECATED: always returns zero
|
||||
ARDUINOJSON_DEPRECATED("always returns zero")
|
||||
size_t memoryUsage() const {
|
||||
|
||||
@@ -19,8 +19,7 @@ template <typename T, typename Enable = void>
|
||||
struct Comparer;
|
||||
|
||||
template <typename T>
|
||||
struct Comparer<T, typename enable_if<IsString<T>::value>::type>
|
||||
: ComparerBase {
|
||||
struct Comparer<T, enable_if_t<IsString<T>::value>> : ComparerBase {
|
||||
T rhs; // TODO: store adapted string?
|
||||
|
||||
explicit Comparer(T value) : rhs(value) {}
|
||||
@@ -46,8 +45,8 @@ struct Comparer<T, typename enable_if<IsString<T>::value>::type>
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Comparer<T, typename enable_if<is_integral<T>::value ||
|
||||
is_floating_point<T>::value>::type>
|
||||
struct Comparer<
|
||||
T, enable_if_t<is_integral<T>::value || is_floating_point<T>::value>>
|
||||
: ComparerBase {
|
||||
T rhs;
|
||||
|
||||
@@ -200,8 +199,8 @@ struct VariantComparer : ComparerBase {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Comparer<T, typename enable_if<is_convertible<
|
||||
T, ArduinoJson::JsonVariantConst>::value>::type>
|
||||
struct Comparer<
|
||||
T, enable_if_t<is_convertible<T, ArduinoJson::JsonVariantConst>::value>>
|
||||
: VariantComparer {
|
||||
explicit Comparer(const T& value)
|
||||
: VariantComparer(static_cast<JsonVariantConst>(value)) {}
|
||||
|
||||
@@ -82,6 +82,21 @@ class VariantData {
|
||||
return var->addElement(resources);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool addValue(T&& value, ResourceManager* resources) {
|
||||
auto array = isNull() ? &toArray() : asArray();
|
||||
return detail::ArrayData::addValue(array, detail::forward<T>(value),
|
||||
resources);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool addValue(VariantData* var, T&& value,
|
||||
ResourceManager* resources) {
|
||||
if (!var)
|
||||
return false;
|
||||
return var->addValue(value, resources);
|
||||
}
|
||||
|
||||
bool asBoolean() const {
|
||||
switch (type()) {
|
||||
case VALUE_IS_BOOLEAN:
|
||||
@@ -338,13 +353,13 @@ class VariantData {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<is_signed<T>::value>::type setInteger(T value) {
|
||||
enable_if_t<is_signed<T>::value> setInteger(T value) {
|
||||
setType(VALUE_IS_SIGNED_INTEGER);
|
||||
content_.asSignedInteger = value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<is_unsigned<T>::value>::type setInteger(T value) {
|
||||
enable_if_t<is_unsigned<T>::value> setInteger(T value) {
|
||||
setType(VALUE_IS_UNSIGNED_INTEGER);
|
||||
content_.asUnsignedInteger = static_cast<JsonUInt>(value);
|
||||
}
|
||||
|
||||
@@ -31,9 +31,8 @@ struct VariantOperators : VariantOperatorTag {
|
||||
// float operator|(JsonVariant, float)
|
||||
// bool operator|(JsonVariant, bool)
|
||||
template <typename T>
|
||||
friend
|
||||
typename enable_if<!IsVariant<T>::value && !is_array<T>::value, T>::type
|
||||
operator|(const TVariant& variant, const T& defaultValue) {
|
||||
friend enable_if_t<!IsVariant<T>::value && !is_array<T>::value, T> operator|(
|
||||
const TVariant& variant, const T& defaultValue) {
|
||||
if (variant.template is<T>())
|
||||
return variant.template as<T>();
|
||||
else
|
||||
@@ -51,8 +50,8 @@ struct VariantOperators : VariantOperatorTag {
|
||||
//
|
||||
// JsonVariant operator|(JsonVariant, JsonVariant)
|
||||
template <typename T>
|
||||
friend typename enable_if<IsVariant<T>::value, JsonVariantConst>::type
|
||||
operator|(const TVariant& variant, T defaultValue) {
|
||||
friend enable_if_t<IsVariant<T>::value, JsonVariantConst> operator|(
|
||||
const TVariant& variant, T defaultValue) {
|
||||
if (variant)
|
||||
return variant;
|
||||
else
|
||||
@@ -75,9 +74,8 @@ struct VariantOperators : VariantOperatorTag {
|
||||
return compare(lhs, rhs) == COMPARE_RESULT_EQUAL;
|
||||
}
|
||||
template <typename T>
|
||||
friend
|
||||
typename enable_if<!is_base_of<VariantOperatorTag, T>::value, bool>::type
|
||||
operator==(TVariant lhs, const T& rhs) {
|
||||
friend enable_if_t<!is_base_of<VariantOperatorTag, T>::value, bool>
|
||||
operator==(TVariant lhs, const T& rhs) {
|
||||
return compare(lhs, rhs) == COMPARE_RESULT_EQUAL;
|
||||
}
|
||||
|
||||
@@ -97,9 +95,8 @@ struct VariantOperators : VariantOperatorTag {
|
||||
return compare(lhs, rhs) != COMPARE_RESULT_EQUAL;
|
||||
}
|
||||
template <typename T>
|
||||
friend
|
||||
typename enable_if<!is_base_of<VariantOperatorTag, T>::value, bool>::type
|
||||
operator!=(TVariant lhs, const T& rhs) {
|
||||
friend enable_if_t<!is_base_of<VariantOperatorTag, T>::value, bool>
|
||||
operator!=(TVariant lhs, const T& rhs) {
|
||||
return compare(lhs, rhs) != COMPARE_RESULT_EQUAL;
|
||||
}
|
||||
|
||||
@@ -119,9 +116,8 @@ struct VariantOperators : VariantOperatorTag {
|
||||
return compare(lhs, rhs) == COMPARE_RESULT_LESS;
|
||||
}
|
||||
template <typename T>
|
||||
friend
|
||||
typename enable_if<!is_base_of<VariantOperatorTag, T>::value, bool>::type
|
||||
operator<(TVariant lhs, const T& rhs) {
|
||||
friend enable_if_t<!is_base_of<VariantOperatorTag, T>::value, bool> operator<(
|
||||
TVariant lhs, const T& rhs) {
|
||||
return compare(lhs, rhs) == COMPARE_RESULT_LESS;
|
||||
}
|
||||
|
||||
@@ -141,9 +137,8 @@ struct VariantOperators : VariantOperatorTag {
|
||||
return (compare(lhs, rhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0;
|
||||
}
|
||||
template <typename T>
|
||||
friend
|
||||
typename enable_if<!is_base_of<VariantOperatorTag, T>::value, bool>::type
|
||||
operator<=(TVariant lhs, const T& rhs) {
|
||||
friend enable_if_t<!is_base_of<VariantOperatorTag, T>::value, bool>
|
||||
operator<=(TVariant lhs, const T& rhs) {
|
||||
return (compare(lhs, rhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0;
|
||||
}
|
||||
|
||||
@@ -163,9 +158,8 @@ struct VariantOperators : VariantOperatorTag {
|
||||
return compare(lhs, rhs) == COMPARE_RESULT_GREATER;
|
||||
}
|
||||
template <typename T>
|
||||
friend
|
||||
typename enable_if<!is_base_of<VariantOperatorTag, T>::value, bool>::type
|
||||
operator>(TVariant lhs, const T& rhs) {
|
||||
friend enable_if_t<!is_base_of<VariantOperatorTag, T>::value, bool> operator>(
|
||||
TVariant lhs, const T& rhs) {
|
||||
return compare(lhs, rhs) == COMPARE_RESULT_GREATER;
|
||||
}
|
||||
|
||||
@@ -185,9 +179,8 @@ struct VariantOperators : VariantOperatorTag {
|
||||
return (compare(lhs, rhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0;
|
||||
}
|
||||
template <typename T>
|
||||
friend
|
||||
typename enable_if<!is_base_of<VariantOperatorTag, T>::value, bool>::type
|
||||
operator>=(TVariant lhs, const T& rhs) {
|
||||
friend enable_if_t<!is_base_of<VariantOperatorTag, T>::value, bool>
|
||||
operator>=(TVariant lhs, const T& rhs) {
|
||||
return (compare(lhs, rhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -46,19 +46,9 @@ class VariantRefBase : public VariantTag {
|
||||
// Casts the value to the specified type.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/as/
|
||||
template <typename T>
|
||||
T as() const;
|
||||
|
||||
typename enable_if<!ConverterNeedsWriteableRef<T>::value, T>::type as()
|
||||
const {
|
||||
return Converter<T>::fromJson(getVariantConst());
|
||||
}
|
||||
|
||||
// Casts the value to the specified type.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/as/
|
||||
template <typename T>
|
||||
typename enable_if<ConverterNeedsWriteableRef<T>::value, T>::type as() const;
|
||||
|
||||
template <typename T,
|
||||
typename = typename enable_if<!is_same<T, TDerived>::value>::type>
|
||||
template <typename T, typename = enable_if_t<!is_same<T, TDerived>::value>>
|
||||
operator T() const {
|
||||
return as<T>();
|
||||
}
|
||||
@@ -66,45 +56,36 @@ class VariantRefBase : public VariantTag {
|
||||
// Sets the value to an empty array.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/to/
|
||||
template <typename T>
|
||||
typename enable_if<is_same<T, JsonArray>::value, JsonArray>::type to() const;
|
||||
enable_if_t<is_same<T, JsonArray>::value, JsonArray> to() const;
|
||||
|
||||
// Sets the value to an empty object.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/to/
|
||||
template <typename T>
|
||||
typename enable_if<is_same<T, JsonObject>::value, JsonObject>::type to()
|
||||
const;
|
||||
enable_if_t<is_same<T, JsonObject>::value, JsonObject> to() const;
|
||||
|
||||
// Sets the value to null.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/to/
|
||||
template <typename T>
|
||||
typename enable_if<is_same<T, JsonVariant>::value, JsonVariant>::type to()
|
||||
const;
|
||||
enable_if_t<is_same<T, JsonVariant>::value, JsonVariant> to() const;
|
||||
|
||||
// Returns true if the value is of the specified type.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/is/
|
||||
template <typename T>
|
||||
FORCE_INLINE
|
||||
typename enable_if<ConverterNeedsWriteableRef<T>::value, bool>::type
|
||||
is() const;
|
||||
FORCE_INLINE bool is() const;
|
||||
|
||||
// Returns true if the value is of the specified type.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/is/
|
||||
// Copies the specified value.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/set/
|
||||
template <typename T>
|
||||
FORCE_INLINE
|
||||
typename enable_if<!ConverterNeedsWriteableRef<T>::value, bool>::type
|
||||
is() const {
|
||||
return Converter<T>::checkJson(getVariantConst());
|
||||
bool set(const T& value) const {
|
||||
return doSet<Converter<remove_cv_t<T>>>(value);
|
||||
}
|
||||
|
||||
// Copies the specified value.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/set/
|
||||
template <typename T>
|
||||
bool set(const T& value) const;
|
||||
|
||||
// Copies the specified value.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/set/
|
||||
template <typename T>
|
||||
bool set(T* value) const;
|
||||
bool set(T* value) const {
|
||||
return doSet<Converter<T*>>(value);
|
||||
}
|
||||
|
||||
// Returns the size of the array or object.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/size/
|
||||
@@ -122,7 +103,7 @@ class VariantRefBase : public VariantTag {
|
||||
// Returns a reference to the new element.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/add/
|
||||
template <typename T>
|
||||
typename enable_if<!is_same<T, JsonVariant>::value, T>::type add() const {
|
||||
enable_if_t<!is_same<T, JsonVariant>::value, T> add() const {
|
||||
return add<JsonVariant>().template to<T>();
|
||||
}
|
||||
|
||||
@@ -130,20 +111,22 @@ class VariantRefBase : public VariantTag {
|
||||
// Returns a reference to the new element.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/add/
|
||||
template <typename T>
|
||||
typename enable_if<is_same<T, JsonVariant>::value, T>::type add() const;
|
||||
enable_if_t<is_same<T, JsonVariant>::value, T> add() const;
|
||||
|
||||
// Appends a value to the array.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/add/
|
||||
template <typename T>
|
||||
bool add(const T& value) const {
|
||||
return add<JsonVariant>().set(value);
|
||||
return detail::VariantData::addValue(getOrCreateData(), value,
|
||||
getResourceManager());
|
||||
}
|
||||
|
||||
// Appends a value to the array.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/add/
|
||||
template <typename T>
|
||||
bool add(T* value) const {
|
||||
return add<JsonVariant>().set(value);
|
||||
return detail::VariantData::addValue(getOrCreateData(), value,
|
||||
getResourceManager());
|
||||
}
|
||||
|
||||
// Removes an element of the array.
|
||||
@@ -155,7 +138,7 @@ class VariantRefBase : public VariantTag {
|
||||
// Removes a member of the object.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/remove/
|
||||
template <typename TChar>
|
||||
typename enable_if<IsString<TChar*>::value>::type remove(TChar* key) const {
|
||||
enable_if_t<IsString<TChar*>::value> remove(TChar* key) const {
|
||||
VariantData::removeMember(getData(), adaptString(key),
|
||||
getResourceManager());
|
||||
}
|
||||
@@ -163,12 +146,21 @@ class VariantRefBase : public VariantTag {
|
||||
// Removes a member of the object.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/remove/
|
||||
template <typename TString>
|
||||
typename enable_if<IsString<TString>::value>::type remove(
|
||||
const TString& key) const {
|
||||
enable_if_t<IsString<TString>::value> remove(const TString& key) const {
|
||||
VariantData::removeMember(getData(), adaptString(key),
|
||||
getResourceManager());
|
||||
}
|
||||
|
||||
// Removes a member of the object or an element of the array.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/remove/
|
||||
template <typename TVariant>
|
||||
enable_if_t<IsVariant<TVariant>::value> remove(const TVariant& key) const {
|
||||
if (key.template is<size_t>())
|
||||
remove(key.template as<size_t>());
|
||||
else
|
||||
remove(key.template as<const char*>());
|
||||
}
|
||||
|
||||
// Gets or sets an array element.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/subscript/
|
||||
ElementProxy<TDerived> operator[](size_t index) const;
|
||||
@@ -176,28 +168,44 @@ class VariantRefBase : public VariantTag {
|
||||
// Returns true if the object contains the specified key.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/containskey/
|
||||
template <typename TString>
|
||||
typename enable_if<IsString<TString>::value, bool>::type containsKey(
|
||||
enable_if_t<IsString<TString>::value, bool> containsKey(
|
||||
const TString& key) const;
|
||||
|
||||
// Returns true if the object contains the specified key.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/containskey/
|
||||
template <typename TChar>
|
||||
typename enable_if<IsString<TChar*>::value, bool>::type containsKey(
|
||||
TChar* key) const;
|
||||
enable_if_t<IsString<TChar*>::value, bool> containsKey(TChar* key) const;
|
||||
|
||||
// Returns true if the object contains the specified key.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/containskey/
|
||||
template <typename TVariant>
|
||||
enable_if_t<IsVariant<TVariant>::value, bool> containsKey(
|
||||
const TVariant& key) const;
|
||||
|
||||
// Gets or sets an object member.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/subscript/
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value,
|
||||
MemberProxy<TDerived, TString>>::type
|
||||
operator[](const TString& key) const;
|
||||
FORCE_INLINE
|
||||
enable_if_t<IsString<TString>::value, MemberProxy<TDerived, TString>>
|
||||
operator[](const TString& key) const;
|
||||
|
||||
// Gets or sets an object member.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/subscript/
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar*>::value,
|
||||
MemberProxy<TDerived, TChar*>>::type
|
||||
operator[](TChar* key) const;
|
||||
FORCE_INLINE
|
||||
enable_if_t<IsString<TChar*>::value, MemberProxy<TDerived, TChar*>>
|
||||
operator[](TChar* key) const;
|
||||
|
||||
// Gets an object member or an array element.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/subscript/
|
||||
template <typename TVariant>
|
||||
enable_if_t<IsVariant<TVariant>::value, JsonVariantConst> operator[](
|
||||
const TVariant& key) const {
|
||||
if (key.template is<size_t>())
|
||||
return operator[](key.template as<size_t>());
|
||||
else
|
||||
return operator[](key.template as<const char*>());
|
||||
}
|
||||
|
||||
// DEPRECATED: use add<JsonVariant>() instead
|
||||
ARDUINOJSON_DEPRECATED("use add<JsonVariant>() instead")
|
||||
@@ -270,6 +278,33 @@ class VariantRefBase : public VariantTag {
|
||||
return ArduinoJson::JsonVariantConst(getData(), getResourceManager());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE enable_if_t<is_same<T, JsonVariantConst>::value, T> getVariant()
|
||||
const {
|
||||
return getVariantConst();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE enable_if_t<is_same<T, JsonVariant>::value, T> getVariant()
|
||||
const {
|
||||
return getVariant();
|
||||
}
|
||||
|
||||
template <typename TConverter, typename T>
|
||||
bool doSet(T&& value) const {
|
||||
return doSet<TConverter>(
|
||||
detail::forward<T>(value),
|
||||
is_same<typename function_traits<
|
||||
decltype(&TConverter::toJson)>::return_type,
|
||||
bool>{});
|
||||
}
|
||||
|
||||
template <typename TConverter, typename T>
|
||||
bool doSet(T&& value, false_type) const;
|
||||
|
||||
template <typename TConverter, typename T>
|
||||
bool doSet(T&& value, true_type) const;
|
||||
|
||||
ArduinoJson::JsonVariant getOrCreateVariant() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -17,9 +17,10 @@ inline JsonVariant VariantRefBase<TDerived>::add() const {
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename T>
|
||||
inline typename enable_if<ConverterNeedsWriteableRef<T>::value, T>::type
|
||||
VariantRefBase<TDerived>::as() const {
|
||||
return Converter<T>::fromJson(getVariant());
|
||||
inline T VariantRefBase<TDerived>::as() const {
|
||||
using variant_type = // JsonVariantConst or JsonVariant?
|
||||
typename function_traits<decltype(&Converter<T>::fromJson)>::arg1_type;
|
||||
return Converter<T>::fromJson(getVariant<variant_type>());
|
||||
}
|
||||
|
||||
template <typename TDerived>
|
||||
@@ -67,7 +68,7 @@ inline void convertToJson(const VariantRefBase<TDerived>& src,
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename T>
|
||||
inline typename enable_if<is_same<T, JsonVariant>::value, T>::type
|
||||
inline enable_if_t<is_same<T, JsonVariant>::value, T>
|
||||
VariantRefBase<TDerived>::add() const {
|
||||
return JsonVariant(
|
||||
detail::VariantData::addElement(getOrCreateData(), getResourceManager()),
|
||||
@@ -76,7 +77,7 @@ VariantRefBase<TDerived>::add() const {
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename TString>
|
||||
inline typename enable_if<IsString<TString>::value, bool>::type
|
||||
inline enable_if_t<IsString<TString>::value, bool>
|
||||
VariantRefBase<TDerived>::containsKey(const TString& key) const {
|
||||
return VariantData::getMember(getData(), adaptString(key),
|
||||
getResourceManager()) != 0;
|
||||
@@ -84,12 +85,19 @@ VariantRefBase<TDerived>::containsKey(const TString& key) const {
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename TChar>
|
||||
inline typename enable_if<IsString<TChar*>::value, bool>::type
|
||||
inline enable_if_t<IsString<TChar*>::value, bool>
|
||||
VariantRefBase<TDerived>::containsKey(TChar* key) const {
|
||||
return VariantData::getMember(getData(), adaptString(key),
|
||||
getResourceManager()) != 0;
|
||||
}
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename TVariant>
|
||||
inline enable_if_t<IsVariant<TVariant>::value, bool>
|
||||
VariantRefBase<TDerived>::containsKey(const TVariant& key) const {
|
||||
return containsKey(key.template as<const char*>());
|
||||
}
|
||||
|
||||
template <typename TDerived>
|
||||
inline JsonVariant VariantRefBase<TDerived>::getVariant() const {
|
||||
return JsonVariant(getData(), getResourceManager());
|
||||
@@ -102,9 +110,10 @@ inline JsonVariant VariantRefBase<TDerived>::getOrCreateVariant() const {
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename T>
|
||||
inline typename enable_if<ConverterNeedsWriteableRef<T>::value, bool>::type
|
||||
VariantRefBase<TDerived>::is() const {
|
||||
return Converter<T>::checkJson(getVariant());
|
||||
inline bool VariantRefBase<TDerived>::is() const {
|
||||
using variant_type = // JsonVariantConst or JsonVariant?
|
||||
typename function_traits<decltype(&Converter<T>::checkJson)>::arg1_type;
|
||||
return Converter<T>::checkJson(getVariant<variant_type>());
|
||||
}
|
||||
|
||||
template <typename TDerived>
|
||||
@@ -115,40 +124,35 @@ inline ElementProxy<TDerived> VariantRefBase<TDerived>::operator[](
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename TString>
|
||||
inline typename enable_if<IsString<TString*>::value,
|
||||
MemberProxy<TDerived, TString*>>::type
|
||||
inline enable_if_t<IsString<TString*>::value, MemberProxy<TDerived, TString*>>
|
||||
VariantRefBase<TDerived>::operator[](TString* key) const {
|
||||
return MemberProxy<TDerived, TString*>(derived(), key);
|
||||
}
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename TString>
|
||||
inline typename enable_if<IsString<TString>::value,
|
||||
MemberProxy<TDerived, TString>>::type
|
||||
inline enable_if_t<IsString<TString>::value, MemberProxy<TDerived, TString>>
|
||||
VariantRefBase<TDerived>::operator[](const TString& key) const {
|
||||
return MemberProxy<TDerived, TString>(derived(), key);
|
||||
}
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename T>
|
||||
inline bool VariantRefBase<TDerived>::set(const T& value) const {
|
||||
Converter<typename detail::remove_cv<T>::type>::toJson(value,
|
||||
getOrCreateVariant());
|
||||
template <typename TConverter, typename T>
|
||||
inline bool VariantRefBase<TDerived>::doSet(T&& value, false_type) const {
|
||||
TConverter::toJson(value, getOrCreateVariant());
|
||||
auto resources = getResourceManager();
|
||||
return resources && !resources->overflowed();
|
||||
}
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename T>
|
||||
inline bool VariantRefBase<TDerived>::set(T* value) const {
|
||||
Converter<T*>::toJson(value, getOrCreateVariant());
|
||||
auto resources = getResourceManager();
|
||||
return resources && !resources->overflowed();
|
||||
template <typename TConverter, typename T>
|
||||
inline bool VariantRefBase<TDerived>::doSet(T&& value, true_type) const {
|
||||
return TConverter::toJson(value, getOrCreateVariant());
|
||||
}
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename T>
|
||||
inline typename enable_if<is_same<T, JsonArray>::value, JsonArray>::type
|
||||
inline enable_if_t<is_same<T, JsonArray>::value, JsonArray>
|
||||
VariantRefBase<TDerived>::to() const {
|
||||
return JsonArray(
|
||||
VariantData::toArray(getOrCreateData(), getResourceManager()),
|
||||
@@ -157,7 +161,7 @@ VariantRefBase<TDerived>::to() const {
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename T>
|
||||
typename enable_if<is_same<T, JsonObject>::value, JsonObject>::type
|
||||
enable_if_t<is_same<T, JsonObject>::value, JsonObject>
|
||||
VariantRefBase<TDerived>::to() const {
|
||||
return JsonObject(
|
||||
VariantData::toObject(getOrCreateData(), getResourceManager()),
|
||||
@@ -166,7 +170,7 @@ VariantRefBase<TDerived>::to() const {
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename T>
|
||||
typename enable_if<is_same<T, JsonVariant>::value, JsonVariant>::type
|
||||
enable_if_t<is_same<T, JsonVariant>::value, JsonVariant>
|
||||
VariantRefBase<TDerived>::to() const {
|
||||
auto data = getOrCreateData();
|
||||
auto resources = getResourceManager();
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ARDUINOJSON_VERSION "7.0.4"
|
||||
#define ARDUINOJSON_VERSION "7.1.0"
|
||||
#define ARDUINOJSON_VERSION_MAJOR 7
|
||||
#define ARDUINOJSON_VERSION_MINOR 0
|
||||
#define ARDUINOJSON_VERSION_REVISION 4
|
||||
#define ARDUINOJSON_VERSION_MACRO V704
|
||||
#define ARDUINOJSON_VERSION_MINOR 1
|
||||
#define ARDUINOJSON_VERSION_REVISION 0
|
||||
#define ARDUINOJSON_VERSION_MACRO V710
|
||||
|
||||
Reference in New Issue
Block a user