Coverage Report

Created: 2024-09-08 06:19

/src/arduinojson/src/ArduinoJson/Variant/VariantData.hpp
Line
Count
Source (jump to first uncovered line)
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2024, Benoit BLANCHON
3
// MIT License
4
5
#pragma once
6
7
#include <ArduinoJson/Memory/MemoryPool.hpp>
8
#include <ArduinoJson/Memory/StringNode.hpp>
9
#include <ArduinoJson/Misc/SerializedValue.hpp>
10
#include <ArduinoJson/Numbers/convertNumber.hpp>
11
#include <ArduinoJson/Strings/JsonString.hpp>
12
#include <ArduinoJson/Strings/StringAdapters.hpp>
13
#include <ArduinoJson/Variant/VariantContent.hpp>
14
15
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
16
17
template <typename T>
18
T parseNumber(const char* s);
19
20
class VariantData {
21
  VariantContent content_;  // must be first to allow cast from array to variant
22
  VariantType type_;
23
  SlotId next_;
24
25
 public:
26
  // Placement new
27
13.2k
  static void* operator new(size_t, void* p) noexcept {
28
13.2k
    return p;
29
13.2k
  }
30
31
0
  static void operator delete(void*, void*) noexcept {}
32
33
15.6k
  VariantData() : type_(VariantType::Null), next_(NULL_SLOT) {}
34
35
13.9k
  SlotId next() const {
36
13.9k
    return next_;
37
13.9k
  }
38
39
10.0k
  void setNext(SlotId slot) {
40
10.0k
    next_ = slot;
41
10.0k
  }
42
43
  template <typename TVisitor>
44
  typename TVisitor::result_type accept(
45
3.82k
      TVisitor& visit, const ResourceManager* resources) const {
46
3.82k
#if ARDUINOJSON_USE_EXTENSIONS
47
3.82k
    auto extension = getExtension(resources);
48
#else
49
    (void)resources;  // silence warning
50
#endif
51
3.82k
    switch (type_) {
52
1.23k
      case VariantType::Float:
53
1.23k
        return visit.visit(content_.asFloat);
54
55
0
#if ARDUINOJSON_USE_DOUBLE
56
419
      case VariantType::Double:
57
419
        return visit.visit(extension->asDouble);
58
0
#endif
59
60
516
      case VariantType::Array:
61
516
        return visit.visit(content_.asArray);
62
63
189
      case VariantType::Object:
64
189
        return visit.visit(content_.asObject);
65
66
0
      case VariantType::LinkedString:
67
0
        return visit.visit(JsonString(content_.asLinkedString));
68
69
352
      case VariantType::OwnedString:
70
352
        return visit.visit(JsonString(content_.asOwnedString->data,
71
352
                                      content_.asOwnedString->length,
72
352
                                      JsonString::Copied));
73
74
0
      case VariantType::RawString:
75
0
        return visit.visit(RawString(content_.asOwnedString->data,
76
0
                                     content_.asOwnedString->length));
77
78
216
      case VariantType::Int32:
79
216
        return visit.visit(static_cast<JsonInteger>(content_.asInt32));
80
81
316
      case VariantType::Uint32:
82
316
        return visit.visit(static_cast<JsonUInt>(content_.asUint32));
83
84
0
#if ARDUINOJSON_USE_LONG_LONG
85
223
      case VariantType::Int64:
86
223
        return visit.visit(extension->asInt64);
87
88
159
      case VariantType::Uint64:
89
159
        return visit.visit(extension->asUint64);
90
0
#endif
91
92
132
      case VariantType::Boolean:
93
132
        return visit.visit(content_.asBoolean != 0);
94
95
66
      default:
96
66
        return visit.visit(nullptr);
97
3.82k
    }
98
3.82k
  }
ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::Writer<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void> >::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::Writer<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void> > >(ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::Writer<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void> >&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Line
Count
Source
45
3.82k
      TVisitor& visit, const ResourceManager* resources) const {
46
3.82k
#if ARDUINOJSON_USE_EXTENSIONS
47
3.82k
    auto extension = getExtension(resources);
48
#else
49
    (void)resources;  // silence warning
50
#endif
51
3.82k
    switch (type_) {
52
1.23k
      case VariantType::Float:
53
1.23k
        return visit.visit(content_.asFloat);
54
55
0
#if ARDUINOJSON_USE_DOUBLE
56
419
      case VariantType::Double:
57
419
        return visit.visit(extension->asDouble);
58
0
#endif
59
60
516
      case VariantType::Array:
61
516
        return visit.visit(content_.asArray);
62
63
189
      case VariantType::Object:
64
189
        return visit.visit(content_.asObject);
65
66
0
      case VariantType::LinkedString:
67
0
        return visit.visit(JsonString(content_.asLinkedString));
68
69
352
      case VariantType::OwnedString:
70
352
        return visit.visit(JsonString(content_.asOwnedString->data,
71
352
                                      content_.asOwnedString->length,
72
352
                                      JsonString::Copied));
73
74
0
      case VariantType::RawString:
75
0
        return visit.visit(RawString(content_.asOwnedString->data,
76
0
                                     content_.asOwnedString->length));
77
78
216
      case VariantType::Int32:
79
216
        return visit.visit(static_cast<JsonInteger>(content_.asInt32));
80
81
316
      case VariantType::Uint32:
82
316
        return visit.visit(static_cast<JsonUInt>(content_.asUint32));
83
84
0
#if ARDUINOJSON_USE_LONG_LONG
85
223
      case VariantType::Int64:
86
223
        return visit.visit(extension->asInt64);
87
88
159
      case VariantType::Uint64:
89
159
        return visit.visit(extension->asUint64);
90
0
#endif
91
92
132
      case VariantType::Boolean:
93
132
        return visit.visit(content_.asBoolean != 0);
94
95
66
      default:
96
66
        return visit.visit(nullptr);
97
3.82k
    }
98
3.82k
  }
Unexecuted instantiation: ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<ArduinoJson::V710HB42::JsonVariantConst, void> >::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<ArduinoJson::V710HB42::JsonVariantConst, void> > >(ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<ArduinoJson::V710HB42::JsonVariantConst, void> >&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::ArrayComparer>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::ArrayComparer> >(ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::ArrayComparer>&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::ObjectComparer>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::ObjectComparer> >(ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::ObjectComparer>&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<double, void> >::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<double, void> > >(ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<double, void> >&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<ArduinoJson::V710HB42::JsonString, void> >::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<ArduinoJson::V710HB42::JsonString, void> > >(ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<ArduinoJson::V710HB42::JsonString, void> >&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::RawComparer>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::RawComparer> >(ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::RawComparer>&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<long, void> >::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<long, void> > >(ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<long, void> >&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<unsigned long, void> >::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<unsigned long, void> > >(ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<unsigned long, void> >&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<bool, void> >::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<bool, void> > >(ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::Comparer<bool, void> >&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::NullComparer>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::NullComparer> >(ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::NullComparer>&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter> >(ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter>&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::DummyWriter>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::DummyWriter> >(ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::DummyWriter>&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::JsonVariantCopier>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::JsonVariantCopier> >(ArduinoJson::V710HB42::detail::VisitorAdapter<ArduinoJson::V710HB42::detail::JsonVariantCopier>&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::PrettyJsonSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::PrettyJsonSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter> >(ArduinoJson::V710HB42::detail::PrettyJsonSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter>&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::PrettyJsonSerializer<ArduinoJson::V710HB42::detail::DummyWriter>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::PrettyJsonSerializer<ArduinoJson::V710HB42::detail::DummyWriter> >(ArduinoJson::V710HB42::detail::PrettyJsonSerializer<ArduinoJson::V710HB42::detail::DummyWriter>&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::MsgPackSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::MsgPackSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter> >(ArduinoJson::V710HB42::detail::MsgPackSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter>&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
Unexecuted instantiation: ArduinoJson::V710HB42::detail::MsgPackSerializer<ArduinoJson::V710HB42::detail::DummyWriter>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::MsgPackSerializer<ArduinoJson::V710HB42::detail::DummyWriter> >(ArduinoJson::V710HB42::detail::MsgPackSerializer<ArduinoJson::V710HB42::detail::DummyWriter>&, ArduinoJson::V710HB42::detail::ResourceManager const*) const
99
100
  template <typename TVisitor>
101
  static typename TVisitor::result_type accept(const VariantData* var,
102
                                               const ResourceManager* resources,
103
926
                                               TVisitor& visit) {
104
926
    if (var != 0)
105
926
      return var->accept(visit, resources);
106
0
    else
107
0
      return visit.visit(nullptr);
108
926
  }
ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::Writer<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void> >::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::Writer<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void> > >(ArduinoJson::V710HB42::detail::VariantData const*, ArduinoJson::V710HB42::detail::ResourceManager const*, ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::Writer<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void> >&)
Line
Count
Source
103
926
                                               TVisitor& visit) {
104
926
    if (var != 0)
105
926
      return var->accept(visit, resources);
106
0
    else
107
0
      return visit.visit(nullptr);
108
926
  }
Unexecuted instantiation: ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter> >(ArduinoJson::V710HB42::detail::VariantData const*, ArduinoJson::V710HB42::detail::ResourceManager const*, ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter>&)
Unexecuted instantiation: ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::DummyWriter>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::DummyWriter> >(ArduinoJson::V710HB42::detail::VariantData const*, ArduinoJson::V710HB42::detail::ResourceManager const*, ArduinoJson::V710HB42::detail::JsonSerializer<ArduinoJson::V710HB42::detail::DummyWriter>&)
Unexecuted instantiation: ArduinoJson::V710HB42::detail::PrettyJsonSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::PrettyJsonSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter> >(ArduinoJson::V710HB42::detail::VariantData const*, ArduinoJson::V710HB42::detail::ResourceManager const*, ArduinoJson::V710HB42::detail::PrettyJsonSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter>&)
Unexecuted instantiation: ArduinoJson::V710HB42::detail::PrettyJsonSerializer<ArduinoJson::V710HB42::detail::DummyWriter>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::PrettyJsonSerializer<ArduinoJson::V710HB42::detail::DummyWriter> >(ArduinoJson::V710HB42::detail::VariantData const*, ArduinoJson::V710HB42::detail::ResourceManager const*, ArduinoJson::V710HB42::detail::PrettyJsonSerializer<ArduinoJson::V710HB42::detail::DummyWriter>&)
Unexecuted instantiation: ArduinoJson::V710HB42::detail::MsgPackSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::MsgPackSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter> >(ArduinoJson::V710HB42::detail::VariantData const*, ArduinoJson::V710HB42::detail::ResourceManager const*, ArduinoJson::V710HB42::detail::MsgPackSerializer<ArduinoJson::V710HB42::detail::StaticStringWriter>&)
Unexecuted instantiation: ArduinoJson::V710HB42::detail::MsgPackSerializer<ArduinoJson::V710HB42::detail::DummyWriter>::result_type ArduinoJson::V710HB42::detail::VariantData::accept<ArduinoJson::V710HB42::detail::MsgPackSerializer<ArduinoJson::V710HB42::detail::DummyWriter> >(ArduinoJson::V710HB42::detail::VariantData const*, ArduinoJson::V710HB42::detail::ResourceManager const*, ArduinoJson::V710HB42::detail::MsgPackSerializer<ArduinoJson::V710HB42::detail::DummyWriter>&)
109
110
0
  VariantData* addElement(ResourceManager* resources) {
111
0
    auto array = isNull() ? &toArray() : asArray();
112
0
    return detail::ArrayData::addElement(array, resources);
113
0
  }
114
115
0
  static VariantData* addElement(VariantData* var, ResourceManager* resources) {
116
0
    if (!var)
117
0
      return nullptr;
118
0
    return var->addElement(resources);
119
0
  }
120
121
  template <typename T>
122
  bool addValue(T&& value, ResourceManager* resources) {
123
    auto array = isNull() ? &toArray() : asArray();
124
    return detail::ArrayData::addValue(array, detail::forward<T>(value),
125
                                       resources);
126
  }
127
128
  template <typename T>
129
  static bool addValue(VariantData* var, T&& value,
130
                       ResourceManager* resources) {
131
    if (!var)
132
      return false;
133
    return var->addValue(value, resources);
134
  }
135
136
0
  bool asBoolean(const ResourceManager* resources) const {
137
0
#if ARDUINOJSON_USE_EXTENSIONS
138
0
    auto extension = getExtension(resources);
139
0
#else
140
0
    (void)resources;  // silence warning
141
0
#endif
142
0
    switch (type_) {
143
0
      case VariantType::Boolean:
144
0
        return content_.asBoolean;
145
0
      case VariantType::Uint32:
146
0
      case VariantType::Int32:
147
0
        return content_.asUint32 != 0;
148
0
      case VariantType::Float:
149
0
        return content_.asFloat != 0;
150
0
#if ARDUINOJSON_USE_DOUBLE
151
0
      case VariantType::Double:
152
0
        return extension->asDouble != 0;
153
0
#endif
154
0
      case VariantType::Null:
155
0
        return false;
156
0
#if ARDUINOJSON_USE_LONG_LONG
157
0
      case VariantType::Uint64:
158
0
      case VariantType::Int64:
159
0
        return extension->asUint64 != 0;
160
0
#endif
161
0
      default:
162
0
        return true;
163
0
    }
164
0
  }
165
166
0
  ArrayData* asArray() {
167
0
    return isArray() ? &content_.asArray : 0;
168
0
  }
169
170
0
  const ArrayData* asArray() const {
171
0
    return const_cast<VariantData*>(this)->asArray();
172
0
  }
173
174
1.52k
  CollectionData* asCollection() {
175
1.52k
    return isCollection() ? &content_.asCollection : 0;
176
1.52k
  }
177
178
0
  const CollectionData* asCollection() const {
179
0
    return const_cast<VariantData*>(this)->asCollection();
180
0
  }
181
182
  template <typename T>
183
  T asFloat(const ResourceManager* resources) const {
184
    static_assert(is_floating_point<T>::value, "T must be a floating point");
185
#if ARDUINOJSON_USE_EXTENSIONS
186
    auto extension = getExtension(resources);
187
#else
188
    (void)resources;  // silence warning
189
#endif
190
    switch (type_) {
191
      case VariantType::Boolean:
192
        return static_cast<T>(content_.asBoolean);
193
      case VariantType::Uint32:
194
        return static_cast<T>(content_.asUint32);
195
      case VariantType::Int32:
196
        return static_cast<T>(content_.asInt32);
197
#if ARDUINOJSON_USE_LONG_LONG
198
      case VariantType::Uint64:
199
        return static_cast<T>(extension->asUint64);
200
      case VariantType::Int64:
201
        return static_cast<T>(extension->asInt64);
202
#endif
203
      case VariantType::LinkedString:
204
      case VariantType::OwnedString:
205
        return parseNumber<T>(content_.asOwnedString->data);
206
      case VariantType::Float:
207
        return static_cast<T>(content_.asFloat);
208
#if ARDUINOJSON_USE_DOUBLE
209
      case VariantType::Double:
210
        return static_cast<T>(extension->asDouble);
211
#endif
212
      default:
213
        return 0;
214
    }
215
  }
216
217
  template <typename T>
218
  T asIntegral(const ResourceManager* resources) const {
219
    static_assert(is_integral<T>::value, "T must be an integral type");
220
#if ARDUINOJSON_USE_EXTENSIONS
221
    auto extension = getExtension(resources);
222
#else
223
    (void)resources;  // silence warning
224
#endif
225
    switch (type_) {
226
      case VariantType::Boolean:
227
        return content_.asBoolean;
228
      case VariantType::Uint32:
229
        return convertNumber<T>(content_.asUint32);
230
      case VariantType::Int32:
231
        return convertNumber<T>(content_.asInt32);
232
#if ARDUINOJSON_USE_LONG_LONG
233
      case VariantType::Uint64:
234
        return convertNumber<T>(extension->asUint64);
235
      case VariantType::Int64:
236
        return convertNumber<T>(extension->asInt64);
237
#endif
238
      case VariantType::LinkedString:
239
        return parseNumber<T>(content_.asLinkedString);
240
      case VariantType::OwnedString:
241
        return parseNumber<T>(content_.asOwnedString->data);
242
      case VariantType::Float:
243
        return convertNumber<T>(content_.asFloat);
244
#if ARDUINOJSON_USE_DOUBLE
245
      case VariantType::Double:
246
        return convertNumber<T>(extension->asDouble);
247
#endif
248
      default:
249
        return 0;
250
    }
251
  }
252
253
0
  ObjectData* asObject() {
254
0
    return isObject() ? &content_.asObject : 0;
255
0
  }
256
257
0
  const ObjectData* asObject() const {
258
0
    return const_cast<VariantData*>(this)->asObject();
259
0
  }
260
261
0
  JsonString asRawString() const {
262
0
    switch (type_) {
263
0
      case VariantType::RawString:
264
0
        return JsonString(content_.asOwnedString->data,
265
0
                          content_.asOwnedString->length, JsonString::Copied);
266
0
      default:
267
0
        return JsonString();
268
0
    }
269
0
  }
270
271
5.02k
  JsonString asString() const {
272
5.02k
    switch (type_) {
273
0
      case VariantType::LinkedString:
274
0
        return JsonString(content_.asLinkedString, JsonString::Linked);
275
5.02k
      case VariantType::OwnedString:
276
5.02k
        return JsonString(content_.asOwnedString->data,
277
5.02k
                          content_.asOwnedString->length, JsonString::Copied);
278
0
      default:
279
0
        return JsonString();
280
5.02k
    }
281
5.02k
  }
282
283
#if ARDUINOJSON_USE_EXTENSIONS
284
  const VariantExtension* getExtension(const ResourceManager* resources) const;
285
#endif
286
287
  VariantData* getElement(size_t index,
288
0
                          const ResourceManager* resources) const {
289
0
    return ArrayData::getElement(asArray(), index, resources);
290
0
  }
291
292
  static VariantData* getElement(const VariantData* var, size_t index,
293
0
                                 const ResourceManager* resources) {
294
0
    return var != 0 ? var->getElement(index, resources) : 0;
295
0
  }
296
297
  template <typename TAdaptedString>
298
  VariantData* getMember(TAdaptedString key,
299
                         const ResourceManager* resources) const {
300
    return ObjectData::getMember(asObject(), key, resources);
301
  }
302
303
  template <typename TAdaptedString>
304
  static VariantData* getMember(const VariantData* var, TAdaptedString key,
305
                                const ResourceManager* resources) {
306
    if (!var)
307
      return 0;
308
    return var->getMember(key, resources);
309
  }
310
311
0
  VariantData* getOrAddElement(size_t index, ResourceManager* resources) {
312
0
    auto array = isNull() ? &toArray() : asArray();
313
0
    if (!array)
314
0
      return nullptr;
315
0
    return array->getOrAddElement(index, resources);
316
0
  }
317
318
  template <typename TAdaptedString>
319
0
  VariantData* getOrAddMember(TAdaptedString key, ResourceManager* resources) {
320
0
    if (key.isNull())
321
0
      return nullptr;
322
0
    auto obj = isNull() ? &toObject() : asObject();
323
0
    if (!obj)
324
0
      return nullptr;
325
0
    return obj->getOrAddMember(key, resources);
326
0
  }
327
328
0
  bool isArray() const {
329
0
    return type_ == VariantType::Array;
330
0
  }
331
332
0
  bool isBoolean() const {
333
0
    return type_ == VariantType::Boolean;
334
0
  }
335
336
1.52k
  bool isCollection() const {
337
1.52k
    return type_ & VariantTypeBits::CollectionMask;
338
1.52k
  }
339
340
276
  bool isFloat() const {
341
276
    return type_ & VariantTypeBits::NumberBit;
342
276
  }
343
344
  template <typename T>
345
  bool isInteger(const ResourceManager* resources) const {
346
#if ARDUINOJSON_USE_LONG_LONG
347
    auto extension = getExtension(resources);
348
#else
349
    (void)resources;  // silence warning
350
#endif
351
    switch (type_) {
352
      case VariantType::Uint32:
353
        return canConvertNumber<T>(content_.asUint32);
354
355
      case VariantType::Int32:
356
        return canConvertNumber<T>(content_.asInt32);
357
358
#if ARDUINOJSON_USE_LONG_LONG
359
      case VariantType::Uint64:
360
        return canConvertNumber<T>(extension->asUint64);
361
362
      case VariantType::Int64:
363
        return canConvertNumber<T>(extension->asInt64);
364
#endif
365
366
      default:
367
        return false;
368
    }
369
  }
370
371
0
  bool isNull() const {
372
0
    return type_ == VariantType::Null;
373
0
  }
374
375
0
  static bool isNull(const VariantData* var) {
376
0
    if (!var)
377
0
      return true;
378
0
    return var->isNull();
379
0
  }
380
381
0
  bool isObject() const {
382
0
    return type_ == VariantType::Object;
383
0
  }
384
385
0
  bool isString() const {
386
0
    return type_ == VariantType::LinkedString ||
387
0
           type_ == VariantType::OwnedString;
388
0
  }
389
390
0
  size_t nesting(const ResourceManager* resources) const {
391
0
    auto collection = asCollection();
392
0
    if (collection)
393
0
      return collection->nesting(resources);
394
0
    else
395
0
      return 0;
396
0
  }
397
398
  static size_t nesting(const VariantData* var,
399
0
                        const ResourceManager* resources) {
400
0
    if (!var)
401
0
      return 0;
402
0
    return var->nesting(resources);
403
0
  }
404
405
0
  void removeElement(size_t index, ResourceManager* resources) {
406
0
    ArrayData::removeElement(asArray(), index, resources);
407
0
  }
408
409
  static void removeElement(VariantData* var, size_t index,
410
0
                            ResourceManager* resources) {
411
0
    if (!var)
412
0
      return;
413
0
    var->removeElement(index, resources);
414
0
  }
415
416
  template <typename TAdaptedString>
417
  void removeMember(TAdaptedString key, ResourceManager* resources) {
418
    ObjectData::removeMember(asObject(), key, resources);
419
  }
420
421
  template <typename TAdaptedString>
422
  static void removeMember(VariantData* var, TAdaptedString key,
423
                           ResourceManager* resources) {
424
    if (!var)
425
      return;
426
    var->removeMember(key, resources);
427
  }
428
429
2.40k
  void reset() {  // TODO: remove
430
2.40k
    type_ = VariantType::Null;
431
2.40k
  }
432
433
525
  void setBoolean(bool value) {
434
525
    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
435
525
    type_ = VariantType::Boolean;
436
525
    content_.asBoolean = value;
437
525
  }
438
439
  template <typename T>
440
3.88k
  enable_if_t<sizeof(T) == 4, bool> setFloat(T value, ResourceManager*) {
441
3.88k
    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
442
3.88k
    type_ = VariantType::Float;
443
3.88k
    content_.asFloat = value;
444
3.88k
    return true;
445
3.88k
  }
446
447
  template <typename T>
448
  enable_if_t<sizeof(T) == 8, bool> setFloat(T value, ResourceManager*);
449
450
  template <typename T>
451
  enable_if_t<is_signed<T>::value, bool> setInteger(T value,
452
                                                    ResourceManager* resources);
453
454
  template <typename T>
455
  enable_if_t<is_unsigned<T>::value, bool> setInteger(
456
      T value, ResourceManager* resources);
457
458
0
  void setRawString(StringNode* s) {
459
0
    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
460
0
    ARDUINOJSON_ASSERT(s);
461
0
    type_ = VariantType::RawString;
462
0
    content_.asOwnedString = s;
463
0
  }
464
465
  template <typename T>
466
  void setRawString(SerializedValue<T> value, ResourceManager* resources);
467
468
  template <typename T>
469
  static void setRawString(VariantData* var, SerializedValue<T> value,
470
0
                           ResourceManager* resources) {
471
0
    if (!var)
472
0
      return;
473
0
    var->clear(resources);
474
0
    var->setRawString(value, resources);
475
0
  }
476
477
  template <typename TAdaptedString>
478
  bool setString(TAdaptedString value, ResourceManager* resources);
479
480
2.46k
  bool setString(StringNode* s, ResourceManager*) {
481
2.46k
    setOwnedString(s);
482
2.46k
    return true;
483
2.46k
  }
484
485
  template <typename TAdaptedString>
486
  static void setString(VariantData* var, TAdaptedString value,
487
0
                        ResourceManager* resources) {
488
0
    if (!var)
489
0
      return;
490
0
    var->clear(resources);
491
0
    var->setString(value, resources);
492
0
  }
Unexecuted instantiation: void ArduinoJson::V710HB42::detail::VariantData::setString<ArduinoJson::V710HB42::detail::StaticStringAdapter>(ArduinoJson::V710HB42::detail::VariantData*, ArduinoJson::V710HB42::detail::StaticStringAdapter, ArduinoJson::V710HB42::detail::ResourceManager*)
Unexecuted instantiation: void ArduinoJson::V710HB42::detail::VariantData::setString<ArduinoJson::V710HB42::detail::JsonStringAdapter>(ArduinoJson::V710HB42::detail::VariantData*, ArduinoJson::V710HB42::detail::JsonStringAdapter, ArduinoJson::V710HB42::detail::ResourceManager*)
493
494
0
  void setLinkedString(const char* s) {
495
0
    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
496
0
    ARDUINOJSON_ASSERT(s);
497
0
    type_ = VariantType::LinkedString;
498
0
    content_.asLinkedString = s;
499
0
  }
500
501
3.53k
  void setOwnedString(StringNode* s) {
502
3.53k
    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
503
3.53k
    ARDUINOJSON_ASSERT(s);
504
3.53k
    type_ = VariantType::OwnedString;
505
3.53k
    content_.asOwnedString = s;
506
3.53k
  }
507
508
0
  size_t size(const ResourceManager* resources) const {
509
0
    if (isObject())
510
0
      return content_.asObject.size(resources);
511
0
512
0
    if (isArray())
513
0
      return content_.asArray.size(resources);
514
0
515
0
    return 0;
516
0
  }
517
518
0
  static size_t size(const VariantData* var, const ResourceManager* resources) {
519
0
    return var != 0 ? var->size(resources) : 0;
520
0
  }
521
522
2.03k
  ArrayData& toArray() {
523
2.03k
    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
524
2.03k
    type_ = VariantType::Array;
525
2.03k
    new (&content_.asArray) ArrayData();
526
2.03k
    return content_.asArray;
527
2.03k
  }
528
529
0
  static ArrayData* toArray(VariantData* var, ResourceManager* resources) {
530
0
    if (!var)
531
0
      return 0;
532
0
    var->clear(resources);
533
0
    return &var->toArray();
534
0
  }
535
536
1.83k
  ObjectData& toObject() {
537
1.83k
    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
538
1.83k
    type_ = VariantType::Object;
539
1.83k
    new (&content_.asObject) ObjectData();
540
1.83k
    return content_.asObject;
541
1.83k
  }
542
543
0
  static ObjectData* toObject(VariantData* var, ResourceManager* resources) {
544
0
    if (!var)
545
0
      return 0;
546
0
    var->clear(resources);
547
0
    return &var->toObject();
548
0
  }
549
550
0
  VariantType type() const {
551
0
    return type_;
552
0
  }
553
554
  // Release the resources used by this variant and set it to null.
555
  void clear(ResourceManager* resources);
556
557
0
  static void clear(VariantData* var, ResourceManager* resources) {
558
0
    if (!var)
559
0
      return;
560
0
    var->clear(resources);
561
0
  }
562
};
563
564
ARDUINOJSON_END_PRIVATE_NAMESPACE