12#define ARDUINOJSON_ENABLE_STD_STRING 1
14#define ARDUINOJSON_USE_LONG_LONG 1
16#include <ArduinoJson.h>
29 if (
size + 1 <= STACK_SIZE) {
30 buffer_ = stack_buffer_;
32 heap_buffer_ =
new char[
size + 1];
33 buffer_ = heap_buffer_;
42 if (other.buffer_ == other.stack_buffer_) {
44 std::memcpy(stack_buffer_, other.stack_buffer_, size_ + 1);
45 buffer_ = stack_buffer_;
48 buffer_ = heap_buffer_;
49 other.heap_buffer_ =
nullptr;
52 other.stack_buffer_[0] =
'\0';
53 other.buffer_ = other.stack_buffer_;
60 delete[] heap_buffer_;
61 heap_buffer_ = other.heap_buffer_;
63 if (other.buffer_ == other.stack_buffer_) {
64 std::memcpy(stack_buffer_, other.stack_buffer_, size_ + 1);
65 buffer_ = stack_buffer_;
67 buffer_ = heap_buffer_;
68 other.heap_buffer_ =
nullptr;
71 other.stack_buffer_[0] =
'\0';
72 other.buffer_ = other.stack_buffer_;
83 const char *
c_str()
const {
return buffer_; }
85 const char *
data()
const {
return buffer_; }
87 size_t size()
const {
return size_; }
92 operator std::string()
const {
return std::string(buffer_, size_); }
98 char *data_writable_() {
return buffer_; }
101 void set_size_(
size_t size) {
103 buffer_[
size] =
'\0';
108 void reallocate_heap_(
size_t size) {
109 delete[] heap_buffer_;
110 heap_buffer_ =
new char[
size + 1];
111 buffer_ = heap_buffer_;
116 char stack_buffer_[STACK_SIZE];
117 char *heap_buffer_{
nullptr};
143 return allocator.
reallocate(
static_cast<uint8_t *
>(ptr), new_size);
167 return parse_json(
reinterpret_cast<const uint8_t *
>(data.c_str()), data.size());
175constexpr size_t JSON_POOL_BYTES = ARDUINOJSON_POOL_CAPACITY *
sizeof(ArduinoJson::detail::VariantData);
178static_assert(
sizeof(
void *) != 4 ||
JSON_ARENA_SIZE == 2176,
"the arena was sized for a 1 KB pool");
182template<
size_t N>
class JsonArena final :
public ArduinoJson::Allocator {
192 return this->fallback_->allocate(
size);
194 size = (
size + ALIGN - 1) & ~(ALIGN - 1);
195 if (
size > N - this->used_) {
196 return this->fallback_->allocate(
size);
198 this->last_ = this->used_;
200 return this->buf_ + this->last_;
203 if (!this->owns_(ptr)) {
204 this->fallback_->deallocate(ptr);
208 if (!this->owns_(ptr)) {
209 return this->fallback_->reallocate(ptr, new_size);
211 const size_t off =
static_cast<uint8_t *
>(ptr) - this->buf_;
212 const size_t size = new_size > N ? N + ALIGN : (new_size + ALIGN - 1) & ~(ALIGN - 1);
213 const bool newest = off == this->last_;
214 if (newest &&
size <= N - off) {
215 this->used_ = off +
size;
219 const size_t old_size = newest ? this->used_ - off : N - off;
220 void *moved = this->fallback_->allocate(new_size);
221 if (moved ==
nullptr) {
224 std::memcpy(moved, ptr, std::min(new_size, old_size));
231 size_t used()
const {
return this->used_; }
234 static constexpr size_t ALIGN =
alignof(std::max_align_t);
235 bool owns_(
const void *ptr)
const {
return ptr >= this->buf_ && ptr < this->buf_ + N; }
236 ArduinoJson::Allocator *fallback_;
237 alignas(ALIGN) uint8_t buf_[N];
250 explicit JsonBuilder(ArduinoJson::Allocator *allocator);
254 if (!root_created_) {
255 root_ = doc_.to<JsonObject>();
256 root_created_ =
true;
272 bool root_created_{
false};
An STL allocator that uses SPI or internal RAM.
T * reallocate(T *p, size_t n)
Bump allocator over a fixed buffer for a document built and serialized in one scope.
JsonArena(ArduinoJson::Allocator *fallback=heap_json_allocator())
void * allocate(size_t size) override
void * reallocate(void *ptr, size_t new_size) override
JsonArena(const JsonArena &)=delete
JsonArena & operator=(const JsonArena &)=delete
size_t used() const
Bytes of the buffer handed out so far.
void deallocate(void *ptr) override
Builder class for creating JSON documents without lambdas.
size_t serialize_to(char *buf, size_t cap)
Serialize into a caller owned buffer.
SerializationBuffer serialize()
Serialize the JSON document to a SerializationBuffer (stack-first allocation) Uses 512-byte stack buf...
Buffer for JSON serialization that uses stack allocation for small payloads.
static constexpr size_t BUFFER_SIZE
Stack buffer size for this instantiation.
size_t size() const
Get string length (excluding null terminator)
SerializationBuffer(size_t size)
Construct with known size (typically from measureJson)
SerializationBuffer & operator=(const SerializationBuffer &)=delete
const char * data() const
Get data pointer.
SerializationBuffer(const SerializationBuffer &)=delete
const char * c_str() const
Get null-terminated C string.
SerializationBuffer & operator=(SerializationBuffer &&other) noexcept
SerializationBuffer(SerializationBuffer &&other) noexcept
std::function< void(JsonObject)> json_build_t
Callback function typedef for building JsonObjects.
ArduinoJson::Allocator * heap_json_allocator()
The allocator a JsonBuilder uses by default (PSRAM first when available)
constexpr size_t JSON_ARENA_SIZE
One pool plus room for copied string nodes; a 40 option select with linked options fits.
bool parse_json(const std::string &data, const json_parse_t &f)
Parse a JSON string and run the provided json parse function if it's valid.
constexpr size_t JSON_POOL_BYTES
Size of one ArduinoJson slot pool, the first allocation every document makes (1 KB on 32 bit targets)
std::function< bool(JsonObject)> json_parse_t
Callback function typedef for parsing JsonObjects.
SerializationBuffer build_json(const json_build_t &f)
Build a JSON string with the provided json build function.
void deallocate(void *ptr) override
void * allocate(size_t size) override
void * reallocate(void *ptr, size_t new_size) override