FastLED 3.9.15
Loading...
Searching...
No Matches

◆ to_string_native()

fl::string fl::Json::to_string_native ( ) const

Definition at line 290 of file json.cpp.

290 {
291 if (!m_value) {
292 return "null";
293 }
294
295 // 🚨 NEW APPROACH: Use fl::deque for memory-efficient JSON serialization
296 // This avoids memory fragmentation and bypasses broken ArduinoJson integration
297 fl::deque<char> json_chars;
298
299 // Helper lambda for appending strings to deque
300 auto append_string = [&json_chars](const char* str) {
301 while (*str) {
302 json_chars.push_back(*str);
303 ++str;
304 }
305 };
306
307 // Helper lambda for appending fl::string to deque
308 auto append_fl_string = [&json_chars](const fl::string& str) {
309 for (size_t i = 0; i < str.size(); ++i) {
310 json_chars.push_back(str[i]);
311 }
312 };
313
314 // Helper lambda for appending escaped strings
315 auto append_escaped_string = [&](const fl::string& str) {
316 json_chars.push_back('"');
317 for (size_t i = 0; i < str.size(); ++i) {
318 char c = str[i];
319 switch (c) {
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;
327 default:
328 json_chars.push_back(c);
329 break;
330 }
331 }
332 json_chars.push_back('"');
333 };
334
335 // Recursive function to serialize JsonValue to deque
336 fl::function<void(const JsonValue&)> serialize_value = [&](const JsonValue& value) {
337 if (value.is_null()) {
338 append_string("null");
339 } else if (value.is_bool()) {
340 auto opt = value.as_bool();
341 if (opt) {
342 append_string(*opt ? "true" : "false");
343 } else {
344 append_string("null");
345 }
346 } else if (value.is_int()) {
347 auto opt = value.as_int();
348 if (opt) {
349 fl::string num_str;
350 num_str.append(*opt);
351 append_fl_string(num_str);
352 } else {
353 append_string("null");
354 }
355 } else if (value.is_float()) {
356 auto opt = value.as_float();
357 if (opt) {
358 fl::string num_str;
359 // Use fl::string::append which already handles float formatting correctly
360 //num_str.append(*opt);
361 num_str.append(static_cast<float>(*opt), 3);
362 append_fl_string(num_str);
363 } else {
364 append_string("null");
365 }
366 } else if (value.is_string()) {
367 auto opt = value.as_string();
368 if (opt) {
369 append_escaped_string(*opt);
370 } else {
371 append_string("null");
372 }
373 } else if (value.is_array()) {
374 auto opt = value.as_array();
375 if (opt) {
376 json_chars.push_back('[');
377 bool first = true;
378 for (const auto& item : *opt) {
379 if (!first) {
380 json_chars.push_back(',');
381 }
382 first = false;
383 if (item) {
384 serialize_value(*item);
385 } else {
386 append_string("null");
387 }
388 }
389 json_chars.push_back(']');
390 } else {
391 append_string("null");
392 }
393 } else if (value.is_object()) {
394 auto opt = value.as_object();
395 if (opt) {
396 json_chars.push_back('{');
397 bool first = true;
398 for (const auto& kv : *opt) {
399 if (!first) {
400 json_chars.push_back(',');
401 }
402 first = false;
403 append_escaped_string(kv.first);
404 json_chars.push_back(':');
405 if (kv.second) {
406 serialize_value(*kv.second);
407 } else {
408 append_string("null");
409 }
410 }
411 json_chars.push_back('}');
412 } else {
413 append_string("null");
414 }
415 } else {
416 // Handle specialized array types
417 if (value.is_audio()) {
418 auto audioOpt = value.as_audio();
419 if (audioOpt) {
420 json_chars.push_back('[');
421 bool first = true;
422 for (const auto& item : *audioOpt) {
423 if (!first) {
424 json_chars.push_back(',');
425 }
426 first = false;
427 fl::string num_str;
428 num_str.append(static_cast<int>(item));
429 append_fl_string(num_str);
430 }
431 json_chars.push_back(']');
432 } else {
433 append_string("null");
434 }
435 } else if (value.is_bytes()) {
436 auto bytesOpt = value.as_bytes();
437 if (bytesOpt) {
438 json_chars.push_back('[');
439 bool first = true;
440 for (const auto& item : *bytesOpt) {
441 if (!first) {
442 json_chars.push_back(',');
443 }
444 first = false;
445 fl::string num_str;
446 num_str.append(static_cast<int>(item));
447 append_fl_string(num_str);
448 }
449 json_chars.push_back(']');
450 } else {
451 append_string("null");
452 }
453 } else if (value.is_floats()) {
454 auto floatsOpt = value.as_floats();
455 if (floatsOpt) {
456 json_chars.push_back('[');
457 bool first = true;
458 for (const auto& item : *floatsOpt) {
459 if (!first) {
460 json_chars.push_back(',');
461 }
462 first = false;
463 fl::string num_str;
464 num_str.append(static_cast<float>(item), 6);
465 append_fl_string(num_str);
466 }
467 json_chars.push_back(']');
468 } else {
469 append_string("null");
470 }
471 } else {
472 append_string("null");
473 }
474 }
475 };
476
477 // Serialize the root value
478 serialize_value(*m_value);
479
480 // Convert deque to fl::string efficiently
481 fl::string result;
482 if (!json_chars.empty()) {
483 // Get pointer to the underlying data and construct string directly
484 result.assign(&json_chars[0], json_chars.size());
485 }
486
487 return result;
488}
T value() const
Definition json.h:1802
fl::shared_ptr< JsonValue > m_value
Definition json.h:1622
void assign(const char *str, fl::size len)
Definition str.h:198
fl::size size() const
Definition deque.h:283
bool empty() const
Definition deque.h:279
void push_back(const T &value)
Definition deque.h:298
string & append(const BitsetFixed< N > &bs)
Definition str.h:675

References fl::string::append(), fl::deque< T, Allocator >::empty(), m_value, fl::deque< T, Allocator >::push_back(), fl::deque< T, Allocator >::size(), and value().

Referenced by to_string(), fl::JsonValue::to_string(), and to_string_native_public().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: