Files
ArduinoJson/src/ArduinoJson/JsonArray.hpp

211 lines
5.9 KiB
C++
Raw Normal View History

// ArduinoJson - arduinojson.org
2018-01-05 09:20:01 +01:00
// Copyright Benoit Blanchon 2014-2018
2014-10-23 23:39:22 +02:00
// MIT License
2014-10-16 00:11:23 +02:00
#pragma once
#include "Data/List.hpp"
#include "Data/ReferenceType.hpp"
#include "Data/ValueSaver.hpp"
#include "JsonVariant.hpp"
2018-03-15 09:56:00 +01:00
#include "Memory/JsonBufferAllocated.hpp"
2018-05-17 13:46:23 +02:00
#include "Polyfills/type_traits.hpp"
#include "Strings/StringTraits.hpp"
2014-10-30 21:51:59 +01:00
2014-11-06 14:48:14 +01:00
// Returns the size (in bytes) of an array with n elements.
// Can be very handy to determine the size of a StaticJsonBuffer.
2014-10-30 21:51:59 +01:00
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
(sizeof(JsonArray) + (NUMBER_OF_ELEMENTS) * sizeof(JsonArray::node_type))
2014-10-16 00:11:23 +02:00
2014-10-23 19:54:00 +02:00
namespace ArduinoJson {
2014-10-30 14:03:33 +01:00
2014-11-06 16:29:29 +01:00
// Forward declarations
2014-10-31 12:27:33 +01:00
class JsonObject;
class JsonBuffer;
namespace Internals {
class JsonArraySubscript;
}
2014-10-31 12:27:33 +01:00
class JsonArray : public Internals::ReferenceType,
public Internals::NonCopyable,
public Internals::List<JsonVariant>,
public Internals::JsonBufferAllocated {
public:
2018-03-15 09:56:00 +01:00
explicit JsonArray(Internals::JsonBuffer *buf) throw()
: Internals::List<JsonVariant>(buf) {}
2014-11-06 16:29:29 +01:00
// Gets the value at the specified index
const Internals::JsonArraySubscript operator[](size_t index) const;
2014-10-23 19:54:00 +02:00
// Gets or sets the value at specified index
Internals::JsonArraySubscript operator[](size_t index);
2014-11-06 14:48:14 +01:00
// Adds the specified value at the end of the array.
//
// bool add(TValue);
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// std::string, String, JsonArray, JsonObject
template <typename T>
bool add(const T &value) {
return add_impl<const T &>(value);
}
//
// bool add(TValue);
// TValue = char*, const char*, const FlashStringHelper*
template <typename T>
bool add(T *value) {
return add_impl<T *>(value);
}
//
// bool add(TValue value, uint8_t decimals);
// TValue = float, double
template <typename T>
DEPRECATED("Second argument is not supported anymore")
bool add(T value, uint8_t) {
return add_impl<const JsonVariant &>(JsonVariant(value));
}
2014-10-25 21:02:13 +02:00
// Sets the value at specified index.
//
// bool add(size_t index, const TValue&);
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// std::string, String, JsonArray, JsonObject
template <typename T>
bool set(size_t index, const T &value) {
return set_impl<const T &>(index, value);
}
//
// bool add(size_t index, TValue);
// TValue = char*, const char*, const FlashStringHelper*
template <typename T>
bool set(size_t index, T *value) {
return set_impl<T *>(index, value);
}
//
// bool set(size_t index, TValue value, uint8_t decimals);
// TValue = float, double
template <typename T>
2018-05-17 13:46:23 +02:00
typename Internals::enable_if<Internals::is_floating_point<T>::value,
bool>::type
set(size_t index, T value, uint8_t decimals) {
return set_impl<const JsonVariant &>(index, JsonVariant(value, decimals));
}
2014-11-06 14:48:14 +01:00
// Gets the value at the specified index.
template <typename T>
typename Internals::JsonVariantAs<T>::type get(size_t index) const {
const_iterator it = begin() += index;
return it != end() ? it->as<T>() : Internals::JsonVariantDefault<T>::get();
}
// Check the type of the value at specified index.
template <typename T>
bool is(size_t index) const {
const_iterator it = begin() += index;
return it != end() ? it->is<T>() : false;
}
2014-11-06 14:48:14 +01:00
// Creates a JsonArray and adds a reference at the end of the array.
2014-10-29 14:24:34 +01:00
JsonArray &createNestedArray();
2014-11-06 14:48:14 +01:00
// Creates a JsonObject and adds a reference at the end of the array.
2014-10-29 14:24:34 +01:00
JsonObject &createNestedObject();
2014-10-23 19:54:00 +02:00
// Removes element at specified index.
void remove(size_t index) {
remove(begin() += index);
}
using Internals::List<JsonVariant>::remove;
2014-11-06 14:48:14 +01:00
// Returns a reference an invalid JsonArray.
2014-11-06 16:29:29 +01:00
// This object is meant to replace a NULL pointer.
2014-11-06 14:48:14 +01:00
// This is used when memory allocation or JSON parsing fail.
static JsonArray &invalid() {
static JsonArray instance(NULL);
return instance;
}
2014-10-27 22:50:50 +01:00
// Imports a 1D array
template <typename T, size_t N>
bool copyFrom(T (&array)[N]) {
return copyFrom(array, N);
}
// Imports a 1D array
template <typename T>
bool copyFrom(T *array, size_t len) {
bool ok = true;
for (size_t i = 0; i < len; i++) {
ok &= add(array[i]);
}
return ok;
}
// Imports a 2D array
template <typename T, size_t N1, size_t N2>
bool copyFrom(T (&array)[N1][N2]) {
bool ok = true;
for (size_t i = 0; i < N1; i++) {
JsonArray &nestedArray = createNestedArray();
for (size_t j = 0; j < N2; j++) {
ok &= nestedArray.add(array[i][j]);
}
}
return ok;
}
// Exports a 1D array
template <typename T, size_t N>
size_t copyTo(T (&array)[N]) const {
return copyTo(array, N);
}
// Exports a 1D array
template <typename T>
size_t copyTo(T *array, size_t len) const {
size_t i = 0;
for (const_iterator it = begin(); it != end() && i < len; ++it)
array[i++] = *it;
return i;
}
// Exports a 2D array
template <typename T, size_t N1, size_t N2>
void copyTo(T (&array)[N1][N2]) const {
size_t i = 0;
for (const_iterator it = begin(); it != end() && i < N1; ++it) {
it->as<JsonArray>().copyTo(array[i++]);
}
}
template <typename Visitor>
void visit(Visitor &visitor) const {
return visitor.acceptArray(*this);
}
2014-10-26 21:18:09 +01:00
private:
template <typename TValueRef>
bool set_impl(size_t index, TValueRef value) {
iterator it = begin() += index;
if (it == end()) return false;
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::ValueSaver<TValueRef>::save(_buffer, *it, value);
}
2014-10-23 19:54:00 +02:00
};
namespace Internals {
template <>
struct JsonVariantDefault<JsonArray> {
static JsonArray &get() {
return JsonArray::invalid();
}
};
} // namespace Internals
} // namespace ArduinoJson