Files
thirdparty-ArduinoJson/src/ArduinoJson/JsonObject.hpp
2018-05-29 08:31:39 +02:00

293 lines
9.7 KiB
C++

// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#include "Data/List.hpp"
#include "Data/ReferenceType.hpp"
#include "Data/ValueSaver.hpp"
#include "JsonPair.hpp"
#include "Memory/JsonBufferAllocated.hpp"
#include "Polyfills/type_traits.hpp"
#include "Strings/StringTraits.hpp"
// Returns the size (in bytes) of an object with n elements.
// Can be very handy to determine the size of a StaticJsonBuffer.
#define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \
(sizeof(JsonObject) + (NUMBER_OF_ELEMENTS) * sizeof(JsonObject::node_type))
namespace ArduinoJson {
// Forward declarations
class JsonArray;
class JsonBuffer;
namespace Internals {
template <typename>
class JsonObjectSubscript;
}
class JsonObject : public Internals::ReferenceType,
public Internals::NonCopyable,
public Internals::List<JsonPair>,
public Internals::JsonBufferAllocated {
public:
// Create an empty JsonArray attached to the specified JsonBuffer.
// You should not use this constructor directly.
explicit JsonObject(Internals::JsonBuffer* buf) throw()
: Internals::List<JsonPair>(buf) {}
// Gets or sets the value associated with the specified key.
//
// JsonObjectSubscript operator[](TKey)
// TKey = const std::string&, const String&
template <typename TString>
Internals::JsonObjectSubscript<const TString&> operator[](
const TString& key) {
return Internals::JsonObjectSubscript<const TString&>(*this, key);
}
//
// JsonObjectSubscript operator[](TKey)
// TKey = char*, const char*, char[], const char[N], const FlashStringHelper*
template <typename TString>
Internals::JsonObjectSubscript<TString*> operator[](TString* key) {
return Internals::JsonObjectSubscript<TString*>(*this, key);
}
// Gets the value associated with the specified key.
//
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const std::string&, const String&
template <typename TString>
const Internals::JsonObjectSubscript<const TString&> operator[](
const TString& key) const {
return Internals::JsonObjectSubscript<const TString&>(
*const_cast<JsonObject*>(this), key);
}
//
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
const Internals::JsonObjectSubscript<TString*> operator[](
TString* key) const {
return Internals::JsonObjectSubscript<TString*>(
*const_cast<JsonObject*>(this), key);
}
// Sets the specified key with the specified value.
//
// bool set(TKey, TValue);
// TKey = const std::string&, const String&
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// std::string, String, JsonArray, JsonObject
template <typename TValue, typename TString>
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 = char*, const char*, const FlashStringHelper*
template <typename TValue, typename TString>
bool set(const TString& key, TValue* value) {
return set_impl<const TString&, TValue*>(key, value);
}
//
// bool set(TKey, const TValue&);
// TKey = char*, const char*, const FlashStringHelper*
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// std::string, String, JsonArray, JsonObject
template <typename TValue, typename TString>
bool set(TString* key, const TValue& value) {
return set_impl<TString*, const TValue&>(key, value);
}
//
// bool set(TKey, TValue);
// TKey = char*, const char*, const FlashStringHelper*
// TValue = char*, const char*, const FlashStringHelper*
template <typename TValue, typename TString>
bool set(TString* key, TValue* value) {
return set_impl<TString*, TValue*>(key, value);
}
// Gets the value associated with the specified key.
//
// TValue get<TValue>(TKey) const;
// TKey = const std::string&, const String&
// TValue = bool, char, long, int, short, float, double,
// 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);
}
//
// TValue get<TValue>(TKey) const;
// TKey = char*, const char*, const FlashStringHelper*
// TValue = bool, char, long, int, short, float, double,
// std::string, String, JsonArray, JsonObject
template <typename TValue, typename TString>
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.
//
//
// bool is<TValue>(TKey) const;
// TKey = const std::string&, const String&
// TValue = bool, char, long, int, short, float, double,
// 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<TValue>(TKey) const;
// TKey = char*, const char*, const FlashStringHelper*
// TValue = bool, char, long, int, short, float, double,
// std::string, String, JsonArray, JsonObject
template <typename TValue, typename TString>
bool is(TString* key) const {
return is_impl<TString*, TValue>(key);
}
// Creates and adds a JsonArray.
//
// JsonArray& createNestedArray(TKey);
// TKey = const std::string&, const String&
template <typename TString>
JsonArray& createNestedArray(const TString& key) {
return createNestedArray_impl<const TString&>(key);
}
// JsonArray& createNestedArray(TKey);
// TKey = char*, const char*, char[], const char[], const FlashStringHelper*
template <typename TString>
JsonArray& createNestedArray(TString* key) {
return createNestedArray_impl<TString*>(key);
}
// Creates and adds a JsonObject.
//
// JsonObject& createNestedObject(TKey);
// TKey = const std::string&, const String&
template <typename TString>
JsonObject& createNestedObject(const TString& key) {
return createNestedObject_impl<const TString&>(key);
}
//
// JsonObject& createNestedObject(TKey);
// TKey = char*, const char*, char[], const char[], const FlashStringHelper*
template <typename TString>
JsonObject& createNestedObject(TString* key) {
return createNestedObject_impl<TString*>(key);
}
// Tells weither the specified key is present and associated with a value.
//
// bool containsKey(TKey);
// TKey = const std::string&, const String&
template <typename TString>
bool containsKey(const TString& key) const {
return findKey<const TString&>(key) != end();
}
//
// bool containsKey(TKey);
// TKey = char*, const char*, char[], const char[], const FlashStringHelper*
template <typename TString>
bool containsKey(TString* key) const {
return findKey<TString*>(key) != end();
}
// Removes the specified key and the associated value.
//
// void remove(TKey);
// TKey = const std::string&, const String&
template <typename TString>
void remove(const TString& key) {
remove(findKey<const TString&>(key));
}
//
// void remove(TKey);
// TKey = char*, const char*, char[], const char[], const FlashStringHelper*
template <typename TString>
void remove(TString* key) {
remove(findKey<TString*>(key));
}
//
// void remove(iterator)
using Internals::List<JsonPair>::remove;
// Returns a reference an invalid JsonObject.
// This object is meant to replace a NULL pointer.
// This is used when memory allocation or JSON parsing fail.
static JsonObject& invalid() {
static JsonObject instance(NULL);
return instance;
}
template <typename Visitor>
void visit(Visitor& visitor) const {
return visitor.acceptObject(*this);
}
private:
// Returns the list node that matches the specified key.
template <typename TStringRef>
iterator findKey(TStringRef key) {
iterator it;
for (it = begin(); it != end(); ++it) {
if (Internals::StringTraits<TStringRef>::equals(key, it->key)) break;
}
return it;
}
template <typename TStringRef>
const_iterator findKey(TStringRef key) const {
return const_cast<JsonObject*>(this)->findKey<TStringRef>(key);
}
template <typename TStringRef, typename TValue>
typename Internals::JsonVariantAs<TValue>::type get_impl(
TStringRef key) const {
const_iterator it = findKey<TStringRef>(key);
return it != end() ? it->value.as<TValue>()
: Internals::JsonVariantDefault<TValue>::get();
}
template <typename TStringRef, typename TValueRef>
bool set_impl(TStringRef key, TValueRef value) {
iterator it = findKey<TStringRef>(key);
if (it == end()) {
it = Internals::List<JsonPair>::add();
if (it == end()) return false;
bool key_ok =
Internals::ValueSaver<TStringRef>::save(_buffer, it->key, key);
if (!key_ok) return false;
}
return Internals::ValueSaver<TValueRef>::save(_buffer, it->value, value);
}
template <typename TStringRef, typename TValue>
bool is_impl(TStringRef key) const {
const_iterator it = findKey<TStringRef>(key);
return it != end() ? it->value.is<TValue>() : false;
}
template <typename TStringRef>
JsonArray& createNestedArray_impl(TStringRef key);
template <typename TStringRef>
JsonObject& createNestedObject_impl(TStringRef key);
};
namespace Internals {
template <>
struct JsonVariantDefault<JsonObject> {
static JsonObject& get() {
return JsonObject::invalid();
}
};
} // namespace Internals
} // namespace ArduinoJson