82 #if !FASTLED_ENABLE_JSON
86 FLArduinoJson::JsonDocument doc;
88 FLArduinoJson::DeserializationError error = FLArduinoJson::deserializeJson(doc, txt.
c_str());
91 FL_WARN(
"JSON parsing failed: " << error.c_str());
100 }
else if (src.is<
bool>()) {
102 }
else if (src.is<int64_t>()) {
105 }
else if (src.is<int32_t>()) {
108 }
else if (src.is<uint32_t>()) {
111 }
else if (src.is<
double>()) {
114 }
else if (src.is<
float>()) {
117 }
else if (src.is<
const char*>()) {
119 }
else if (src.is<FLArduinoJson::JsonArrayConst>()) {
120 FLArduinoJson::JsonArrayConst arr = src.as<FLArduinoJson::JsonArrayConst>();
123 if (arr.size() == 0) {
136 struct ArrayTypeInfo {
147 void checkNumericValue(
double val) {
149 bool isInteger = val ==
floor(val);
150 if (!isInteger || val < 0 || val >
UINT8_MAX) {
153 if (!isInteger || val < INT16_MIN || val >
INT16_MAX) {
156 if (!canBeRepresentedAsFloat(val)) {
161 void checkIntegerValue(int64_t val) {
166 if (val < INT16_MIN || val >
INT16_MAX) {
169 if (val < -16777216 || val > 16777216) {
174 ArrayType getBestType()
const {
175 if (isUint8)
return ALL_UINT8;
176 if (isInt16)
return ALL_INT16;
177 if (isFloat)
return ALL_FLOATS;
178 return GENERIC_ARRAY;
182 ArrayTypeInfo typeInfo;
184 #if FASTLED_DEBUG_LEVEL >= 2
185 FASTLED_WARN(
"Array conversion: processing " << arr.size() <<
" items");
188 for (
const auto& item : arr) {
190 if (!item.is<int32_t>() && !item.is<int64_t>() && !item.is<
double>()) {
191 typeInfo.disableAll();
192 #if FASTLED_DEBUG_LEVEL >= 2
193 FASTLED_WARN(
"Non-numeric value found, no optimization possible");
199 if (item.is<
double>()) {
200 double val = item.as<
double>();
201 typeInfo.checkNumericValue(val);
203 int64_t val = item.is<int32_t>() ? item.as<int32_t>() : item.as<int64_t>();
204 typeInfo.checkIntegerValue(val);
209 ArrayType arrayType = arr.size() > 0 ? typeInfo.getBestType() : GENERIC_ARRAY;
216 for (
const auto& item : arr) {
217 if (item.is<
double>()) {
218 byteData.
push_back(
static_cast<uint8_t
>(item.as<
double>()));
220 int64_t val = item.is<int32_t>() ? item.as<int32_t>() : item.as<int64_t>();
221 byteData.
push_back(
static_cast<uint8_t
>(val));
229 for (
const auto& item : arr) {
230 if (item.is<
double>()) {
231 intData.
push_back(
static_cast<int16_t
>(item.as<
double>()));
233 int64_t val = item.is<int32_t>() ? item.as<int32_t>() : item.as<int64_t>();
234 intData.
push_back(
static_cast<int16_t
>(val));
242 for (
const auto& item : arr) {
243 if (item.is<
double>()) {
244 floatData.
push_back(
static_cast<float>(item.as<
double>()));
246 int64_t val = item.is<int32_t>() ? item.as<int32_t>() : item.as<int64_t>();
247 floatData.
push_back(
static_cast<float>(val));
256 for (
const auto& item : arr) {
262 }
else if (src.is<FLArduinoJson::JsonObjectConst>()) {
264 for (
const auto& kv : src.as<FLArduinoJson::JsonObjectConst>()) {
265 obj[
fl::string(kv.key().c_str())] = convert(kv.value());
273 return Converter::convert(doc.as<FLArduinoJson::JsonVariantConst>());
300 auto append_string = [&json_chars](
const char* str) {
308 auto append_fl_string = [&json_chars](
const fl::string& str) {
309 for (
size_t i = 0; i < str.size(); ++i) {
315 auto append_escaped_string = [&](
const fl::string& str) {
317 for (
size_t i = 0; i < str.size(); ++i) {
320 case '"': append_string(
"\\\"");
break;
321 case '\\': append_string(
"\\\\");
break;
322 case '\n': append_string(
"\\n");
break;
323 case '\r': append_string(
"\\r");
break;
324 case '\t': append_string(
"\\t");
break;
325 case '\b': append_string(
"\\b");
break;
326 case '\f': append_string(
"\\f");
break;
337 if (
value.is_null()) {
338 append_string(
"null");
339 }
else if (
value.is_bool()) {
340 auto opt =
value.as_bool();
342 append_string(*opt ?
"true" :
"false");
344 append_string(
"null");
346 }
else if (
value.is_int()) {
347 auto opt =
value.as_int();
351 append_fl_string(num_str);
353 append_string(
"null");
355 }
else if (
value.is_float()) {
356 auto opt =
value.as_float();
361 num_str.
append(
static_cast<float>(*opt), 3);
362 append_fl_string(num_str);
364 append_string(
"null");
366 }
else if (
value.is_string()) {
367 auto opt =
value.as_string();
369 append_escaped_string(*opt);
371 append_string(
"null");
373 }
else if (
value.is_array()) {
374 auto opt =
value.as_array();
378 for (
const auto& item : *opt) {
384 serialize_value(*item);
386 append_string(
"null");
391 append_string(
"null");
393 }
else if (
value.is_object()) {
394 auto opt =
value.as_object();
398 for (
const auto& kv : *opt) {
403 append_escaped_string(kv.first);
406 serialize_value(*kv.second);
408 append_string(
"null");
413 append_string(
"null");
417 if (
value.is_audio()) {
418 auto audioOpt =
value.as_audio();
422 for (
const auto& item : *audioOpt) {
428 num_str.
append(
static_cast<int>(item));
429 append_fl_string(num_str);
433 append_string(
"null");
435 }
else if (
value.is_bytes()) {
436 auto bytesOpt =
value.as_bytes();
440 for (
const auto& item : *bytesOpt) {
446 num_str.
append(
static_cast<int>(item));
447 append_fl_string(num_str);
451 append_string(
"null");
453 }
else if (
value.is_floats()) {
454 auto floatsOpt =
value.as_floats();
458 for (
const auto& item : *floatsOpt) {
464 num_str.
append(
static_cast<float>(item), 6);
465 append_fl_string(num_str);
469 append_string(
"null");
472 append_string(
"null");
482 if (!json_chars.
empty()) {
484 result.assign(&json_chars[0], json_chars.
size());