mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-16 12:02:14 +02:00
Renamed JsonBuffer to MemoryPool
This commit is contained in:
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../Memory/JsonBuffer.hpp"
|
#include "../Memory/MemoryPool.hpp"
|
||||||
#include "ListConstIterator.hpp"
|
#include "ListConstIterator.hpp"
|
||||||
#include "ListIterator.hpp"
|
#include "ListIterator.hpp"
|
||||||
|
|
||||||
@ -32,8 +32,8 @@ class List {
|
|||||||
return nodeCount;
|
return nodeCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator add(JsonBuffer *buffer) {
|
iterator add(MemoryPool *memoryPool) {
|
||||||
node_type *newNode = new (buffer) node_type();
|
node_type *newNode = new (memoryPool) node_type();
|
||||||
|
|
||||||
if (_firstNode) {
|
if (_firstNode) {
|
||||||
node_type *lastNode = _firstNode;
|
node_type *lastNode = _firstNode;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include <stddef.h> // for NULL
|
#include <stddef.h> // for NULL
|
||||||
|
|
||||||
#include "../Memory/JsonBufferAllocated.hpp"
|
#include "../Memory/AllocableInMemoryPool.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
@ -14,7 +14,7 @@ namespace Internals {
|
|||||||
// A node for a singly-linked list.
|
// A node for a singly-linked list.
|
||||||
// Used by List<T> and its iterators.
|
// Used by List<T> and its iterators.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct ListNode : public Internals::JsonBufferAllocated {
|
struct ListNode : public Internals::AllocableInMemoryPool {
|
||||||
ListNode() NOEXCEPT : next(NULL) {}
|
ListNode() NOEXCEPT : next(NULL) {}
|
||||||
|
|
||||||
ListNode<T> *next;
|
ListNode<T> *next;
|
||||||
|
@ -16,11 +16,12 @@ namespace ArduinoJson {
|
|||||||
namespace Internals {
|
namespace Internals {
|
||||||
|
|
||||||
template <template <typename, typename> class TDeserializer,
|
template <template <typename, typename> class TDeserializer,
|
||||||
typename TJsonBuffer, typename TReader, typename TWriter>
|
typename TMemoryPool, typename TReader, typename TWriter>
|
||||||
TDeserializer<TReader, TWriter> makeDeserializer(TJsonBuffer *buffer,
|
TDeserializer<TReader, TWriter> makeDeserializer(TMemoryPool &memoryPool,
|
||||||
TReader reader, TWriter writer,
|
TReader reader, TWriter writer,
|
||||||
uint8_t nestingLimit) {
|
uint8_t nestingLimit) {
|
||||||
return TDeserializer<TReader, TWriter>(buffer, reader, writer, nestingLimit);
|
return TDeserializer<TReader, TWriter>(memoryPool, reader, writer,
|
||||||
|
nestingLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeserializationError deserialize(TDocument& doc, TString input);
|
// DeserializationError deserialize(TDocument& doc, TString input);
|
||||||
@ -32,9 +33,9 @@ typename Internals::enable_if<!Internals::is_array<TString>::value,
|
|||||||
DeserializationError>::type
|
DeserializationError>::type
|
||||||
deserialize(TDocument &doc, const TString &input) {
|
deserialize(TDocument &doc, const TString &input) {
|
||||||
using namespace Internals;
|
using namespace Internals;
|
||||||
return makeDeserializer<TDeserializer>(&doc.buffer(), makeReader(input),
|
return makeDeserializer<TDeserializer>(
|
||||||
makeStringStorage(doc.buffer(), input),
|
doc.memoryPool(), makeReader(input),
|
||||||
doc.nestingLimit)
|
makeStringStorage(doc.memoryPool(), input), doc.nestingLimit)
|
||||||
.parse(doc.template to<JsonVariantData>());
|
.parse(doc.template to<JsonVariantData>());
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -45,9 +46,9 @@ template <template <typename, typename> class TDeserializer, typename TDocument,
|
|||||||
typename TChar>
|
typename TChar>
|
||||||
DeserializationError deserialize(TDocument &doc, TChar *input) {
|
DeserializationError deserialize(TDocument &doc, TChar *input) {
|
||||||
using namespace Internals;
|
using namespace Internals;
|
||||||
return makeDeserializer<TDeserializer>(&doc.buffer(), makeReader(input),
|
return makeDeserializer<TDeserializer>(
|
||||||
makeStringStorage(doc.buffer(), input),
|
doc.memoryPool(), makeReader(input),
|
||||||
doc.nestingLimit)
|
makeStringStorage(doc.memoryPool(), input), doc.nestingLimit)
|
||||||
.parse(doc.template to<JsonVariantData>());
|
.parse(doc.template to<JsonVariantData>());
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -61,8 +62,8 @@ DeserializationError deserialize(TDocument &doc, TChar *input,
|
|||||||
size_t inputSize) {
|
size_t inputSize) {
|
||||||
using namespace Internals;
|
using namespace Internals;
|
||||||
return makeDeserializer<TDeserializer>(
|
return makeDeserializer<TDeserializer>(
|
||||||
&doc.buffer(), makeReader(input, inputSize),
|
doc.memoryPool(), makeReader(input, inputSize),
|
||||||
makeStringStorage(doc.buffer(), input), doc.nestingLimit)
|
makeStringStorage(doc.memoryPool(), input), doc.nestingLimit)
|
||||||
.parse(doc.template to<JsonVariantData>());
|
.parse(doc.template to<JsonVariantData>());
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -73,9 +74,9 @@ template <template <typename, typename> class TDeserializer, typename TDocument,
|
|||||||
typename TStream>
|
typename TStream>
|
||||||
DeserializationError deserialize(TDocument &doc, TStream &input) {
|
DeserializationError deserialize(TDocument &doc, TStream &input) {
|
||||||
using namespace Internals;
|
using namespace Internals;
|
||||||
return makeDeserializer<TDeserializer>(&doc.buffer(), makeReader(input),
|
return makeDeserializer<TDeserializer>(
|
||||||
makeStringStorage(doc.buffer(), input),
|
doc.memoryPool(), makeReader(input),
|
||||||
doc.nestingLimit)
|
makeStringStorage(doc.memoryPool(), input), doc.nestingLimit)
|
||||||
.parse(doc.template to<JsonVariantData>());
|
.parse(doc.template to<JsonVariantData>());
|
||||||
}
|
}
|
||||||
} // namespace Internals
|
} // namespace Internals
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "JsonArray.hpp"
|
#include "JsonArray.hpp"
|
||||||
#include "JsonObject.hpp"
|
#include "JsonObject.hpp"
|
||||||
#include "JsonVariant.hpp"
|
#include "JsonVariant.hpp"
|
||||||
#include "Memory/DynamicJsonBuffer.hpp"
|
#include "Memory/DynamicMemoryPool.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
|
|
||||||
@ -17,7 +17,8 @@ class DynamicJsonDocument {
|
|||||||
|
|
||||||
DynamicJsonDocument() : nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {}
|
DynamicJsonDocument() : nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {}
|
||||||
DynamicJsonDocument(size_t capacity)
|
DynamicJsonDocument(size_t capacity)
|
||||||
: nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT), _buffer(capacity) {}
|
: nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT),
|
||||||
|
_memoryPool(capacity) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool is() const {
|
bool is() const {
|
||||||
@ -35,7 +36,7 @@ class DynamicJsonDocument {
|
|||||||
JsonObject>::type
|
JsonObject>::type
|
||||||
to() {
|
to() {
|
||||||
clear();
|
clear();
|
||||||
JsonObject object(&_buffer);
|
JsonObject object(&_memoryPool);
|
||||||
getVariant().set(object);
|
getVariant().set(object);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
@ -46,7 +47,7 @@ class DynamicJsonDocument {
|
|||||||
JsonArray>::type
|
JsonArray>::type
|
||||||
to() {
|
to() {
|
||||||
clear();
|
clear();
|
||||||
JsonArray array(&_buffer);
|
JsonArray array(&_memoryPool);
|
||||||
getVariant().set(array);
|
getVariant().set(array);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
@ -70,17 +71,17 @@ class DynamicJsonDocument {
|
|||||||
return _rootData;
|
return _rootData;
|
||||||
}
|
}
|
||||||
|
|
||||||
Internals::DynamicJsonBuffer& buffer() {
|
Internals::DynamicMemoryPool& memoryPool() {
|
||||||
return _buffer;
|
return _memoryPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
_buffer.clear();
|
_memoryPool.clear();
|
||||||
_rootData.setNull();
|
_rootData.setNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t memoryUsage() const {
|
size_t memoryUsage() const {
|
||||||
return _buffer.size();
|
return _memoryPool.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename Visitor>
|
||||||
@ -90,10 +91,10 @@ class DynamicJsonDocument {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
JsonVariant getVariant() const {
|
JsonVariant getVariant() const {
|
||||||
return JsonVariant(&_buffer, &_rootData);
|
return JsonVariant(&_memoryPool, &_rootData);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutable Internals::DynamicJsonBuffer _buffer;
|
mutable Internals::DynamicMemoryPool _memoryPool;
|
||||||
mutable Internals::JsonVariantData _rootData;
|
mutable Internals::JsonVariantData _rootData;
|
||||||
};
|
};
|
||||||
} // namespace ArduinoJson
|
} // namespace ArduinoJson
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "../Deserialization/deserialize.hpp"
|
#include "../Deserialization/deserialize.hpp"
|
||||||
#include "../JsonVariant.hpp"
|
#include "../JsonVariant.hpp"
|
||||||
#include "../Memory/JsonBuffer.hpp"
|
#include "../Memory/MemoryPool.hpp"
|
||||||
#include "../Numbers/isFloat.hpp"
|
#include "../Numbers/isFloat.hpp"
|
||||||
#include "../Numbers/isInteger.hpp"
|
#include "../Numbers/isInteger.hpp"
|
||||||
#include "../Polyfills/type_traits.hpp"
|
#include "../Polyfills/type_traits.hpp"
|
||||||
@ -18,9 +18,9 @@ namespace Internals {
|
|||||||
template <typename TReader, typename TStringStorage>
|
template <typename TReader, typename TStringStorage>
|
||||||
class JsonDeserializer {
|
class JsonDeserializer {
|
||||||
public:
|
public:
|
||||||
JsonDeserializer(JsonBuffer *buffer, TReader reader,
|
JsonDeserializer(MemoryPool &memoryPool, TReader reader,
|
||||||
TStringStorage stringStorage, uint8_t nestingLimit)
|
TStringStorage stringStorage, uint8_t nestingLimit)
|
||||||
: _buffer(buffer),
|
: _memoryPool(&memoryPool),
|
||||||
_reader(reader),
|
_reader(reader),
|
||||||
_stringStorage(stringStorage),
|
_stringStorage(stringStorage),
|
||||||
_nestingLimit(nestingLimit),
|
_nestingLimit(nestingLimit),
|
||||||
@ -68,7 +68,7 @@ class JsonDeserializer {
|
|||||||
DeserializationError parseArray(JsonVariantData &variant) {
|
DeserializationError parseArray(JsonVariantData &variant) {
|
||||||
if (_nestingLimit == 0) return DeserializationError::TooDeep;
|
if (_nestingLimit == 0) return DeserializationError::TooDeep;
|
||||||
|
|
||||||
JsonArrayData *array = new (_buffer) JsonArrayData;
|
JsonArrayData *array = new (_memoryPool) JsonArrayData;
|
||||||
if (!array) return DeserializationError::NoMemory;
|
if (!array) return DeserializationError::NoMemory;
|
||||||
variant.setArray(*array);
|
variant.setArray(*array);
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ class JsonDeserializer {
|
|||||||
// Read each value
|
// Read each value
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// Allocate slot in array
|
// Allocate slot in array
|
||||||
JsonVariantData *value = array->addSlot(_buffer);
|
JsonVariantData *value = array->addSlot(_memoryPool);
|
||||||
if (!value) return DeserializationError::NoMemory;
|
if (!value) return DeserializationError::NoMemory;
|
||||||
|
|
||||||
// 1 - Parse value
|
// 1 - Parse value
|
||||||
@ -107,7 +107,7 @@ class JsonDeserializer {
|
|||||||
DeserializationError parseObject(JsonVariantData &variant) {
|
DeserializationError parseObject(JsonVariantData &variant) {
|
||||||
if (_nestingLimit == 0) return DeserializationError::TooDeep;
|
if (_nestingLimit == 0) return DeserializationError::TooDeep;
|
||||||
|
|
||||||
JsonObjectData *object = new (_buffer) JsonObjectData;
|
JsonObjectData *object = new (_memoryPool) JsonObjectData;
|
||||||
if (!object) return DeserializationError::NoMemory;
|
if (!object) return DeserializationError::NoMemory;
|
||||||
variant.setObject(*object);
|
variant.setObject(*object);
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ class JsonDeserializer {
|
|||||||
if (!eat(':')) return DeserializationError::InvalidInput;
|
if (!eat(':')) return DeserializationError::InvalidInput;
|
||||||
|
|
||||||
// Allocate slot in object
|
// Allocate slot in object
|
||||||
JsonVariantData *value = object->addSlot(_buffer, key);
|
JsonVariantData *value = object->addSlot(_memoryPool, key);
|
||||||
if (!value) return DeserializationError::NoMemory;
|
if (!value) return DeserializationError::NoMemory;
|
||||||
|
|
||||||
// Parse value
|
// Parse value
|
||||||
@ -335,7 +335,7 @@ class JsonDeserializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonBuffer *_buffer;
|
MemoryPool *_memoryPool;
|
||||||
TReader _reader;
|
TReader _reader;
|
||||||
TStringStorage _stringStorage;
|
TStringStorage _stringStorage;
|
||||||
uint8_t _nestingLimit;
|
uint8_t _nestingLimit;
|
||||||
|
@ -21,12 +21,12 @@ class JsonArray {
|
|||||||
public:
|
public:
|
||||||
typedef JsonArrayIterator iterator;
|
typedef JsonArrayIterator iterator;
|
||||||
|
|
||||||
FORCE_INLINE JsonArray() : _buffer(0), _data(0) {}
|
FORCE_INLINE JsonArray() : _memoryPool(0), _data(0) {}
|
||||||
FORCE_INLINE JsonArray(Internals::JsonBuffer* buf,
|
FORCE_INLINE JsonArray(Internals::MemoryPool* buf,
|
||||||
Internals::JsonArrayData* arr)
|
Internals::JsonArrayData* arr)
|
||||||
: _buffer(buf), _data(arr) {}
|
: _memoryPool(buf), _data(arr) {}
|
||||||
FORCE_INLINE explicit JsonArray(Internals::JsonBuffer* buf)
|
FORCE_INLINE explicit JsonArray(Internals::MemoryPool* buf)
|
||||||
: _buffer(buf), _data(new (buf) Internals::JsonArrayData()) {}
|
: _memoryPool(buf), _data(new (buf) Internals::JsonArrayData()) {}
|
||||||
|
|
||||||
// Adds the specified value at the end of the array.
|
// Adds the specified value at the end of the array.
|
||||||
//
|
//
|
||||||
@ -47,7 +47,7 @@ class JsonArray {
|
|||||||
|
|
||||||
FORCE_INLINE iterator begin() const {
|
FORCE_INLINE iterator begin() const {
|
||||||
if (!_data) return iterator();
|
if (!_data) return iterator();
|
||||||
return iterator(_buffer, _data->begin());
|
return iterator(_memoryPool, _data->begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE iterator end() const {
|
FORCE_INLINE iterator end() const {
|
||||||
@ -192,12 +192,12 @@ class JsonArray {
|
|||||||
template <typename TValueRef>
|
template <typename TValueRef>
|
||||||
FORCE_INLINE bool add_impl(TValueRef value) {
|
FORCE_INLINE bool add_impl(TValueRef value) {
|
||||||
if (!_data) return false;
|
if (!_data) return false;
|
||||||
iterator it = iterator(_buffer, _data->add(_buffer));
|
iterator it = iterator(_memoryPool, _data->add(_memoryPool));
|
||||||
if (it == end()) return false;
|
if (it == end()) return false;
|
||||||
return it->set(value);
|
return it->set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Internals::JsonBuffer* _buffer;
|
Internals::MemoryPool* _memoryPool;
|
||||||
Internals::JsonArrayData* _data;
|
Internals::JsonArrayData* _data;
|
||||||
};
|
};
|
||||||
} // namespace ArduinoJson
|
} // namespace ArduinoJson
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
#include "Data/JsonVariantData.hpp"
|
#include "Data/JsonVariantData.hpp"
|
||||||
#include "Data/List.hpp"
|
#include "Data/List.hpp"
|
||||||
#include "Memory/JsonBufferAllocated.hpp"
|
#include "Memory/AllocableInMemoryPool.hpp"
|
||||||
#include "Polyfills/type_traits.hpp"
|
#include "Polyfills/type_traits.hpp"
|
||||||
|
|
||||||
// Returns the size (in bytes) of an array with n elements.
|
// Returns the size (in bytes) of an array with n elements.
|
||||||
// Can be very handy to determine the size of a StaticJsonBuffer.
|
// Can be very handy to determine the size of a StaticMemoryPool.
|
||||||
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
|
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
|
||||||
(sizeof(ArduinoJson::Internals::JsonArrayData) + \
|
(sizeof(ArduinoJson::Internals::JsonArrayData) + \
|
||||||
(NUMBER_OF_ELEMENTS) * \
|
(NUMBER_OF_ELEMENTS) * \
|
||||||
@ -18,9 +18,9 @@
|
|||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
struct JsonArrayData : List<JsonVariantData>, JsonBufferAllocated {
|
struct JsonArrayData : List<JsonVariantData>, AllocableInMemoryPool {
|
||||||
JsonVariantData* addSlot(JsonBuffer* buffer) {
|
JsonVariantData* addSlot(MemoryPool* memoryPool) {
|
||||||
iterator it = add(buffer);
|
iterator it = add(memoryPool);
|
||||||
return it != end() ? &*it : 0;
|
return it != end() ? &*it : 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -11,14 +11,14 @@ namespace ArduinoJson {
|
|||||||
|
|
||||||
inline JsonArray JsonArray::createNestedArray() {
|
inline JsonArray JsonArray::createNestedArray() {
|
||||||
if (!_data) return JsonArray();
|
if (!_data) return JsonArray();
|
||||||
JsonArray array(_buffer);
|
JsonArray array(_memoryPool);
|
||||||
if (!array.isNull()) add(array);
|
if (!array.isNull()) add(array);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline JsonObject JsonArray::createNestedObject() {
|
inline JsonObject JsonArray::createNestedObject() {
|
||||||
if (!_data) return JsonObject();
|
if (!_data) return JsonObject();
|
||||||
JsonObject object(_buffer);
|
JsonObject object(_memoryPool);
|
||||||
if (!object.isNull()) add(object);
|
if (!object.isNull()) add(object);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@ namespace ArduinoJson {
|
|||||||
|
|
||||||
class JsonVariantPtr {
|
class JsonVariantPtr {
|
||||||
public:
|
public:
|
||||||
JsonVariantPtr(Internals::JsonBuffer *buffer,
|
JsonVariantPtr(Internals::MemoryPool *memoryPool,
|
||||||
Internals::JsonVariantData *data)
|
Internals::JsonVariantData *data)
|
||||||
: _variant(buffer, data) {}
|
: _variant(memoryPool, data) {}
|
||||||
|
|
||||||
JsonVariant *operator->() {
|
JsonVariant *operator->() {
|
||||||
return &_variant;
|
return &_variant;
|
||||||
@ -32,15 +32,15 @@ class JsonArrayIterator {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
JsonArrayIterator() {}
|
JsonArrayIterator() {}
|
||||||
explicit JsonArrayIterator(Internals::JsonBuffer *buffer,
|
explicit JsonArrayIterator(Internals::MemoryPool *memoryPool,
|
||||||
internal_iterator iterator)
|
internal_iterator iterator)
|
||||||
: _iterator(iterator), _buffer(buffer) {}
|
: _iterator(iterator), _memoryPool(memoryPool) {}
|
||||||
|
|
||||||
JsonVariant operator*() const {
|
JsonVariant operator*() const {
|
||||||
return JsonVariant(_buffer, &*_iterator);
|
return JsonVariant(_memoryPool, &*_iterator);
|
||||||
}
|
}
|
||||||
JsonVariantPtr operator->() {
|
JsonVariantPtr operator->() {
|
||||||
return JsonVariantPtr(_buffer, &*_iterator);
|
return JsonVariantPtr(_memoryPool, &*_iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const JsonArrayIterator &other) const {
|
bool operator==(const JsonArrayIterator &other) const {
|
||||||
@ -67,6 +67,6 @@ class JsonArrayIterator {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
internal_iterator _iterator;
|
internal_iterator _iterator;
|
||||||
Internals::JsonBuffer *_buffer;
|
Internals::MemoryPool *_memoryPool;
|
||||||
};
|
};
|
||||||
} // namespace ArduinoJson
|
} // namespace ArduinoJson
|
||||||
|
@ -16,16 +16,16 @@ class JsonObject {
|
|||||||
public:
|
public:
|
||||||
typedef JsonObjectIterator iterator;
|
typedef JsonObjectIterator iterator;
|
||||||
|
|
||||||
FORCE_INLINE JsonObject() : _buffer(0), _data(0) {}
|
FORCE_INLINE JsonObject() : _memoryPool(0), _data(0) {}
|
||||||
FORCE_INLINE JsonObject(Internals::JsonBuffer* buf,
|
FORCE_INLINE JsonObject(Internals::MemoryPool* buf,
|
||||||
Internals::JsonObjectData* object)
|
Internals::JsonObjectData* object)
|
||||||
: _buffer(buf), _data(object) {}
|
: _memoryPool(buf), _data(object) {}
|
||||||
FORCE_INLINE explicit JsonObject(Internals::JsonBuffer* buf)
|
FORCE_INLINE explicit JsonObject(Internals::MemoryPool* buf)
|
||||||
: _buffer(buf), _data(new (buf) Internals::JsonObjectData()) {}
|
: _memoryPool(buf), _data(new (buf) Internals::JsonObjectData()) {}
|
||||||
|
|
||||||
FORCE_INLINE iterator begin() const {
|
FORCE_INLINE iterator begin() const {
|
||||||
if (!_data) return iterator();
|
if (!_data) return iterator();
|
||||||
return iterator(_buffer, _data->begin());
|
return iterator(_memoryPool, _data->begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tells weither the specified key is present and associated with a value.
|
// Tells weither the specified key is present and associated with a value.
|
||||||
@ -264,15 +264,17 @@ class JsonObject {
|
|||||||
FORCE_INLINE typename Internals::JsonVariantAs<TValue>::type get_impl(
|
FORCE_INLINE typename Internals::JsonVariantAs<TValue>::type get_impl(
|
||||||
TStringRef key) const {
|
TStringRef key) const {
|
||||||
internal_iterator it = findKey<TStringRef>(key);
|
internal_iterator it = findKey<TStringRef>(key);
|
||||||
return it != _data->end() ? JsonVariant(_buffer, &it->value).as<TValue>()
|
return it != _data->end()
|
||||||
: TValue();
|
? JsonVariant(_memoryPool, &it->value).as<TValue>()
|
||||||
|
: TValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TStringRef, typename TValue>
|
template <typename TStringRef, typename TValue>
|
||||||
FORCE_INLINE bool is_impl(TStringRef key) const {
|
FORCE_INLINE bool is_impl(TStringRef key) const {
|
||||||
internal_iterator it = findKey<TStringRef>(key);
|
internal_iterator it = findKey<TStringRef>(key);
|
||||||
return it != _data->end() ? JsonVariant(_buffer, &it->value).is<TValue>()
|
return it != _data->end()
|
||||||
: false;
|
? JsonVariant(_memoryPool, &it->value).is<TValue>()
|
||||||
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TStringRef>
|
template <typename TStringRef>
|
||||||
@ -293,13 +295,13 @@ class JsonObject {
|
|||||||
if (it == _data->end()) {
|
if (it == _data->end()) {
|
||||||
// add the key
|
// add the key
|
||||||
// TODO: use JsonPairData directly, we don't need an iterator
|
// TODO: use JsonPairData directly, we don't need an iterator
|
||||||
it = _data->add(_buffer);
|
it = _data->add(_memoryPool);
|
||||||
if (it == _data->end()) return false;
|
if (it == _data->end()) return false;
|
||||||
if (!set_key(it, key)) return false;
|
if (!set_key(it, key)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the value
|
// save the value
|
||||||
return JsonVariant(_buffer, &it->value).set(value);
|
return JsonVariant(_memoryPool, &it->value).set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool set_key(internal_iterator& it, const char* key) {
|
FORCE_INLINE bool set_key(internal_iterator& it, const char* key) {
|
||||||
@ -309,13 +311,13 @@ class JsonObject {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE bool set_key(internal_iterator& it, const T& key) {
|
FORCE_INLINE bool set_key(internal_iterator& it, const T& key) {
|
||||||
const char* dup = Internals::makeString(key).save(_buffer);
|
const char* dup = Internals::makeString(key).save(_memoryPool);
|
||||||
if (!dup) return false;
|
if (!dup) return false;
|
||||||
it->key = dup;
|
it->key = dup;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutable Internals::JsonBuffer* _buffer;
|
mutable Internals::MemoryPool* _memoryPool;
|
||||||
mutable Internals::JsonObjectData* _data;
|
mutable Internals::JsonObjectData* _data;
|
||||||
};
|
};
|
||||||
} // namespace ArduinoJson
|
} // namespace ArduinoJson
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
#include "Data/List.hpp"
|
#include "Data/List.hpp"
|
||||||
#include "JsonPair.hpp"
|
#include "JsonPair.hpp"
|
||||||
#include "Memory/JsonBufferAllocated.hpp"
|
#include "Memory/AllocableInMemoryPool.hpp"
|
||||||
#include "Polyfills/type_traits.hpp"
|
#include "Polyfills/type_traits.hpp"
|
||||||
|
|
||||||
// Returns the size (in bytes) of an object with n elements.
|
// Returns the size (in bytes) of an object with n elements.
|
||||||
// Can be very handy to determine the size of a StaticJsonBuffer.
|
// Can be very handy to determine the size of a StaticMemoryPool.
|
||||||
#define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \
|
#define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \
|
||||||
(sizeof(ArduinoJson::Internals::JsonObjectData) + \
|
(sizeof(ArduinoJson::Internals::JsonObjectData) + \
|
||||||
(NUMBER_OF_ELEMENTS) * \
|
(NUMBER_OF_ELEMENTS) * \
|
||||||
@ -18,9 +18,9 @@
|
|||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
struct JsonObjectData : List<JsonPairData>, JsonBufferAllocated {
|
struct JsonObjectData : List<JsonPairData>, AllocableInMemoryPool {
|
||||||
JsonVariantData* addSlot(JsonBuffer* buffer, const char* key) {
|
JsonVariantData* addSlot(MemoryPool* memoryPool, const char* key) {
|
||||||
iterator it = add(buffer);
|
iterator it = add(memoryPool);
|
||||||
if (it == end()) return 0;
|
if (it == end()) return 0;
|
||||||
it->key = key;
|
it->key = key;
|
||||||
return &it->value;
|
return &it->value;
|
||||||
|
@ -22,7 +22,7 @@ inline JsonArray JsonObject::createNestedArray(TString* key) {
|
|||||||
template <typename TStringRef>
|
template <typename TStringRef>
|
||||||
inline JsonArray JsonObject::createNestedArray_impl(TStringRef key) {
|
inline JsonArray JsonObject::createNestedArray_impl(TStringRef key) {
|
||||||
if (!_data) return JsonArray();
|
if (!_data) return JsonArray();
|
||||||
JsonArray array(_buffer);
|
JsonArray array(_memoryPool);
|
||||||
if (!array.isNull()) set(key, array);
|
if (!array.isNull()) set(key, array);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ inline JsonArray JsonObject::createNestedArray_impl(TStringRef key) {
|
|||||||
template <typename TStringRef>
|
template <typename TStringRef>
|
||||||
inline JsonObject JsonObject::createNestedObject_impl(TStringRef key) {
|
inline JsonObject JsonObject::createNestedObject_impl(TStringRef key) {
|
||||||
if (!_data) return JsonObject();
|
if (!_data) return JsonObject();
|
||||||
JsonObject object(_buffer);
|
JsonObject object(_memoryPool);
|
||||||
if (!object.isNull()) set(key, object);
|
if (!object.isNull()) set(key, object);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ namespace ArduinoJson {
|
|||||||
|
|
||||||
class JsonPairPtr {
|
class JsonPairPtr {
|
||||||
public:
|
public:
|
||||||
JsonPairPtr(Internals::JsonBuffer *buffer, Internals::JsonPairData *data)
|
JsonPairPtr(Internals::MemoryPool *memoryPool, Internals::JsonPairData *data)
|
||||||
: _pair(buffer, data) {}
|
: _pair(memoryPool, data) {}
|
||||||
|
|
||||||
const JsonPair *operator->() const {
|
const JsonPair *operator->() const {
|
||||||
return &_pair;
|
return &_pair;
|
||||||
@ -32,15 +32,15 @@ class JsonObjectIterator {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
JsonObjectIterator() {}
|
JsonObjectIterator() {}
|
||||||
explicit JsonObjectIterator(Internals::JsonBuffer *buffer,
|
explicit JsonObjectIterator(Internals::MemoryPool *memoryPool,
|
||||||
internal_iterator iterator)
|
internal_iterator iterator)
|
||||||
: _buffer(buffer), _iterator(iterator) {}
|
: _memoryPool(memoryPool), _iterator(iterator) {}
|
||||||
|
|
||||||
JsonPair operator*() const {
|
JsonPair operator*() const {
|
||||||
return JsonPair(_buffer, &*_iterator);
|
return JsonPair(_memoryPool, &*_iterator);
|
||||||
}
|
}
|
||||||
JsonPairPtr operator->() {
|
JsonPairPtr operator->() {
|
||||||
return JsonPairPtr(_buffer, &*_iterator);
|
return JsonPairPtr(_memoryPool, &*_iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const JsonObjectIterator &other) const {
|
bool operator==(const JsonObjectIterator &other) const {
|
||||||
@ -66,7 +66,7 @@ class JsonObjectIterator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Internals::JsonBuffer *_buffer;
|
Internals::MemoryPool *_memoryPool;
|
||||||
internal_iterator _iterator;
|
internal_iterator _iterator;
|
||||||
};
|
};
|
||||||
} // namespace ArduinoJson
|
} // namespace ArduinoJson
|
||||||
|
@ -19,8 +19,8 @@ struct JsonPairData {
|
|||||||
// A key value pair for JsonObjectData.
|
// A key value pair for JsonObjectData.
|
||||||
class JsonPair {
|
class JsonPair {
|
||||||
public:
|
public:
|
||||||
JsonPair(Internals::JsonBuffer* buffer, Internals::JsonPairData* data)
|
JsonPair(Internals::MemoryPool* memoryPool, Internals::JsonPairData* data)
|
||||||
: _key(data->key), _value(buffer, &data->value) {}
|
: _key(data->key), _value(memoryPool, &data->value) {}
|
||||||
|
|
||||||
const char* key() const {
|
const char* key() const {
|
||||||
return _key;
|
return _key;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "Data/JsonVariantData.hpp"
|
#include "Data/JsonVariantData.hpp"
|
||||||
#include "JsonVariant.hpp"
|
#include "JsonVariant.hpp"
|
||||||
#include "JsonVariantBase.hpp"
|
#include "JsonVariantBase.hpp"
|
||||||
#include "Memory/JsonBuffer.hpp"
|
#include "Memory/MemoryPool.hpp"
|
||||||
#include "Polyfills/type_traits.hpp"
|
#include "Polyfills/type_traits.hpp"
|
||||||
#include "Serialization/DynamicStringWriter.hpp"
|
#include "Serialization/DynamicStringWriter.hpp"
|
||||||
#include "SerializedValue.hpp"
|
#include "SerializedValue.hpp"
|
||||||
@ -31,12 +31,12 @@ class JsonObject;
|
|||||||
class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||||
public:
|
public:
|
||||||
// Intenal use only
|
// Intenal use only
|
||||||
FORCE_INLINE JsonVariant(Internals::JsonBuffer *buffer,
|
FORCE_INLINE JsonVariant(Internals::MemoryPool *memoryPool,
|
||||||
Internals::JsonVariantData *data)
|
Internals::JsonVariantData *data)
|
||||||
: _buffer(buffer), _data(data) {}
|
: _memoryPool(memoryPool), _data(data) {}
|
||||||
|
|
||||||
// Creates an uninitialized JsonVariant
|
// Creates an uninitialized JsonVariant
|
||||||
FORCE_INLINE JsonVariant() : _buffer(0), _data(0) {}
|
FORCE_INLINE JsonVariant() : _memoryPool(0), _data(0) {}
|
||||||
|
|
||||||
// set(bool value)
|
// set(bool value)
|
||||||
FORCE_INLINE bool set(bool value) {
|
FORCE_INLINE bool set(bool value) {
|
||||||
@ -106,7 +106,7 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
|||||||
!Internals::is_same<const char *, T>::value>::type * = 0) {
|
!Internals::is_same<const char *, T>::value>::type * = 0) {
|
||||||
if (!_data) return false;
|
if (!_data) return false;
|
||||||
const char *dup =
|
const char *dup =
|
||||||
Internals::makeString(value.data(), value.size()).save(_buffer);
|
Internals::makeString(value.data(), value.size()).save(_memoryPool);
|
||||||
if (dup)
|
if (dup)
|
||||||
_data->setRaw(dup, value.size());
|
_data->setRaw(dup, value.size());
|
||||||
else
|
else
|
||||||
@ -122,7 +122,7 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
|||||||
typename Internals::enable_if<Internals::IsString<T>::value>::type * =
|
typename Internals::enable_if<Internals::IsString<T>::value>::type * =
|
||||||
0) {
|
0) {
|
||||||
if (!_data) return false;
|
if (!_data) return false;
|
||||||
const char *dup = Internals::makeString(value).save(_buffer);
|
const char *dup = Internals::makeString(value).save(_memoryPool);
|
||||||
if (dup) {
|
if (dup) {
|
||||||
_data->setString(dup);
|
_data->setString(dup);
|
||||||
return true;
|
return true;
|
||||||
@ -139,7 +139,7 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
|||||||
typename Internals::enable_if<Internals::IsString<T *>::value>::type * =
|
typename Internals::enable_if<Internals::IsString<T *>::value>::type * =
|
||||||
0) {
|
0) {
|
||||||
if (!_data) return false;
|
if (!_data) return false;
|
||||||
const char *dup = Internals::makeString(value).save(_buffer);
|
const char *dup = Internals::makeString(value).save(_memoryPool);
|
||||||
if (dup) {
|
if (dup) {
|
||||||
_data->setString(dup);
|
_data->setString(dup);
|
||||||
return true;
|
return true;
|
||||||
@ -341,7 +341,7 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Internals::JsonBuffer *_buffer;
|
Internals::MemoryPool *_memoryPool;
|
||||||
Internals::JsonVariantData *_data;
|
Internals::JsonVariantData *_data;
|
||||||
}; // namespace ArduinoJson
|
}; // namespace ArduinoJson
|
||||||
} // namespace ArduinoJson
|
} // namespace ArduinoJson
|
||||||
|
@ -49,7 +49,7 @@ inline typename Internals::enable_if<
|
|||||||
JsonArray>::value,
|
JsonArray>::value,
|
||||||
JsonArray>::type
|
JsonArray>::type
|
||||||
JsonVariant::as() const {
|
JsonVariant::as() const {
|
||||||
return _data ? JsonArray(_buffer, _data->asArray()) : JsonArray();
|
return _data ? JsonArray(_memoryPool, _data->asArray()) : JsonArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -58,6 +58,6 @@ inline typename Internals::enable_if<
|
|||||||
JsonObject>::value,
|
JsonObject>::value,
|
||||||
T>::type
|
T>::type
|
||||||
JsonVariant::as() const {
|
JsonVariant::as() const {
|
||||||
return _data ? JsonObject(_buffer, _data->asObject()) : JsonObject();
|
return _data ? JsonObject(_memoryPool, _data->asObject()) : JsonObject();
|
||||||
}
|
}
|
||||||
} // namespace ArduinoJson
|
} // namespace ArduinoJson
|
||||||
|
22
src/ArduinoJson/Memory/AllocableInMemoryPool.hpp
Normal file
22
src/ArduinoJson/Memory/AllocableInMemoryPool.hpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "MemoryPool.hpp"
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
|
||||||
|
class AllocableInMemoryPool {
|
||||||
|
public:
|
||||||
|
void *operator new(size_t n, MemoryPool *memoryPool) NOEXCEPT {
|
||||||
|
if (!memoryPool) return NULL;
|
||||||
|
return memoryPool->alloc(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void *, MemoryPool *)NOEXCEPT {}
|
||||||
|
};
|
||||||
|
} // namespace Internals
|
||||||
|
} // namespace ArduinoJson
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "JsonBuffer.hpp"
|
#include "MemoryPool.hpp"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ class DefaultAllocator {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename TAllocator>
|
template <typename TAllocator>
|
||||||
class DynamicJsonBufferBase : public JsonBuffer {
|
class DynamicMemoryPoolBase : public MemoryPool {
|
||||||
struct Block;
|
struct Block;
|
||||||
struct EmptyBlock {
|
struct EmptyBlock {
|
||||||
Block* next;
|
Block* next;
|
||||||
@ -45,27 +45,27 @@ class DynamicJsonBufferBase : public JsonBuffer {
|
|||||||
public:
|
public:
|
||||||
enum { EmptyBlockSize = sizeof(EmptyBlock) };
|
enum { EmptyBlockSize = sizeof(EmptyBlock) };
|
||||||
|
|
||||||
DynamicJsonBufferBase(size_t initialSize = 256)
|
DynamicMemoryPoolBase(size_t initialSize = 256)
|
||||||
: _head(NULL), _nextBlockCapacity(initialSize) {}
|
: _head(NULL), _nextBlockCapacity(initialSize) {}
|
||||||
|
|
||||||
~DynamicJsonBufferBase() {
|
~DynamicMemoryPoolBase() {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the number of bytes occupied in the buffer
|
// Gets the number of bytes occupied in the memoryPool
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
for (const Block* b = _head; b; b = b->next) total += b->size;
|
for (const Block* b = _head; b; b = b->next) total += b->size;
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocates the specified amount of bytes in the buffer
|
// Allocates the specified amount of bytes in the memoryPool
|
||||||
virtual void* alloc(size_t bytes) {
|
virtual void* alloc(size_t bytes) {
|
||||||
alignNextAlloc();
|
alignNextAlloc();
|
||||||
return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes);
|
return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resets the buffer.
|
// Resets the memoryPool.
|
||||||
// USE WITH CAUTION: this invalidates all previously allocated data
|
// USE WITH CAUTION: this invalidates all previously allocated data
|
||||||
void clear() {
|
void clear() {
|
||||||
Block* currentBlock = _head;
|
Block* currentBlock = _head;
|
||||||
@ -80,7 +80,7 @@ class DynamicJsonBufferBase : public JsonBuffer {
|
|||||||
|
|
||||||
class String {
|
class String {
|
||||||
public:
|
public:
|
||||||
String(DynamicJsonBufferBase* parent)
|
String(DynamicMemoryPoolBase* parent)
|
||||||
: _parent(parent), _start(NULL), _length(0) {}
|
: _parent(parent), _start(NULL), _length(0) {}
|
||||||
|
|
||||||
void append(char c) {
|
void append(char c) {
|
||||||
@ -104,7 +104,7 @@ class DynamicJsonBufferBase : public JsonBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DynamicJsonBufferBase* _parent;
|
DynamicMemoryPoolBase* _parent;
|
||||||
char* _start;
|
char* _start;
|
||||||
size_t _length;
|
size_t _length;
|
||||||
};
|
};
|
||||||
@ -152,11 +152,11 @@ class DynamicJsonBufferBase : public JsonBuffer {
|
|||||||
size_t _nextBlockCapacity;
|
size_t _nextBlockCapacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implements a JsonBuffer with dynamic memory allocation.
|
// Implements a MemoryPool with dynamic memory allocation.
|
||||||
// You are strongly encouraged to consider using StaticJsonBuffer which is much
|
// You are strongly encouraged to consider using StaticMemoryPool which is much
|
||||||
// more suitable for embedded systems.
|
// more suitable for embedded systems.
|
||||||
typedef Internals::DynamicJsonBufferBase<Internals::DefaultAllocator>
|
typedef Internals::DynamicMemoryPoolBase<Internals::DefaultAllocator>
|
||||||
DynamicJsonBuffer;
|
DynamicMemoryPool;
|
||||||
} // namespace Internals
|
} // namespace Internals
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
@ -1,22 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2018
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "JsonBuffer.hpp"
|
|
||||||
|
|
||||||
namespace ArduinoJson {
|
|
||||||
namespace Internals {
|
|
||||||
|
|
||||||
class JsonBufferAllocated {
|
|
||||||
public:
|
|
||||||
void *operator new(size_t n, JsonBuffer *jsonBuffer) NOEXCEPT {
|
|
||||||
if (!jsonBuffer) return NULL;
|
|
||||||
return jsonBuffer->alloc(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator delete(void *, JsonBuffer *)NOEXCEPT {}
|
|
||||||
};
|
|
||||||
} // namespace Internals
|
|
||||||
} // namespace ArduinoJson
|
|
@ -14,11 +14,11 @@
|
|||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
// Handle the memory management (done in derived classes) and calls the parser.
|
// Handle the memory management (done in derived classes) and calls the parser.
|
||||||
// This abstract class is implemented by StaticJsonBuffer which implements a
|
// This abstract class is implemented by StaticMemoryPool which implements a
|
||||||
// fixed memory allocation.
|
// fixed memory allocation.
|
||||||
class JsonBuffer {
|
class MemoryPool {
|
||||||
public:
|
public:
|
||||||
// Allocates n bytes in the JsonBuffer.
|
// Allocates n bytes in the MemoryPool.
|
||||||
// Return a pointer to the allocated memory or NULL if allocation fails.
|
// Return a pointer to the allocated memory or NULL if allocation fails.
|
||||||
virtual void *alloc(size_t size) = 0;
|
virtual void *alloc(size_t size) = 0;
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ class JsonBuffer {
|
|||||||
// CAUTION: NO VIRTUAL DESTRUCTOR!
|
// CAUTION: NO VIRTUAL DESTRUCTOR!
|
||||||
// If we add a virtual constructor the Arduino compiler will add malloc()
|
// If we add a virtual constructor the Arduino compiler will add malloc()
|
||||||
// and free() to the binary, adding 706 useless bytes.
|
// and free() to the binary, adding 706 useless bytes.
|
||||||
~JsonBuffer() {}
|
~MemoryPool() {}
|
||||||
|
|
||||||
// Preserve aligment if necessary
|
// Preserve aligment if necessary
|
||||||
static FORCE_INLINE size_t round_size_up(size_t bytes) {
|
static FORCE_INLINE size_t round_size_up(size_t bytes) {
|
@ -5,16 +5,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../Polyfills/mpl/max.hpp"
|
#include "../Polyfills/mpl/max.hpp"
|
||||||
#include "JsonBuffer.hpp"
|
#include "MemoryPool.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
|
|
||||||
class StaticJsonBufferBase : public JsonBuffer {
|
class StaticMemoryPoolBase : public MemoryPool {
|
||||||
public:
|
public:
|
||||||
class String {
|
class String {
|
||||||
public:
|
public:
|
||||||
String(StaticJsonBufferBase* parent) : _parent(parent) {
|
String(StaticMemoryPoolBase* parent) : _parent(parent) {
|
||||||
_start = parent->_buffer + parent->_size;
|
_start = parent->_buffer + parent->_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,31 +36,31 @@ class StaticJsonBufferBase : public JsonBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StaticJsonBufferBase* _parent;
|
StaticMemoryPoolBase* _parent;
|
||||||
char* _start;
|
char* _start;
|
||||||
};
|
};
|
||||||
|
|
||||||
StaticJsonBufferBase(char* buffer, size_t capa)
|
StaticMemoryPoolBase(char* memoryPool, size_t capa)
|
||||||
: _buffer(buffer), _capacity(capa), _size(0) {}
|
: _buffer(memoryPool), _capacity(capa), _size(0) {}
|
||||||
|
|
||||||
// Gets the capacity of the buffer in bytes
|
// Gets the capacity of the memoryPool in bytes
|
||||||
size_t capacity() const {
|
size_t capacity() const {
|
||||||
return _capacity;
|
return _capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the current usage of the buffer in bytes
|
// Gets the current usage of the memoryPool in bytes
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocates the specified amount of bytes in the buffer
|
// Allocates the specified amount of bytes in the memoryPool
|
||||||
virtual void* alloc(size_t bytes) {
|
virtual void* alloc(size_t bytes) {
|
||||||
alignNextAlloc();
|
alignNextAlloc();
|
||||||
if (!canAlloc(bytes)) return NULL;
|
if (!canAlloc(bytes)) return NULL;
|
||||||
return doAlloc(bytes);
|
return doAlloc(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resets the buffer.
|
// Resets the memoryPool.
|
||||||
// USE WITH CAUTION: this invalidates all previously allocated data
|
// USE WITH CAUTION: this invalidates all previously allocated data
|
||||||
void clear() {
|
void clear() {
|
||||||
_size = 0;
|
_size = 0;
|
||||||
@ -71,7 +71,7 @@ class StaticJsonBufferBase : public JsonBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~StaticJsonBufferBase() {}
|
~StaticMemoryPoolBase() {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void alignNextAlloc() {
|
void alignNextAlloc() {
|
||||||
@ -103,16 +103,16 @@ class StaticJsonBufferBase : public JsonBuffer {
|
|||||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Implements a JsonBuffer with fixed memory allocation.
|
// Implements a MemoryPool with fixed memory allocation.
|
||||||
// The template paramenter CAPACITY specifies the capacity of the buffer in
|
// The template paramenter CAPACITY specifies the capacity of the memoryPool in
|
||||||
// bytes.
|
// bytes.
|
||||||
template <size_t CAPACITY>
|
template <size_t CAPACITY>
|
||||||
class StaticJsonBuffer : public Internals::StaticJsonBufferBase {
|
class StaticMemoryPool : public Internals::StaticMemoryPoolBase {
|
||||||
static const size_t ACTUAL_CAPACITY = Internals::Max<1, CAPACITY>::value;
|
static const size_t ACTUAL_CAPACITY = Internals::Max<1, CAPACITY>::value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit StaticJsonBuffer()
|
explicit StaticMemoryPool()
|
||||||
: Internals::StaticJsonBufferBase(_buffer, ACTUAL_CAPACITY) {}
|
: Internals::StaticMemoryPoolBase(_buffer, ACTUAL_CAPACITY) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char _buffer[ACTUAL_CAPACITY];
|
char _buffer[ACTUAL_CAPACITY];
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "../Deserialization/deserialize.hpp"
|
#include "../Deserialization/deserialize.hpp"
|
||||||
#include "../JsonVariant.hpp"
|
#include "../JsonVariant.hpp"
|
||||||
#include "../Memory/JsonBuffer.hpp"
|
#include "../Memory/MemoryPool.hpp"
|
||||||
#include "../Polyfills/type_traits.hpp"
|
#include "../Polyfills/type_traits.hpp"
|
||||||
#include "./endianess.hpp"
|
#include "./endianess.hpp"
|
||||||
#include "./ieee754.hpp"
|
#include "./ieee754.hpp"
|
||||||
@ -17,9 +17,9 @@ namespace Internals {
|
|||||||
template <typename TReader, typename TStringStorage>
|
template <typename TReader, typename TStringStorage>
|
||||||
class MsgPackDeserializer {
|
class MsgPackDeserializer {
|
||||||
public:
|
public:
|
||||||
MsgPackDeserializer(JsonBuffer *buffer, TReader reader,
|
MsgPackDeserializer(MemoryPool &memoryPool, TReader reader,
|
||||||
TStringStorage stringStorage, uint8_t nestingLimit)
|
TStringStorage stringStorage, uint8_t nestingLimit)
|
||||||
: _buffer(buffer),
|
: _memoryPool(&memoryPool),
|
||||||
_reader(reader),
|
_reader(reader),
|
||||||
_stringStorage(stringStorage),
|
_stringStorage(stringStorage),
|
||||||
_nestingLimit(nestingLimit) {}
|
_nestingLimit(nestingLimit) {}
|
||||||
@ -240,7 +240,7 @@ class MsgPackDeserializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DeserializationError readArray(JsonVariantData &variant, size_t n) {
|
DeserializationError readArray(JsonVariantData &variant, size_t n) {
|
||||||
JsonArrayData *array = new (_buffer) JsonArrayData;
|
JsonArrayData *array = new (_memoryPool) JsonArrayData;
|
||||||
if (!array) return DeserializationError::NoMemory;
|
if (!array) return DeserializationError::NoMemory;
|
||||||
|
|
||||||
variant.setArray(*array);
|
variant.setArray(*array);
|
||||||
@ -251,7 +251,7 @@ class MsgPackDeserializer {
|
|||||||
if (_nestingLimit == 0) return DeserializationError::TooDeep;
|
if (_nestingLimit == 0) return DeserializationError::TooDeep;
|
||||||
--_nestingLimit;
|
--_nestingLimit;
|
||||||
for (; n; --n) {
|
for (; n; --n) {
|
||||||
JsonVariantData *value = array.addSlot(_buffer);
|
JsonVariantData *value = array.addSlot(_memoryPool);
|
||||||
if (!value) return DeserializationError::NoMemory;
|
if (!value) return DeserializationError::NoMemory;
|
||||||
|
|
||||||
DeserializationError err = parse(*value);
|
DeserializationError err = parse(*value);
|
||||||
@ -269,7 +269,7 @@ class MsgPackDeserializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DeserializationError readObject(JsonVariantData &variant, size_t n) {
|
DeserializationError readObject(JsonVariantData &variant, size_t n) {
|
||||||
JsonObjectData *object = new (_buffer) JsonObjectData;
|
JsonObjectData *object = new (_memoryPool) JsonObjectData;
|
||||||
if (!object) return DeserializationError::NoMemory;
|
if (!object) return DeserializationError::NoMemory;
|
||||||
variant.setObject(*object);
|
variant.setObject(*object);
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ class MsgPackDeserializer {
|
|||||||
if (err) return err;
|
if (err) return err;
|
||||||
if (!key.isString()) return DeserializationError::NotSupported;
|
if (!key.isString()) return DeserializationError::NotSupported;
|
||||||
|
|
||||||
JsonVariantData *value = object.addSlot(_buffer, key.asString());
|
JsonVariantData *value = object.addSlot(_memoryPool, key.asString());
|
||||||
if (!value) return DeserializationError::NoMemory;
|
if (!value) return DeserializationError::NoMemory;
|
||||||
|
|
||||||
err = parse(*value);
|
err = parse(*value);
|
||||||
@ -295,7 +295,7 @@ class MsgPackDeserializer {
|
|||||||
return DeserializationError::Ok;
|
return DeserializationError::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonBuffer *_buffer;
|
MemoryPool *_memoryPool;
|
||||||
TReader _reader;
|
TReader _reader;
|
||||||
TStringStorage _stringStorage;
|
TStringStorage _stringStorage;
|
||||||
uint8_t _nestingLimit;
|
uint8_t _nestingLimit;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "JsonVariant.hpp"
|
#include "JsonVariant.hpp"
|
||||||
#include "Memory/StaticJsonBuffer.hpp"
|
#include "Memory/StaticMemoryPool.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
|
|
||||||
@ -16,8 +16,8 @@ class StaticJsonDocument {
|
|||||||
|
|
||||||
StaticJsonDocument() : nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {}
|
StaticJsonDocument() : nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {}
|
||||||
|
|
||||||
Internals::StaticJsonBufferBase& buffer() {
|
Internals::StaticMemoryPoolBase& memoryPool() {
|
||||||
return _buffer;
|
return _memoryPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -36,7 +36,7 @@ class StaticJsonDocument {
|
|||||||
JsonObject>::type
|
JsonObject>::type
|
||||||
to() {
|
to() {
|
||||||
clear();
|
clear();
|
||||||
JsonObject object(&_buffer);
|
JsonObject object(&_memoryPool);
|
||||||
getVariant().set(object);
|
getVariant().set(object);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
@ -47,7 +47,7 @@ class StaticJsonDocument {
|
|||||||
JsonArray>::type
|
JsonArray>::type
|
||||||
to() {
|
to() {
|
||||||
clear();
|
clear();
|
||||||
JsonArray array(&_buffer);
|
JsonArray array(&_memoryPool);
|
||||||
getVariant().set(array);
|
getVariant().set(array);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
@ -72,12 +72,12 @@ class StaticJsonDocument {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
_buffer.clear();
|
_memoryPool.clear();
|
||||||
_rootData.setNull();
|
_rootData.setNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t memoryUsage() const {
|
size_t memoryUsage() const {
|
||||||
return _buffer.size();
|
return _memoryPool.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename Visitor>
|
||||||
@ -87,10 +87,10 @@ class StaticJsonDocument {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
JsonVariant getVariant() const {
|
JsonVariant getVariant() const {
|
||||||
return JsonVariant(&_buffer, &_rootData);
|
return JsonVariant(&_memoryPool, &_rootData);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutable Internals::StaticJsonBuffer<CAPACITY> _buffer;
|
mutable Internals::StaticMemoryPool<CAPACITY> _memoryPool;
|
||||||
mutable Internals::JsonVariantData _rootData;
|
mutable Internals::JsonVariantData _rootData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,19 +7,19 @@
|
|||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
|
|
||||||
template <typename TJsonBuffer>
|
template <typename TMemoryPool>
|
||||||
class StringCopier {
|
class StringCopier {
|
||||||
public:
|
public:
|
||||||
StringCopier(TJsonBuffer& jb) : _jb(&jb) {}
|
StringCopier(TMemoryPool& memoryPool) : _memoryPool(&memoryPool) {}
|
||||||
|
|
||||||
typedef typename TJsonBuffer::String String;
|
typedef typename TMemoryPool::String String;
|
||||||
|
|
||||||
String startString() {
|
String startString() {
|
||||||
return _jb->startString();
|
return _memoryPool->startString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TJsonBuffer* _jb;
|
TMemoryPool* _memoryPool;
|
||||||
};
|
};
|
||||||
} // namespace Internals
|
} // namespace Internals
|
||||||
} // namespace ArduinoJson
|
} // namespace ArduinoJson
|
||||||
|
@ -28,7 +28,7 @@ class StringMover {
|
|||||||
TChar* _startPtr;
|
TChar* _startPtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
StringMover(TChar* buffer) : _ptr(buffer) {}
|
StringMover(TChar* ptr) : _ptr(ptr) {}
|
||||||
|
|
||||||
String startString() {
|
String startString() {
|
||||||
return String(&_ptr);
|
return String(&_ptr);
|
||||||
|
@ -10,35 +10,35 @@
|
|||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
|
|
||||||
template <typename TJsonBuffer, typename TInput, typename Enable = void>
|
template <typename TMemoryPool, typename TInput, typename Enable = void>
|
||||||
struct StringStorage {
|
struct StringStorage {
|
||||||
typedef StringCopier<TJsonBuffer> type;
|
typedef StringCopier<TMemoryPool> type;
|
||||||
|
|
||||||
static type create(TJsonBuffer& jb, TInput&) {
|
static type create(TMemoryPool& jb, TInput&) {
|
||||||
return type(jb);
|
return type(jb);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TJsonBuffer, typename TChar>
|
template <typename TMemoryPool, typename TChar>
|
||||||
struct StringStorage<TJsonBuffer, TChar*,
|
struct StringStorage<TMemoryPool, TChar*,
|
||||||
typename enable_if<!is_const<TChar>::value>::type> {
|
typename enable_if<!is_const<TChar>::value>::type> {
|
||||||
typedef StringMover<TChar> type;
|
typedef StringMover<TChar> type;
|
||||||
|
|
||||||
static type create(TJsonBuffer&, TChar* input) {
|
static type create(TMemoryPool&, TChar* input) {
|
||||||
return type(input);
|
return type(input);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TJsonBuffer, typename TInput>
|
template <typename TMemoryPool, typename TInput>
|
||||||
typename StringStorage<TJsonBuffer, TInput>::type makeStringStorage(
|
typename StringStorage<TMemoryPool, TInput>::type makeStringStorage(
|
||||||
TJsonBuffer& jb, TInput& input) {
|
TMemoryPool& jb, TInput& input) {
|
||||||
return StringStorage<TJsonBuffer, TInput>::create(jb, input);
|
return StringStorage<TMemoryPool, TInput>::create(jb, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TJsonBuffer, typename TChar>
|
template <typename TMemoryPool, typename TChar>
|
||||||
typename StringStorage<TJsonBuffer, TChar*>::type makeStringStorage(
|
typename StringStorage<TMemoryPool, TChar*>::type makeStringStorage(
|
||||||
TJsonBuffer& jb, TChar* input) {
|
TMemoryPool& jb, TChar* input) {
|
||||||
return StringStorage<TJsonBuffer, TChar*>::create(jb, input);
|
return StringStorage<TMemoryPool, TChar*>::create(jb, input);
|
||||||
}
|
}
|
||||||
} // namespace Internals
|
} // namespace Internals
|
||||||
} // namespace ArduinoJson
|
} // namespace ArduinoJson
|
||||||
|
@ -14,10 +14,10 @@ class ArduinoString {
|
|||||||
ArduinoString(const ::String& str) : _str(&str) {}
|
ArduinoString(const ::String& str) : _str(&str) {}
|
||||||
|
|
||||||
template <typename Buffer>
|
template <typename Buffer>
|
||||||
const char* save(Buffer* buffer) const {
|
const char* save(Buffer* memoryPool) const {
|
||||||
if (is_null()) return NULL;
|
if (is_null()) return NULL;
|
||||||
size_t n = _str->length() + 1;
|
size_t n = _str->length() + 1;
|
||||||
void* dup = buffer->alloc(n);
|
void* dup = memoryPool->alloc(n);
|
||||||
if (dup != NULL) memcpy(dup, _str->c_str(), n);
|
if (dup != NULL) memcpy(dup, _str->c_str(), n);
|
||||||
return static_cast<const char*>(dup);
|
return static_cast<const char*>(dup);
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,9 @@ class FixedSizeFlashString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Buffer>
|
template <typename Buffer>
|
||||||
const char* save(Buffer* buffer) const {
|
const char* save(Buffer* memoryPool) const {
|
||||||
if (!_str) return NULL;
|
if (!_str) return NULL;
|
||||||
void* dup = buffer->alloc(_size);
|
void* dup = memoryPool->alloc(_size);
|
||||||
if (dup != NULL) memcpy_P(dup, (const char*)_str, _size);
|
if (dup != NULL) memcpy_P(dup, (const char*)_str, _size);
|
||||||
return static_cast<const char*>(dup);
|
return static_cast<const char*>(dup);
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,9 @@ class FixedSizeRamString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Buffer>
|
template <typename Buffer>
|
||||||
const char* save(Buffer* buffer) const {
|
const char* save(Buffer* memoryPool) const {
|
||||||
if (!_str) return NULL;
|
if (!_str) return NULL;
|
||||||
void* dup = buffer->alloc(_size);
|
void* dup = memoryPool->alloc(_size);
|
||||||
if (!dup) return NULL;
|
if (!dup) return NULL;
|
||||||
memcpy(dup, _str, _size);
|
memcpy(dup, _str, _size);
|
||||||
return static_cast<const char*>(dup);
|
return static_cast<const char*>(dup);
|
||||||
|
@ -14,9 +14,9 @@ class StlString {
|
|||||||
StlString(const std::string& str) : _str(&str) {}
|
StlString(const std::string& str) : _str(&str) {}
|
||||||
|
|
||||||
template <typename Buffer>
|
template <typename Buffer>
|
||||||
const char* save(Buffer* buffer) const {
|
const char* save(Buffer* memoryPool) const {
|
||||||
size_t n = _str->length() + 1;
|
size_t n = _str->length() + 1;
|
||||||
void* dup = buffer->alloc(n);
|
void* dup = memoryPool->alloc(n);
|
||||||
if (dup != NULL) memcpy(dup, _str->c_str(), n);
|
if (dup != NULL) memcpy(dup, _str->c_str(), n);
|
||||||
return static_cast<const char*>(dup);
|
return static_cast<const char*>(dup);
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,10 @@ class ZeroTerminatedFlashString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Buffer>
|
template <typename Buffer>
|
||||||
const char* save(Buffer* buffer) const {
|
const char* save(Buffer* memoryPool) const {
|
||||||
if (!_str) return NULL;
|
if (!_str) return NULL;
|
||||||
size_t n = size() + 1; // copy the terminator
|
size_t n = size() + 1; // copy the terminator
|
||||||
void* dup = buffer->alloc(n);
|
void* dup = memoryPool->alloc(n);
|
||||||
if (dup != NULL) memcpy_P(dup, (const char*)_str, n);
|
if (dup != NULL) memcpy_P(dup, (const char*)_str, n);
|
||||||
return static_cast<const char*>(dup);
|
return static_cast<const char*>(dup);
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,10 @@ class ZeroTerminatedRamString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Buffer>
|
template <typename Buffer>
|
||||||
const char* save(Buffer* buffer) const {
|
const char* save(Buffer* memoryPool) const {
|
||||||
if (!_str) return NULL;
|
if (!_str) return NULL;
|
||||||
size_t n = size() + 1;
|
size_t n = size() + 1;
|
||||||
void* dup = buffer->alloc(n);
|
void* dup = memoryPool->alloc(n);
|
||||||
if (!dup) return NULL;
|
if (!dup) return NULL;
|
||||||
memcpy(dup, _str, n);
|
memcpy(dup, _str, n);
|
||||||
return static_cast<const char*>(dup);
|
return static_cast<const char*>(dup);
|
||||||
|
@ -71,7 +71,7 @@ if(MSVC)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(DynamicJsonBuffer)
|
add_subdirectory(DynamicMemoryPool)
|
||||||
add_subdirectory(IntegrationTests)
|
add_subdirectory(IntegrationTests)
|
||||||
add_subdirectory(JsonArray)
|
add_subdirectory(JsonArray)
|
||||||
add_subdirectory(JsonDeserializer)
|
add_subdirectory(JsonDeserializer)
|
||||||
@ -84,4 +84,4 @@ add_subdirectory(Misc)
|
|||||||
add_subdirectory(MsgPackDeserializer)
|
add_subdirectory(MsgPackDeserializer)
|
||||||
add_subdirectory(MsgPackSerializer)
|
add_subdirectory(MsgPackSerializer)
|
||||||
add_subdirectory(Numbers)
|
add_subdirectory(Numbers)
|
||||||
add_subdirectory(StaticJsonBuffer)
|
add_subdirectory(StaticMemoryPool)
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
# ArduinoJson - arduinojson.org
|
|
||||||
# Copyright Benoit Blanchon 2014-2018
|
|
||||||
# MIT License
|
|
||||||
|
|
||||||
add_executable(DynamicJsonBufferTests
|
|
||||||
alloc.cpp
|
|
||||||
no_memory.cpp
|
|
||||||
size.cpp
|
|
||||||
startString.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(DynamicJsonBufferTests catch)
|
|
||||||
add_test(DynamicJsonBuffer DynamicJsonBufferTests)
|
|
@ -1,29 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2018
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#include <ArduinoJson/Memory/DynamicJsonBuffer.hpp>
|
|
||||||
#include <catch.hpp>
|
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
|
||||||
|
|
||||||
TEST_CASE("DynamicJsonBuffer::size()") {
|
|
||||||
DynamicJsonBuffer buffer;
|
|
||||||
|
|
||||||
SECTION("Initial size is 0") {
|
|
||||||
REQUIRE(0 == buffer.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Increases after alloc()") {
|
|
||||||
buffer.alloc(1);
|
|
||||||
REQUIRE(1U <= buffer.size());
|
|
||||||
buffer.alloc(1);
|
|
||||||
REQUIRE(2U <= buffer.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Goes back to 0 after clear()") {
|
|
||||||
buffer.alloc(1);
|
|
||||||
buffer.clear();
|
|
||||||
REQUIRE(0 == buffer.size());
|
|
||||||
}
|
|
||||||
}
|
|
13
test/DynamicMemoryPool/CMakeLists.txt
Normal file
13
test/DynamicMemoryPool/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# ArduinoJson - arduinojson.org
|
||||||
|
# Copyright Benoit Blanchon 2014-2018
|
||||||
|
# MIT License
|
||||||
|
|
||||||
|
add_executable(DynamicMemoryPoolTests
|
||||||
|
alloc.cpp
|
||||||
|
no_memory.cpp
|
||||||
|
size.cpp
|
||||||
|
startString.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(DynamicMemoryPoolTests catch)
|
||||||
|
add_test(DynamicMemoryPool DynamicMemoryPoolTests)
|
@ -18,7 +18,7 @@ std::stringstream allocatorLog;
|
|||||||
|
|
||||||
struct SpyingAllocator : DefaultAllocator {
|
struct SpyingAllocator : DefaultAllocator {
|
||||||
void* allocate(size_t n) {
|
void* allocate(size_t n) {
|
||||||
allocatorLog << "A" << (n - DynamicJsonBuffer::EmptyBlockSize);
|
allocatorLog << "A" << (n - DynamicMemoryPool::EmptyBlockSize);
|
||||||
return DefaultAllocator::allocate(n);
|
return DefaultAllocator::allocate(n);
|
||||||
}
|
}
|
||||||
void deallocate(void* p) {
|
void deallocate(void* p) {
|
||||||
@ -27,20 +27,20 @@ struct SpyingAllocator : DefaultAllocator {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CASE("DynamicJsonBuffer::alloc()") {
|
TEST_CASE("DynamicMemoryPool::alloc()") {
|
||||||
SECTION("Returns different pointers") {
|
SECTION("Returns different pointers") {
|
||||||
DynamicJsonBuffer buffer;
|
DynamicMemoryPool memoryPool;
|
||||||
void* p1 = buffer.alloc(1);
|
void* p1 = memoryPool.alloc(1);
|
||||||
void* p2 = buffer.alloc(2);
|
void* p2 = memoryPool.alloc(2);
|
||||||
REQUIRE(p1 != p2);
|
REQUIRE(p1 != p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Doubles allocation size when full") {
|
SECTION("Doubles allocation size when full") {
|
||||||
allocatorLog.str("");
|
allocatorLog.str("");
|
||||||
{
|
{
|
||||||
DynamicJsonBufferBase<SpyingAllocator> buffer(1);
|
DynamicMemoryPoolBase<SpyingAllocator> memoryPool(1);
|
||||||
buffer.alloc(1);
|
memoryPool.alloc(1);
|
||||||
buffer.alloc(1);
|
memoryPool.alloc(1);
|
||||||
}
|
}
|
||||||
REQUIRE(allocatorLog.str() == "A1A2FF");
|
REQUIRE(allocatorLog.str() == "A1A2FF");
|
||||||
}
|
}
|
||||||
@ -48,11 +48,11 @@ TEST_CASE("DynamicJsonBuffer::alloc()") {
|
|||||||
SECTION("Resets allocation size after clear()") {
|
SECTION("Resets allocation size after clear()") {
|
||||||
allocatorLog.str("");
|
allocatorLog.str("");
|
||||||
{
|
{
|
||||||
DynamicJsonBufferBase<SpyingAllocator> buffer(1);
|
DynamicMemoryPoolBase<SpyingAllocator> memoryPool(1);
|
||||||
buffer.alloc(1);
|
memoryPool.alloc(1);
|
||||||
buffer.alloc(1);
|
memoryPool.alloc(1);
|
||||||
buffer.clear();
|
memoryPool.clear();
|
||||||
buffer.alloc(1);
|
memoryPool.alloc(1);
|
||||||
}
|
}
|
||||||
REQUIRE(allocatorLog.str() == "A1A2FFA1F");
|
REQUIRE(allocatorLog.str() == "A1A2FFA1F");
|
||||||
}
|
}
|
||||||
@ -60,15 +60,15 @@ TEST_CASE("DynamicJsonBuffer::alloc()") {
|
|||||||
SECTION("Makes a big allocation when needed") {
|
SECTION("Makes a big allocation when needed") {
|
||||||
allocatorLog.str("");
|
allocatorLog.str("");
|
||||||
{
|
{
|
||||||
DynamicJsonBufferBase<SpyingAllocator> buffer(1);
|
DynamicMemoryPoolBase<SpyingAllocator> memoryPool(1);
|
||||||
buffer.alloc(42);
|
memoryPool.alloc(42);
|
||||||
}
|
}
|
||||||
REQUIRE(allocatorLog.str() == "A42F");
|
REQUIRE(allocatorLog.str() == "A42F");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Alignment") {
|
SECTION("Alignment") {
|
||||||
// make room for two but not three
|
// make room for two but not three
|
||||||
DynamicJsonBuffer tinyBuf(2 * sizeof(void*) + 1);
|
DynamicMemoryPool tinyBuf(2 * sizeof(void*) + 1);
|
||||||
|
|
||||||
REQUIRE(isAligned(tinyBuf.alloc(1))); // this on is aligned by design
|
REQUIRE(isAligned(tinyBuf.alloc(1))); // this on is aligned by design
|
||||||
REQUIRE(isAligned(tinyBuf.alloc(1))); // this one fits in the first block
|
REQUIRE(isAligned(tinyBuf.alloc(1))); // this one fits in the first block
|
@ -14,8 +14,8 @@ struct NoMemoryAllocator {
|
|||||||
void deallocate(void*) {}
|
void deallocate(void*) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CASE("DynamicJsonBuffer no memory") {
|
TEST_CASE("DynamicMemoryPool no memory") {
|
||||||
DynamicJsonBufferBase<NoMemoryAllocator> _jsonBuffer;
|
DynamicMemoryPoolBase<NoMemoryAllocator> _memoryPool;
|
||||||
|
|
||||||
SECTION("FixCodeCoverage") {
|
SECTION("FixCodeCoverage") {
|
||||||
// call this function to fix code coverage
|
// call this function to fix code coverage
|
||||||
@ -33,8 +33,8 @@ TEST_CASE("DynamicJsonBuffer no memory") {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
SECTION("startString()") {
|
SECTION("startString()") {
|
||||||
DynamicJsonBufferBase<NoMemoryAllocator>::String str =
|
DynamicMemoryPoolBase<NoMemoryAllocator>::String str =
|
||||||
_jsonBuffer.startString();
|
_memoryPool.startString();
|
||||||
str.append('!');
|
str.append('!');
|
||||||
REQUIRE(0 == str.c_str());
|
REQUIRE(0 == str.c_str());
|
||||||
}
|
}
|
29
test/DynamicMemoryPool/size.cpp
Normal file
29
test/DynamicMemoryPool/size.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson/Memory/DynamicMemoryPool.hpp>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
|
TEST_CASE("DynamicMemoryPool::size()") {
|
||||||
|
DynamicMemoryPool memoryPool;
|
||||||
|
|
||||||
|
SECTION("Initial size is 0") {
|
||||||
|
REQUIRE(0 == memoryPool.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Increases after alloc()") {
|
||||||
|
memoryPool.alloc(1);
|
||||||
|
REQUIRE(1U <= memoryPool.size());
|
||||||
|
memoryPool.alloc(1);
|
||||||
|
REQUIRE(2U <= memoryPool.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Goes back to 0 after clear()") {
|
||||||
|
memoryPool.alloc(1);
|
||||||
|
memoryPool.clear();
|
||||||
|
REQUIRE(0 == memoryPool.size());
|
||||||
|
}
|
||||||
|
}
|
@ -2,16 +2,16 @@
|
|||||||
// Copyright Benoit Blanchon 2014-2018
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#include <ArduinoJson/Memory/DynamicJsonBuffer.hpp>
|
#include <ArduinoJson/Memory/DynamicMemoryPool.hpp>
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
TEST_CASE("DynamicJsonBuffer::startString()") {
|
TEST_CASE("DynamicMemoryPool::startString()") {
|
||||||
SECTION("WorksWhenBufferIsBigEnough") {
|
SECTION("WorksWhenBufferIsBigEnough") {
|
||||||
DynamicJsonBuffer jsonBuffer(6);
|
DynamicMemoryPool memoryPool(6);
|
||||||
|
|
||||||
DynamicJsonBuffer::String str = jsonBuffer.startString();
|
DynamicMemoryPool::String str = memoryPool.startString();
|
||||||
str.append('h');
|
str.append('h');
|
||||||
str.append('e');
|
str.append('e');
|
||||||
str.append('l');
|
str.append('l');
|
||||||
@ -22,9 +22,9 @@ TEST_CASE("DynamicJsonBuffer::startString()") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION("GrowsWhenBufferIsTooSmall") {
|
SECTION("GrowsWhenBufferIsTooSmall") {
|
||||||
DynamicJsonBuffer jsonBuffer(5);
|
DynamicMemoryPool memoryPool(5);
|
||||||
|
|
||||||
DynamicJsonBuffer::String str = jsonBuffer.startString();
|
DynamicMemoryPool::String str = memoryPool.startString();
|
||||||
str.append('h');
|
str.append('h');
|
||||||
str.append('e');
|
str.append('e');
|
||||||
str.append('l');
|
str.append('l');
|
||||||
@ -35,15 +35,15 @@ TEST_CASE("DynamicJsonBuffer::startString()") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION("SizeIncreases") {
|
SECTION("SizeIncreases") {
|
||||||
DynamicJsonBuffer jsonBuffer(5);
|
DynamicMemoryPool memoryPool(5);
|
||||||
|
|
||||||
DynamicJsonBuffer::String str = jsonBuffer.startString();
|
DynamicMemoryPool::String str = memoryPool.startString();
|
||||||
REQUIRE(0 == jsonBuffer.size());
|
REQUIRE(0 == memoryPool.size());
|
||||||
|
|
||||||
str.append('h');
|
str.append('h');
|
||||||
REQUIRE(1 == jsonBuffer.size());
|
REQUIRE(1 == memoryPool.size());
|
||||||
|
|
||||||
str.c_str();
|
str.c_str();
|
||||||
REQUIRE(2 == jsonBuffer.size());
|
REQUIRE(2 == memoryPool.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,7 +19,7 @@ TEST_CASE("JsonArray::copyFrom()") {
|
|||||||
REQUIRE(std::string("[1,2,3]") == json);
|
REQUIRE(std::string("[1,2,3]") == json);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("OneDimension_JsonBufferTooSmall") {
|
SECTION("OneDimension_MemoryPoolTooSmall") {
|
||||||
const size_t SIZE = JSON_ARRAY_SIZE(2);
|
const size_t SIZE = JSON_ARRAY_SIZE(2);
|
||||||
StaticJsonDocument<SIZE> doc;
|
StaticJsonDocument<SIZE> doc;
|
||||||
JsonArray array = doc.to<JsonArray>();
|
JsonArray array = doc.to<JsonArray>();
|
||||||
@ -46,7 +46,7 @@ TEST_CASE("JsonArray::copyFrom()") {
|
|||||||
REQUIRE(std::string("[[1,2,3],[4,5,6]]") == json);
|
REQUIRE(std::string("[[1,2,3],[4,5,6]]") == json);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("TwoDimensions_JsonBufferTooSmall") {
|
SECTION("TwoDimensions_MemoryPoolTooSmall") {
|
||||||
const size_t SIZE =
|
const size_t SIZE =
|
||||||
JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2);
|
JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2);
|
||||||
StaticJsonDocument<SIZE> doc;
|
StaticJsonDocument<SIZE> doc;
|
||||||
|
@ -57,7 +57,7 @@ TEST_CASE("deserialize JSON array with a StaticJsonDocument") {
|
|||||||
deserializeJson(doc, " [ \"1234567\" ] ");
|
deserializeJson(doc, " [ \"1234567\" ] ");
|
||||||
|
|
||||||
REQUIRE(JSON_ARRAY_SIZE(1) + sizeof("1234567") == doc.memoryUsage());
|
REQUIRE(JSON_ARRAY_SIZE(1) + sizeof("1234567") == doc.memoryUsage());
|
||||||
// note: we use a string of 8 bytes to be sure that the StaticJsonBuffer
|
// note: we use a string of 8 bytes to be sure that the StaticMemoryPool
|
||||||
// will not insert bytes to enforce alignement
|
// will not insert bytes to enforce alignement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
# ArduinoJson - arduinojson.org
|
|
||||||
# Copyright Benoit Blanchon 2014-2018
|
|
||||||
# MIT License
|
|
||||||
|
|
||||||
add_executable(StaticJsonBufferTests
|
|
||||||
alloc.cpp
|
|
||||||
size.cpp
|
|
||||||
startString.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(StaticJsonBufferTests catch)
|
|
||||||
add_test(StaticJsonBuffer StaticJsonBufferTests)
|
|
@ -1,44 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2018
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#include <ArduinoJson/Memory/StaticJsonBuffer.hpp>
|
|
||||||
#include <catch.hpp>
|
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
|
||||||
|
|
||||||
TEST_CASE("StaticJsonBuffer::size()") {
|
|
||||||
StaticJsonBuffer<64> buffer;
|
|
||||||
|
|
||||||
SECTION("Capacity equals template parameter") {
|
|
||||||
REQUIRE(64 == buffer.capacity());
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Initial size is 0") {
|
|
||||||
REQUIRE(0 == buffer.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Increases after alloc()") {
|
|
||||||
buffer.alloc(1);
|
|
||||||
REQUIRE(1U <= buffer.size());
|
|
||||||
buffer.alloc(1);
|
|
||||||
REQUIRE(2U <= buffer.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Doesn't grow when buffer is full") {
|
|
||||||
buffer.alloc(64);
|
|
||||||
buffer.alloc(1);
|
|
||||||
REQUIRE(64 == buffer.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Does't grow when buffer is too small for alloc") {
|
|
||||||
buffer.alloc(65);
|
|
||||||
REQUIRE(0 == buffer.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Goes back to zero after clear()") {
|
|
||||||
buffer.alloc(1);
|
|
||||||
buffer.clear();
|
|
||||||
REQUIRE(0 == buffer.size());
|
|
||||||
}
|
|
||||||
}
|
|
12
test/StaticMemoryPool/CMakeLists.txt
Normal file
12
test/StaticMemoryPool/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# ArduinoJson - arduinojson.org
|
||||||
|
# Copyright Benoit Blanchon 2014-2018
|
||||||
|
# MIT License
|
||||||
|
|
||||||
|
add_executable(StaticMemoryPoolTests
|
||||||
|
alloc.cpp
|
||||||
|
size.cpp
|
||||||
|
startString.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(StaticMemoryPoolTests catch)
|
||||||
|
add_test(StaticMemoryPool StaticMemoryPoolTests)
|
@ -2,7 +2,7 @@
|
|||||||
// Copyright Benoit Blanchon 2014-2018
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#include <ArduinoJson/Memory/StaticJsonBuffer.hpp>
|
#include <ArduinoJson/Memory/StaticMemoryPool.hpp>
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
@ -13,42 +13,42 @@ static bool isAligned(void *ptr) {
|
|||||||
return (addr & mask) == 0;
|
return (addr & mask) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("StaticJsonBuffer::alloc()") {
|
TEST_CASE("StaticMemoryPool::alloc()") {
|
||||||
StaticJsonBuffer<64> buffer;
|
StaticMemoryPool<64> memoryPool;
|
||||||
|
|
||||||
SECTION("Returns different addresses") {
|
SECTION("Returns different addresses") {
|
||||||
void *p1 = buffer.alloc(1);
|
void *p1 = memoryPool.alloc(1);
|
||||||
void *p2 = buffer.alloc(1);
|
void *p2 = memoryPool.alloc(1);
|
||||||
REQUIRE(p1 != p2);
|
REQUIRE(p1 != p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Returns non-NULL when using full capacity") {
|
SECTION("Returns non-NULL when using full capacity") {
|
||||||
void *p = buffer.alloc(64);
|
void *p = memoryPool.alloc(64);
|
||||||
REQUIRE(0 != p);
|
REQUIRE(0 != p);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Returns NULL when full") {
|
SECTION("Returns NULL when full") {
|
||||||
buffer.alloc(64);
|
memoryPool.alloc(64);
|
||||||
void *p = buffer.alloc(1);
|
void *p = memoryPool.alloc(1);
|
||||||
REQUIRE(0 == p);
|
REQUIRE(0 == p);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Returns NULL when buffer is too small") {
|
SECTION("Returns NULL when memoryPool is too small") {
|
||||||
void *p = buffer.alloc(65);
|
void *p = memoryPool.alloc(65);
|
||||||
REQUIRE(0 == p);
|
REQUIRE(0 == p);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Returns aligned pointers") {
|
SECTION("Returns aligned pointers") {
|
||||||
for (size_t size = 1; size <= sizeof(void *); size++) {
|
for (size_t size = 1; size <= sizeof(void *); size++) {
|
||||||
void *p = buffer.alloc(1);
|
void *p = memoryPool.alloc(1);
|
||||||
REQUIRE(isAligned(p));
|
REQUIRE(isAligned(p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Returns same address after clear()") {
|
SECTION("Returns same address after clear()") {
|
||||||
void *p1 = buffer.alloc(1);
|
void *p1 = memoryPool.alloc(1);
|
||||||
buffer.clear();
|
memoryPool.clear();
|
||||||
void *p2 = buffer.alloc(1);
|
void *p2 = memoryPool.alloc(1);
|
||||||
REQUIRE(p1 == p2);
|
REQUIRE(p1 == p2);
|
||||||
}
|
}
|
||||||
}
|
}
|
44
test/StaticMemoryPool/size.cpp
Normal file
44
test/StaticMemoryPool/size.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson/Memory/StaticMemoryPool.hpp>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
|
TEST_CASE("StaticMemoryPool::size()") {
|
||||||
|
StaticMemoryPool<64> memoryPool;
|
||||||
|
|
||||||
|
SECTION("Capacity equals template parameter") {
|
||||||
|
REQUIRE(64 == memoryPool.capacity());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Initial size is 0") {
|
||||||
|
REQUIRE(0 == memoryPool.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Increases after alloc()") {
|
||||||
|
memoryPool.alloc(1);
|
||||||
|
REQUIRE(1U <= memoryPool.size());
|
||||||
|
memoryPool.alloc(1);
|
||||||
|
REQUIRE(2U <= memoryPool.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Doesn't grow when memoryPool is full") {
|
||||||
|
memoryPool.alloc(64);
|
||||||
|
memoryPool.alloc(1);
|
||||||
|
REQUIRE(64 == memoryPool.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Does't grow when memoryPool is too small for alloc") {
|
||||||
|
memoryPool.alloc(65);
|
||||||
|
REQUIRE(0 == memoryPool.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Goes back to zero after clear()") {
|
||||||
|
memoryPool.alloc(1);
|
||||||
|
memoryPool.clear();
|
||||||
|
REQUIRE(0 == memoryPool.size());
|
||||||
|
}
|
||||||
|
}
|
@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
TEST_CASE("StaticJsonBuffer::startString()") {
|
TEST_CASE("StaticMemoryPool::startString()") {
|
||||||
SECTION("WorksWhenBufferIsBigEnough") {
|
SECTION("WorksWhenBufferIsBigEnough") {
|
||||||
StaticJsonBuffer<6> jsonBuffer;
|
StaticMemoryPool<6> memoryPool;
|
||||||
|
|
||||||
StaticJsonBufferBase::String str = jsonBuffer.startString();
|
StaticMemoryPoolBase::String str = memoryPool.startString();
|
||||||
str.append('h');
|
str.append('h');
|
||||||
str.append('e');
|
str.append('e');
|
||||||
str.append('l');
|
str.append('l');
|
||||||
@ -22,9 +22,9 @@ TEST_CASE("StaticJsonBuffer::startString()") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION("ReturnsNullWhenTooSmall") {
|
SECTION("ReturnsNullWhenTooSmall") {
|
||||||
StaticJsonBuffer<5> jsonBuffer;
|
StaticMemoryPool<5> memoryPool;
|
||||||
|
|
||||||
StaticJsonBufferBase::String str = jsonBuffer.startString();
|
StaticMemoryPoolBase::String str = memoryPool.startString();
|
||||||
str.append('h');
|
str.append('h');
|
||||||
str.append('e');
|
str.append('e');
|
||||||
str.append('l');
|
str.append('l');
|
||||||
@ -35,15 +35,15 @@ TEST_CASE("StaticJsonBuffer::startString()") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION("SizeIncreases") {
|
SECTION("SizeIncreases") {
|
||||||
StaticJsonBuffer<5> jsonBuffer;
|
StaticMemoryPool<5> memoryPool;
|
||||||
|
|
||||||
StaticJsonBufferBase::String str = jsonBuffer.startString();
|
StaticMemoryPoolBase::String str = memoryPool.startString();
|
||||||
REQUIRE(0 == jsonBuffer.size());
|
REQUIRE(0 == memoryPool.size());
|
||||||
|
|
||||||
str.append('h');
|
str.append('h');
|
||||||
REQUIRE(1 == jsonBuffer.size());
|
REQUIRE(1 == memoryPool.size());
|
||||||
|
|
||||||
str.c_str();
|
str.c_str();
|
||||||
REQUIRE(2 == jsonBuffer.size());
|
REQUIRE(2 == memoryPool.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user