// ArduinoJson - arduinojson.org // Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once #include "Data/JsonBufferAllocated.hpp" #include "Data/List.hpp" #include "Data/ReferenceType.hpp" #include "Data/ValueSaver.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" // Returns the size (in bytes) of an array with n elements. // Can be very handy to determine the size of a StaticJsonBuffer. #define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \ (sizeof(JsonArray) + (NUMBER_OF_ELEMENTS) * sizeof(JsonArray::node_type)) namespace ArduinoJson { // Forward declarations class JsonObject; class JsonBuffer; namespace Internals { class JsonArraySubscript; } // An array of JsonVariant. // // 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(). class JsonArray : public Internals::JsonPrintable, public Internals::ReferenceType, public Internals::NonCopyable, public Internals::List, 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) throw() : Internals::List(buffer) {} // Gets the value at the specified index const Internals::JsonArraySubscript operator[](size_t index) const; // Gets or sets the value at specified index Internals::JsonArraySubscript operator[](size_t index); // 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 bool add(const T &value) { return add_impl(value); } // // bool add(TValue); // TValue = char*, const char*, const FlashStringHelper* template bool add(T *value) { return add_impl(value); } // // bool add(TValue value, uint8_t decimals); // TValue = float, double template DEPRECATED("Second argument is not supported anymore") bool add(T value, uint8_t) { return add_impl(JsonVariant(value)); } // 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 bool set(size_t index, const T &value) { return set_impl(index, value); } // // bool add(size_t index, TValue); // TValue = char*, const char*, const FlashStringHelper* template bool set(size_t index, T *value) { return set_impl(index, value); } // // bool set(size_t index, TValue value, uint8_t decimals); // TValue = float, double template typename Internals::EnableIf::value, bool>::type set(size_t index, T value, uint8_t decimals) { return set_impl(index, JsonVariant(value, decimals)); } // Gets the value at the specified index. template typename Internals::JsonVariantAs::type get(size_t index) const { const_iterator it = begin() += index; return it != end() ? it->as() : Internals::JsonVariantDefault::get(); } // Check the type of the value at specified index. template bool is(size_t index) const { const_iterator it = begin() += index; return it != end() ? it->is() : false; } // Creates a JsonArray and adds a reference at the end of the array. // It's a shortcut for JsonBuffer::createArray() and JsonArray::add() JsonArray &createNestedArray(); // Creates a JsonObject and adds a reference at the end of the array. // It's a shortcut for JsonBuffer::createObject() and JsonArray::add() JsonObject &createNestedObject(); // Removes element at specified index. void remove(size_t index) { remove(begin() += index); } using Internals::List::remove; // Returns a reference an invalid JsonArray. // This object is meant to replace a NULL pointer. // This is used when memory allocation or JSON parsing fail. static JsonArray &invalid() { static JsonArray instance(NULL); return instance; } // Imports a 1D array template bool copyFrom(T (&array)[TN]) { return copyFrom(array, TN); } // Imports a 1D array template 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 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 size_t copyTo(T (&array)[TN]) const { return copyTo(array, TN); } // Exports a 1D array template 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 void copyTo(T (&array)[N1][N2]) const { size_t i = 0; for (const_iterator it = begin(); it != end() && i < N1; ++it) { it->as().copyTo(array[i++]); } } #if ARDUINOJSON_ENABLE_DEPRECATED DEPRECATED("use remove() instead") FORCE_INLINE void removeAt(size_t index) { return remove(index); } #endif private: template bool set_impl(size_t index, TValueRef value) { iterator it = begin() += index; if (it == end()) return false; return Internals::ValueSaver::save(_buffer, *it, value); } template bool add_impl(TValueRef value) { iterator it = Internals::List::add(); if (it == end()) return false; return Internals::ValueSaver::save(_buffer, *it, value); } }; namespace Internals { template <> struct JsonVariantDefault { static JsonArray &get() { return JsonArray::invalid(); } }; } }