JsonVariant.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. // Copyright Benoit Blanchon 2014
  2. // MIT License
  3. //
  4. // Arduino JSON library
  5. // https://github.com/bblanchon/ArduinoJson
  6. #pragma once
  7. #include <stddef.h>
  8. #include <stdint.h> // for uint8_t
  9. #include "Internals/JsonPrintable.hpp"
  10. #include "Internals/JsonVariantContent.hpp"
  11. #include "Internals/JsonVariantType.hpp"
  12. namespace ArduinoJson {
  13. // Forward declarations.
  14. class JsonArray;
  15. class JsonObject;
  16. // A variant that can be a any value serializable to a JSON value.
  17. //
  18. // It can be set to:
  19. // - a boolean
  20. // - a char, short, int or a long (signed or unsigned)
  21. // - a string (const char*)
  22. // - a reference to a JsonArray or JsonObject
  23. class JsonVariant : public Internals::JsonPrintable<JsonVariant> {
  24. public:
  25. // Creates an uninitialized JsonVariant
  26. JsonVariant() : _type(Internals::JSON_UNDEFINED) {}
  27. // Initializes a JsonVariant with the specified value.
  28. template <typename T>
  29. explicit JsonVariant(T value) {
  30. set(value);
  31. }
  32. // Tells weither the variant is valid.
  33. bool success() const {
  34. return _type != Internals::JSON_INVALID &&
  35. _type != Internals::JSON_UNDEFINED;
  36. }
  37. // Sets the variant to a boolean value.
  38. // It will be serialized as "true" or "false" in JSON.
  39. void set(bool value);
  40. // Sets the variant to a floating point value.
  41. // The second argument specifies the number of decimal digits to write in
  42. // the JSON string.
  43. void set(double value, uint8_t decimals = 2);
  44. // Sets the variant to be an integer value.
  45. void set(signed long value);
  46. void set(signed char value) { set(static_cast<long>(value)); }
  47. void set(signed int value) { set(static_cast<long>(value)); }
  48. void set(signed short value) { set(static_cast<long>(value)); }
  49. void set(unsigned char value) { set(static_cast<long>(value)); }
  50. void set(unsigned int value) { set(static_cast<long>(value)); }
  51. void set(unsigned long value) { set(static_cast<long>(value)); }
  52. void set(unsigned short value) { set(static_cast<long>(value)); }
  53. // Sets the variant to be a string.
  54. void set(const char *value);
  55. // Sets the variant to be a reference to an array.
  56. void set(JsonArray &array);
  57. // Sets the variant to be a reference to an object.
  58. void set(JsonObject &object);
  59. // Sets the variant to the specified value.
  60. template <typename T>
  61. JsonVariant &operator=(T value) {
  62. set(value);
  63. return *this;
  64. }
  65. // Sets the variant to be a reference to an array.
  66. JsonVariant &operator=(JsonArray &array) {
  67. set(array);
  68. return *this;
  69. }
  70. // Sets the variant to be a reference to an object.
  71. JsonVariant &operator=(JsonObject &object) {
  72. set(object);
  73. return *this;
  74. }
  75. // Gets the variant as a boolean value.
  76. // Returns false if the variant is not a boolean value.
  77. operator bool() const;
  78. // Gets the variant as a floating-point value.
  79. // Returns 0.0 if the variant is not a floating-point value
  80. operator double() const;
  81. operator float() const { return static_cast<float>(as<double>()); }
  82. // Gets the variant as an integer value.
  83. // Returns 0 if the variant is not an integer value.
  84. operator signed long() const;
  85. operator signed char() const { return cast_long_to<signed char>(); }
  86. operator signed int() const { return cast_long_to<signed int>(); }
  87. operator signed short() const { return cast_long_to<signed short>(); }
  88. operator unsigned char() const { return cast_long_to<unsigned char>(); }
  89. operator unsigned int() const { return cast_long_to<unsigned int>(); }
  90. operator unsigned long() const { return cast_long_to<unsigned long>(); }
  91. operator unsigned short() const { return cast_long_to<unsigned short>(); }
  92. // Gets the variant as a string.
  93. // Returns NULL if variant is not a string.
  94. operator const char *() const;
  95. const char *asString() const { return as<const char *>(); }
  96. // Gets the variant as an array.
  97. // Returns a reference to the JsonArray or JsonArray::invalid() if the variant
  98. // is not an array.
  99. operator JsonArray &() const;
  100. JsonArray &asArray() const { return as<JsonArray &>(); }
  101. // Gets the variant as an object.
  102. // Returns a reference to the JsonObject or JsonObject::invalid() if the
  103. // variant is not an object.
  104. operator JsonObject &() const;
  105. JsonObject &asObject() const { return as<JsonObject &>(); }
  106. // Get the variant as the specified type.
  107. // See cast operators for details.
  108. template <typename T>
  109. T as() const {
  110. return static_cast<T>(*this);
  111. }
  112. // Tells weither the variant has the specified type.
  113. // Returns true if the variant has type type T, false otherwise.
  114. template <typename T>
  115. bool is() const {
  116. return false;
  117. }
  118. // Returns an invalid variant.
  119. // This is meant to replace a NULL pointer.
  120. static JsonVariant &invalid() { return _invalid; }
  121. // Serialize the variant to a JsonWriter
  122. template <typename T>
  123. void writeTo(T &writer) const;
  124. // Mimics an array or an object.
  125. // Returns the size of the array or object if the variant has that type.
  126. // Returns 0 if the variant is neither an array nor an object
  127. size_t size() const;
  128. // Mimics an array.
  129. // Returns the element at specified index if the variant is an array.
  130. // Returns JsonVariant::invalid() if the variant is not an array.
  131. JsonVariant &operator[](int index);
  132. // Mimics an object.
  133. // Returns the value associated with the specified key if the variant is an
  134. // object.
  135. // Return JsonVariant::invalid() if the variant is not an object.
  136. JsonVariant &operator[](const char *key);
  137. private:
  138. // Special constructor used only to create _invalid.
  139. JsonVariant(Internals::JsonVariantType type) : _type(type) {}
  140. // Helper for interger cast operators
  141. template <typename T>
  142. T cast_long_to() const {
  143. return static_cast<T>(as<long>());
  144. }
  145. // The current type of the variant
  146. Internals::JsonVariantType _type;
  147. // The various alternatives for the value of the variant.
  148. Internals::JsonVariantContent _content;
  149. // The instance returned by JsonVariant::invalid()
  150. static JsonVariant _invalid;
  151. };
  152. template <>
  153. inline bool JsonVariant::is<long>() const {
  154. return _type == Internals::JSON_LONG;
  155. }
  156. template <>
  157. inline bool JsonVariant::is<double>() const {
  158. return _type >= Internals::JSON_DOUBLE_0_DECIMALS;
  159. }
  160. template <typename T>
  161. inline bool operator==(const JsonVariant &left, T right) {
  162. return left.as<T>() == right;
  163. }
  164. template <typename T>
  165. inline bool operator==(T left, const JsonVariant &right) {
  166. return left == right.as<T>();
  167. }
  168. template <typename T>
  169. inline bool operator!=(const JsonVariant &left, T right) {
  170. return left.as<T>() != right;
  171. }
  172. template <typename T>
  173. inline bool operator!=(T left, const JsonVariant &right) {
  174. return left != right.as<T>();
  175. }
  176. template <typename T>
  177. inline bool operator<=(const JsonVariant &left, T right) {
  178. return left.as<T>() <= right;
  179. }
  180. template <typename T>
  181. inline bool operator<=(T left, const JsonVariant &right) {
  182. return left <= right.as<T>();
  183. }
  184. template <typename T>
  185. inline bool operator>=(const JsonVariant &left, T right) {
  186. return left.as<T>() >= right;
  187. }
  188. template <typename T>
  189. inline bool operator>=(T left, const JsonVariant &right) {
  190. return left >= right.as<T>();
  191. }
  192. template <typename T>
  193. inline bool operator<(const JsonVariant &left, T right) {
  194. return left.as<T>() < right;
  195. }
  196. template <typename T>
  197. inline bool operator<(T left, const JsonVariant &right) {
  198. return left < right.as<T>();
  199. }
  200. template <typename T>
  201. inline bool operator>(const JsonVariant &left, T right) {
  202. return left.as<T>() > right;
  203. }
  204. template <typename T>
  205. inline bool operator>(T left, const JsonVariant &right) {
  206. return left > right.as<T>();
  207. }
  208. }