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-23 19:54:00 +02:00
|
|
|
namespace ArduinoJson {
|
|
|
|
class JsonBuffer;
|
|
|
|
|
|
|
|
namespace Internals {
|
|
|
|
class JsonWriter;
|
|
|
|
|
|
|
|
class JsonNode {
|
|
|
|
enum JsonNodeType {
|
|
|
|
JSON_UNDEFINED,
|
|
|
|
JSON_NULL,
|
|
|
|
JSON_ARRAY,
|
|
|
|
JSON_OBJECT,
|
|
|
|
JSON_KEY_VALUE,
|
|
|
|
JSON_BOOLEAN,
|
|
|
|
JSON_STRING,
|
|
|
|
JSON_LONG,
|
|
|
|
JSON_PROXY,
|
|
|
|
JSON_DOUBLE_0_DECIMALS,
|
|
|
|
JSON_DOUBLE_1_DECIMAL,
|
|
|
|
JSON_DOUBLE_2_DECIMALS
|
|
|
|
// etc.
|
|
|
|
};
|
|
|
|
|
|
|
|
union JsonNodeContent {
|
|
|
|
bool asBoolean;
|
|
|
|
double asDouble;
|
|
|
|
long asInteger;
|
|
|
|
const char *asString;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
const char *key;
|
|
|
|
JsonNode *value;
|
|
|
|
} asKeyValue;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
JsonNode *child;
|
|
|
|
JsonBuffer *buffer;
|
|
|
|
} asContainer;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
JsonNode *target;
|
|
|
|
} asProxy;
|
|
|
|
};
|
|
|
|
|
2014-10-23 23:13:13 +02:00
|
|
|
public:
|
2014-10-23 19:54:00 +02:00
|
|
|
JsonNode() : next(0), type(JSON_UNDEFINED) {}
|
|
|
|
|
|
|
|
JsonNode *next;
|
|
|
|
|
2014-10-23 23:13:13 +02:00
|
|
|
void writeTo(JsonWriter &); // TODO: <- move in JsonNodeSerializer
|
2014-10-23 19:54:00 +02:00
|
|
|
|
|
|
|
void setAsArray(JsonBuffer *buffer) {
|
|
|
|
type = JSON_ARRAY;
|
|
|
|
content.asContainer.child = 0;
|
|
|
|
content.asContainer.buffer = buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setAsBoolean(bool value) {
|
|
|
|
type = JSON_BOOLEAN;
|
|
|
|
content.asBoolean = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setAsLong(int value) {
|
|
|
|
type = JSON_LONG;
|
|
|
|
content.asInteger = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setAsString(char const *value) {
|
|
|
|
type = JSON_STRING;
|
|
|
|
content.asString = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setAsDouble(double value, int decimals) {
|
|
|
|
type = static_cast<JsonNodeType>(JSON_DOUBLE_0_DECIMALS + decimals);
|
|
|
|
content.asDouble = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setAsObject(JsonBuffer *buffer) {
|
|
|
|
type = JSON_OBJECT;
|
|
|
|
content.asContainer.child = 0;
|
|
|
|
content.asContainer.buffer = buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setAsObjectKeyValue(const char *key, JsonNode *value) {
|
|
|
|
type = JSON_KEY_VALUE;
|
|
|
|
content.asKeyValue.key = key;
|
|
|
|
content.asKeyValue.value = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool getAsBoolean() {
|
|
|
|
return type == JSON_BOOLEAN ? content.asBoolean : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
double getAsDouble() {
|
|
|
|
return type >= JSON_DOUBLE_0_DECIMALS ? content.asDouble : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
long getAsInteger() { return type == JSON_LONG ? content.asInteger : 0; }
|
|
|
|
|
|
|
|
const char *getAsString() {
|
|
|
|
return type == JSON_STRING ? content.asString : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonBuffer *getContainerBuffer() {
|
2014-10-23 23:13:13 +02:00
|
|
|
if (type == JSON_PROXY) return content.asProxy.target->getContainerBuffer();
|
2014-10-23 19:54:00 +02:00
|
|
|
return type == JSON_ARRAY || type == JSON_OBJECT
|
|
|
|
? content.asContainer.buffer
|
|
|
|
: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonNode *getContainerChild() {
|
2014-10-23 23:13:13 +02:00
|
|
|
if (type == JSON_PROXY) return content.asProxy.target->getContainerChild();
|
2014-10-23 19:54:00 +02:00
|
|
|
return type == JSON_ARRAY || type == JSON_OBJECT ? content.asContainer.child
|
|
|
|
: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *getAsObjectKey() {
|
|
|
|
return type == JSON_KEY_VALUE ? content.asKeyValue.key : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonNode *getAsObjectValue() {
|
|
|
|
return type == JSON_KEY_VALUE ? content.asKeyValue.value : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonNode *getProxyTarget() {
|
|
|
|
return type == JSON_PROXY ? content.asProxy.target : this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isArray() { return type == JSON_ARRAY; }
|
|
|
|
|
|
|
|
bool isObject() { return type == JSON_OBJECT; }
|
|
|
|
|
|
|
|
void addChild(JsonNode *childToAdd);
|
|
|
|
|
|
|
|
void removeChild(JsonNode *childToRemove);
|
|
|
|
|
|
|
|
void duplicate(JsonNode *other);
|
|
|
|
|
2014-10-23 23:13:13 +02:00
|
|
|
private:
|
2014-10-23 19:54:00 +02:00
|
|
|
JsonNodeType type;
|
|
|
|
JsonNodeContent content;
|
|
|
|
|
2014-10-23 23:13:13 +02:00
|
|
|
inline void writeArrayTo(
|
|
|
|
JsonWriter &); // TODO: <- move in JsonNodeSerializer
|
|
|
|
inline void writeObjectTo(
|
|
|
|
JsonWriter &); // TODO: <- move in JsonNodeSerializer
|
2014-10-23 19:54:00 +02:00
|
|
|
|
|
|
|
void setAsProxyOfSelf();
|
|
|
|
|
|
|
|
void setAsProxyOf(JsonNode *target) {
|
|
|
|
type = JSON_PROXY;
|
|
|
|
content.asProxy.target = target;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2014-10-23 23:45:36 +02:00
|
|
|
}
|