mirror of
https://github.com/eledio-devices/thirdparty-ArduinoJson.git
synced 2025-11-01 16:14:05 +01:00
Added JsonArrayConst, JsonObjectConst, and JsonVariantConst
This commit is contained in:
99
src/ArduinoJson/Data/ArrayFunctions.hpp
Normal file
99
src/ArduinoJson/Data/ArrayFunctions.hpp
Normal file
@@ -0,0 +1,99 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonVariantData.hpp"
|
||||
#include "Slot.hpp"
|
||||
#include "SlotFunctions.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline JsonVariantData* arrayAdd(JsonArrayData* arr, MemoryPool* pool) {
|
||||
if (!arr) return 0;
|
||||
|
||||
Slot* slot = new (pool) Slot();
|
||||
if (!slot) return 0;
|
||||
|
||||
slot->next = 0;
|
||||
|
||||
if (arr->tail) {
|
||||
slot->prev = arr->tail;
|
||||
arr->tail->next = slot;
|
||||
arr->tail = slot;
|
||||
} else {
|
||||
slot->prev = 0;
|
||||
arr->head = slot;
|
||||
arr->tail = slot;
|
||||
}
|
||||
|
||||
return &slot->value;
|
||||
}
|
||||
|
||||
inline Slot* arrayGetSlot(const JsonArrayData* arr, size_t index) {
|
||||
if (!arr) return 0;
|
||||
return slotAdvance(arr->head, index);
|
||||
}
|
||||
|
||||
inline JsonVariantData* arrayGet(const JsonArrayData* arr, size_t index) {
|
||||
Slot* slot = arrayGetSlot(arr, index);
|
||||
return slot ? &slot->value : 0;
|
||||
}
|
||||
|
||||
inline void arrayRemove(JsonArrayData* arr, Slot* slot) {
|
||||
if (!arr || !slot) return;
|
||||
|
||||
if (slot->prev)
|
||||
slot->prev->next = slot->next;
|
||||
else
|
||||
arr->head = slot->next;
|
||||
if (slot->next)
|
||||
slot->next->prev = slot->prev;
|
||||
else
|
||||
arr->tail = slot->prev;
|
||||
}
|
||||
|
||||
inline void arrayRemove(JsonArrayData* arr, size_t index) {
|
||||
arrayRemove(arr, arrayGetSlot(arr, index));
|
||||
}
|
||||
|
||||
inline void arrayClear(JsonArrayData* arr) {
|
||||
if (!arr) return;
|
||||
arr->head = 0;
|
||||
arr->tail = 0;
|
||||
}
|
||||
|
||||
bool variantCopy(JsonVariantData*, const JsonVariantData*, MemoryPool*);
|
||||
|
||||
inline bool arrayCopy(JsonArrayData* dst, const JsonArrayData* src,
|
||||
MemoryPool* pool) {
|
||||
if (!dst || !src) return false;
|
||||
arrayClear(dst);
|
||||
for (Slot* s = src->head; s; s = s->next) {
|
||||
if (!variantCopy(arrayAdd(dst, pool), &s->value, pool)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool variantEquals(const JsonVariantData*, const JsonVariantData*);
|
||||
|
||||
inline bool arrayEquals(const JsonArrayData* a1, const JsonArrayData* a2) {
|
||||
if (a1 == a2) return true;
|
||||
if (!a1 || !a2) return false;
|
||||
Slot* s1 = a1->head;
|
||||
Slot* s2 = a2->head;
|
||||
for (;;) {
|
||||
if (s1 == s2) return true;
|
||||
if (!s1 || !s2) return false;
|
||||
if (!variantEquals(&s1->value, &s2->value)) return false;
|
||||
s1 = s1->next;
|
||||
s2 = s2->next;
|
||||
}
|
||||
}
|
||||
|
||||
inline size_t arraySize(const JsonArrayData* arr) {
|
||||
if (!arr) return 0;
|
||||
return slotSize(arr->head);
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,15 +0,0 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Polyfills/type_traits.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class JsonVariantTag {};
|
||||
|
||||
template <typename T>
|
||||
struct IsVariant : is_base_of<JsonVariantTag, T> {};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -6,6 +6,13 @@
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class JsonArray;
|
||||
class JsonArrayConst;
|
||||
class JsonObject;
|
||||
class JsonObjectConst;
|
||||
class JsonVariant;
|
||||
class JsonVariantConst;
|
||||
|
||||
// A metafunction that returns the type of the value returned by
|
||||
// JsonVariant::as<T>()
|
||||
template <typename T>
|
||||
@@ -18,4 +25,25 @@ struct JsonVariantAs<char*> {
|
||||
typedef const char* type;
|
||||
};
|
||||
|
||||
// A metafunction that returns the type of the value returned by
|
||||
// JsonVariant::as<T>()
|
||||
template <typename T>
|
||||
struct JsonVariantConstAs {
|
||||
typedef typename JsonVariantAs<T>::type type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct JsonVariantConstAs<JsonVariant> {
|
||||
typedef JsonVariantConst type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct JsonVariantConstAs<JsonObject> {
|
||||
typedef JsonObjectConst type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct JsonVariantConstAs<JsonArray> {
|
||||
typedef JsonArrayConst type;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
123
src/ArduinoJson/Data/ObjectFunctions.hpp
Normal file
123
src/ArduinoJson/Data/ObjectFunctions.hpp
Normal file
@@ -0,0 +1,123 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonVariantData.hpp"
|
||||
#include "SlotFunctions.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TKey>
|
||||
inline Slot* objectFindSlot(const JsonObjectData* obj, TKey key) {
|
||||
if (!obj) return 0;
|
||||
Slot* slot = obj->head;
|
||||
while (slot) {
|
||||
if (key.equals(slot->key)) break;
|
||||
slot = slot->next;
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
inline bool objectContainsKey(const JsonObjectData* obj, const TKey& key) {
|
||||
return objectFindSlot(obj, key) != 0;
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
inline JsonVariantData* objectAdd(JsonObjectData* obj, TKey key,
|
||||
MemoryPool* pool) {
|
||||
Slot* slot = new (pool) Slot();
|
||||
if (!slot) return 0;
|
||||
|
||||
slot->next = 0;
|
||||
|
||||
if (obj->tail) {
|
||||
slot->prev = obj->tail;
|
||||
obj->tail->next = slot;
|
||||
obj->tail = slot;
|
||||
} else {
|
||||
slot->prev = 0;
|
||||
obj->head = slot;
|
||||
obj->tail = slot;
|
||||
}
|
||||
|
||||
if (!slotSetKey(slot, key, pool)) return 0;
|
||||
return &slot->value;
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
inline JsonVariantData* objectSet(JsonObjectData* obj, TKey key,
|
||||
MemoryPool* pool) {
|
||||
if (!obj) return 0;
|
||||
|
||||
// ignore null key
|
||||
if (key.isNull()) return 0;
|
||||
|
||||
// search a matching key
|
||||
Slot* slot = objectFindSlot(obj, key);
|
||||
if (slot) return &slot->value;
|
||||
|
||||
return objectAdd(obj, key, pool);
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
inline JsonVariantData* objectGet(const JsonObjectData* obj, TKey key) {
|
||||
Slot* slot = objectFindSlot(obj, key);
|
||||
return slot ? &slot->value : 0;
|
||||
}
|
||||
|
||||
inline void objectClear(JsonObjectData* obj) {
|
||||
if (!obj) return;
|
||||
obj->head = 0;
|
||||
obj->tail = 0;
|
||||
}
|
||||
|
||||
inline void objectRemove(JsonObjectData* obj, Slot* slot) {
|
||||
if (!obj) return;
|
||||
if (!slot) return;
|
||||
if (slot->prev)
|
||||
slot->prev->next = slot->next;
|
||||
else
|
||||
obj->head = slot->next;
|
||||
if (slot->next)
|
||||
slot->next->prev = slot->prev;
|
||||
else
|
||||
obj->tail = slot->prev;
|
||||
}
|
||||
|
||||
inline size_t objectSize(const JsonObjectData* obj) {
|
||||
if (!obj) return 0;
|
||||
return slotSize(obj->head);
|
||||
}
|
||||
|
||||
// bool variantCopy(JsonVariantData*, const JsonVariantData*, MemoryPool*);
|
||||
|
||||
inline bool objectCopy(JsonObjectData* dst, const JsonObjectData* src,
|
||||
MemoryPool* pool) {
|
||||
if (!dst || !src) return false;
|
||||
objectClear(dst);
|
||||
for (Slot* s = src->head; s; s = s->next) {
|
||||
JsonVariantData* var;
|
||||
if (s->value.keyIsStatic)
|
||||
var = objectAdd(dst, ZeroTerminatedRamStringConst(s->key), pool);
|
||||
else
|
||||
var = objectAdd(dst, ZeroTerminatedRamString(s->key), pool);
|
||||
if (!variantCopy(var, &s->value, pool)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool objectEquals(const JsonObjectData* o1, const JsonObjectData* o2) {
|
||||
if (o1 == o2) return true;
|
||||
if (!o1 || !o2) return false;
|
||||
|
||||
for (Slot* s = o1->head; s; s = s->next) {
|
||||
JsonVariantData* v1 = &s->value;
|
||||
JsonVariantData* v2 = objectGet(o2, makeString(s->key));
|
||||
if (!variantEquals(v1, v2)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
59
src/ArduinoJson/Data/SlotFunctions.hpp
Normal file
59
src/ArduinoJson/Data/SlotFunctions.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Strings/StringTypes.hpp"
|
||||
#include "JsonVariantData.hpp"
|
||||
#include "Slot.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TKey>
|
||||
inline bool slotSetKey(Slot* slot, TKey key, MemoryPool* pool) {
|
||||
const char* dup = key.save(pool);
|
||||
if (!dup) return false;
|
||||
slot->key = dup;
|
||||
slot->value.keyIsStatic = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool slotSetKey(Slot* slot, ZeroTerminatedRamStringConst key,
|
||||
MemoryPool* pool) {
|
||||
slot->key = key.save(pool);
|
||||
slot->value.keyIsStatic = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool slotSetKey(Slot* slot, StringInMemoryPool key, MemoryPool* pool) {
|
||||
slot->key = key.save(pool);
|
||||
slot->value.keyIsStatic = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline const Slot* slotAdvance(const Slot* slot, size_t distance) {
|
||||
while (distance && slot) {
|
||||
slot = slot->next;
|
||||
distance--;
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
inline Slot* slotAdvance(Slot* slot, size_t distance) {
|
||||
while (distance && slot) {
|
||||
slot = slot->next;
|
||||
distance--;
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
inline size_t slotSize(const Slot* slot) {
|
||||
size_t n = 0;
|
||||
while (slot) {
|
||||
n++;
|
||||
slot = slot->next;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
48
src/ArduinoJson/Data/VariantAs.hpp
Normal file
48
src/ArduinoJson/Data/VariantAs.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Serialization/DynamicStringWriter.hpp"
|
||||
#include "VariantFunctions.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class JsonVariantConst;
|
||||
|
||||
template <typename T>
|
||||
inline typename enable_if<is_integral<T>::value, T>::type variantAs(
|
||||
const JsonVariantData* _data) {
|
||||
return variantAsIntegral<T>(_data);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline typename enable_if<is_same<T, bool>::value, T>::type variantAs(
|
||||
const JsonVariantData* _data) {
|
||||
return variantAsBoolean(_data);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline typename enable_if<is_floating_point<T>::value, T>::type variantAs(
|
||||
const JsonVariantData* _data) {
|
||||
return variantAsFloat<T>(_data);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline typename enable_if<is_same<T, const char*>::value ||
|
||||
is_same<T, char*>::value,
|
||||
const char*>::type
|
||||
variantAs(const JsonVariantData* _data) {
|
||||
return variantAsString(_data);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline typename enable_if<is_same<JsonVariantConst, T>::value, T>::type
|
||||
variantAs(const JsonVariantData* _data);
|
||||
|
||||
template <typename T>
|
||||
inline typename enable_if<IsWriteableString<T>::value, T>::type variantAs(
|
||||
const JsonVariantData* _data);
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
29
src/ArduinoJson/Data/VariantAsImpl.hpp
Normal file
29
src/ArduinoJson/Data/VariantAsImpl.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../JsonVariant.hpp"
|
||||
#include "../Serialization/DynamicStringWriter.hpp"
|
||||
#include "VariantFunctions.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
inline typename enable_if<is_same<JsonVariantConst, T>::value, T>::type
|
||||
variantAs(const JsonVariantData* _data) {
|
||||
return JsonVariantConst(_data);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline typename enable_if<IsWriteableString<T>::value, T>::type variantAs(
|
||||
const JsonVariantData* _data) {
|
||||
const char* cstr = variantAsString(_data);
|
||||
if (cstr) return T(cstr);
|
||||
T s;
|
||||
serializeJson(JsonVariantConst(_data), s);
|
||||
return s;
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
287
src/ArduinoJson/Data/VariantFunctions.hpp
Normal file
287
src/ArduinoJson/Data/VariantFunctions.hpp
Normal file
@@ -0,0 +1,287 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Numbers/parseFloat.hpp"
|
||||
#include "../Numbers/parseInteger.hpp"
|
||||
#include "../SerializedValue.hpp"
|
||||
#include "ArrayFunctions.hpp"
|
||||
#include "JsonVariantData.hpp"
|
||||
#include "ObjectFunctions.hpp"
|
||||
#include "Slot.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
inline T variantAsIntegral(const JsonVariantData* var) {
|
||||
if (!var) return 0;
|
||||
switch (var->type) {
|
||||
case JSON_POSITIVE_INTEGER:
|
||||
case JSON_BOOLEAN:
|
||||
return T(var->content.asInteger);
|
||||
case JSON_NEGATIVE_INTEGER:
|
||||
return T(~var->content.asInteger + 1);
|
||||
case JSON_LINKED_STRING:
|
||||
case JSON_OWNED_STRING:
|
||||
return parseInteger<T>(var->content.asString);
|
||||
case JSON_FLOAT:
|
||||
return T(var->content.asFloat);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool variantAsBoolean(const JsonVariantData* var) {
|
||||
return variantAsIntegral<int>(var) != 0;
|
||||
}
|
||||
|
||||
// T = float/double
|
||||
template <typename T>
|
||||
inline T variantAsFloat(const JsonVariantData* var) {
|
||||
if (!var) return 0;
|
||||
switch (var->type) {
|
||||
case JSON_POSITIVE_INTEGER:
|
||||
case JSON_BOOLEAN:
|
||||
return static_cast<T>(var->content.asInteger);
|
||||
case JSON_NEGATIVE_INTEGER:
|
||||
return -static_cast<T>(var->content.asInteger);
|
||||
case JSON_LINKED_STRING:
|
||||
case JSON_OWNED_STRING:
|
||||
return parseFloat<T>(var->content.asString);
|
||||
case JSON_FLOAT:
|
||||
return static_cast<T>(var->content.asFloat);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline const char* variantAsString(const JsonVariantData* var) {
|
||||
if (!var) return 0;
|
||||
if (var &&
|
||||
(var->type == JSON_LINKED_STRING || var->type == JSON_OWNED_STRING))
|
||||
return var->content.asString;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline JsonArrayData* variantAsArray(JsonVariantData* var) {
|
||||
if (var && var->type == JSON_ARRAY)
|
||||
return &var->content.asArray;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline const JsonArrayData* variantAsArray(const JsonVariantData* var) {
|
||||
if (var && var->type == JSON_ARRAY)
|
||||
return &var->content.asArray;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline JsonObjectData* variantAsObject(JsonVariantData* var) {
|
||||
if (var && var->type == JSON_OBJECT)
|
||||
return &var->content.asObject;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline const JsonObjectData* variantAsObject(const JsonVariantData* var) {
|
||||
if (var && var->type == JSON_OBJECT)
|
||||
return &var->content.asObject;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool variantSetBoolean(JsonVariantData* var, bool value) {
|
||||
if (!var) return false;
|
||||
var->type = JSON_BOOLEAN;
|
||||
var->content.asInteger = static_cast<JsonUInt>(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool variantSetFloat(JsonVariantData* var, JsonFloat value) {
|
||||
if (!var) return false;
|
||||
var->type = JSON_FLOAT;
|
||||
var->content.asFloat = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool variantSetSignedInteger(JsonVariantData* var, T value) {
|
||||
if (!var) return false;
|
||||
if (value >= 0) {
|
||||
var->type = JSON_POSITIVE_INTEGER;
|
||||
var->content.asInteger = static_cast<JsonUInt>(value);
|
||||
} else {
|
||||
var->type = JSON_NEGATIVE_INTEGER;
|
||||
var->content.asInteger = ~static_cast<JsonUInt>(value) + 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool variantSetSignedInteger(JsonVariantData* var, JsonUInt value) {
|
||||
if (!var) return false;
|
||||
var->type = JSON_POSITIVE_INTEGER;
|
||||
var->content.asInteger = static_cast<JsonUInt>(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool variantSetLinkedRaw(JsonVariantData* var,
|
||||
SerializedValue<const char*> value) {
|
||||
if (!var) return false;
|
||||
var->type = JSON_LINKED_RAW;
|
||||
var->content.asRaw.data = value.data();
|
||||
var->content.asRaw.size = value.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool variantSetOwnedRaw(JsonVariantData* var, SerializedValue<T> value,
|
||||
MemoryPool* pool) {
|
||||
if (!var) return false;
|
||||
const char* dup = makeString(value.data(), value.size()).save(pool);
|
||||
if (dup) {
|
||||
var->type = JSON_OWNED_RAW;
|
||||
var->content.asRaw.data = dup;
|
||||
var->content.asRaw.size = value.size();
|
||||
return true;
|
||||
} else {
|
||||
var->type = JSON_NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool variantSetString(JsonVariantData* var, T value, MemoryPool* pool) {
|
||||
if (!var) return false;
|
||||
const char* dup = value.save(pool);
|
||||
if (dup) {
|
||||
var->type = JSON_OWNED_STRING;
|
||||
var->content.asString = dup;
|
||||
return true;
|
||||
} else {
|
||||
var->type = JSON_NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool variantSetString(JsonVariantData* var, const char* value) {
|
||||
if (!var) return false;
|
||||
var->type = JSON_LINKED_STRING;
|
||||
var->content.asString = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool variantSetString(JsonVariantData* var, const char* value,
|
||||
MemoryPool* pool) {
|
||||
return variantSetString(var, makeString(const_cast<char*>(value)), pool);
|
||||
}
|
||||
|
||||
inline void variantSetNull(JsonVariantData* var) {
|
||||
if (var) var->type = JSON_NULL;
|
||||
}
|
||||
|
||||
inline JsonArrayData* variantToArray(JsonVariantData* var) {
|
||||
if (!var) return 0;
|
||||
var->type = JSON_ARRAY;
|
||||
var->content.asArray.head = 0;
|
||||
var->content.asArray.tail = 0;
|
||||
return &var->content.asArray;
|
||||
}
|
||||
|
||||
inline JsonObjectData* variantToObject(JsonVariantData* var) {
|
||||
if (!var) return 0;
|
||||
var->type = JSON_OBJECT;
|
||||
var->content.asObject.head = 0;
|
||||
var->content.asObject.tail = 0;
|
||||
return &var->content.asObject;
|
||||
}
|
||||
|
||||
inline bool variantCopy(JsonVariantData* dst, const JsonVariantData* src,
|
||||
MemoryPool* pool) {
|
||||
if (!dst) return false;
|
||||
if (!src) {
|
||||
dst->type = JSON_NULL;
|
||||
return true;
|
||||
}
|
||||
switch (src->type) {
|
||||
case JSON_ARRAY:
|
||||
return arrayCopy(variantToArray(dst), &src->content.asArray, pool);
|
||||
case JSON_OBJECT:
|
||||
return objectCopy(variantToObject(dst), &src->content.asObject, pool);
|
||||
case JSON_OWNED_STRING:
|
||||
return variantSetString(dst, src->content.asString, pool);
|
||||
case JSON_OWNED_RAW:
|
||||
return variantSetOwnedRaw(
|
||||
dst,
|
||||
serialized(const_cast<char*>(src->content.asRaw.data),
|
||||
src->content.asRaw.size),
|
||||
pool);
|
||||
default:
|
||||
*dst = *src;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool variantIsInteger(const JsonVariantData* var) {
|
||||
return var && (var->type == JSON_POSITIVE_INTEGER ||
|
||||
var->type == JSON_NEGATIVE_INTEGER);
|
||||
}
|
||||
|
||||
inline bool variantIsFloat(const JsonVariantData* var) {
|
||||
return var &&
|
||||
(var->type == JSON_FLOAT || var->type == JSON_POSITIVE_INTEGER ||
|
||||
var->type == JSON_NEGATIVE_INTEGER);
|
||||
}
|
||||
|
||||
inline bool variantIsString(const JsonVariantData* var) {
|
||||
return var &&
|
||||
(var->type == JSON_LINKED_STRING || var->type == JSON_OWNED_STRING);
|
||||
}
|
||||
|
||||
inline bool variantIsArray(const JsonVariantData* var) {
|
||||
return var && var->type == JSON_ARRAY;
|
||||
}
|
||||
|
||||
inline bool variantIsObject(const JsonVariantData* var) {
|
||||
return var && var->type == JSON_OBJECT;
|
||||
}
|
||||
|
||||
inline bool variantIsNull(const JsonVariantData* var) {
|
||||
return var == 0 || var->type == JSON_NULL;
|
||||
}
|
||||
|
||||
inline bool variantEquals(const JsonVariantData* a, const JsonVariantData* b) {
|
||||
if (a == b) return true;
|
||||
if (!a || !b) return false;
|
||||
if (a->type != b->type) return false;
|
||||
|
||||
switch (a->type) {
|
||||
case JSON_LINKED_RAW:
|
||||
case JSON_OWNED_RAW:
|
||||
case JSON_LINKED_STRING:
|
||||
case JSON_OWNED_STRING:
|
||||
return !strcmp(a->content.asString, b->content.asString);
|
||||
|
||||
case JSON_BOOLEAN:
|
||||
case JSON_POSITIVE_INTEGER:
|
||||
case JSON_NEGATIVE_INTEGER:
|
||||
return a->content.asInteger == b->content.asInteger;
|
||||
|
||||
case JSON_ARRAY:
|
||||
return arrayEquals(&a->content.asArray, &b->content.asArray);
|
||||
|
||||
case JSON_OBJECT:
|
||||
return objectEquals(&a->content.asObject, &b->content.asObject);
|
||||
|
||||
case JSON_FLOAT:
|
||||
return a->content.asFloat == b->content.asFloat;
|
||||
|
||||
case JSON_NULL:
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
Reference in New Issue
Block a user