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

bblanchon / ArduinoJson / 9401199389

06 Jun 2024 12:50PM CUT coverage: 99.563% (+0.2%) from 99.362%
9401199389

push

github

bblanchon
Rewrite fromJson

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

3876 of 3893 relevant lines covered (99.56%)

10740.81 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-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,020✔
62
    ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
63
    auto data = getData(dst);
1,020✔
64
    if (!data)
1,020✔
65
      return false;
16✔
66
    data->setInteger(src, getResourceManager(dst));
1,004✔
67
    return true;
1,004✔
68
  }
69

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

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

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

89
  static T fromJson(JsonVariantConst src) {
1✔
90
    auto data = getData(src);
1✔
91
    return data ? static_cast<T>(data->template asIntegral<int>()) : T();
1✔
92
  }
93

94
  static bool checkJson(JsonVariantConst src) {
18✔
95
    auto data = getData(src);
18✔
96
    return data && data->template isInteger<int>();
18✔
97
  }
98
};
99

100
template <>
101
struct Converter<bool> : private detail::VariantAttorney {
102
  static bool toJson(bool src, JsonVariant dst) {
250✔
103
    auto data = getData(dst);
250✔
104
    if (!data)
250✔
105
      return false;
2✔
106
    data->setBoolean(src, getResourceManager(dst));
248✔
107
    return true;
248✔
108
  }
109

110
  static bool fromJson(JsonVariantConst src) {
1,248✔
111
    auto data = getData(src);
1,248✔
112
    return data ? data->asBoolean() : false;
1,248✔
113
  }
114

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

121
template <typename T>
122
struct Converter<T, detail::enable_if_t<detail::is_floating_point<T>::value>>
123
    : private detail::VariantAttorney {
124
  static bool toJson(T src, JsonVariant dst) {
62✔
125
    auto data = getData(dst);
62✔
126
    if (!data)
62✔
127
      return false;
1✔
128
    data->setFloat(static_cast<JsonFloat>(src), getResourceManager(dst));
61✔
129
    return true;
61✔
130
  }
131

132
  static T fromJson(JsonVariantConst src) {
118✔
133
    auto data = getData(src);
118✔
134
    return data ? data->template asFloat<T>() : 0;
118✔
135
  }
136

137
  static bool checkJson(JsonVariantConst src) {
45✔
138
    auto data = getData(src);
45✔
139
    return data && data->isFloat();
45✔
140
  }
141
};
142

143
template <>
144
struct Converter<const char*> : private detail::VariantAttorney {
145
  static void toJson(const char* src, JsonVariant dst) {
65,903✔
146
    detail::VariantData::setString(getData(dst), detail::adaptString(src),
65,903✔
147
                                   getResourceManager(dst));
148
  }
65,903✔
149

150
  static const char* fromJson(JsonVariantConst src) {
61✔
151
    auto data = getData(src);
61✔
152
    return data ? data->asString().c_str() : 0;
61✔
153
  }
154

155
  static bool checkJson(JsonVariantConst src) {
47✔
156
    auto data = getData(src);
47✔
157
    return data && data->isString();
47✔
158
  }
159
};
160

161
template <>
162
struct Converter<JsonString> : private detail::VariantAttorney {
163
  static void toJson(JsonString src, JsonVariant dst) {
44✔
164
    detail::VariantData::setString(getData(dst), detail::adaptString(src),
44✔
165
                                   getResourceManager(dst));
166
  }
44✔
167

168
  static JsonString fromJson(JsonVariantConst src) {
465✔
169
    auto data = getData(src);
465✔
170
    return data ? data->asString() : 0;
465✔
171
  }
172

173
  static bool checkJson(JsonVariantConst src) {
39✔
174
    auto data = getData(src);
39✔
175
    return data && data->isString();
39✔
176
  }
177
};
178

179
template <typename T>
180
inline detail::enable_if_t<detail::IsString<T>::value> convertToJson(
131✔
181
    const T& src, JsonVariant dst) {
182
  using namespace detail;
183
  auto data = VariantAttorney::getData(dst);
131✔
184
  auto resources = VariantAttorney::getResourceManager(dst);
131✔
185
  detail::VariantData::setString(data, adaptString(src), resources);
131✔
186
}
131✔
187

188
// SerializedValue<std::string>
189
// SerializedValue<String>
190
// SerializedValue<const __FlashStringHelper*>
191
template <typename T>
192
struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
193
  static void toJson(SerializedValue<T> src, JsonVariant dst) {
36✔
194
    detail::VariantData::setRawString(getData(dst), src,
36✔
195
                                      getResourceManager(dst));
196
  }
36✔
197
};
198

199
template <>
200
struct Converter<detail::nullptr_t> : private detail::VariantAttorney {
201
  static void toJson(detail::nullptr_t, JsonVariant dst) {
6✔
202
    detail::VariantData::setNull(getData(dst), getResourceManager(dst));
6✔
203
  }
6✔
204
  static detail::nullptr_t fromJson(JsonVariantConst) {
1✔
205
    return nullptr;
1✔
206
  }
207
  static bool checkJson(JsonVariantConst src) {
3✔
208
    auto data = getData(src);
3✔
209
    return data == 0 || data->isNull();
3✔
210
  }
211
};
212

213
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
214

215
namespace detail {
216
class StringBuilderPrint : public Print {
217
 public:
218
  StringBuilderPrint(ResourceManager* resources) : copier_(resources) {
8✔
219
    copier_.startString();
8✔
220
  }
8✔
221

222
  StringNode* save() {
4✔
223
    ARDUINOJSON_ASSERT(!overflowed());
224
    return copier_.save();
4✔
225
  }
226

227
  size_t write(uint8_t c) {
52✔
228
    copier_.append(char(c));
52✔
229
    return copier_.isValid() ? 1 : 0;
52✔
230
  }
231

232
  size_t write(const uint8_t* buffer, size_t size) {
4✔
233
    for (size_t i = 0; i < size; i++) {
54✔
234
      copier_.append(char(buffer[i]));
52✔
235
      if (!copier_.isValid())
52✔
236
        return i;
2✔
237
    }
238
    return size;
2✔
239
  }
240

241
  bool overflowed() const {
8✔
242
    return !copier_.isValid();
8✔
243
  }
244

245
 private:
246
  StringBuilder copier_;
247
};
248
}  // namespace detail
249

250
inline void convertToJson(const ::Printable& src, JsonVariant dst) {
9✔
251
  auto resources = detail::VariantAttorney::getResourceManager(dst);
9✔
252
  auto data = detail::VariantAttorney::getData(dst);
9✔
253
  if (!resources || !data)
9✔
254
    return;
5✔
255
  detail::StringBuilderPrint print(resources);
8✔
256
  src.printTo(print);
8✔
257
  if (print.overflowed()) {
8✔
258
    data->setNull();
4✔
259
    return;
4✔
260
  }
261
  data->setOwnedString(print.save());
4✔
262
}
263

264
#endif
265

266
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
267

268
inline void convertFromJson(JsonVariantConst src, ::String& dst) {
269
  JsonString str = src.as<JsonString>();
270
  if (str)
271
    dst = str.c_str();
272
  else
273
    serializeJson(src, dst);
274
}
275

276
inline bool canConvertFromJson(JsonVariantConst src, const ::String&) {
277
  return src.is<JsonString>();
278
}
279

280
#endif
281

282
#if ARDUINOJSON_ENABLE_STD_STRING
283

284
inline void convertFromJson(JsonVariantConst src, std::string& dst) {
434✔
285
  JsonString str = src.as<JsonString>();
434✔
286
  if (str)
434✔
287
    dst.assign(str.c_str(), str.size());
55✔
288
  else
289
    serializeJson(src, dst);
379✔
290
}
434✔
291

292
inline bool canConvertFromJson(JsonVariantConst src, const std::string&) {
21✔
293
  return src.is<JsonString>();
21✔
294
}
295

296
#endif
297

298
#if ARDUINOJSON_ENABLE_STRING_VIEW
299

300
inline void convertFromJson(JsonVariantConst src, std::string_view& dst) {
5✔
301
  JsonString str = src.as<JsonString>();
5✔
302
  if (str)  // the standard doesn't allow passing null to the constructor
5✔
303
    dst = std::string_view(str.c_str(), str.size());
4✔
304
}
5✔
305

306
inline bool canConvertFromJson(JsonVariantConst src, const std::string_view&) {
2✔
307
  return src.is<JsonString>();
2✔
308
}
309

310
#endif
311

312
template <>
313
struct Converter<JsonArrayConst> : private detail::VariantAttorney {
314
  static void toJson(JsonArrayConst src, JsonVariant dst) {
3✔
315
    if (src.isNull())
3✔
316
      dst.set(nullptr);
×
317
    else
318
      dst.to<JsonArray>().set(src);
3✔
319
  }
3✔
320

321
  static JsonArrayConst fromJson(JsonVariantConst src) {
34✔
322
    auto data = getData(src);
34✔
323
    auto array = data ? data->asArray() : nullptr;
34✔
324
    return JsonArrayConst(array, getResourceManager(src));
34✔
325
  }
326

327
  static bool checkJson(JsonVariantConst src) {
80✔
328
    auto data = getData(src);
80✔
329
    return data && data->isArray();
80✔
330
  }
331
};
332

333
template <>
334
struct Converter<JsonArray> : private detail::VariantAttorney {
335
  static void toJson(JsonVariantConst src, JsonVariant dst) {
11✔
336
    if (src.isNull())
11✔
337
      dst.set(nullptr);
1✔
338
    else
339
      dst.to<JsonArray>().set(src);
10✔
340
  }
11✔
341

342
  static JsonArray fromJson(JsonVariant src) {
75✔
343
    auto data = getData(src);
75✔
344
    auto resources = getResourceManager(src);
75✔
345
    return JsonArray(data != 0 ? data->asArray() : 0, resources);
75✔
346
  }
347

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

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

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

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

375
template <>
376
struct Converter<JsonObject> : private detail::VariantAttorney {
377
  static void toJson(JsonVariantConst src, JsonVariant dst) {
18✔
378
    if (src.isNull())
18✔
379
      dst.set(nullptr);
1✔
380
    else
381
      dst.to<JsonObject>().set(src);
17✔
382
  }
18✔
383

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

390
  static bool checkJson(JsonVariant src) {
44✔
391
    auto data = getData(src);
44✔
392
    return data && data->isObject();
44✔
393
  }
394
};
395

396
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