57 const u32 biased_exp = (bits >> 23) & 0xFFu;
58 const u32 mantissa = bits & 0x7FFFFFu;
59 return biased_exp == 0xFFu || biased_exp > 151u ||
60 (biased_exp == 151u && mantissa != 0u);
143 size_t start_pos =
mPos;
146 bool has_int =
false;
147 bool has_float =
false;
148 bool has_float_beyond_precision =
false;
149 bool has_string =
false;
150 bool has_bool =
false;
151 bool has_null =
false;
175 if (c ==
'[' || c ==
'{') {
195 else if (c ==
'-' || (c >=
'0' && c <=
'9')) {
196 size_t num_start =
mPos;
197 bool is_float =
false;
199 if (c ==
'-')
mPos++;
217#if FL_PLATFORM_HAS_LARGE_MEMORY
224 has_float_beyond_precision =
true;
231 has_float_beyond_precision =
true;
238 if (val < int_min) int_min = val;
239 if (val > int_max) int_max = val;
243 else if (c ==
't' &&
mPos + 3 <
mLen &&
249 else if (c ==
'f' &&
mPos + 4 <
mLen &&
256 else if (c ==
'n' &&
mPos + 3 <
mLen &&
280 int type_count = (has_int ? 1 : 0) + (has_float ? 1 : 0) +
281 (has_string ? 1 : 0) + (has_bool ? 1 : 0) + (has_null ? 1 : 0);
286 if (type_count == 1 || (type_count == 2 && has_int && has_float)) {
287 if (has_float || (has_int && has_float)) {
289 if (has_float_beyond_precision) {
296 if (int_min >= 0 && int_max <= 255) {
299 if (int_min >= -32768 && int_max <= 32767) {
333#if FL_PLATFORM_HAS_LARGE_MEMORY
334 size_t saved_pos =
mPos;
377 size_t start =
mPos + 1;
405 if (c ==
'-' || (c >=
'0' && c <=
'9')) {
409 if (c ==
'-')
mPos++;
634 for (
size_t i = 0; i <
span.
size(); i++) {
635 if (
span[i] ==
'\\') {
647 for (
size_t i = 0; i <
span.
size(); i++) {
649 char next =
span[i + 1];
651 case '"':
result +=
'"'; i++;
break;
652 case '\\':
result +=
'\\'; i++;
break;
653 case '/':
result +=
'/'; i++;
break;
654 case 'b':
result +=
'\b'; i++;
break;
655 case 'f':
result +=
'\f'; i++;
break;
656 case 'n':
result +=
'\n'; i++;
break;
657 case 'r':
result +=
'\r'; i++;
break;
658 case 't':
result +=
'\t'; i++;
break;
675 bool all_numeric =
true;
678 bool has_float =
false;
679 bool has_float_beyond_precision =
false;
681 for (
const auto& elem : arr) {
687 if (elem->is_int()) {
688 auto val = elem->as_int();
691 min_val = (v < min_val) ? v : min_val;
692 max_val = (v > max_val) ? v : max_val;
697 }
else if (elem->is_float()) {
699 auto val = elem->as_float();
708 has_float_beyond_precision =
true;
721 if (has_float_beyond_precision) {
728 if (min_val >= 0 && max_val <= 255) {
732 if (min_val >= -32768 && max_val <= 32767) {
738 if (min_val >= -16777216 && max_val <= 16777216) {
747 if (!arr)
return array_val;
755 for (
const auto& elem : *arr) {
756 auto val = elem->as_int();
765 for (
const auto& elem : *arr) {
766 auto val = elem->as_int();
767 if (val) vec.
push_back(
static_cast<i16
>(*val));
775 for (
const auto& elem : *arr) {
776 if (elem->is_float()) {
777 auto val = elem->as_float();
779 }
else if (elem->is_int()) {
780 auto val = elem->as_int();
788 vec.
push_back(
static_cast<float>(
static_cast<fl::i32
>(*val)));
823 while (p <
end && (*p ==
' ' || *p ==
'\t' || *p ==
'\n' || *p ==
'\r')) p++;
827 const char* num_start = p;
829 while (p < end && *p >=
'0' && *p <=
'9') p++;
832 out_vec.push_back(
static_cast<T
>(val));
835 while (p <
end && (*p ==
' ' || *p ==
'\t' || *p ==
'\n' || *p ==
'\r')) p++;
838 if (p <
end && *p ==
',') p++;
852 while (p <
end && (*p ==
' ' || *p ==
'\t' || *p ==
'\n' || *p ==
'\r')) p++;
856 const char* num_start = p;
857 bool is_float =
false;
860 while (p < end && *p >=
'0' && *p <=
'9') p++;
862 if (p <
end && *p ==
'.') {
865 while (p < end && *p >=
'0' && *p <=
'9') p++;
868 if (p <
end && (*p ==
'e' || *p ==
'E')) {
871 if (p <
end && (*p ==
'+' || *p ==
'-')) p++;
872 while (p < end && *p >=
'0' && *p <=
'9') p++;
877#if FL_PLATFORM_HAS_LARGE_MEMORY
888 val =
static_cast<T
>(0);
891 val =
static_cast<T
>(
fl::parseInt(num_start, p - num_start));
893 out_vec.push_back(val);
896 while (p <
end && (*p ==
' ' || *p ==
'\t' || *p ==
'\n' || *p ==
'\r')) p++;
899 if (p <
end && *p ==
',') p++;
947#if FL_PLATFORM_HAS_LARGE_MEMORY
983 auto obj_val =
mStack.back().value;
1015 mStack.back().pending_key.empty()) {
1039 bool is_float =
false;
1040 for (
size_t i = 0; i <
value.size(); i++) {
1048#if FL_PLATFORM_HAS_LARGE_MEMORY
1058 i64 i64_val =
static_cast<i64>(i);
1071 i64 i64_val =
static_cast<i64>(i);
1113 JsonTokenizer tokenizer;
1116 JsonValidator validator;
1117 if (!tokenizer.parse(txt, validator) || !validator.is_valid()) {
1122 JsonBuilder builder;
1123 if (!tokenizer.parse(txt, builder)) {
1127 return builder.get_result();
1136 JsonTokenizer tokenizer;
1137 JsonValidator validator;
1138 return tokenizer.parse(txt, validator) && validator.is_valid();
1160 while (*str) {
out.push_back(*str++); }
1164 for (
size_t i = 0; i < str.size(); ++i) {
1165 out.push_back(str[i]);
1171 for (
size_t i = 0; i < str.size(); ++i) {
1174 case '"':
append(
"\\\"");
break;
1175 case '\\':
append(
"\\\\");
break;
1176 case '\n':
append(
"\\n");
break;
1177 case '\r':
append(
"\\r");
break;
1178 case '\t':
append(
"\\t");
break;
1179 case '\b':
append(
"\\b");
break;
1180 case '\f':
append(
"\\f");
break;
1181 default:
out.push_back(c);
break;
1193 value->data.visit(*
this);
1208#if FL_PLATFORM_HAS_LARGE_MEMORY
1233 for (
const auto& item : arr) {
1234 if (!first)
out.push_back(
',');
1248 for (
const auto& kv : obj) {
1249 if (!first)
out.push_back(
',');
1261 for (
const auto& item :
audio) {
1262 if (!first)
out.push_back(
',');
1265 num_str.
append(
static_cast<int>(item));
1274 for (
const auto& item : bytes) {
1275 if (!first)
out.push_back(
',');
1278 num_str.
append(
static_cast<int>(item));
1287 for (
const auto& item : floats) {
1288 if (!first)
out.push_back(
',');
1290#if FL_PLATFORM_HAS_LARGE_MEMORY
1322 if (!json_chars.
empty()) {
1324 for (fl::size i = 0; i < json_chars.
size(); ++i) {
1325 result.push_back(json_chars[i]);
1341 size_t len =
strlen(jsonStr);
1342 for (
size_t i = 0; i < len; ++i) {
1343 char c = jsonStr[i];
1344 if (c !=
' ' && c !=
'\t' && c !=
'\n' && c !=
'\r') {
JsonBuilder() FL_NO_EXCEPT
fl::StringInterner mInterner
bool parse_float_array(const fl::span< const char > &span, fl::vector< T > &out_vec) FL_NO_EXCEPT
void push_value(const fl::shared_ptr< json_value > &val) FL_NO_EXCEPT
bool parse_int_array(const fl::span< const char > &span, fl::vector< T > &out_vec) FL_NO_EXCEPT
fl::shared_ptr< json_value > get_result() FL_NO_EXCEPT
fl::shared_ptr< json_value > mRoot
ParseState on_token(JsonToken token, const fl::span< const char > &value) FL_NO_EXCEPT override
fl::vector_inlined< StackFrame, 8 > mStack
bool parse(fl::string_view input, JsonVisitor &visitor) FL_NO_EXCEPT
JsonTokenizer(bool enable_lookahead=true) FL_NO_EXCEPT
bool parse(const fl::string &input, JsonVisitor &visitor) FL_NO_EXCEPT
void skip_whitespace() FL_NO_EXCEPT
JsonToken next_token(fl::span< const char > &out_value) FL_NO_EXCEPT
JsonToken scan_array_lookahead(fl::span< const char > &out_span) FL_NO_EXCEPT
JsonValidator() FL_NO_EXCEPT
fl::vector_inlined< char, 32 > mBracketStack
ParseState on_token(JsonToken token, const fl::span< const char > &value) FL_NO_EXCEPT override
bool is_valid() const FL_NO_EXCEPT
virtual ~JsonVisitor() FL_NO_EXCEPT=default
virtual ParseState on_token(JsonToken token, const fl::span< const char > &value) FL_NO_EXCEPT=0
void clear(bool freeMemory=false) FL_NO_EXCEPT
bool empty() const FL_NO_EXCEPT
fl::size size() const FL_NO_EXCEPT
bool empty() const FL_NO_EXCEPT
void set_value(const fl::shared_ptr< json_value > &value) FL_NO_EXCEPT
fl::shared_ptr< json_value > mValue
fl::string to_string_native() const FL_NO_EXCEPT
static fl::string normalize_json_string(const char *jsonStr) FL_NO_EXCEPT
const T * data() const FL_NO_EXCEPT
constexpr fl::size size() const FL_NO_EXCEPT
string & append(const bitset_fixed< N > &bs) FL_NO_EXCEPT
void reserve(fl::size n) FL_NO_EXCEPT
void push_back(const T &value) FL_NO_EXCEPT
FastLED's Elegant JSON Library: fl::json
Centralized logging categories for FastLED hardware interfaces and subsystems.
constexpr T * end(T(&array)[N]) FL_NO_EXCEPT
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
shared_ptr< T > make_shared(Args &&... args) FL_NO_EXCEPT
ArrayType classify_array(const json_array &arr) FL_NO_EXCEPT
bool has_escape_sequences(const fl::span< const char > &span) FL_NO_EXCEPT
fl::shared_ptr< json_value > optimize_array(fl::shared_ptr< json_value > array_val) FL_NO_EXCEPT
fl::string unescape_string(const fl::span< const char > &span) FL_NO_EXCEPT
constexpr int MAX_JSON_DEPTH
decltype(nullptr) nullptr_t
json_value & get_null_json_value() FL_NO_EXCEPT
u8 u8 fract8 blur_amount FL_NO_EXCEPT
constexpr int type_rank< T >::value
u32 ieee754_parse_decimal(const char *s, fl::size len, fl::size *consumed) FL_NO_EXCEPT
Parse a decimal floating-point number into IEEE 754 single-precision bits.
json_object & get_empty_json_obj() FL_NO_EXCEPT
int parseInt(const char *str, fl::size len) FL_NO_EXCEPT
Parse an integer from a character buffer.
static bool float_bits_magnitude_exceeds_2_24(u32 bits) FL_NO_EXCEPT
fl::vector< fl::shared_ptr< json_value > > json_array
expected< T, E > result
Alias for expected (Rust-style naming)
To bit_cast(const From &from) FL_NO_EXCEPT
fl::flat_map< fl::string, fl::shared_ptr< json_value >, fl::StringFastLess > json_object
fl::string ieee754_format_decimal(u32 bits, int precision) FL_NO_EXCEPT
Format IEEE 754 single-precision bits as decimal text.
VectorN< T, INLINED_SIZE > vector_inlined
fl::string serializeValue(const json_value &value) FL_NO_EXCEPT
FASTLED_FORCE_INLINE size_t strlen(const char *s) FL_NO_EXCEPT
Base definition for an LED controller.
void accept(const json_object &obj) FL_NO_EXCEPT
void accept(const json_array &arr) FL_NO_EXCEPT
void accept(const fl::vector< i16 > &audio) FL_NO_EXCEPT
void accept(const i64 &i) FL_NO_EXCEPT
void serialize_value(const json_value *value) FL_NO_EXCEPT
void accept(const fl::vector< float > &floats) FL_NO_EXCEPT
void append_escaped(const fl::string &str) FL_NO_EXCEPT
void accept(const bool &b) FL_NO_EXCEPT
void accept(const fl::string &s) FL_NO_EXCEPT
void accept(const fl::nullptr_t &) FL_NO_EXCEPT
void append(const char *str) FL_NO_EXCEPT
void accept(const fl::vector< u8 > &bytes) FL_NO_EXCEPT
void append_str(const fl::string &str) FL_NO_EXCEPT
void accept(const float &f) FL_NO_EXCEPT
enum fl::anonymous_namespace{json.cpp.hpp}::JsonBuilder::StackFrame::Type type
fl::shared_ptr< json_value > value
static bool parse2_validate_only(const fl::string &txt) FL_NO_EXCEPT
static fl::shared_ptr< json_value > parse2(const fl::string &txt) FL_NO_EXCEPT
fl::string to_string() const FL_NO_EXCEPT
static constexpr T min() FL_NO_EXCEPT
static constexpr T max() FL_NO_EXCEPT