blob: 25be67806d5351290f9a562e4845bb914cc9c694 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
#include "lib/ArduinoJson/Polyfills/integer.hpp"
#include "lib/ArduinoJson/Polyfills/limits.hpp"
#include "lib/ArduinoJson/Polyfills/type_traits.hpp"
#include "lib/ArduinoJson/Strings/StoragePolicy.hpp"
#include "lib/ArduinoJson/Variant/VariantContent.hpp"
namespace ARDUINOJSON_NAMESPACE {
typedef int_t<ARDUINOJSON_SLOT_OFFSET_SIZE * 8>::type VariantSlotDiff;
class VariantSlot {
// CAUTION: same layout as VariantData
// we cannot use composition because it adds padding
// (+20% on ESP8266 for example)
VariantContent _content;
uint8_t _flags;
VariantSlotDiff _next;
const char* _key;
public:
// Must be a POD!
// - no constructor
// - no destructor
// - no virtual
// - no inheritance
VariantData* data() {
return reinterpret_cast<VariantData*>(&_content);
}
const VariantData* data() const {
return reinterpret_cast<const VariantData*>(&_content);
}
VariantSlot* next() {
return _next ? this + _next : 0;
}
const VariantSlot* next() const {
return const_cast<VariantSlot*>(this)->next();
}
VariantSlot* next(size_t distance) {
VariantSlot* slot = this;
while (distance--) {
if (!slot->_next)
return 0;
slot += slot->_next;
}
return slot;
}
const VariantSlot* next(size_t distance) const {
return const_cast<VariantSlot*>(this)->next(distance);
}
void setNext(VariantSlot* slot) {
ARDUINOJSON_ASSERT(!slot || slot - this >=
numeric_limits<VariantSlotDiff>::lowest());
ARDUINOJSON_ASSERT(!slot || slot - this <=
numeric_limits<VariantSlotDiff>::highest());
_next = VariantSlotDiff(slot ? slot - this : 0);
}
void setNextNotNull(VariantSlot* slot) {
ARDUINOJSON_ASSERT(slot != 0);
ARDUINOJSON_ASSERT(slot - this >=
numeric_limits<VariantSlotDiff>::lowest());
ARDUINOJSON_ASSERT(slot - this <=
numeric_limits<VariantSlotDiff>::highest());
_next = VariantSlotDiff(slot - this);
}
void setKey(const char* k, storage_policies::store_by_copy) {
ARDUINOJSON_ASSERT(k != NULL);
_flags |= OWNED_KEY_BIT;
_key = k;
}
void setKey(const char* k, storage_policies::store_by_address) {
ARDUINOJSON_ASSERT(k != NULL);
_flags &= VALUE_MASK;
_key = k;
}
const char* key() const {
return _key;
}
bool ownsKey() const {
return (_flags & OWNED_KEY_BIT) != 0;
}
void clear() {
_next = 0;
_flags = 0;
_key = 0;
}
void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance) {
if (_flags & OWNED_KEY_BIT)
_key += stringDistance;
if (_flags & OWNED_VALUE_BIT)
_content.asString += stringDistance;
if (_flags & COLLECTION_MASK)
_content.asCollection.movePointers(stringDistance, variantDistance);
}
};
} // namespace ARDUINOJSON_NAMESPACE
|