diff --git a/src/src/DataStructs/KeyValueStruct.h b/src/src/DataStructs/KeyValueStruct.h index bf1a48678..04ecfaf7b 100644 --- a/src/src/DataStructs/KeyValueStruct.h +++ b/src/src/DataStructs/KeyValueStruct.h @@ -137,7 +137,7 @@ struct KeyValueStruct String getID() const; operator bool() const { - return _key.operator bool(); + return getNrValues() || _key.operator bool(); } size_t getNrValues() const { return _values.size(); } diff --git a/src/src/DataStructs/ValueStruct.cpp b/src/src/DataStructs/ValueStruct.cpp index f61569067..47daef1ed 100644 --- a/src/src/DataStructs/ValueStruct.cpp +++ b/src/src/DataStructs/ValueStruct.cpp @@ -96,7 +96,9 @@ ValueStruct& ValueStruct::deepCopy(const ValueStruct& rhs) ValueStruct::ValueStruct(const bool& val) : _isSSO(0), _valueType((uint64_t)ValueStruct::ValueType::Bool), + _preferredFormat(0), _caseFormat(0), + _trimTrailingZeros(0), _size(1), u64_val(val ? 1ull : 0ull) {} @@ -105,8 +107,8 @@ ValueStruct::ValueStruct(int val) : _isSSO(0), _valueType((uint64_t)ValueStruct::ValueType::Int), _preferredFormat((uint64_t)PreferredFormat::Default), - _minNrDigits(1), _caseFormat(0), + _minNrDigits(1), _size(sizeof(val) * 8), i64_val(val) {} @@ -116,8 +118,8 @@ ValueStruct::ValueStruct(int32_t val) : _isSSO(0), _valueType((uint64_t)ValueStruct::ValueType::Int), _preferredFormat((uint64_t)PreferredFormat::Default), - _minNrDigits(1), _caseFormat(0), + _minNrDigits(1), _size(sizeof(val) * 8), i64_val(val) {} @@ -127,8 +129,8 @@ ValueStruct::ValueStruct(uint32_t val) : _isSSO(0), _valueType((uint64_t)ValueStruct::ValueType::UInt), _preferredFormat((uint64_t)PreferredFormat::Default), - _minNrDigits(1), _caseFormat(0), + _minNrDigits(1), _size(sizeof(val) * 8), u64_val(val) {} @@ -138,8 +140,8 @@ ValueStruct::ValueStruct(size_t val) : _isSSO(0), _valueType((uint64_t)ValueStruct::ValueType::UInt), _preferredFormat((uint64_t)PreferredFormat::Default), - _minNrDigits(1), _caseFormat(0), + _minNrDigits(1), _size(sizeof(val) * 8), u64_val(val) {} @@ -149,8 +151,8 @@ ValueStruct::ValueStruct(const uint64_t& val) : _isSSO(0), _valueType((uint64_t)ValueStruct::ValueType::UInt), _preferredFormat((uint64_t)PreferredFormat::Default), - _minNrDigits(1), _caseFormat(0), + _minNrDigits(1), _size(sizeof(val) * 8), u64_val(val) {} @@ -159,8 +161,8 @@ ValueStruct::ValueStruct(const int64_t& val) : _isSSO(0), _valueType((uint64_t)ValueStruct::ValueType::Int), _preferredFormat((uint64_t)PreferredFormat::Default), - _minNrDigits(1), _caseFormat(0), + _minNrDigits(1), _size(sizeof(val) * 8), i64_val(val) {} @@ -169,10 +171,11 @@ ValueStruct::ValueStruct(const float& val, uint8_t nrDecimals, bool trimTrailingZeros) : _isSSO(0), - _trimTrailingZeros((uint64_t)trimTrailingZeros), _valueType((uint64_t)ValueStruct::ValueType::Float), - _nrDecimals((uint64_t)nrDecimals), + _preferredFormat(0), _caseFormat(0), + _trimTrailingZeros((uint64_t)trimTrailingZeros), + _nrDecimals((uint64_t)nrDecimals), _size(sizeof(val) * 8), f_val(val) {} @@ -181,10 +184,11 @@ ValueStruct::ValueStruct(const double& val, uint8_t nrDecimals, bool trimTrailingZeros) : _isSSO(0), - _trimTrailingZeros((uint64_t)trimTrailingZeros), _valueType((uint64_t)ValueStruct::ValueType::Double), - _nrDecimals((uint64_t)nrDecimals), + _preferredFormat(0), _caseFormat(0), + _trimTrailingZeros((uint64_t)trimTrailingZeros), + _nrDecimals((uint64_t)nrDecimals), _size(sizeof(val) * 8), d_val(val) {} @@ -192,6 +196,7 @@ ValueStruct::ValueStruct(const double& val, ValueStruct::ValueStruct(const char*val) : _isSSO(0), _valueType((uint64_t)ValueStruct::ValueType::String), + _preferredFormat(0), _caseFormat(0), _size(val ? strlen_P((const char *)(val)) : 0), str_val(nullptr) @@ -217,6 +222,7 @@ ValueStruct::ValueStruct(const char*val) : ValueStruct::ValueStruct(const String& val) : _isSSO(0), _valueType((uint64_t)ValueStruct::ValueType::String), + _preferredFormat(0), _caseFormat(0), _size(val.length()), str_val(nullptr) @@ -243,6 +249,7 @@ ValueStruct::ValueStruct(const String& val) : ValueStruct::ValueStruct(String&& val) : _isSSO(0), _valueType((uint64_t)ValueStruct::ValueType::String), + _preferredFormat(0), _caseFormat(0), _size(val.length()), str_val(nullptr) @@ -273,6 +280,7 @@ ValueStruct::ValueStruct(String&& val) : ValueStruct::ValueStruct(const __FlashStringHelper *val) : _isSSO(0), _valueType((uint64_t)ValueStruct::ValueType::FlashString), + _preferredFormat(0), _caseFormat(0), _size(val ? strlen_P((const char *)(val)) : 0), str_val((void *)(val)) diff --git a/src/src/DataStructs/ValueStruct.h b/src/src/DataStructs/ValueStruct.h index b0341407f..8b3e79d19 100644 --- a/src/src/DataStructs/ValueStruct.h +++ b/src/src/DataStructs/ValueStruct.h @@ -43,7 +43,9 @@ public: _isSSO(0), _valueType((uint64_t)ValueStruct::ValueType::Unset), str_val(nullptr) - {} + { + memset(bytes_all, 0, sizeof(bytes_all)); + } ~ValueStruct(); @@ -151,13 +153,21 @@ private: union { struct { - uint64_t _isSSO : 1; + // Need to have the most important bits for formatting strings in the first byte + // When more bits are needed for storing SSO strings, + // move the first byte of SSO string (VALUE_STRUCT_SSO_FIRST_CHAR_INDEX) + // and decrease max. nr of SSO bytes (VALUE_STRUCT_SSO_MAX_SIZE) + + uint64_t _isSSO : 1; + uint64_t _valueType : 3; + uint64_t _preferredFormat : 2; + uint64_t _caseFormat : 2; + + // --- End of 1st byte + uint64_t _trimTrailingZeros : 1; - uint64_t _valueType : 4; - uint64_t _preferredFormat : 2; + uint64_t _minNrDigits : 7; // For printing ints with leading zeroes uint64_t _nrDecimals : 8; - uint64_t _minNrDigits : 6; // For printing ints with leading zeroes - uint64_t _caseFormat : 2; uint64_t _size : 16; // Length of string or nr of bits uint64_t unused : 24; diff --git a/src/src/Helpers/KeyValueWriter_JSON.cpp b/src/src/Helpers/KeyValueWriter_JSON.cpp index deb9e3691..84d247998 100644 --- a/src/src/Helpers/KeyValueWriter_JSON.cpp +++ b/src/src/Helpers/KeyValueWriter_JSON.cpp @@ -185,7 +185,7 @@ void KeyValueWriter_JSON::writeValue(const ValueStruct& val, bool forceString) case ValueStruct::ValueType::Int: case ValueStruct::ValueType::UInt: - pr.print(str); + pr.print(to_json_value(str, val.getPreferredFormat() != ValueStruct::PreferredFormat::Default)); return; case ValueStruct::ValueType::Bool: diff --git a/src/src/Helpers/StringConverter.cpp b/src/src/Helpers/StringConverter.cpp index 5fbd182f0..dc29304d4 100644 --- a/src/src/Helpers/StringConverter.cpp +++ b/src/src/Helpers/StringConverter.cpp @@ -812,7 +812,18 @@ String parseStringToEndKeepCase(const String& string, uint8_t indexFind, char se uint8_t nextArgument = indexFind; bool hasArgument = false; - while (GetArgvBeginEnd(string.c_str(), nextArgument, tmppos_begin, tmppos_end, separator)) + + unsigned int string_pos = 0, argc_pos = 0; + const char *string_c_str = string.c_str(); + + while (GetArgvBeginEnd(string_c_str, + string.length(), + nextArgument, + tmppos_begin, + tmppos_end, + string_pos, + argc_pos, + separator)) { hasArgument = true; @@ -1644,8 +1655,37 @@ bool HasArgv(const char *string, unsigned int argc) { } bool GetArgv(const char *string, String& argvString, unsigned int argc, char separator) { + const size_t string_len = strlen(string); + unsigned int string_pos = 0, argc_pos = 0; + + return GetArgv( + string, + string_len, + argvString, + argc, + string_pos, + argc_pos, + separator); +} + +bool GetArgv(const char *string, + const size_t &string_len, + String & argvString, + unsigned int argc, + unsigned int &string_pos, + unsigned int &argc_pos, + char separator) +{ int pos_begin, pos_end; - bool hasArgument = GetArgvBeginEnd(string, argc, pos_begin, pos_end, separator); + bool hasArgument = GetArgvBeginEnd( + string, + string_len, + argc, + pos_begin, + pos_end, + string_pos, + argc_pos, + separator); free_string(argvString); @@ -1660,14 +1700,38 @@ bool GetArgv(const char *string, String& argvString, unsigned int argc, char sep return true; } -bool GetArgvBeginEnd(const char *string, const unsigned int argc, int& pos_begin, int& pos_end, char separator) { +/* +bool GetArgvBeginEnd(const char *string, const unsigned int argc, int& pos_begin, int& pos_end, char separator) +{ + const size_t string_len = strlen(string); + unsigned int string_pos = 0, argc_pos = 0; + + return GetArgvBeginEnd( + string, + string_len, + argc, + pos_begin, + pos_end, + string_pos, + argc_pos, + separator); +} +*/ + +bool GetArgvBeginEnd(const char *string, + const size_t &string_len, + const unsigned int argc, + int & pos_begin, + int & pos_end, + unsigned int &string_pos, + unsigned int &argc_pos, + char separator) +{ pos_begin = -1; pos_end = -1; if (string == nullptr) { return false; } - size_t string_len = strlen(string); - unsigned int string_pos = 0, argc_pos = 0; bool parenthesis = false; char matching_parenthesis = '"'; diff --git a/src/src/Helpers/StringConverter.h b/src/src/Helpers/StringConverter.h index 04a7567db..b3722c4f6 100644 --- a/src/src/Helpers/StringConverter.h +++ b/src/src/Helpers/StringConverter.h @@ -443,11 +443,28 @@ bool GetArgv(const char *string, unsigned int argc, char separator = ','); +bool GetArgv(const char *string, + const size_t & string_len, + String & argvString, + unsigned int argc, + unsigned int & string_pos, + unsigned int & argc_pos, + char separator = ','); +/* bool GetArgvBeginEnd(const char *string, const unsigned int argc, int & pos_begin, int & pos_end, char separator = ','); +*/ +bool GetArgvBeginEnd(const char *string, + const size_t & string_len, + const unsigned int argc, + int & pos_begin, + int & pos_end, + unsigned int & string_pos, + unsigned int & argc_pos, + char separator = ','); #endif // HELPERS_STRINGCONVERTER_H diff --git a/src/src/Helpers/StringParser.cpp b/src/src/Helpers/StringParser.cpp index d6ef85182..a619616a1 100644 --- a/src/src/Helpers/StringParser.cpp +++ b/src/src/Helpers/StringParser.cpp @@ -1120,13 +1120,16 @@ KeyValueStruct parseArguments( String result; uint8_t indexFind = 1; - if (!GetArgv(string.c_str(), result, indexFind, separator)) { + unsigned int string_pos = 0, argc_pos = 0; + const char *string_c_str = string.c_str(); + + if (!GetArgv(string_c_str, string.length(), result, indexFind, string_pos, argc_pos, separator)) { return KeyValueStruct(); } KeyValueStruct res(result); res._key.setCaseFormat(ValueStruct::CaseFormat::ToLower); - while (GetArgv(string.c_str(), result, ++indexFind, separator)) + while (GetArgv(string_c_str, string.length(), result, indexFind, string_pos, argc_pos, separator)) { if (keepRawStrings) { res.appendValue(result); } else { diff --git a/src/src/WebServer/JSON.cpp b/src/src/WebServer/JSON.cpp index ab65ea34d..8fe67d56d 100644 --- a/src/src/WebServer/JSON.cpp +++ b/src/src/WebServer/JSON.cpp @@ -638,7 +638,7 @@ void handle_json_stream_task_value_data(TaskValuesWriterHelper*data) writer->write({ F("NrDecimals"), nrDecimals }); # if FEATURE_STRING_VARIABLES - if (!data->hasPresentation) { + if (data->hasPresentation) { KeyValueStruct kv(F("Presentation"), data->presentation); kv.setID(data->format_ID(TaskValuesWriterHelper::ID_type::Presentation)); writer->write(kv);