290 {
292 return "null";
293 }
294
295
296
297 fl::deque<char> json_chars;
298
299
300 auto append_string = [&json_chars](const char* str) {
301 while (*str) {
303 ++str;
304 }
305 };
306
307
308 auto append_fl_string = [&json_chars](const fl::string& str) {
309 for (size_t i = 0; i < str.size(); ++i) {
311 }
312 };
313
314
315 auto append_escaped_string = [&](const fl::string& str) {
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:
329 break;
330 }
331 }
333 };
334
335
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;
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
360
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) {
377 bool first = true;
378 for (const auto& item : *opt) {
379 if (!first) {
381 }
382 first = false;
383 if (item) {
384 serialize_value(*item);
385 } else {
386 append_string("null");
387 }
388 }
390 } else {
391 append_string("null");
392 }
393 }
else if (
value.is_object()) {
394 auto opt =
value.as_object();
395 if (opt) {
397 bool first = true;
398 for (const auto& kv : *opt) {
399 if (!first) {
401 }
402 first = false;
403 append_escaped_string(kv.first);
405 if (kv.second) {
406 serialize_value(*kv.second);
407 } else {
408 append_string("null");
409 }
410 }
412 } else {
413 append_string("null");
414 }
415 } else {
416
417 if (
value.is_audio()) {
418 auto audioOpt =
value.as_audio();
419 if (audioOpt) {
421 bool first = true;
422 for (const auto& item : *audioOpt) {
423 if (!first) {
425 }
426 first = false;
427 fl::string num_str;
428 num_str.
append(
static_cast<int>(item));
429 append_fl_string(num_str);
430 }
432 } else {
433 append_string("null");
434 }
435 }
else if (
value.is_bytes()) {
436 auto bytesOpt =
value.as_bytes();
437 if (bytesOpt) {
439 bool first = true;
440 for (const auto& item : *bytesOpt) {
441 if (!first) {
443 }
444 first = false;
445 fl::string num_str;
446 num_str.
append(
static_cast<int>(item));
447 append_fl_string(num_str);
448 }
450 } else {
451 append_string("null");
452 }
453 }
else if (
value.is_floats()) {
454 auto floatsOpt =
value.as_floats();
455 if (floatsOpt) {
457 bool first = true;
458 for (const auto& item : *floatsOpt) {
459 if (!first) {
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 }
468 } else {
469 append_string("null");
470 }
471 } else {
472 append_string("null");
473 }
474 }
475 };
476
477
479
480
481 fl::string result;
482 if (!json_chars.
empty()) {
483
484 result.
assign(&json_chars[0], json_chars.
size());
485 }
486
487 return result;
488}
fl::shared_ptr< JsonValue > m_value
void assign(const char *str, fl::size len)
void push_back(const T &value)
string & append(const BitsetFixed< N > &bs)