• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bblanchon / ArduinoJson / 10572597112

27 Aug 2024 06:03AM UTC coverage: 99.194% (-0.3%) from 99.512%
10572597112

push

github

bblanchon
Merge conf_test for linux and windows

This reverts commit 83516e174.

3940 of 3972 relevant lines covered (99.19%)

10537.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.95
/src/ArduinoJson/Variant/ConverterImpl.hpp
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2024, Benoit BLANCHON
3
// MIT License
4

5
#pragma once
6

7
#include <ArduinoJson/Json/JsonSerializer.hpp>
8
#include <ArduinoJson/Memory/StringBuilder.hpp>
9
#include <ArduinoJson/Polyfills/utility.hpp>
10
#include <ArduinoJson/Variant/JsonVariantConst.hpp>
11

12
#if ARDUINOJSON_ENABLE_STD_STRING
13
#  include <string>
14
#endif
15

16
#if ARDUINOJSON_ENABLE_STRING_VIEW
17
#  include <string_view>
18
#endif
19

20
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
21

22
template <typename T, typename Enable>
23
struct Converter {
24
  static_assert(!detail::is_same<T, char>::value,
25
                "type 'char' is not supported, use 'signed char', 'unsigned "
26
                "char' or another integer type instead");
27

28
  static void toJson(const T& src, JsonVariant dst) {
152✔
29
    // clang-format off
30
    convertToJson(src, dst); // Error here? See https://arduinojson.org/v7/unsupported-set/
152✔
31
    // clang-format on
32
  }
152✔
33

34
  static T fromJson(JsonVariantConst src) {
440✔
35
    static_assert(!detail::is_same<T, char*>::value,
36
                  "type 'char*' is not supported, use 'const char*' instead");
37

38
    // clang-format off
39
    T result; // Error here? See https://arduinojson.org/v7/non-default-constructible/
439✔
40
    convertFromJson(src, result);  // Error here? See https://arduinojson.org/v7/unsupported-as/
440✔
41
    // clang-format on
42
    return result;
440✔
43
  }
44

45
  static bool checkJson(JsonVariantConst src) {
25✔
46
    static_assert(!detail::is_same<T, char*>::value,
47
                  "type 'char*' is not supported, use 'const char*' instead");
48

49
    T dummy = T();
46✔
50
    // clang-format off
51
    return canConvertFromJson(src, dummy);  // Error here? See https://arduinojson.org/v7/unsupported-is/
50✔
52
    // clang-format on
53
  }
54
};
55

56
template <typename T>
57
struct Converter<T, detail::enable_if_t<detail::is_integral<T>::value &&
58
                                        !detail::is_same<bool, T>::value &&
59
                                        !detail::is_same<char, T>::value>>
60
    : private detail::VariantAttorney {
61
  static bool toJson(T src, JsonVariant dst) {
1,408✔
62
    ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
63
    auto data = getData(dst);
1,408✔
64
    if (!data)
1,408✔
65
      return false;
16✔
66
    auto resources = getResourceManager(dst);
1,392✔
67
    data->clear(resources);
1,392✔
68
    data->setInteger(src, resources);
1,392✔
69
    return true;
1,392✔
70
  }
71

72
  static T fromJson(JsonVariantConst src) {
183✔
73
    ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
74
    auto data = getData(src);
183✔
75
    auto resources = getResourceManager(src);
183✔
76
    return data ? data->template asIntegral<T>(resources) : T();
183✔
77
  }
78

79
  static bool checkJson(JsonVariantConst src) {
131✔
80
    auto data = getData(src);
131✔
81
    auto resources = getResourceManager(src);
131✔
82
    return data && data->template isInteger<T>(resources);
131✔
83
  }
84
};
85

86
template <typename T>
87
struct Converter<T, detail::enable_if_t<detail::is_enum<T>::value>>
88
    : private detail::VariantAttorney {
89
  static bool toJson(T src, JsonVariant dst) {
1✔
90
    return dst.set(static_cast<JsonInteger>(src));
1✔
91
  }
92

93
  static T fromJson(JsonVariantConst src) {
1✔
94
    auto data = getData(src);
1✔
95
    auto resources = getResourceManager(src);
1✔
96
    return data ? static_cast<T>(data->template asIntegral<int>(resources))
1✔
97
                : T();
1✔
98
  }
99

100
  static bool checkJson(JsonVariantConst src) {
18✔
101
    auto data = getData(src);
18✔
102
    auto resources = getResourceManager(src);
18✔
103
    return data && data->template isInteger<int>(resources);
18✔
104
  }
105
};
106

107
template <>
108
struct Converter<bool> : private detail::VariantAttorney {
109
  static bool toJson(bool src, JsonVariant dst) {
250✔
110
    auto data = getData(dst);
250✔
111
    if (!data)
250✔
112
      return false;
2✔
113
    auto resources = getResourceManager(dst);
248✔
114
    data->clear(resources);
248✔
115
    data->setBoolean(src);
248✔
116
    return true;
248✔
117
  }
118

119
  static bool fromJson(JsonVariantConst src) {
1,248✔
120
    auto data = getData(src);
1,248✔
121
    auto resources = getResourceManager(src);
1,248✔
122
    return data ? data->asBoolean(resources) : false;
1,248✔
123
  }
124

125
  static bool checkJson(JsonVariantConst src) {
38✔
126
    auto data = getData(src);
38✔
127
    return data && data->isBoolean();
38✔
128
  }
129
};
130

131
template <typename T>
132
struct Converter<T, detail::enable_if_t<detail::is_floating_point<T>::value>>
133
    : private detail::VariantAttorney {
134
  static bool toJson(T src, JsonVariant dst) {
62✔
135
    auto data = getData(dst);
62✔
136
    if (!data)
62✔
137
      return false;
1✔
138
    auto resources = getResourceManager(dst);
61✔
139
    data->clear(resources);
61✔
140
    data->setFloat(src, resources);
61✔
141
    return true;
61✔
142
  }
143

144
  static T fromJson(JsonVariantConst src) {
44✔
145
    auto data = getData(src);
44✔
146
    auto resources = getResourceManager(src);
44✔
147
    return data ? data->template asFloat<T>(resources) : 0;
44✔
148
  }
149

150
  static bool checkJson(JsonVariantConst src) {
45✔
151
    auto data = getData(src);
45✔
152
    return data && data->isFloat();
45✔
153
  }
154
};
155

156
template <>
157
struct Converter<const char*> : private detail::VariantAttorney {
158
  static void toJson(const char* src, JsonVariant dst) {
65,905✔
159
    detail::VariantData::setString(getData(dst), detail::adaptString(src),
65,905✔
160
                                   getResourceManager(dst));
161
  }
65,905✔
162

163
  static const char* fromJson(JsonVariantConst src) {
61✔
164
    auto data = getData(src);
61✔
165
    return data ? data->asString().c_str() : 0;
61✔
166
  }
167

168
  static bool checkJson(JsonVariantConst src) {
47✔
169
    auto data = getData(src);
47✔
170
    return data && data->isString();
47✔
171
  }
172
};
173

174
template <>
175
struct Converter<JsonString> : private detail::VariantAttorney {
176
  static void toJson(JsonString src, JsonVariant dst) {
44✔
177
    detail::VariantData::setString(getData(dst), detail::adaptString(src),
44✔
178
                                   getResourceManager(dst));
179
  }
44✔
180

181
  static JsonString fromJson(JsonVariantConst src) {
465✔
182
    auto data = getData(src);
465✔
183
    return data ? data->asString() : 0;
465✔
184
  }
185

186
  static bool checkJson(JsonVariantConst src) {
39✔
187
    auto data = getData(src);
39✔
188
    return data && data->isString();
39✔
189
  }
190
};
191

192
template <typename T>
193
inline detail::enable_if_t<detail::IsString<T>::value> convertToJson(
131✔
194
    const T& src, JsonVariant dst) {
195
  using namespace detail;
196
  auto data = VariantAttorney::getData(dst);
131✔
197
  auto resources = VariantAttorney::getResourceManager(dst);
131✔
198
  detail::VariantData::setString(data, adaptString(src), resources);
131✔
199
}
131✔
200

201
// SerializedValue<std::string>
202
// SerializedValue<String>
203
// SerializedValue<const __FlashStringHelper*>
204
template <typename T>
205
struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
206
  static void toJson(SerializedValue<T> src, JsonVariant dst) {
36✔
207
    detail::VariantData::setRawString(getData(dst), src,
36✔
208
                                      getResourceManager(dst));
209
  }
36✔
210
};
211

212
template <>
213
struct Converter<detail::nullptr_t> : private detail::VariantAttorney {
214
  static void toJson(detail::nullptr_t, JsonVariant dst) {
6✔
215
    detail::VariantData::clear(getData(dst), getResourceManager(dst));
6✔
216
  }
6✔
217
  static detail::nullptr_t fromJson(JsonVariantConst) {
1✔
218
    return nullptr;
1✔
219
  }
220
  static bool checkJson(JsonVariantConst src) {
3✔
221
    auto data = getData(src);
3✔
222
    return data == 0 || data->isNull();
3✔
223
  }
224
};
225

226
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
227

228
namespace detail {
229
class StringBuilderPrint : public Print {
230
 public:
231
  StringBuilderPrint(ResourceManager* resources) : copier_(resources) {
8✔
232
    copier_.startString();
8✔
233
  }
8✔
234

235
  StringNode* save() {
4✔
236
    ARDUINOJSON_ASSERT(!overflowed());
237
    return copier_.save();
4✔
238
  }
239

240
  size_t write(uint8_t c) {
52✔
241
    copier_.append(char(c));
52✔
242
    return copier_.isValid() ? 1 : 0;
52✔
243
  }
244

245
  size_t write(const uint8_t* buffer, size_t size) {
4✔
246
    for (size_t i = 0; i < size; i++) {
54✔
247
      copier_.append(char(buffer[i]));
52✔
248
      if (!copier_.isValid())
52✔
249
        return i;
2✔
250
    }
251
    return size;
2✔
252
  }
253

254
  bool overflowed() const {
8✔
255
    return !copier_.isValid();
8✔
256
  }
257

258
 private:
259
  StringBuilder copier_;
260
};
261
}  // namespace detail
262

263
inline void convertToJson(const ::Printable& src, JsonVariant dst) {
9✔
264
  auto resources = detail::VariantAttorney::getResourceManager(dst);
9✔
265
  auto data = detail::VariantAttorney::getData(dst);
9✔
266
  if (!resources || !data)
9✔
267
    return;
5✔
268
  data->clear(resources);
8✔
269
  detail::StringBuilderPrint print(resources);
8✔
270
  src.printTo(print);
8✔
271
  if (print.overflowed())
8✔
272
    return;
4✔
273
  data->setOwnedString(print.save());
4✔
274
}
275

276
#endif
277

278
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
279

280
inline void convertFromJson(JsonVariantConst src, ::String& dst) {
281
  JsonString str = src.as<JsonString>();
282
  if (str)
283
    dst = str.c_str();
284
  else
285
    serializeJson(src, dst);
286
}
287

288
inline bool canConvertFromJson(JsonVariantConst src, const ::String&) {
289
  return src.is<JsonString>();
290
}
291

292
#endif
293

294
#if ARDUINOJSON_ENABLE_STD_STRING
295

296
inline void convertFromJson(JsonVariantConst src, std::string& dst) {
434✔
297
  JsonString str = src.as<JsonString>();
434✔
298
  if (str)
434✔
299
    dst.assign(str.c_str(), str.size());
55✔
300
  else
301
    serializeJson(src, dst);
379✔
302
}
434✔
303

304
inline bool canConvertFromJson(JsonVariantConst src, const std::string&) {
21✔
305
  return src.is<JsonString>();
21✔
306
}
307

308
#endif
309

310
#if ARDUINOJSON_ENABLE_STRING_VIEW
311

312
inline void convertFromJson(JsonVariantConst src, std::string_view& dst) {
5✔
313
  JsonString str = src.as<JsonString>();
5✔
314
  if (str)  // the standard doesn't allow passing null to the constructor
5✔
315
    dst = std::string_view(str.c_str(), str.size());
4✔
316
}
5✔
317

318
inline bool canConvertFromJson(JsonVariantConst src, const std::string_view&) {
2✔
319
  return src.is<JsonString>();
2✔
320
}
321

322
#endif
323

324
template <>
325
struct Converter<JsonArrayConst> : private detail::VariantAttorney {
326
  static void toJson(JsonArrayConst src, JsonVariant dst) {
3✔
327
    if (src.isNull())
3✔
328
      dst.set(nullptr);
×
329
    else
330
      dst.to<JsonArray>().set(src);
3✔
331
  }
3✔
332

333
  static JsonArrayConst fromJson(JsonVariantConst src) {
34✔
334
    auto data = getData(src);
34✔
335
    auto array = data ? data->asArray() : nullptr;
34✔
336
    return JsonArrayConst(array, getResourceManager(src));
34✔
337
  }
338

339
  static bool checkJson(JsonVariantConst src) {
80✔
340
    auto data = getData(src);
80✔
341
    return data && data->isArray();
80✔
342
  }
343
};
344

345
template <>
346
struct Converter<JsonArray> : private detail::VariantAttorney {
347
  static void toJson(JsonVariantConst src, JsonVariant dst) {
11✔
348
    if (src.isNull())
11✔
349
      dst.set(nullptr);
1✔
350
    else
351
      dst.to<JsonArray>().set(src);
10✔
352
  }
11✔
353

354
  static JsonArray fromJson(JsonVariant src) {
75✔
355
    auto data = getData(src);
75✔
356
    auto resources = getResourceManager(src);
75✔
357
    return JsonArray(data != 0 ? data->asArray() : 0, resources);
75✔
358
  }
359

360
  static bool checkJson(JsonVariant src) {
16✔
361
    auto data = getData(src);
16✔
362
    return data && data->isArray();
16✔
363
  }
364
};
365

366
template <>
367
struct Converter<JsonObjectConst> : private detail::VariantAttorney {
368
  static void toJson(JsonVariantConst src, JsonVariant dst) {
9✔
369
    if (src.isNull())
9✔
370
      dst.set(nullptr);
×
371
    else
372
      dst.to<JsonObject>().set(src);
9✔
373
  }
9✔
374

375
  static JsonObjectConst fromJson(JsonVariantConst src) {
35✔
376
    auto data = getData(src);
35✔
377
    auto object = data != 0 ? data->asObject() : nullptr;
35✔
378
    return JsonObjectConst(object, getResourceManager(src));
35✔
379
  }
380

381
  static bool checkJson(JsonVariantConst src) {
303✔
382
    auto data = getData(src);
303✔
383
    return data && data->isObject();
303✔
384
  }
385
};
386

387
template <>
388
struct Converter<JsonObject> : private detail::VariantAttorney {
389
  static void toJson(JsonVariantConst src, JsonVariant dst) {
18✔
390
    if (src.isNull())
18✔
391
      dst.set(nullptr);
1✔
392
    else
393
      dst.to<JsonObject>().set(src);
17✔
394
  }
18✔
395

396
  static JsonObject fromJson(JsonVariant src) {
104✔
397
    auto data = getData(src);
104✔
398
    auto resources = getResourceManager(src);
104✔
399
    return JsonObject(data != 0 ? data->asObject() : 0, resources);
104✔
400
  }
401

402
  static bool checkJson(JsonVariant src) {
46✔
403
    auto data = getData(src);
46✔
404
    return data && data->isObject();
46✔
405
  }
406
};
407

408
ARDUINOJSON_END_PUBLIC_NAMESPACE
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc