Files
ArduinoJson/src/ArduinoJson/JsonArray.hpp

270 lines
6.6 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/JsonVariantData.hpp"
#include "JsonArrayIterator.hpp"
2014-10-16 00:11:23 +02:00
// Returns the size (in bytes) of an array with n elements.
// Can be very handy to determine the size of a StaticMemoryPool.
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::Slot))
namespace ARDUINOJSON_NAMESPACE {
2014-10-30 14:03:33 +01:00
2014-10-31 12:27:33 +01:00
class JsonObject;
class JsonArraySubscript;
2014-10-31 12:27:33 +01:00
class JsonArray {
friend class JsonVariant;
2014-11-06 16:29:29 +01:00
public:
typedef JsonArrayIterator iterator;
2014-10-23 19:54:00 +02:00
2018-09-03 16:14:21 +02:00
FORCE_INLINE JsonArray() : _memoryPool(0), _data(0) {}
FORCE_INLINE JsonArray(MemoryPool* pool, JsonArrayData* arr)
: _memoryPool(pool), _data(arr) {}
operator JsonVariant() {
return JsonVariant(_memoryPool, getVariantData(_data));
}
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, serialized, JsonVariant,
// std::string, String, JsonObject
template <typename T>
2018-08-31 16:29:08 +02:00
FORCE_INLINE bool add(const T& value) {
return add().set(value);
}
// Adds the specified value at the end of the array.
FORCE_INLINE bool add(JsonArray value) {
return add().set(value);
}
//
// bool add(TValue);
// TValue = char*, const char*, const FlashStringHelper*
template <typename T>
2018-08-31 16:29:08 +02:00
FORCE_INLINE bool add(T* value) {
return add().set(value);
}
JsonVariant add() {
if (!_data) return JsonVariant();
Slot* slot = new (_memoryPool) Slot();
if (!slot) return JsonVariant();
slot->next = 0;
if (_data->tail) {
slot->prev = _data->tail;
_data->tail->next = slot;
_data->tail = slot;
} else {
slot->prev = 0;
_data->head = slot;
_data->tail = slot;
}
return JsonVariant(_memoryPool, &slot->value);
}
2014-10-25 21:02:13 +02:00
2018-08-31 16:29:08 +02:00
FORCE_INLINE iterator begin() const {
if (!_data) return iterator();
return iterator(_memoryPool, _data->head);
}
2014-11-06 14:48:14 +01:00
2018-08-31 16:29:08 +02:00
FORCE_INLINE iterator end() const {
return iterator();
}
2014-11-06 14:48:14 +01:00
// Imports a 1D array
template <typename T, size_t N>
2018-08-31 16:29:08 +02:00
FORCE_INLINE 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;
}
// Copy a JsonArray
bool copyFrom(JsonArray src) {
bool ok = _data != 0;
for (iterator it = src.begin(); it != src.end(); ++it) {
ok &= add(*it);
}
return ok;
}
// Exports a 1D array
template <typename T, size_t N>
2018-08-31 16:29:08 +02:00
FORCE_INLINE 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 (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 {
if (!_data) return;
size_t i = 0;
for (iterator it = begin(); it != end() && i < N1; ++it) {
it->as<JsonArray>().copyTo(array[i++]);
}
}
2018-08-31 16:29:08 +02:00
FORCE_INLINE JsonArray createNestedArray();
FORCE_INLINE JsonObject createNestedObject();
FORCE_INLINE JsonArraySubscript operator[](size_t index);
FORCE_INLINE const JsonArraySubscript operator[](size_t index) const;
FORCE_INLINE bool operator==(JsonArray rhs) const {
iterator it1 = begin();
iterator it2 = rhs.begin();
for (;;) {
if (it1 == end() && it2 == rhs.end()) return true;
if (it1 == end()) return false;
if (it2 == end()) return false;
if (*it1 != *it2) return false;
++it1;
++it2;
}
}
// Gets the value at the specified index.
template <typename T>
FORCE_INLINE typename JsonVariantAs<T>::type get(size_t index) const {
iterator it = begin() += index;
return it != end() ? it->as<T>() : T();
}
// Check the type of the value at specified index.
template <typename T>
2018-08-31 16:29:08 +02:00
FORCE_INLINE bool is(size_t index) const {
iterator it = begin() += index;
return it != end() ? it->is<T>() : false;
}
// Removes element at specified position.
2018-08-31 16:29:08 +02:00
FORCE_INLINE void remove(iterator it) {
if (!_data) return;
Slot* slot = it.internal();
if (!slot) return;
if (slot->prev)
slot->prev->next = slot->next;
else
_data->head = slot->next;
if (slot->next)
slot->next->prev = slot->prev;
else
_data->tail = slot->prev;
}
// Removes element at specified index.
2018-08-31 16:29:08 +02:00
FORCE_INLINE void remove(size_t index) {
remove(begin() += index);
}
// Sets the value at specified index.
//
// bool add(size_t index, const TValue&);
// TValue = bool, long, int, short, float, double, serialized, JsonVariant,
// std::string, String, JsonArrayData, JsonObject
template <typename T>
2018-08-31 16:29:08 +02:00
FORCE_INLINE bool set(size_t index, const T& value) {
if (!_data) return false;
return set_impl<const T&>(index, value);
}
//
// bool add(size_t index, TValue);
// TValue = char*, const char*, const FlashStringHelper*
template <typename T>
2018-08-31 16:29:08 +02:00
FORCE_INLINE bool set(size_t index, T* value) {
if (!_data) return false;
return set_impl<T*>(index, value);
}
// Sets the value at specified index.
//
// bool add(size_t index, JsonArray);
template <typename T>
FORCE_INLINE bool set(size_t index, JsonArray value) {
if (!_data) return false;
return get<JsonVariant>(index).set(value);
}
2018-08-31 16:29:08 +02:00
FORCE_INLINE size_t size() const {
if (!_data) return 0;
Slot* slot = _data->head;
size_t n = 0;
while (slot) {
slot = slot->next;
n++;
}
return n;
}
2018-08-31 16:29:08 +02:00
FORCE_INLINE bool isNull() const {
return _data == 0;
}
template <typename Visitor>
FORCE_INLINE void accept(Visitor& visitor) const {
if (_data)
visitor.visitArray(*this);
else
visitor.visitNull();
}
2014-10-26 21:18:09 +01:00
private:
template <typename TValueRef>
2018-08-31 16:29:08 +02:00
FORCE_INLINE bool set_impl(size_t index, TValueRef value) {
iterator it = begin() += index;
if (it == end()) return false;
return it->set(value);
}
template <typename TValueRef>
2018-08-31 16:29:08 +02:00
FORCE_INLINE bool add_impl(TValueRef value) {
return add().set(value);
}
MemoryPool* _memoryPool;
JsonArrayData* _data;
};
} // namespace ARDUINOJSON_NAMESPACE