JsonArray.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // Copyright Benoit Blanchon 2014-2017
  2. // MIT License
  3. //
  4. // Arduino JSON library
  5. // https://github.com/bblanchon/ArduinoJson
  6. // If you like this project, please add a star!
  7. #pragma once
  8. #include "Data/JsonBufferAllocated.hpp"
  9. #include "Data/List.hpp"
  10. #include "Data/ReferenceType.hpp"
  11. #include "Data/ValueSetter.hpp"
  12. #include "JsonVariant.hpp"
  13. #include "Serialization/JsonPrintable.hpp"
  14. #include "StringTraits/StringTraits.hpp"
  15. #include "TypeTraits/EnableIf.hpp"
  16. #include "TypeTraits/IsArray.hpp"
  17. #include "TypeTraits/IsFloatingPoint.hpp"
  18. #include "TypeTraits/IsSame.hpp"
  19. // Returns the size (in bytes) of an array with n elements.
  20. // Can be very handy to determine the size of a StaticJsonBuffer.
  21. #define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
  22. (sizeof(JsonArray) + (NUMBER_OF_ELEMENTS) * sizeof(JsonArray::node_type))
  23. namespace ArduinoJson {
  24. // Forward declarations
  25. class JsonObject;
  26. class JsonBuffer;
  27. class JsonArraySubscript;
  28. // An array of JsonVariant.
  29. //
  30. // The constructor is private, instances must be created via
  31. // JsonBuffer::createArray() or JsonBuffer::parseArray().
  32. // A JsonArray can be serialized to a JSON string via JsonArray::printTo().
  33. // It can also be deserialized from a JSON string via JsonBuffer::parseArray().
  34. class JsonArray : public Internals::JsonPrintable<JsonArray>,
  35. public Internals::ReferenceType,
  36. public Internals::List<JsonVariant>,
  37. public Internals::JsonBufferAllocated {
  38. public:
  39. // Create an empty JsonArray attached to the specified JsonBuffer.
  40. // You should not call this constructor directly.
  41. // Instead, use JsonBuffer::createArray() or JsonBuffer::parseArray().
  42. explicit JsonArray(JsonBuffer *buffer)
  43. : Internals::List<JsonVariant>(buffer) {}
  44. // Gets the value at the specified index
  45. const JsonArraySubscript operator[](size_t index) const;
  46. // Gets or sets the value at specified index
  47. JsonArraySubscript operator[](size_t index);
  48. // Adds the specified value at the end of the array.
  49. //
  50. // bool add(TValue);
  51. // TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
  52. // const std::string&, const String&,
  53. // const JsonArray&, const JsonObject&
  54. template <typename T>
  55. typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type add(
  56. const T &value) {
  57. return add_impl<const T &>(value);
  58. }
  59. //
  60. // bool add(TValue);
  61. // TValue = const char*, const char[N], const FlashStringHelper*
  62. template <typename T>
  63. bool add(const T *value) {
  64. return add_impl<const T *>(value);
  65. }
  66. //
  67. // bool add(TValue value, uint8_t decimals);
  68. // TValue = float, double
  69. template <typename T>
  70. bool add(T value, uint8_t decimals) {
  71. return add_impl<const JsonVariant &>(JsonVariant(value, decimals));
  72. }
  73. // Sets the value at specified index.
  74. //
  75. // bool add(size_t index, TValue);
  76. // TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
  77. // const std::string&, const String&,
  78. // const JsonArray&, const JsonObject&
  79. template <typename T>
  80. typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type set(
  81. size_t index, const T &value) {
  82. return set_impl<const T &>(index, value);
  83. }
  84. //
  85. // bool add(size_t index, TValue);
  86. // TValue = const char*, const char[N], const FlashStringHelper*
  87. template <typename T>
  88. bool set(size_t index, const T *value) {
  89. return set_impl<const T *>(index, value);
  90. }
  91. //
  92. // bool set(size_t index, TValue value, uint8_t decimals);
  93. // TValue = float, double
  94. template <typename T>
  95. typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
  96. bool>::type
  97. set(size_t index, T value, uint8_t decimals) {
  98. return set_impl<const JsonVariant &>(index, JsonVariant(value, decimals));
  99. }
  100. // Gets the value at the specified index.
  101. template <typename T>
  102. typename Internals::JsonVariantAs<T>::type get(size_t index) const {
  103. node_type *node = findNode(index);
  104. return node ? node->content.as<T>()
  105. : Internals::JsonVariantDefault<T>::get();
  106. }
  107. // Check the type of the value at specified index.
  108. template <typename T>
  109. bool is(size_t index) const {
  110. node_type *node = findNode(index);
  111. return node ? node->content.is<T>() : false;
  112. }
  113. // Creates a JsonArray and adds a reference at the end of the array.
  114. // It's a shortcut for JsonBuffer::createArray() and JsonArray::add()
  115. JsonArray &createNestedArray();
  116. // Creates a JsonObject and adds a reference at the end of the array.
  117. // It's a shortcut for JsonBuffer::createObject() and JsonArray::add()
  118. JsonObject &createNestedObject();
  119. // Removes element at specified index.
  120. void removeAt(size_t index) {
  121. removeNode(findNode(index));
  122. }
  123. // Returns a reference an invalid JsonArray.
  124. // This object is meant to replace a NULL pointer.
  125. // This is used when memory allocation or JSON parsing fail.
  126. static JsonArray &invalid() {
  127. static JsonArray instance(NULL);
  128. return instance;
  129. }
  130. // Imports a 1D array
  131. template <typename T, size_t N>
  132. bool copyFrom(T (&array)[N]) {
  133. return copyFrom(array, N);
  134. }
  135. // Imports a 1D array
  136. template <typename T>
  137. bool copyFrom(T *array, size_t len) {
  138. bool ok = true;
  139. for (size_t i = 0; i < len; i++) {
  140. ok &= add(array[i]);
  141. }
  142. return ok;
  143. }
  144. // Imports a 2D array
  145. template <typename T, size_t N1, size_t N2>
  146. bool copyFrom(T (&array)[N1][N2]) {
  147. bool ok = true;
  148. for (size_t i = 0; i < N1; i++) {
  149. JsonArray &nestedArray = createNestedArray();
  150. for (size_t j = 0; j < N2; j++) {
  151. ok &= nestedArray.add(array[i][j]);
  152. }
  153. }
  154. return ok;
  155. }
  156. // Exports a 1D array
  157. template <typename T, size_t N>
  158. size_t copyTo(T (&array)[N]) const {
  159. return copyTo(array, N);
  160. }
  161. // Exports a 1D array
  162. template <typename T>
  163. size_t copyTo(T *array, size_t len) const {
  164. size_t i = 0;
  165. for (const_iterator it = begin(); it != end() && i < len; ++it)
  166. array[i++] = *it;
  167. return i;
  168. }
  169. // Exports a 2D array
  170. template <typename T, size_t N1, size_t N2>
  171. void copyTo(T (&array)[N1][N2]) const {
  172. size_t i = 0;
  173. for (const_iterator it = begin(); it != end() && i < N1; ++it) {
  174. it->as<JsonArray>().copyTo(array[i++]);
  175. }
  176. }
  177. private:
  178. node_type *findNode(size_t index) const {
  179. node_type *node = _firstNode;
  180. while (node && index--) node = node->next;
  181. return node;
  182. }
  183. template <typename TValueRef>
  184. bool set_impl(size_t index, TValueRef value) {
  185. node_type *node = findNode(index);
  186. if (!node) return false;
  187. return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
  188. value);
  189. }
  190. template <typename TValueRef>
  191. bool add_impl(TValueRef value) {
  192. node_type *node = addNewNode();
  193. if (!node) return false;
  194. return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
  195. value);
  196. }
  197. };
  198. namespace Internals {
  199. template <>
  200. struct JsonVariantDefault<JsonArray> {
  201. static JsonArray &get() {
  202. return JsonArray::invalid();
  203. }
  204. };
  205. }
  206. }