Files
ArduinoJson/src/ArduinoJson/JsonArray.hpp

232 lines
7.0 KiB
C++
Raw Normal View History

// Copyright Benoit Blanchon 2014-2017
2014-10-23 23:39:22 +02:00
// MIT License
//
// Arduino JSON library
2017-03-25 22:05:06 +01:00
// https://bblanchon.github.io/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 "Data/JsonBufferAllocated.hpp"
#include "Data/List.hpp"
#include "Data/ReferenceType.hpp"
#include "Data/ValueSetter.hpp"
#include "JsonVariant.hpp"
#include "Serialization/JsonPrintable.hpp"
#include "StringTraits/StringTraits.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsArray.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
const JsonArraySubscript operator[](size_t index) const;
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(TValue);
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
template <typename T>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type add(
const T &value) {
return add_impl<const T &>(value);
}
//
// bool add(TValue);
// TValue = const char*, const char[N], const FlashStringHelper*
template <typename T>
bool add(const T *value) {
return add_impl<const T *>(value);
}
//
// bool add(TValue value, uint8_t decimals);
// TValue = float, double
template <typename T>
bool add(T value, uint8_t decimals) {
return add_impl<const JsonVariant &>(JsonVariant(value, decimals));
}
2014-10-25 21:02:13 +02:00
// Sets the value at specified index.
//
// bool add(size_t index, TValue);
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
template <typename T>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type set(
size_t index, const T &value) {
return set_impl<const T &>(index, value);
}
//
// bool add(size_t index, TValue);
// TValue = const char*, const char[N], const FlashStringHelper*
template <typename T>
bool set(size_t index, const T *value) {
return set_impl<const T *>(index, value);
}
//
// bool set(size_t index, TValue value, uint8_t decimals);
// TValue = float, double
template <typename T>
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<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.
// 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 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++]);
}
}
#if ARDUINOJSON_ENABLE_DEPRECATED
DEPRECATED("use remove() instead")
FORCE_INLINE void removeAt(size_t index) {
return remove(index);
}
#endif
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::ValueSetter<TValueRef>::set(_buffer, *it, value);
}
template <typename TValueRef>
bool add_impl(TValueRef value) {
iterator it = Internals::List<JsonVariant>::add();
if (it == end()) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, *it, value);
}
2014-10-23 19:54:00 +02:00
};
namespace Internals {
template <>
struct JsonVariantDefault<JsonArray> {
static JsonArray &get() {
return JsonArray::invalid();
}
};
}
2014-10-18 23:05:54 +02:00
}