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

bblanchon / ArduinoJson / 8738040343

18 Apr 2024 12:39PM CUT coverage: 99.589%. Remained the same
8738040343

push

github

bblanchon
Fix error "pasting X and Y does not give a valid preprocessing token"

3639 of 3654 relevant lines covered (99.59%)

13017.28 hits per line

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

98.89
/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) {
142✔
29
    // clang-format off
30
    convertToJson(src, dst); // Error here? See https://arduinojson.org/v7/unsupported-set/
142✔
31
    // clang-format on
32
  }
142✔
33

34
  static T fromJson(JsonVariantConst src) {
436✔
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/
435✔
40
    convertFromJson(src, result);  // Error here? See https://arduinojson.org/v7/unsupported-as/
436✔
41
    // clang-format on
42
    return result;
436✔
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<
58
    T, typename detail::enable_if<detail::is_integral<T>::value &&
59
                                  !detail::is_same<bool, T>::value &&
60
                                  !detail::is_same<char, T>::value>::type>
61
    : private detail::VariantAttorney {
62
  static void toJson(T src, JsonVariant dst) {
1,002✔
63
    ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
64
    auto data = getData(dst);
1,002✔
65
    if (data)
1,002✔
66
      data->setInteger(src, getResourceManager(dst));
978✔
67
  }
1,002✔
68

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

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

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

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

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

99
template <>
100
struct Converter<bool> : private detail::VariantAttorney {
101
  static void toJson(bool src, JsonVariant dst) {
251✔
102
    auto data = getData(dst);
251✔
103
    if (data)
251✔
104
      data->setBoolean(src, getResourceManager(dst));
248✔
105
  }
251✔
106

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

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

118
template <typename T>
119
struct Converter<
120
    T, typename detail::enable_if<detail::is_floating_point<T>::value>::type>
121
    : private detail::VariantAttorney {
122
  static void toJson(T src, JsonVariant dst) {
63✔
123
    auto data = getData(dst);
63✔
124
    if (data)
63✔
125
      data->setFloat(static_cast<JsonFloat>(src), getResourceManager(dst));
61✔
126
  }
63✔
127

128
  static T fromJson(JsonVariantConst src) {
118✔
129
    auto data = getData(src);
118✔
130
    return data ? data->template asFloat<T>() : 0;
118✔
131
  }
132

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

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

146
  static const char* fromJson(JsonVariantConst src) {
37✔
147
    auto data = getData(src);
37✔
148
    return data ? data->asString().c_str() : 0;
37✔
149
  }
150

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

157
template <>
158
struct Converter<JsonString> : private detail::VariantAttorney {
159
  static void toJson(JsonString src, JsonVariant dst) {
35✔
160
    detail::VariantData::setString(getData(dst), detail::adaptString(src),
35✔
161
                                   getResourceManager(dst));
162
  }
35✔
163

164
  static JsonString fromJson(JsonVariantConst src) {
461✔
165
    auto data = getData(src);
461✔
166
    return data ? data->asString() : 0;
461✔
167
  }
168

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

175
template <typename T>
176
inline typename detail::enable_if<detail::IsString<T>::value>::type
177
convertToJson(const T& src, JsonVariant dst) {
123✔
178
  using namespace detail;
179
  auto data = VariantAttorney::getData(dst);
123✔
180
  auto resources = VariantAttorney::getResourceManager(dst);
123✔
181
  detail::VariantData::setString(data, adaptString(src), resources);
123✔
182
}
123✔
183

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

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

209
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
210

211
namespace detail {
212
class StringBuilderPrint : public Print {
213
 public:
214
  StringBuilderPrint(ResourceManager* resources) : copier_(resources) {
8✔
215
    copier_.startString();
8✔
216
  }
8✔
217

218
  StringNode* save() {
4✔
219
    ARDUINOJSON_ASSERT(!overflowed());
220
    return copier_.save();
4✔
221
  }
222

223
  size_t write(uint8_t c) {
52✔
224
    copier_.append(char(c));
52✔
225
    return copier_.isValid() ? 1 : 0;
52✔
226
  }
227

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

237
  bool overflowed() const {
8✔
238
    return !copier_.isValid();
8✔
239
  }
240

241
 private:
242
  StringBuilder copier_;
243
};
244
}  // namespace detail
245

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

260
#endif
261

262
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
263

264
inline void convertFromJson(JsonVariantConst src, ::String& dst) {
265
  JsonString str = src.as<JsonString>();
266
  if (str)
267
    dst = str.c_str();
268
  else
269
    serializeJson(src, dst);
270
}
271

272
inline bool canConvertFromJson(JsonVariantConst src, const ::String&) {
273
  return src.is<JsonString>();
274
}
275

276
#endif
277

278
#if ARDUINOJSON_ENABLE_STD_STRING
279

280
inline void convertFromJson(JsonVariantConst src, std::string& dst) {
430✔
281
  JsonString str = src.as<JsonString>();
430✔
282
  if (str)
430✔
283
    dst.assign(str.c_str(), str.size());
52✔
284
  else
285
    serializeJson(src, dst);
378✔
286
}
430✔
287

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

292
#endif
293

294
#if ARDUINOJSON_ENABLE_STRING_VIEW
295

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

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

306
#endif
307

308
namespace detail {
309
template <typename T>
310
struct ConverterNeedsWriteableRef {
311
 protected:  // <- to avoid GCC's "all member functions in class are private"
312
  static int probe(T (*f)(ArduinoJson::JsonVariant));
313
  static char probe(T (*f)(ArduinoJson::JsonVariantConst));
314

315
 public:
316
  static const bool value =
317
      sizeof(probe(Converter<T>::fromJson)) == sizeof(int);
318
};
319
}  // namespace detail
320

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

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

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

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

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

357
  static detail::InvalidConversion<JsonVariantConst, JsonArray> fromJson(
358
      JsonVariantConst);
359

360
  static bool checkJson(JsonVariantConst) {
9✔
361
    return false;
9✔
362
  }
363

364
  static bool checkJson(JsonVariant src) {
16✔
365
    auto data = getData(src);
16✔
366
    return data && data->isArray();
16✔
367
  }
368
};
369

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

379
  static JsonObjectConst fromJson(JsonVariantConst src) {
27✔
380
    auto data = getData(src);
27✔
381
    auto object = data != 0 ? data->asObject() : nullptr;
27✔
382
    return JsonObjectConst(object, getResourceManager(src));
27✔
383
  }
384

385
  static bool checkJson(JsonVariantConst src) {
303✔
386
    auto data = getData(src);
303✔
387
    return data && data->isObject();
303✔
388
  }
389
};
390

391
template <>
392
struct Converter<JsonObject> : private detail::VariantAttorney {
393
  static void toJson(JsonVariantConst src, JsonVariant dst) {
12✔
394
    if (src.isNull())
12✔
395
      dst.set(nullptr);
1✔
396
    else
397
      dst.to<JsonObject>().set(src);
11✔
398
  }
12✔
399

400
  static JsonObject fromJson(JsonVariant src) {
95✔
401
    auto data = getData(src);
95✔
402
    auto resources = getResourceManager(src);
95✔
403
    return JsonObject(data != 0 ? data->asObject() : 0, resources);
95✔
404
  }
405

406
  static detail::InvalidConversion<JsonVariantConst, JsonObject> fromJson(
407
      JsonVariantConst);
408

409
  static bool checkJson(JsonVariantConst) {
9✔
410
    return false;
9✔
411
  }
412

413
  static bool checkJson(JsonVariant src) {
44✔
414
    auto data = getData(src);
44✔
415
    return data && data->isObject();
44✔
416
  }
417
};
418

419
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