mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-11-03 08:01:41 +01:00
Change string copy policy: only string literal are stored by pointer
This commit is contained in:
@@ -66,7 +66,8 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
|
||||
// Appends a value to the array.
|
||||
// https://arduinojson.org/v7/api/jsonarray/add/
|
||||
template <typename T>
|
||||
template <typename T,
|
||||
typename = detail::enable_if_t<!detail::is_const<T>::value>>
|
||||
bool add(T* value) const {
|
||||
return detail::ArrayData::addValue(data_, value, resources_);
|
||||
}
|
||||
|
||||
@@ -144,7 +144,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
|
||||
// Replaces the root with the specified value.
|
||||
// https://arduinojson.org/v7/api/jsondocument/set/
|
||||
template <typename TChar>
|
||||
template <typename TChar,
|
||||
typename = detail::enable_if_t<!detail::is_const<TChar>::value>>
|
||||
bool set(TChar* src) {
|
||||
return to<JsonVariant>().set(src);
|
||||
}
|
||||
@@ -197,7 +198,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
// https://arduinojson.org/v7/api/jsondocument/subscript/
|
||||
template <typename TChar>
|
||||
detail::enable_if_t<
|
||||
detail::IsString<TChar*>::value,
|
||||
detail::IsString<TChar*>::value && !detail::is_const<TChar>::value,
|
||||
detail::MemberProxy<JsonDocument&, detail::AdaptedString<TChar*>>>
|
||||
operator[](TChar* key) {
|
||||
return {*this, detail::adaptString(key)};
|
||||
@@ -215,7 +216,9 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
// Gets a root object's member.
|
||||
// https://arduinojson.org/v7/api/jsondocument/subscript/
|
||||
template <typename TChar>
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value, JsonVariantConst>
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value &&
|
||||
!detail::is_const<TChar>::value,
|
||||
JsonVariantConst>
|
||||
operator[](TChar* key) const {
|
||||
return JsonVariantConst(
|
||||
data_.getMember(detail::adaptString(key), &resources_), &resources_);
|
||||
@@ -273,7 +276,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
|
||||
// Appends a value to the root array.
|
||||
// https://arduinojson.org/v7/api/jsondocument/add/
|
||||
template <typename TChar>
|
||||
template <typename TChar,
|
||||
typename = detail::enable_if_t<!detail::is_const<TChar>::value>>
|
||||
bool add(TChar* value) {
|
||||
return data_.addValue(value, &resources_);
|
||||
}
|
||||
@@ -289,7 +293,9 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
// Removes a member of the root object.
|
||||
// https://arduinojson.org/v7/api/jsondocument/remove/
|
||||
template <typename TChar>
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value> remove(TChar* key) {
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value &&
|
||||
!detail::is_const<TChar>::value>
|
||||
remove(TChar* key) {
|
||||
detail::VariantData::removeMember(getData(), detail::adaptString(key),
|
||||
getResourceManager());
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// https://arduinojson.org/v7/api/jsonobject/subscript/
|
||||
template <typename TChar>
|
||||
detail::enable_if_t<
|
||||
detail::IsString<TChar*>::value,
|
||||
detail::IsString<TChar*>::value && !detail::is_const<TChar>::value,
|
||||
detail::MemberProxy<JsonObject, detail::AdaptedString<TChar*>>>
|
||||
operator[](TChar* key) const {
|
||||
return {*this, detail::adaptString(key)};
|
||||
@@ -175,8 +175,9 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// https://arduinojson.org/v7/api/jsonobject/containskey/
|
||||
template <typename TChar>
|
||||
ARDUINOJSON_DEPRECATED("use obj[\"key\"].is<T>() instead")
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value, bool> containsKey(
|
||||
TChar* key) const {
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value &&
|
||||
!detail::is_const<TChar>::value,
|
||||
bool> containsKey(TChar* key) const {
|
||||
return detail::ObjectData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,9 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
// Gets the member with specified key.
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/subscript/
|
||||
template <typename TChar>
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value, JsonVariantConst>
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value &&
|
||||
!detail::is_const<TChar>::value,
|
||||
JsonVariantConst>
|
||||
operator[](TChar* key) const {
|
||||
return JsonVariantConst(detail::ObjectData::getMember(
|
||||
data_, detail::adaptString(key), resources_),
|
||||
|
||||
@@ -39,7 +39,7 @@ class MemberProxy
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename T, typename = enable_if_t<!is_const<T>::value>>
|
||||
MemberProxy& operator=(T* src) {
|
||||
this->set(src);
|
||||
return *this;
|
||||
|
||||
@@ -76,6 +76,15 @@ struct StringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
struct StringAdapter<const char (&)[N]> {
|
||||
using AdaptedString = RamString;
|
||||
|
||||
static AdaptedString adapt(const char (&p)[N]) {
|
||||
return RamString(p, N - 1, true);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TChar, size_t N>
|
||||
struct StringAdapter<TChar[N], enable_if_t<IsChar<TChar>::value>> {
|
||||
using AdaptedString = RamString;
|
||||
@@ -86,15 +95,6 @@ struct StringAdapter<TChar[N], enable_if_t<IsChar<TChar>::value>> {
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct StringAdapter<const char*, void> {
|
||||
using AdaptedString = RamString;
|
||||
|
||||
static AdaptedString adapt(const char* p) {
|
||||
return AdaptedString(p, p ? ::strlen(p) : 0, true);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TChar>
|
||||
struct SizedStringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
|
||||
using AdaptedString = RamString;
|
||||
|
||||
@@ -13,7 +13,7 @@ template <typename T, typename Enable = void>
|
||||
struct IsString : false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct IsString<T, void_t<typename StringAdapter<T>::AdaptedString>>
|
||||
struct IsString<T, void_t<typename StringAdapterFor<T>::AdaptedString>>
|
||||
: true_type {};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -4,8 +4,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/utility.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
// a meta function that tells if the type is a string literal (const char[N])
|
||||
template <typename T>
|
||||
struct IsStringLiteral : false_type {};
|
||||
|
||||
template <size_t N>
|
||||
struct IsStringLiteral<const char (&)[N]> : true_type {};
|
||||
|
||||
template <typename TString, typename Enable = void>
|
||||
struct StringAdapter;
|
||||
|
||||
@@ -13,18 +22,25 @@ template <typename TString, typename Enable = void>
|
||||
struct SizedStringAdapter;
|
||||
|
||||
template <typename TString>
|
||||
typename StringAdapter<TString>::AdaptedString adaptString(const TString& s) {
|
||||
return StringAdapter<TString>::adapt(s);
|
||||
using StringAdapterFor =
|
||||
StringAdapter<conditional_t<IsStringLiteral<TString>::value, TString,
|
||||
remove_cv_t<remove_reference_t<TString>>>>;
|
||||
|
||||
template <typename T>
|
||||
using AdaptedString = typename StringAdapterFor<T>::AdaptedString;
|
||||
|
||||
template <typename TString>
|
||||
AdaptedString<TString> adaptString(TString&& s) {
|
||||
return StringAdapterFor<TString>::adapt(detail::forward<TString>(s));
|
||||
}
|
||||
|
||||
template <typename TChar>
|
||||
typename StringAdapter<TChar*>::AdaptedString adaptString(TChar* p) {
|
||||
template <typename TChar, typename = enable_if_t<!is_const<TChar>::value>>
|
||||
AdaptedString<TChar*> adaptString(TChar* p) {
|
||||
return StringAdapter<TChar*>::adapt(p);
|
||||
}
|
||||
|
||||
template <typename TChar>
|
||||
typename SizedStringAdapter<TChar*>::AdaptedString adaptString(TChar* p,
|
||||
size_t n) {
|
||||
AdaptedString<TChar*> adaptString(TChar* p, size_t n) {
|
||||
return SizedStringAdapter<TChar*>::adapt(p, n);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,8 +70,4 @@ static void stringGetChars(TAdaptedString s, char* p, size_t n) {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
using AdaptedString =
|
||||
typename StringAdapter<remove_reference_t<T>>::AdaptedString;
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
||||
@@ -31,7 +31,7 @@ struct Converter {
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
static T fromJson(JsonVariantConst src) {
|
||||
static detail::decay_t<T> fromJson(JsonVariantConst src) {
|
||||
static_assert(!detail::is_same<T, char*>::value,
|
||||
"type 'char*' is not supported, use 'const char*' instead");
|
||||
|
||||
|
||||
@@ -120,7 +120,9 @@ class JsonVariantConst : public detail::VariantTag,
|
||||
// Gets object's member with specified key.
|
||||
// https://arduinojson.org/v7/api/jsonvariantconst/subscript/
|
||||
template <typename TChar>
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value, JsonVariantConst>
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value &&
|
||||
!detail::is_const<TChar>::value,
|
||||
JsonVariantConst>
|
||||
operator[](TChar* key) const {
|
||||
return JsonVariantConst(detail::VariantData::getMember(
|
||||
data_, detail::adaptString(key), resources_),
|
||||
@@ -153,8 +155,9 @@ class JsonVariantConst : public detail::VariantTag,
|
||||
// https://arduinojson.org/v7/api/jsonvariantconst/containskey/
|
||||
template <typename TChar>
|
||||
ARDUINOJSON_DEPRECATED("use obj[\"key\"].is<T>() instead")
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value, bool> containsKey(
|
||||
TChar* key) const {
|
||||
detail::enable_if_t<detail::IsString<TChar*>::value &&
|
||||
!detail::is_const<TChar>::value,
|
||||
bool> containsKey(TChar* key) const {
|
||||
return detail::VariantData::getMember(getData(), detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
}
|
||||
|
||||
@@ -77,12 +77,15 @@ class VariantRefBase : public VariantTag {
|
||||
// https://arduinojson.org/v7/api/jsonvariant/set/
|
||||
template <typename T>
|
||||
bool set(const T& value) const {
|
||||
return doSet<Converter<remove_cv_t<T>>>(value);
|
||||
using TypeForConverter = conditional_t<IsStringLiteral<T>::value, T,
|
||||
remove_cv_t<remove_reference_t<T>>>;
|
||||
return doSet<Converter<TypeForConverter>>(value);
|
||||
}
|
||||
|
||||
// Copies the specified value.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/set/
|
||||
template <typename T>
|
||||
template <typename T,
|
||||
typename = detail::enable_if_t<!detail::is_const<T>::value>>
|
||||
bool set(T* value) const {
|
||||
return doSet<Converter<T*>>(value);
|
||||
}
|
||||
@@ -123,7 +126,7 @@ class VariantRefBase : public VariantTag {
|
||||
|
||||
// Appends a value to the array.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/add/
|
||||
template <typename T>
|
||||
template <typename T, typename = enable_if_t<!is_const<T>::value>>
|
||||
bool add(T* value) const {
|
||||
return detail::VariantData::addValue(getOrCreateData(), value,
|
||||
getResourceManager());
|
||||
@@ -195,7 +198,7 @@ class VariantRefBase : public VariantTag {
|
||||
// Gets or sets an object member.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/subscript/
|
||||
template <typename TChar>
|
||||
FORCE_INLINE enable_if_t<IsString<TChar*>::value,
|
||||
FORCE_INLINE enable_if_t<IsString<TChar*>::value && !is_const<TChar>::value,
|
||||
MemberProxy<TDerived, AdaptedString<TChar*>>>
|
||||
operator[](TChar* key) const;
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ inline ElementProxy<TDerived> VariantRefBase<TDerived>::operator[](
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename TChar>
|
||||
inline enable_if_t<IsString<TChar*>::value,
|
||||
inline enable_if_t<IsString<TChar*>::value && !is_const<TChar>::value,
|
||||
MemberProxy<TDerived, AdaptedString<TChar*>>>
|
||||
VariantRefBase<TDerived>::operator[](TChar* key) const {
|
||||
return {derived(), adaptString(key)};
|
||||
|
||||
Reference in New Issue
Block a user