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

bblanchon / ArduinoJson / 10680315983

03 Sep 2024 09:30AM CUT coverage: 99.497%. First build
10680315983

push

github

bblanchon
Fu

2 of 2 new or added lines in 1 file covered. (100.0%)

3957 of 3977 relevant lines covered (99.5%)

10631.34 hits per line

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

98.94
/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) {
441✔
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/
440✔
40
    convertFromJson(src, result);  // Error here? See https://arduinojson.org/v7/unsupported-as/
441✔
41
    // clang-format on
42
    return result;
441✔
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,418✔
62
    ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
63
    auto data = getData(dst);
1,418✔
64
    if (!data)
1,418✔
65
      return false;
16✔
66
    auto resources = getResourceManager(dst);
1,402✔
67
    data->clear(resources);
1,402✔
68
    return data->setInteger(src, resources);
1,402✔
69
  }
70

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

224
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
225

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

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

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

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

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

256
 private:
257
  StringBuilder copier_;
258
};
259
}  // namespace detail
260

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

274
#endif
275

276
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
277

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

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

290
#endif
291

292
#if ARDUINOJSON_ENABLE_STD_STRING
293

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

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

306
#endif
307

308
#if ARDUINOJSON_ENABLE_STRING_VIEW
309

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

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

320
#endif
321

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

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

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

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

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

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

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

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

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

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

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

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

406
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