forked from bblanchon/ArduinoJson
Changed the rules of string duplication (fixes #658)
This commit is contained in:
34
src/ArduinoJson/Data/ValueSaver.hpp
Normal file
34
src/ArduinoJson/Data/ValueSaver.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../JsonBuffer.hpp"
|
||||
#include "../JsonVariant.hpp"
|
||||
#include "../StringTraits/StringTraits.hpp"
|
||||
#include "../TypeTraits/EnableIf.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
template <typename Source, typename Enable = void>
|
||||
struct ValueSaver {
|
||||
template <typename Destination>
|
||||
static bool save(JsonBuffer*, Destination& destination, Source source) {
|
||||
destination = source;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Source>
|
||||
struct ValueSaver<Source, typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsString<Source>::value>::type> {
|
||||
template <typename Destination>
|
||||
static bool save(JsonBuffer* buffer, Destination& destination,
|
||||
Source source) {
|
||||
return StringTraits<Source>::save(source, destination, buffer);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../JsonBuffer.hpp"
|
||||
#include "../JsonVariant.hpp"
|
||||
#include "../StringTraits/StringTraits.hpp"
|
||||
#include "../TypeTraits/EnableIf.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
template <typename TSourceRef, typename Enable = void>
|
||||
struct ValueSetter {
|
||||
template <typename TDestination>
|
||||
static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) {
|
||||
destination = source;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TSourceRef>
|
||||
struct ValueSetter<TSourceRef, typename TypeTraits::EnableIf<StringTraits<
|
||||
TSourceRef>::should_duplicate>::type> {
|
||||
template <typename TDestination>
|
||||
static bool set(JsonBuffer* buffer, TDestination& destination,
|
||||
TSourceRef source) {
|
||||
const char* copy = buffer->strdup(source);
|
||||
if (!copy) return false;
|
||||
destination = copy;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TSourceRef>
|
||||
struct ValueSetter<TSourceRef, typename TypeTraits::EnableIf<!StringTraits<
|
||||
TSourceRef>::should_duplicate>::type> {
|
||||
template <typename TDestination>
|
||||
static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) {
|
||||
// unsigned char* -> char*
|
||||
destination = reinterpret_cast<const char*>(source);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
#include "Data/JsonBufferAllocated.hpp"
|
||||
#include "Data/List.hpp"
|
||||
#include "Data/ReferenceType.hpp"
|
||||
#include "Data/ValueSetter.hpp"
|
||||
#include "Data/ValueSaver.hpp"
|
||||
#include "JsonVariant.hpp"
|
||||
#include "Serialization/JsonPrintable.hpp"
|
||||
#include "StringTraits/StringTraits.hpp"
|
||||
@ -56,19 +56,17 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||
//
|
||||
// bool add(TValue);
|
||||
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
|
||||
// const std::string&, const String&,
|
||||
// const JsonArray&, const JsonObject&
|
||||
// std::string, String, JsonArray, JsonObject
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type add(
|
||||
const T &value) {
|
||||
bool add(const T &value) {
|
||||
return add_impl<const T &>(value);
|
||||
}
|
||||
//
|
||||
// bool add(TValue);
|
||||
// TValue = const char*, const char[N], const FlashStringHelper*
|
||||
// TValue = char*, const char*, const FlashStringHelper*
|
||||
template <typename T>
|
||||
bool add(const T *value) {
|
||||
return add_impl<const T *>(value);
|
||||
bool add(T *value) {
|
||||
return add_impl<T *>(value);
|
||||
}
|
||||
//
|
||||
// bool add(TValue value, uint8_t decimals);
|
||||
@ -81,21 +79,19 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||
|
||||
// Sets the value at specified index.
|
||||
//
|
||||
// bool add(size_t index, TValue);
|
||||
// bool add(size_t index, const TValue&);
|
||||
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
|
||||
// const std::string&, const String&,
|
||||
// const JsonArray&, const JsonObject&
|
||||
// std::string, String, JsonArray, JsonObject
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type set(
|
||||
size_t index, const T &value) {
|
||||
bool set(size_t index, const T &value) {
|
||||
return set_impl<const T &>(index, value);
|
||||
}
|
||||
//
|
||||
// bool add(size_t index, TValue);
|
||||
// TValue = const char*, const char[N], const FlashStringHelper*
|
||||
// TValue = char*, const char*, const FlashStringHelper*
|
||||
template <typename T>
|
||||
bool set(size_t index, const T *value) {
|
||||
return set_impl<const T *>(index, value);
|
||||
bool set(size_t index, T *value) {
|
||||
return set_impl<T *>(index, value);
|
||||
}
|
||||
//
|
||||
// bool set(size_t index, TValue value, uint8_t decimals);
|
||||
@ -208,14 +204,14 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||
bool set_impl(size_t index, TValueRef value) {
|
||||
iterator it = begin() += index;
|
||||
if (it == end()) return false;
|
||||
return Internals::ValueSetter<TValueRef>::set(_buffer, *it, value);
|
||||
return Internals::ValueSaver<TValueRef>::save(_buffer, *it, value);
|
||||
}
|
||||
|
||||
template <typename TValueRef>
|
||||
bool add_impl(TValueRef value) {
|
||||
iterator it = Internals::List<JsonVariant>::add();
|
||||
if (it == end()) return false;
|
||||
return Internals::ValueSetter<TValueRef>::set(_buffer, *it, value);
|
||||
return Internals::ValueSaver<TValueRef>::save(_buffer, *it, value);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -25,10 +25,9 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
|
||||
|
||||
// Replaces the value
|
||||
//
|
||||
// operator=(TValue)
|
||||
// operator=(const TValue&)
|
||||
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
|
||||
// const std::string&, const String&,
|
||||
// const JsonArray&, const JsonObject&
|
||||
// std::string, String, JsonArray, JsonObject
|
||||
template <typename T>
|
||||
FORCE_INLINE JsonArraySubscript& operator=(const T& src) {
|
||||
_array.set(_index, src);
|
||||
@ -36,9 +35,9 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
|
||||
}
|
||||
//
|
||||
// operator=(TValue)
|
||||
// TValue = const char*, const char[N], const FlashStringHelper*
|
||||
// TValue = char*, const char*, const FlashStringHelper*
|
||||
template <typename T>
|
||||
FORCE_INLINE JsonArraySubscript& operator=(const T* src) {
|
||||
FORCE_INLINE JsonArraySubscript& operator=(T* src) {
|
||||
_array.set(_index, src);
|
||||
return *this;
|
||||
}
|
||||
@ -59,19 +58,18 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
|
||||
|
||||
// Replaces the value
|
||||
//
|
||||
// bool set(TValue)
|
||||
// bool set(const TValue&)
|
||||
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
|
||||
// const std::string&, const String&,
|
||||
// const JsonArray&, const JsonObject&
|
||||
// std::string, String, JsonArray, JsonObject
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(const TValue& value) {
|
||||
return _array.set(_index, value);
|
||||
}
|
||||
//
|
||||
// bool set(TValue)
|
||||
// TValue = const char*, const char[N], const FlashStringHelper*
|
||||
// TValue = char*, const char*, const FlashStringHelper*
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(const TValue* value) {
|
||||
FORCE_INLINE bool set(TValue* value) {
|
||||
return _array.set(_index, value);
|
||||
}
|
||||
//
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "Data/JsonBufferAllocated.hpp"
|
||||
#include "Data/List.hpp"
|
||||
#include "Data/ReferenceType.hpp"
|
||||
#include "Data/ValueSetter.hpp"
|
||||
#include "Data/ValueSaver.hpp"
|
||||
#include "JsonPair.hpp"
|
||||
#include "Serialization/JsonPrintable.hpp"
|
||||
#include "StringTraits/StringTraits.hpp"
|
||||
@ -50,17 +50,15 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
// JsonObjectSubscript operator[](TKey)
|
||||
// TKey = const std::string&, const String&
|
||||
template <typename TString>
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
|
||||
JsonObjectSubscript<const TString&> >::type
|
||||
operator[](const TString& key) {
|
||||
JsonObjectSubscript<const TString&> operator[](const TString& key) {
|
||||
return JsonObjectSubscript<const TString&>(*this, key);
|
||||
}
|
||||
//
|
||||
// JsonObjectSubscript operator[](TKey)
|
||||
// TKey = const char*, const char[N], const FlashStringHelper*
|
||||
// TKey = char*, const char*, char[], const char[N], const FlashStringHelper*
|
||||
template <typename TString>
|
||||
JsonObjectSubscript<const TString*> operator[](const TString* key) {
|
||||
return JsonObjectSubscript<const TString*>(*this, key);
|
||||
JsonObjectSubscript<TString*> operator[](TString* key) {
|
||||
return JsonObjectSubscript<TString*>(*this, key);
|
||||
}
|
||||
|
||||
// Gets the value associated with the specified key.
|
||||
@ -68,10 +66,8 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
// const JsonObjectSubscript operator[](TKey) const;
|
||||
// TKey = const std::string&, const String&
|
||||
template <typename TString>
|
||||
typename TypeTraits::EnableIf<
|
||||
!TypeTraits::IsArray<TString>::value,
|
||||
const JsonObjectSubscript<const TString&> >::type
|
||||
operator[](const TString& key) const {
|
||||
const JsonObjectSubscript<const TString&> operator[](
|
||||
const TString& key) const {
|
||||
return JsonObjectSubscript<const TString&>(*const_cast<JsonObject*>(this),
|
||||
key);
|
||||
}
|
||||
@ -79,10 +75,8 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
// const JsonObjectSubscript operator[](TKey) const;
|
||||
// TKey = const char*, const char[N], const FlashStringHelper*
|
||||
template <typename TString>
|
||||
const JsonObjectSubscript<const TString*> operator[](
|
||||
const TString* key) const {
|
||||
return JsonObjectSubscript<const TString*>(*const_cast<JsonObject*>(this),
|
||||
key);
|
||||
const JsonObjectSubscript<TString*> operator[](TString* key) const {
|
||||
return JsonObjectSubscript<TString*>(*const_cast<JsonObject*>(this), key);
|
||||
}
|
||||
|
||||
// Sets the specified key with the specified value.
|
||||
@ -90,43 +84,35 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
// bool set(TKey, TValue);
|
||||
// TKey = const std::string&, const String&
|
||||
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
|
||||
// const std::string&, const String&,
|
||||
// const JsonArray&, const JsonObject&
|
||||
// std::string, String, JsonArray, JsonObject
|
||||
template <typename TValue, typename TString>
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value &&
|
||||
!TypeTraits::IsArray<TValue>::value,
|
||||
bool>::type
|
||||
set(const TString& key, const TValue& value) {
|
||||
bool set(const TString& key, const TValue& value) {
|
||||
return set_impl<const TString&, const TValue&>(key, value);
|
||||
}
|
||||
//
|
||||
// bool set(TKey, TValue);
|
||||
// TKey = const std::string&, const String&
|
||||
// TValue = const char*, const char[N], const FlashStringHelper*
|
||||
// TValue = char*, const char*, const FlashStringHelper*
|
||||
template <typename TValue, typename TString>
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
|
||||
bool>::type
|
||||
set(const TString& key, const TValue* value) {
|
||||
return set_impl<const TString&, const TValue*>(key, value);
|
||||
bool set(const TString& key, TValue* value) {
|
||||
return set_impl<const TString&, TValue*>(key, value);
|
||||
}
|
||||
//
|
||||
// bool set(TKey, TValue);
|
||||
// TKey = const char*, const char[N], const FlashStringHelper*
|
||||
// bool set(TKey, const TValue&);
|
||||
// TKey = char*, const char*, const FlashStringHelper*
|
||||
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
|
||||
// const std::string&, const String&,
|
||||
// const JsonArray&, const JsonObject&
|
||||
// std::string, String, JsonArray, JsonObject
|
||||
template <typename TValue, typename TString>
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TValue>::value, bool>::type
|
||||
set(const TString* key, const TValue& value) {
|
||||
return set_impl<const TString*, const TValue&>(key, value);
|
||||
bool set(TString* key, const TValue& value) {
|
||||
return set_impl<TString*, const TValue&>(key, value);
|
||||
}
|
||||
//
|
||||
// bool set(TKey, TValue);
|
||||
// TKey = const char*, const char[N], const FlashStringHelper*
|
||||
// TValue = const char*, const char[N], const FlashStringHelper*
|
||||
// TKey = char*, const char*, const FlashStringHelper*
|
||||
// TValue = char*, const char*, const FlashStringHelper*
|
||||
template <typename TValue, typename TString>
|
||||
bool set(const TString* key, const TValue* value) {
|
||||
return set_impl<const TString*, const TValue*>(key, value);
|
||||
bool set(TString* key, TValue* value) {
|
||||
return set_impl<TString*, TValue*>(key, value);
|
||||
}
|
||||
//
|
||||
// bool set(TKey, TValue, uint8_t decimals);
|
||||
@ -134,8 +120,7 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
// TValue = float, double
|
||||
template <typename TValue, typename TString>
|
||||
DEPRECATED("Second argument is not supported anymore")
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<TValue>::value &&
|
||||
!TypeTraits::IsArray<TString>::value,
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<TValue>::value,
|
||||
bool>::type
|
||||
set(const TString& key, TValue value, uint8_t) {
|
||||
return set_impl<const TString&, const JsonVariant&>(key,
|
||||
@ -143,41 +128,35 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
}
|
||||
//
|
||||
// bool set(TKey, TValue, uint8_t decimals);
|
||||
// TKey = const char*, const char[N], const FlashStringHelper*
|
||||
// TKey = char*, const char*, const FlashStringHelper*
|
||||
// TValue = float, double
|
||||
template <typename TValue, typename TString>
|
||||
DEPRECATED("Second argument is not supported anymore")
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<TValue>::value,
|
||||
bool>::type
|
||||
set(const TString* key, TValue value, uint8_t) {
|
||||
return set_impl<const TString*, const JsonVariant&>(key,
|
||||
JsonVariant(value));
|
||||
set(TString* key, TValue value, uint8_t) {
|
||||
return set_impl<TString*, const JsonVariant&>(key, JsonVariant(value));
|
||||
}
|
||||
|
||||
// Gets the value associated with the specified key.
|
||||
//
|
||||
// TValue get<TValue>(TKey);
|
||||
// TValue get<TValue>(TKey) const;
|
||||
// TKey = const std::string&, const String&
|
||||
// TValue = bool, char, long, int, short, float, double,
|
||||
// const std::string&, const String&,
|
||||
// const JsonArray&, const JsonObject&
|
||||
// std::string, String, JsonArray, JsonObject
|
||||
template <typename TValue, typename TString>
|
||||
typename TypeTraits::EnableIf<
|
||||
!TypeTraits::IsArray<TString>::value,
|
||||
typename Internals::JsonVariantAs<TValue>::type>::type
|
||||
get(const TString& key) const {
|
||||
typename Internals::JsonVariantAs<TValue>::type get(
|
||||
const TString& key) const {
|
||||
return get_impl<const TString&, TValue>(key);
|
||||
}
|
||||
//
|
||||
// TValue get<TValue>(TKey);
|
||||
// TKey = const char*, const char[N], const FlashStringHelper*
|
||||
// TValue get<TValue>(TKey) const;
|
||||
// TKey = char*, const char*, const FlashStringHelper*
|
||||
// TValue = bool, char, long, int, short, float, double,
|
||||
// const std::string&, const String&,
|
||||
// const JsonArray&, const JsonObject&
|
||||
// std::string, String, JsonArray, JsonObject
|
||||
template <typename TValue, typename TString>
|
||||
typename Internals::JsonVariantAs<TValue>::type get(
|
||||
const TString* key) const {
|
||||
return get_impl<const TString*, TValue>(key);
|
||||
typename Internals::JsonVariantAs<TValue>::type get(TString* key) const {
|
||||
return get_impl<TString*, TValue>(key);
|
||||
}
|
||||
|
||||
// Checks the type of the value associated with the specified key.
|
||||
@ -186,23 +165,19 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
// bool is<TValue>(TKey) const;
|
||||
// TKey = const std::string&, const String&
|
||||
// TValue = bool, char, long, int, short, float, double,
|
||||
// const std::string&, const String&,
|
||||
// const JsonArray&, const JsonObject&
|
||||
// std::string, String, JsonArray, JsonObject
|
||||
template <typename TValue, typename TString>
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
|
||||
bool>::type
|
||||
is(const TString& key) const {
|
||||
bool is(const TString& key) const {
|
||||
return is_impl<const TString&, TValue>(key);
|
||||
}
|
||||
//
|
||||
// bool is<TValue>(TKey) const;
|
||||
// TKey = const char*, const char[N], const FlashStringHelper*
|
||||
// TKey = char*, const char*, const FlashStringHelper*
|
||||
// TValue = bool, char, long, int, short, float, double,
|
||||
// const std::string&, const String&,
|
||||
// const JsonArray&, const JsonObject&
|
||||
// std::string, String, JsonArray, JsonObject
|
||||
template <typename TValue, typename TString>
|
||||
bool is(const TString* key) const {
|
||||
return is_impl<const TString*, TValue>(key);
|
||||
bool is(TString* key) const {
|
||||
return is_impl<TString*, TValue>(key);
|
||||
}
|
||||
|
||||
// Creates and adds a JsonArray.
|
||||
@ -210,16 +185,14 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
// JsonArray& createNestedArray(TKey);
|
||||
// TKey = const std::string&, const String&
|
||||
template <typename TString>
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
|
||||
JsonArray&>::type
|
||||
createNestedArray(const TString& key) {
|
||||
JsonArray& createNestedArray(const TString& key) {
|
||||
return createNestedArray_impl<const TString&>(key);
|
||||
}
|
||||
// JsonArray& createNestedArray(TKey);
|
||||
// TKey = const char*, const char[N], const FlashStringHelper*
|
||||
// TKey = char*, const char*, char[], const char[], const FlashStringHelper*
|
||||
template <typename TString>
|
||||
JsonArray& createNestedArray(const TString* key) {
|
||||
return createNestedArray_impl<const TString*>(key);
|
||||
JsonArray& createNestedArray(TString* key) {
|
||||
return createNestedArray_impl<TString*>(key);
|
||||
}
|
||||
|
||||
// Creates and adds a JsonObject.
|
||||
@ -227,17 +200,15 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
// JsonObject& createNestedObject(TKey);
|
||||
// TKey = const std::string&, const String&
|
||||
template <typename TString>
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
|
||||
JsonObject&>::type
|
||||
createNestedObject(const TString& key) {
|
||||
JsonObject& createNestedObject(const TString& key) {
|
||||
return createNestedObject_impl<const TString&>(key);
|
||||
}
|
||||
//
|
||||
// JsonObject& createNestedObject(TKey);
|
||||
// TKey = const char*, const char[N], const FlashStringHelper*
|
||||
// TKey = char*, const char*, char[], const char[], const FlashStringHelper*
|
||||
template <typename TString>
|
||||
JsonObject& createNestedObject(const TString* key) {
|
||||
return createNestedObject_impl<const TString*>(key);
|
||||
JsonObject& createNestedObject(TString* key) {
|
||||
return createNestedObject_impl<TString*>(key);
|
||||
}
|
||||
|
||||
// Tells weither the specified key is present and associated with a value.
|
||||
@ -245,17 +216,15 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
// bool containsKey(TKey);
|
||||
// TKey = const std::string&, const String&
|
||||
template <typename TString>
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
|
||||
bool>::type
|
||||
containsKey(const TString& key) const {
|
||||
bool containsKey(const TString& key) const {
|
||||
return findKey<const TString&>(key) != end();
|
||||
}
|
||||
//
|
||||
// bool containsKey(TKey);
|
||||
// TKey = const char*, const char[N], const FlashStringHelper*
|
||||
// TKey = char*, const char*, char[], const char[], const FlashStringHelper*
|
||||
template <typename TString>
|
||||
bool containsKey(const TString* key) const {
|
||||
return findKey<const TString*>(key) != end();
|
||||
bool containsKey(TString* key) const {
|
||||
return findKey<TString*>(key) != end();
|
||||
}
|
||||
|
||||
// Removes the specified key and the associated value.
|
||||
@ -263,17 +232,15 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
// void remove(TKey);
|
||||
// TKey = const std::string&, const String&
|
||||
template <typename TString>
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
|
||||
void>::type
|
||||
remove(const TString& key) {
|
||||
void remove(const TString& key) {
|
||||
remove(findKey<const TString&>(key));
|
||||
}
|
||||
//
|
||||
// void remove(TKey);
|
||||
// TKey = const char*, const char[N], const FlashStringHelper*
|
||||
// TKey = char*, const char*, char[], const char[], const FlashStringHelper*
|
||||
template <typename TString>
|
||||
void remove(const TString* key) {
|
||||
remove(findKey<const TString*>(key));
|
||||
void remove(TString* key) {
|
||||
remove(findKey<TString*>(key));
|
||||
}
|
||||
//
|
||||
// void remove(iterator)
|
||||
@ -318,10 +285,10 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
if (it == end()) return false;
|
||||
|
||||
bool key_ok =
|
||||
Internals::ValueSetter<TStringRef>::set(_buffer, it->key, key);
|
||||
Internals::ValueSaver<TStringRef>::save(_buffer, it->key, key);
|
||||
if (!key_ok) return false;
|
||||
}
|
||||
return Internals::ValueSetter<TValueRef>::set(_buffer, it->value, value);
|
||||
return Internals::ValueSaver<TValueRef>::save(_buffer, it->value, value);
|
||||
}
|
||||
|
||||
template <typename TStringRef, typename TValue>
|
||||
|
@ -31,10 +31,9 @@ class JsonObjectSubscript
|
||||
|
||||
// Set the specified value
|
||||
//
|
||||
// operator=(TValue);
|
||||
// operator=(const TValue&);
|
||||
// TValue = bool, char, long, int, short, float, double,
|
||||
// const std::string&, const String&,
|
||||
// const JsonArray&, const JsonObject&
|
||||
// std::string, String, JsonArray, JsonObject
|
||||
template <typename TValue>
|
||||
FORCE_INLINE
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TValue>::value,
|
||||
@ -45,7 +44,7 @@ class JsonObjectSubscript
|
||||
}
|
||||
//
|
||||
// operator=(TValue);
|
||||
// TValue = const char*, const char[N], const FlashStringHelper*
|
||||
// TValue = char*, const char*, const FlashStringHelper*
|
||||
template <typename TValue>
|
||||
FORCE_INLINE this_type& operator=(const TValue* src) {
|
||||
_object.set(_key, src);
|
||||
@ -68,10 +67,9 @@ class JsonObjectSubscript
|
||||
|
||||
// Sets the specified value.
|
||||
//
|
||||
// bool set(TValue);
|
||||
// bool set(const TValue&);
|
||||
// TValue = bool, char, long, int, short, float, double, RawJson, JsonVariant,
|
||||
// const std::string&, const String&,
|
||||
// const JsonArray&, const JsonObject&
|
||||
// std::string, String, JsonArray, JsonObject
|
||||
template <typename TValue>
|
||||
FORCE_INLINE
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TValue>::value,
|
||||
@ -81,7 +79,7 @@ class JsonObjectSubscript
|
||||
}
|
||||
//
|
||||
// bool set(TValue);
|
||||
// TValue = const char*, const char[N], const FlashStringHelper*
|
||||
// TValue = char*, const char, const FlashStringHelper*
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(const TValue* value) {
|
||||
return _object.set(_key, value);
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#ifdef _MSC_VER // Visual Studio
|
||||
|
||||
#define FORCE_INLINE __forceinline
|
||||
#define FORCE_INLINE // __forceinline causes C4714 when returning std::string
|
||||
#define NO_INLINE __declspec(noinline)
|
||||
#define DEPRECATED(msg) __declspec(deprecated(msg))
|
||||
|
||||
|
@ -33,6 +33,7 @@ struct CharPointerTraits {
|
||||
return strcmp(reinterpret_cast<const char*>(str), expected) == 0;
|
||||
}
|
||||
|
||||
// TODO: remove
|
||||
template <typename Buffer>
|
||||
static char* duplicate(const TChar* str, Buffer* buffer) {
|
||||
if (!str) return NULL;
|
||||
@ -44,12 +45,46 @@ struct CharPointerTraits {
|
||||
|
||||
static const bool has_append = false;
|
||||
static const bool has_equals = true;
|
||||
static const bool should_duplicate = false;
|
||||
};
|
||||
|
||||
// const char*, const unsigned char*, const signed char*
|
||||
template <typename TChar>
|
||||
struct StringTraits<TChar*, typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsChar<TChar>::value>::type>
|
||||
: CharPointerTraits<TChar> {};
|
||||
TypeTraits::IsChar<TChar>::value &&
|
||||
TypeTraits::IsConst<TChar>::value>::type>
|
||||
: CharPointerTraits<TChar> {
|
||||
// Just save the pointer
|
||||
template <typename Buffer, typename Destination>
|
||||
static typename TypeTraits::EnableIf<TypeTraits::IsConst<TChar>::value,
|
||||
bool>::type
|
||||
save(const TChar* source, Destination& dest, Buffer*) {
|
||||
dest = reinterpret_cast<const char*>(source);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// char*, unsigned char*, signed char*
|
||||
template <typename TChar>
|
||||
struct StringTraits<TChar*, typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsChar<TChar>::value &&
|
||||
!TypeTraits::IsConst<TChar>::value>::type>
|
||||
: CharPointerTraits<TChar> {
|
||||
// Make a copy of the string
|
||||
template <typename Buffer, typename Destination>
|
||||
static typename TypeTraits::EnableIf<!TypeTraits::IsConst<TChar>::value,
|
||||
bool>::type
|
||||
save(const TChar* source, Destination& dest, Buffer* buffer) {
|
||||
if (source) {
|
||||
size_t size = strlen(reinterpret_cast<const char*>(source)) + 1;
|
||||
void* dup = buffer->alloc(size);
|
||||
if (!dup) return false;
|
||||
memcpy(dup, source, size);
|
||||
dest = reinterpret_cast<const char*>(dup);
|
||||
} else {
|
||||
dest = reinterpret_cast<const char*>(source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ struct StringTraits<const __FlashStringHelper*, void> {
|
||||
return strcmp_P(expected, (const char*)str) == 0;
|
||||
}
|
||||
|
||||
// TODO: remove
|
||||
template <typename Buffer>
|
||||
static char* duplicate(const __FlashStringHelper* str, Buffer* buffer) {
|
||||
if (!str) return NULL;
|
||||
@ -43,9 +44,22 @@ struct StringTraits<const __FlashStringHelper*, void> {
|
||||
return static_cast<char*>(dup);
|
||||
}
|
||||
|
||||
template <typename Buffer, typename Destination>
|
||||
static bool save(const __FlashStringHelper* source, Destination& dest,
|
||||
Buffer* buffer) {
|
||||
if (source) {
|
||||
size_t size = strlen_P((const char*)source) + 1;
|
||||
void* dup = buffer->alloc(size);
|
||||
if (dup != NULL) memcpy_P(dup, (const char*)source, size);
|
||||
dest = reinterpret_cast<const char*>(dup);
|
||||
} else {
|
||||
dest = reinterpret_cast<const char*>(source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static const bool has_append = false;
|
||||
static const bool has_equals = true;
|
||||
static const bool should_duplicate = true;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ namespace Internals {
|
||||
|
||||
template <typename TString>
|
||||
struct StdStringTraits {
|
||||
// TODO: remove
|
||||
template <typename Buffer>
|
||||
static char* duplicate(const TString& str, Buffer* buffer) {
|
||||
if (!str.c_str()) return NULL; // <- Arduino string can return NULL
|
||||
@ -28,6 +29,21 @@ struct StdStringTraits {
|
||||
return static_cast<char*>(dup);
|
||||
}
|
||||
|
||||
template <typename Buffer, typename Destination>
|
||||
static bool save(const TString& str, Destination& dest, Buffer* buffer) {
|
||||
// Arduino's String::c_str() can return NULL
|
||||
if (str.c_str()) {
|
||||
size_t size = str.length() + 1;
|
||||
void* dup = buffer->alloc(size);
|
||||
if (!dup) return false;
|
||||
memcpy(dup, str.c_str(), size);
|
||||
dest = reinterpret_cast<const char*>(dup);
|
||||
} else {
|
||||
dest = str.c_str();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct Reader : CharPointerTraits<char>::Reader {
|
||||
Reader(const TString& str) : CharPointerTraits<char>::Reader(str.c_str()) {}
|
||||
};
|
||||
@ -46,7 +62,6 @@ struct StdStringTraits {
|
||||
|
||||
static const bool has_append = true;
|
||||
static const bool has_equals = true;
|
||||
static const bool should_duplicate = true;
|
||||
};
|
||||
|
||||
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "../TypeTraits/EnableIf.hpp"
|
||||
#include "../TypeTraits/IsBaseOf.hpp"
|
||||
#include "../TypeTraits/IsChar.hpp"
|
||||
#include "../TypeTraits/IsConst.hpp"
|
||||
#include "../TypeTraits/RemoveReference.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
Reference in New Issue
Block a user