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

bblanchon / ArduinoJson / 5641653306

pending completion
5641653306

push

github

bblanchon
friend member

32 of 32 new or added lines in 4 files covered. (100.0%)

3444 of 3458 relevant lines covered (99.6%)

8764.75 hits per line

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

98.88
/src/ArduinoJson/Variant/ConverterImpl.hpp
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2023, 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
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
13

14
template <typename T, typename Enable>
15
struct Converter {
16
  static void toJson(const T& src, JsonVariant dst) {
126✔
17
    // clang-format off
18
    convertToJson(src, dst); // Error here? See https://arduinojson.org/v6/unsupported-set/
126✔
19
    // clang-format on
20
  }
126✔
21

22
  static T fromJson(JsonVariantConst src) {
373✔
23
    // clang-format off
24
    T result; // Error here? See https://arduinojson.org/v6/non-default-constructible/
372✔
25
    convertFromJson(src, result);  // Error here? See https://arduinojson.org/v6/unsupported-as/
373✔
26
    // clang-format on
27
    return result;
373✔
28
  }
29

30
  static bool checkJson(JsonVariantConst src) {
25✔
31
    T dummy = T();
46✔
32
    // clang-format off
33
    return canConvertFromJson(src, dummy);  // Error here? See https://arduinojson.org/v6/unsupported-is/
50✔
34
    // clang-format on
35
  }
36
};
37

38
template <typename T>
39
struct Converter<
40
    T, typename detail::enable_if<detail::is_integral<T>::value &&
41
                                  !detail::is_same<bool, T>::value &&
42
                                  !detail::is_same<char, T>::value>::type>
43
    : private detail::VariantAttorney {
44
  static void toJson(T src, JsonVariant dst) {
976✔
45
    ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
46
    auto data = getData(dst);
976✔
47
    if (data)
976✔
48
      data->setInteger(src, getResourceManager(dst));
951✔
49
  }
976✔
50

51
  static T fromJson(JsonVariantConst src) {
212✔
52
    ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
53
    auto data = getData(src);
212✔
54
    return data ? data->template asIntegral<T>() : T();
212✔
55
  }
56

57
  static bool checkJson(JsonVariantConst src) {
110✔
58
    auto data = getData(src);
110✔
59
    return data && data->template isInteger<T>();
110✔
60
  }
61
};
62

63
template <typename T>
64
struct Converter<T, typename detail::enable_if<detail::is_enum<T>::value>::type>
65
    : private detail::VariantAttorney {
66
  static void toJson(T src, JsonVariant dst) {
1✔
67
    dst.set(static_cast<JsonInteger>(src));
1✔
68
  }
1✔
69

70
  static T fromJson(JsonVariantConst src) {
1✔
71
    auto data = getData(src);
1✔
72
    return data ? static_cast<T>(data->template asIntegral<int>()) : T();
1✔
73
  }
74

75
  static bool checkJson(JsonVariantConst src) {
18✔
76
    auto data = getData(src);
18✔
77
    return data && data->template isInteger<int>();
18✔
78
  }
79
};
80

81
template <>
82
struct Converter<bool> : private detail::VariantAttorney {
83
  static void toJson(bool src, JsonVariant dst) {
250✔
84
    auto data = getData(dst);
250✔
85
    if (data)
250✔
86
      data->setBoolean(src, getResourceManager(dst));
247✔
87
  }
250✔
88

89
  static bool fromJson(JsonVariantConst src) {
1,252✔
90
    auto data = getData(src);
1,252✔
91
    return data ? data->asBoolean() : false;
1,252✔
92
  }
93

94
  static bool checkJson(JsonVariantConst src) {
38✔
95
    auto data = getData(src);
38✔
96
    return data && data->isBoolean();
38✔
97
  }
98
};
99

100
template <typename T>
101
struct Converter<
102
    T, typename detail::enable_if<detail::is_floating_point<T>::value>::type>
103
    : private detail::VariantAttorney {
104
  static void toJson(T src, JsonVariant dst) {
63✔
105
    auto data = getData(dst);
63✔
106
    if (data)
63✔
107
      data->setFloat(static_cast<JsonFloat>(src), getResourceManager(dst));
61✔
108
  }
63✔
109

110
  static T fromJson(JsonVariantConst src) {
118✔
111
    auto data = getData(src);
118✔
112
    return data ? data->template asFloat<T>() : 0;
118✔
113
  }
114

115
  static bool checkJson(JsonVariantConst src) {
45✔
116
    auto data = getData(src);
45✔
117
    return data && data->isFloat();
45✔
118
  }
119
};
120

121
template <>
122
struct Converter<const char*> : private detail::VariantAttorney {
123
  static void toJson(const char* src, JsonVariant dst) {
65,838✔
124
    detail::VariantData::setString(getData(dst), detail::adaptString(src),
131,676✔
125
                                   getResourceManager(dst));
126
  }
65,838✔
127

128
  static const char* fromJson(JsonVariantConst src) {
38✔
129
    auto data = getData(src);
38✔
130
    return data ? data->asString().c_str() : 0;
38✔
131
  }
132

133
  static bool checkJson(JsonVariantConst src) {
35✔
134
    auto data = getData(src);
35✔
135
    return data && data->isString();
35✔
136
  }
137
};
138

139
template <>
140
struct Converter<JsonString> : private detail::VariantAttorney {
141
  static void toJson(JsonString src, JsonVariant dst) {
28✔
142
    detail::VariantData::setString(getData(dst), detail::adaptString(src),
56✔
143
                                   getResourceManager(dst));
144
  }
28✔
145

146
  static JsonString fromJson(JsonVariantConst src) {
398✔
147
    auto data = getData(src);
398✔
148
    return data ? data->asString() : 0;
398✔
149
  }
150

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

157
template <typename T>
158
inline typename detail::enable_if<detail::IsString<T>::value>::type
159
convertToJson(const T& src, JsonVariant dst) {
107✔
160
  using namespace detail;
161
  auto data = VariantAttorney::getData(dst);
107✔
162
  auto resources = VariantAttorney::getResourceManager(dst);
107✔
163
  detail::VariantData::setString(data, adaptString(src), resources);
107✔
164
}
107✔
165

166
// SerializedValue<std::string>
167
// SerializedValue<String>
168
// SerializedValue<const __FlashStringHelper*>
169
template <typename T>
170
struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
171
  static void toJson(SerializedValue<T> src, JsonVariant dst) {
37✔
172
    detail::VariantData::setRawString(getData(dst), src,
74✔
173
                                      getResourceManager(dst));
174
  }
37✔
175
};
176

177
template <>
178
struct Converter<detail::nullptr_t> : private detail::VariantAttorney {
179
  static void toJson(detail::nullptr_t, JsonVariant dst) {
6✔
180
    detail::VariantData::setNull(getData(dst), getResourceManager(dst));
12✔
181
  }
6✔
182
  static detail::nullptr_t fromJson(JsonVariantConst) {
1✔
183
    return nullptr;
1✔
184
  }
185
  static bool checkJson(JsonVariantConst src) {
3✔
186
    auto data = getData(src);
3✔
187
    return data == 0 || data->isNull();
3✔
188
  }
189
};
190

191
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
192

193
namespace detail {
194
class StringBuilderPrint : public Print {
195
 public:
196
  StringBuilderPrint(ResourceManager* resources) : copier_(resources) {
8✔
197
    copier_.startString();
8✔
198
  }
8✔
199

200
  StringNode* save() {
4✔
201
    ARDUINOJSON_ASSERT(!overflowed());
202
    return copier_.save();
4✔
203
  }
204

205
  size_t write(uint8_t c) {
52✔
206
    copier_.append(char(c));
52✔
207
    return copier_.isValid() ? 1 : 0;
52✔
208
  }
209

210
  size_t write(const uint8_t* buffer, size_t size) {
4✔
211
    for (size_t i = 0; i < size; i++) {
54✔
212
      copier_.append(char(buffer[i]));
52✔
213
      if (!copier_.isValid())
52✔
214
        return i;
2✔
215
    }
216
    return size;
2✔
217
  }
218

219
  bool overflowed() const {
8✔
220
    return !copier_.isValid();
8✔
221
  }
222

223
 private:
224
  StringBuilder copier_;
225
};
226
}  // namespace detail
227

228
inline void convertToJson(const ::Printable& src, JsonVariant dst) {
9✔
229
  auto resources = detail::VariantAttorney::getResourceManager(dst);
9✔
230
  auto data = detail::VariantAttorney::getData(dst);
9✔
231
  if (!resources || !data)
9✔
232
    return;
5✔
233
  detail::StringBuilderPrint print(resources);
8✔
234
  src.printTo(print);
8✔
235
  if (print.overflowed()) {
8✔
236
    data->setNull();
4✔
237
    return;
4✔
238
  }
239
  data->setOwnedString(print.save());
4✔
240
}
241

242
#endif
243

244
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
245

246
inline void convertFromJson(JsonVariantConst src, ::String& dst) {
247
  JsonString str = src.as<JsonString>();
248
  if (str)
249
    dst = str.c_str();
250
  else
251
    serializeJson(src, dst);
252
}
253

254
inline bool canConvertFromJson(JsonVariantConst src, const ::String&) {
255
  return src.is<JsonString>();
256
}
257

258
#endif
259

260
#if ARDUINOJSON_ENABLE_STD_STRING
261

262
inline void convertFromJson(JsonVariantConst src, std::string& dst) {
368✔
263
  JsonString str = src.as<JsonString>();
264
  if (str)
368✔
265
    dst.assign(str.c_str(), str.size());
52✔
266
  else
267
    serializeJson(src, dst);
316✔
268
}
368✔
269

270
inline bool canConvertFromJson(JsonVariantConst src, const std::string&) {
21✔
271
  return src.is<JsonString>();
21✔
272
}
273

274
#endif
275

276
#if ARDUINOJSON_ENABLE_STRING_VIEW
277

278
inline void convertFromJson(JsonVariantConst src, std::string_view& dst) {
4✔
279
  JsonString str = src.as<JsonString>();
280
  if (str)  // the standard doesn't allow passing null to the constructor
4✔
281
    dst = std::string_view(str.c_str(), str.size());
3✔
282
}
4✔
283

284
inline bool canConvertFromJson(JsonVariantConst src, const std::string_view&) {
2✔
285
  return src.is<JsonString>();
2✔
286
}
287

288
#endif
289

290
namespace detail {
291
template <typename T>
292
struct ConverterNeedsWriteableRef {
293
 protected:  // <- to avoid GCC's "all member functions in class are private"
294
  static int probe(T (*f)(ArduinoJson::JsonVariant));
295
  static char probe(T (*f)(ArduinoJson::JsonVariantConst));
296

297
 public:
298
  static const bool value =
299
      sizeof(probe(Converter<T>::fromJson)) == sizeof(int);
300
};
301
}  // namespace detail
302

303
template <>
304
struct Converter<JsonArrayConst> : private detail::VariantAttorney {
305
  static void toJson(JsonArrayConst src, JsonVariant dst) {
4✔
306
    if (src.isNull())
4✔
307
      dst.set(nullptr);
×
308
    else
309
      dst.to<JsonArray>().set(src);
8✔
310
  }
4✔
311

312
  static JsonArrayConst fromJson(JsonVariantConst src) {
33✔
313
    auto data = getData(src);
33✔
314
    auto array = data ? data->asArray() : nullptr;
33✔
315
    return JsonArrayConst(array, getResourceManager(src));
33✔
316
  }
317

318
  static bool checkJson(JsonVariantConst src) {
82✔
319
    auto data = getData(src);
82✔
320
    return data && data->isArray();
82✔
321
  }
322
};
323

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

333
  static JsonArray fromJson(JsonVariant src) {
76✔
334
    auto data = getData(src);
76✔
335
    auto resources = getResourceManager(src);
76✔
336
    return JsonArray(data != 0 ? data->asArray() : 0, resources);
152✔
337
  }
338

339
  static detail::InvalidConversion<JsonVariantConst, JsonArray> fromJson(
340
      JsonVariantConst);
341

342
  static bool checkJson(JsonVariantConst) {
9✔
343
    return false;
9✔
344
  }
345

346
  static bool checkJson(JsonVariant src) {
20✔
347
    auto data = getData(src);
20✔
348
    return data && data->isArray();
20✔
349
  }
350
};
351

352
template <>
353
struct Converter<JsonObjectConst> : private detail::VariantAttorney {
354
  static void toJson(JsonVariantConst src, JsonVariant dst) {
7✔
355
    if (src.isNull())
7✔
356
      dst.set(nullptr);
×
357
    else
358
      dst.to<JsonObject>().set(src);
14✔
359
  }
7✔
360

361
  static JsonObjectConst fromJson(JsonVariantConst src) {
18✔
362
    auto data = getData(src);
18✔
363
    auto object = data != 0 ? data->asObject() : nullptr;
18✔
364
    return JsonObjectConst(object, getResourceManager(src));
18✔
365
  }
366

367
  static bool checkJson(JsonVariantConst src) {
304✔
368
    auto data = getData(src);
304✔
369
    return data && data->isObject();
304✔
370
  }
371
};
372

373
template <>
374
struct Converter<JsonObject> : private detail::VariantAttorney {
375
  static void toJson(JsonVariantConst src, JsonVariant dst) {
11✔
376
    if (src.isNull())
11✔
377
      dst.set(nullptr);
2✔
378
    else
379
      dst.to<JsonObject>().set(src);
20✔
380
  }
11✔
381

382
  static JsonObject fromJson(JsonVariant src) {
97✔
383
    auto data = getData(src);
97✔
384
    auto resources = getResourceManager(src);
97✔
385
    return JsonObject(data != 0 ? data->asObject() : 0, resources);
194✔
386
  }
387

388
  static detail::InvalidConversion<JsonVariantConst, JsonObject> fromJson(
389
      JsonVariantConst);
390

391
  static bool checkJson(JsonVariantConst) {
9✔
392
    return false;
9✔
393
  }
394

395
  static bool checkJson(JsonVariant src) {
53✔
396
    auto data = getData(src);
53✔
397
    return data && data->isObject();
53✔
398
  }
399
};
400

401
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

© 2025 Coveralls, Inc