Files
ArduinoJson/include/ArduinoJson/JsonVariant.hpp

257 lines
7.4 KiB
C++
Raw Normal View History

2014-10-23 23:39:22 +02:00
// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
2014-10-16 00:11:23 +02:00
#pragma once
2014-10-26 21:18:09 +01:00
#include <stddef.h>
2014-11-03 18:28:24 +01:00
#include <stdint.h> // for uint8_t
2014-10-26 21:18:09 +01:00
2014-11-05 08:53:41 +01:00
#include "Internals/JsonPrintable.hpp"
2014-11-04 09:51:25 +01:00
#include "Internals/JsonVariantContent.hpp"
#include "Internals/JsonVariantType.hpp"
2014-10-16 00:11:23 +02:00
2014-10-23 19:54:00 +02:00
namespace ArduinoJson {
2014-10-31 12:27:33 +01:00
2014-11-06 16:58:24 +01:00
// Forward declarations.
2014-10-31 12:27:33 +01:00
class JsonArray;
class JsonObject;
2014-11-06 16:58:24 +01:00
// A variant that can be a any value serializable to a JSON value.
//
// It can be set to:
// - a boolean
// - a char, short, int or a long (signed or unsigned)
// - a string (const char*)
// - a reference to a JsonArray or JsonObject
2014-11-05 08:53:41 +01:00
class JsonVariant : public Internals::JsonPrintable<JsonVariant> {
public:
2014-11-06 16:58:24 +01:00
// Creates an uninitialized JsonVariant
2014-11-04 09:51:25 +01:00
JsonVariant() : _type(Internals::JSON_UNDEFINED) {}
2014-10-29 14:24:34 +01:00
2014-11-06 16:58:24 +01:00
// Initializes a JsonVariant with the specified value.
2014-11-04 10:20:47 +01:00
template <typename T>
explicit JsonVariant(T value) {
set(value);
}
2014-11-06 16:58:24 +01:00
// Tells weither the variant is valid.
2014-11-07 17:27:30 +01:00
bool success() const {
2014-11-06 16:58:24 +01:00
return _type != Internals::JSON_INVALID &&
_type != Internals::JSON_UNDEFINED;
}
// Sets the variant to a boolean value.
// It will be serialized as "true" or "false" in JSON.
2014-10-29 14:24:34 +01:00
void set(bool value);
2014-11-06 16:58:24 +01:00
// Sets the variant to a floating point value.
// The second argument specifies the number of decimal digits to write in
// the JSON string.
2014-11-03 18:28:24 +01:00
void set(double value, uint8_t decimals = 2);
2014-11-06 16:58:24 +01:00
// Sets the variant to be an integer value.
void set(signed long value);
void set(signed char value) { set(static_cast<long>(value)); }
void set(signed int value) { set(static_cast<long>(value)); }
void set(signed short value) { set(static_cast<long>(value)); }
void set(unsigned char value) { set(static_cast<long>(value)); }
void set(unsigned int value) { set(static_cast<long>(value)); }
void set(unsigned long value) { set(static_cast<long>(value)); }
void set(unsigned short value) { set(static_cast<long>(value)); }
2014-11-06 16:58:24 +01:00
// Sets the variant to be a string.
void set(const char *value);
2014-11-06 16:58:24 +01:00
// Sets the variant to be a reference to an array.
2014-10-29 14:24:34 +01:00
void set(JsonArray &array);
2014-11-06 16:58:24 +01:00
// Sets the variant to be a reference to an object.
2014-10-29 14:24:34 +01:00
void set(JsonObject &object);
2014-11-06 16:58:24 +01:00
// Sets the variant to the specified value.
2014-10-29 21:18:27 +01:00
template <typename T>
2014-11-04 09:51:25 +01:00
JsonVariant &operator=(T value) {
2014-10-29 21:18:27 +01:00
set(value);
return *this;
}
2014-11-06 16:58:24 +01:00
// Sets the variant to be a reference to an array.
2014-11-04 09:51:25 +01:00
JsonVariant &operator=(JsonArray &array) {
2014-10-29 21:18:27 +01:00
set(array);
return *this;
}
2014-11-06 16:58:24 +01:00
// Sets the variant to be a reference to an object.
2014-11-04 09:51:25 +01:00
JsonVariant &operator=(JsonObject &object) {
2014-10-29 21:18:27 +01:00
set(object);
return *this;
}
2014-11-06 16:58:24 +01:00
// Gets the variant as a boolean value.
// Returns false if the variant is not a boolean value.
2014-10-30 10:49:02 +01:00
operator bool() const;
2014-11-06 16:58:24 +01:00
// Gets the variant as a floating-point value.
// Returns 0.0 if the variant is not a floating-point value
2014-10-30 10:49:02 +01:00
operator double() const;
2014-11-04 16:48:23 +01:00
operator float() const { return static_cast<float>(as<double>()); }
2014-11-06 16:58:24 +01:00
// Gets the variant as an integer value.
// Returns 0 if the variant is not an integer value.
operator signed long() const;
2014-11-06 16:58:24 +01:00
operator signed char() const { return cast_long_to<signed char>(); }
operator signed int() const { return cast_long_to<signed int>(); }
operator signed short() const { return cast_long_to<signed short>(); }
operator unsigned char() const { return cast_long_to<unsigned char>(); }
operator unsigned int() const { return cast_long_to<unsigned int>(); }
operator unsigned long() const { return cast_long_to<unsigned long>(); }
operator unsigned short() const { return cast_long_to<unsigned short>(); }
// Gets the variant as a string.
// Returns NULL if variant is not a string.
operator const char *() const;
2014-11-06 16:58:24 +01:00
const char *asString() const { return as<const char *>(); }
// Gets the variant as an array.
// Returns a reference to the JsonArray or JsonArray::invalid() if the variant
// is not an array.
2014-10-30 10:49:02 +01:00
operator JsonArray &() const;
2014-11-06 16:58:24 +01:00
JsonArray &asArray() const { return as<JsonArray &>(); }
2014-10-30 10:49:02 +01:00
2014-11-06 16:58:24 +01:00
// Gets the variant as an object.
// Returns a reference to the JsonObject or JsonObject::invalid() if the
// variant is not an object.
operator JsonObject &() const;
JsonObject &asObject() const { return as<JsonObject &>(); }
2014-10-27 13:34:54 +01:00
2014-11-06 16:58:24 +01:00
// Get the variant as the specified type.
// See cast operators for details.
2014-10-27 22:50:50 +01:00
template <typename T>
2014-11-03 14:37:50 +01:00
T as() const {
2014-10-30 10:49:02 +01:00
return static_cast<T>(*this);
}
2014-10-23 19:54:00 +02:00
2014-11-06 16:58:24 +01:00
// Tells weither the variant has the specified type.
// Returns true if the variant has type type T, false otherwise.
2014-11-03 18:23:39 +01:00
template <typename T>
bool is() const {
return false;
}
2014-11-06 16:58:24 +01:00
// Returns an invalid variant.
// This is meant to replace a NULL pointer.
2014-11-04 09:51:25 +01:00
static JsonVariant &invalid() { return _invalid; }
2014-10-24 16:12:05 +02:00
2014-11-06 16:58:24 +01:00
// Serialize the variant to a JsonWriter
void writeTo(Internals::JsonWriter &writer) const;
2014-10-26 21:18:09 +01:00
2014-11-06 16:58:24 +01:00
// Mimics an array or an object.
// Returns the size of the array or object if the variant has that type.
// Returns 0 if the variant is neither an array nor an object
2014-11-04 10:20:47 +01:00
size_t size() const;
2014-11-06 16:58:24 +01:00
// Mimics an array.
// Returns the element at specified index if the variant is an array.
// Returns JsonVariant::invalid() if the variant is not an array.
2014-11-04 10:20:47 +01:00
JsonVariant &operator[](int index);
2014-11-06 16:58:24 +01:00
// Mimics an object.
// Returns the value associated with the specified key if the variant is an
// object.
// Return JsonVariant::invalid() if the variant is not an object.
JsonVariant &operator[](const char *key);
2014-11-04 10:20:47 +01:00
2014-10-26 21:18:09 +01:00
private:
// Special constructor used only to create _invalid.
JsonVariant(Internals::JsonVariantType type) : _type(type) {}
2014-11-06 16:58:24 +01:00
// Helper for interger cast operators
template <typename T>
T cast_long_to() const {
return static_cast<T>(as<long>());
}
2014-10-30 14:03:33 +01:00
2014-11-06 16:58:24 +01:00
// The current type of the variant
2014-11-04 09:51:25 +01:00
Internals::JsonVariantType _type;
2014-11-06 16:58:24 +01:00
// The various alternatives for the value of the variant.
2014-11-04 09:51:25 +01:00
Internals::JsonVariantContent _content;
2014-11-06 16:58:24 +01:00
// The instance returned by JsonVariant::invalid()
2014-11-04 09:51:25 +01:00
static JsonVariant _invalid;
2014-10-23 19:54:00 +02:00
};
2014-11-03 14:37:50 +01:00
2014-11-03 18:23:39 +01:00
template <>
2014-11-04 09:51:25 +01:00
inline bool JsonVariant::is<long>() const {
2014-11-03 18:23:39 +01:00
return _type == Internals::JSON_LONG;
}
template <>
2014-11-04 09:51:25 +01:00
inline bool JsonVariant::is<double>() const {
2014-11-03 18:23:39 +01:00
return _type >= Internals::JSON_DOUBLE_0_DECIMALS;
}
2014-11-03 14:37:50 +01:00
template <typename T>
2014-11-04 09:51:25 +01:00
inline bool operator==(const JsonVariant &left, T right) {
2014-11-03 14:37:50 +01:00
return left.as<T>() == right;
}
template <typename T>
2014-11-04 09:51:25 +01:00
inline bool operator==(T left, const JsonVariant &right) {
2014-11-03 14:37:50 +01:00
return left == right.as<T>();
}
2014-11-03 18:23:39 +01:00
template <typename T>
2014-11-04 09:51:25 +01:00
inline bool operator!=(const JsonVariant &left, T right) {
2014-11-03 18:23:39 +01:00
return left.as<T>() != right;
}
template <typename T>
2014-11-04 09:51:25 +01:00
inline bool operator!=(T left, const JsonVariant &right) {
2014-11-03 18:23:39 +01:00
return left != right.as<T>();
}
template <typename T>
2014-11-04 09:51:25 +01:00
inline bool operator<=(const JsonVariant &left, T right) {
2014-11-03 18:23:39 +01:00
return left.as<T>() <= right;
}
template <typename T>
2014-11-04 09:51:25 +01:00
inline bool operator<=(T left, const JsonVariant &right) {
2014-11-03 18:23:39 +01:00
return left <= right.as<T>();
}
template <typename T>
2014-11-04 09:51:25 +01:00
inline bool operator>=(const JsonVariant &left, T right) {
2014-11-03 18:23:39 +01:00
return left.as<T>() >= right;
}
template <typename T>
2014-11-04 09:51:25 +01:00
inline bool operator>=(T left, const JsonVariant &right) {
2014-11-03 18:23:39 +01:00
return left >= right.as<T>();
}
template <typename T>
2014-11-04 09:51:25 +01:00
inline bool operator<(const JsonVariant &left, T right) {
2014-11-03 18:23:39 +01:00
return left.as<T>() < right;
}
template <typename T>
2014-11-04 09:51:25 +01:00
inline bool operator<(T left, const JsonVariant &right) {
2014-11-03 18:23:39 +01:00
return left < right.as<T>();
}
template <typename T>
2014-11-04 09:51:25 +01:00
inline bool operator>(const JsonVariant &left, T right) {
2014-11-03 18:23:39 +01:00
return left.as<T>() > right;
}
template <typename T>
2014-11-04 09:51:25 +01:00
inline bool operator>(T left, const JsonVariant &right) {
2014-11-03 18:23:39 +01:00
return left > right.as<T>();
}
2014-10-30 14:03:33 +01:00
}