Changed the rules of string duplication (fixes #658)

This commit is contained in:
Benoit Blanchon
2018-01-14 13:46:28 +01:00
parent 5c33fd4b94
commit e92612b511
22 changed files with 416 additions and 224 deletions

View 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);
}
};
}
}

View File

@ -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;
}
};
}
}

View File

@ -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);
}
};

View File

@ -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);
}
//

View File

@ -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>

View File

@ -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);

View File

@ -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))

View File

@ -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;
}
};
}
}

View File

@ -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;
};
}
}

View File

@ -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

View File

@ -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 {