Files
ArduinoJson/include/ArduinoJson/JsonArray.hpp

231 lines
7.1 KiB
C++
Raw Normal View History

// Copyright Benoit Blanchon 2014-2016
2014-10-23 23:39:22 +02:00
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
2014-10-23 23:39:22 +02:00
2014-10-16 00:11:23 +02:00
#pragma once
#include "Internals/JsonBufferAllocated.hpp"
2014-11-05 08:53:41 +01:00
#include "Internals/JsonPrintable.hpp"
#include "Internals/List.hpp"
2014-10-31 12:27:33 +01:00
#include "Internals/ReferenceType.hpp"
#include "Internals/StringFuncs.hpp"
#include "Internals/ValueSetter.hpp"
#include "JsonVariant.hpp"
#include "TypeTraits/ConstRefOrConstPtr.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsFloatingPoint.hpp"
#include "TypeTraits/IsSame.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;
class JsonArraySubscript;
2014-10-31 12:27:33 +01:00
2014-11-06 14:48:14 +01:00
// An array of JsonVariant.
2014-11-06 16:29:29 +01:00
//
// The constructor is private, instances must be created via
// JsonBuffer::createArray() or JsonBuffer::parseArray().
// A JsonArray can be serialized to a JSON string via JsonArray::printTo().
// It can also be deserialized from a JSON string via JsonBuffer::parseArray().
2014-11-05 08:53:41 +01:00
class JsonArray : public Internals::JsonPrintable<JsonArray>,
public Internals::ReferenceType,
public Internals::List<JsonVariant>,
public Internals::JsonBufferAllocated {
public:
// Create an empty JsonArray attached to the specified JsonBuffer.
// You should not call this constructor directly.
// Instead, use JsonBuffer::createArray() or JsonBuffer::parseArray().
explicit JsonArray(JsonBuffer *buffer)
: Internals::List<JsonVariant>(buffer) {}
2014-11-06 16:29:29 +01:00
// Gets the value at the specified index
JsonVariant operator[](size_t index) const {
return get<JsonVariant>(index);
}
2014-10-23 19:54:00 +02:00
// Gets or sets the value at specified index
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(bool);
// bool add(char);
// bool add(long);
// bool add(int);
// bool add(short);
// bool add(float value);
// bool add(double value);
// bool add(const char*);
// bool add(const char[]);
// bool add(const char[N]);
// bool add(RawJson);
// bool add(const std::string&)
// bool add(const String&)
// bool add(const JsonVariant&);
// bool add(JsonArray&);
// bool add(JsonObject&);
template <typename T>
bool add(const T &value) {
// reduce the number of template function instanciation to reduce code size
return addNodeImpl<typename TypeTraits::ConstRefOrConstPtr<T>::type>(value);
}
// bool add(float value, uint8_t decimals);
// bool add(double value, uint8_t decimals);
template <typename T>
bool add(T value, uint8_t decimals) {
return add(JsonVariant(value, decimals));
}
2014-10-25 21:02:13 +02:00
// Sets the value at specified index.
//
// bool set(size_t index, bool value);
// bool set(size_t index, long value);
// bool set(size_t index, int value);
// bool set(size_t index, short value);
// bool set(size_t index, const std::string&)
// bool set(size_t index, const String&)
// bool set(size_t index, const JsonVariant&);
// bool set(size_t index, JsonArray&);
// bool set(size_t index, JsonObject&);
template <typename T>
bool set(size_t index, const T &value) {
// reduce the number of template function instanciation to reduce code size
return setNodeAt<typename TypeTraits::ConstRefOrConstPtr<T>::type>(index,
value);
}
// bool set(size_t index, float value, uint8_t decimals = 2);
// bool set(size_t index, double value, uint8_t decimals = 2);
template <typename T>
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
bool>::type
set(size_t index, T value, uint8_t decimals) {
return set(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 {
node_type *node = getNodeAt(index);
return node ? node->content.as<T>()
: Internals::JsonVariantDefault<T>::get();
;
}
// Check the type of the value at specified index.
template <typename T>
bool is(size_t index) const {
node_type *node = getNodeAt(index);
return node ? node->content.is<T>() : false;
}
2014-11-06 14:48:14 +01:00
// Creates a JsonArray and adds a reference at the end of the array.
// It's a shortcut for JsonBuffer::createArray() and JsonArray::add()
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.
// It's a shortcut for JsonBuffer::createObject() and JsonArray::add()
2014-10-29 14:24:34 +01:00
JsonObject &createNestedObject();
2014-10-23 19:54:00 +02:00
// Removes element at specified index.
void removeAt(size_t index) {
removeNode(getNodeAt(index));
}
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->asArray().copyTo(array[i++]);
}
}
2014-10-26 21:18:09 +01:00
private:
node_type *getNodeAt(size_t index) const {
node_type *node = _firstNode;
while (node && index--) node = node->next;
return node;
}
template <typename TValueRef>
bool setNodeAt(size_t index, TValueRef value) {
node_type *node = getNodeAt(index);
if (!node) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
value);
}
template <typename TValueRef>
bool addNodeImpl(TValueRef value) {
node_type *node = addNewNode();
if (!node) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
value);
}
2014-10-23 19:54:00 +02:00
};
2014-10-18 23:05:54 +02:00
}