diff --git a/components/core/src/clp/TraceableException.hpp b/components/core/src/clp/TraceableException.hpp index cd8e33f4b..f17c6ef0d 100644 --- a/components/core/src/clp/TraceableException.hpp +++ b/components/core/src/clp/TraceableException.hpp @@ -39,6 +39,7 @@ class TraceableException : public std::exception { // Macros // Define a version of __FILE__ that's relative to the source directory #ifdef SOURCE_PATH_SIZE + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) #define __FILENAME__ ((__FILE__) + SOURCE_PATH_SIZE) #else // We don't know the source path size, so just default to __FILE__ diff --git a/components/core/src/clp/ffi/defs.hpp b/components/core/src/clp/ffi/defs.hpp new file mode 100644 index 000000000..fa7405f65 --- /dev/null +++ b/components/core/src/clp/ffi/defs.hpp @@ -0,0 +1,68 @@ +#ifndef CLP_FFI_DEFS_HPP +#define CLP_FFI_DEFS_HPP + +#include +#include +#include +#include +#include + +#include "../ErrorCode.hpp" +#include "../TraceableException.hpp" + +namespace clp::ffi { +/* + * These constants can be used by callers to store the version of the schemas and encoding methods + * they're using. At some point, we may update and/or add built-in schemas/encoding methods. So + * callers must store the versions they used for encoding to ensure that they can choose the same + * versions for decoding. + * + * We use versions which look like package names in anticipation of users writing their own custom + * schemas and encoding methods. + */ +constexpr std::string_view cVariableEncodingMethodsVersion + = "com.yscope.clp.VariableEncodingMethodsV1"; +constexpr std::string_view cVariablesSchemaVersion = "com.yscope.clp.VariablesSchemaV2"; + +constexpr std::string_view cTooFewDictionaryVarsErrorMessage + = "There are fewer dictionary variables than dictionary variable placeholders in the " + "logtype."; +constexpr std::string_view cTooFewEncodedVarsErrorMessage + = "There are fewer encoded variables than encoded variable placeholders in the logtype."; +constexpr std::string_view cUnexpectedEscapeCharacterMessage + = "Unexpected escape character without escaped value at the end of the logtype."; +constexpr std::string_view cTooManyDigitsErrorMsg = "Encoded number of digits doesn't match " + "encoded digits in encoded float."; + +constexpr size_t cMaxDigitsInRepresentableEightByteFloatVar = 16; +constexpr size_t cMaxDigitsInRepresentableFourByteFloatVar = 8; +constexpr uint64_t cEightByteEncodedFloatNumDigits = 54; +constexpr uint64_t cFourByteEncodedFloatNumDigits = 25; +constexpr uint64_t cEightByteEncodedFloatDigitsBitMask = (1ULL << 54) - 1; +constexpr uint32_t cFourByteEncodedFloatDigitsBitMask = (1UL << 25) - 1; + +constexpr size_t cDecimalBase = 10; +constexpr uint32_t cLowerFourDigitsBitMask = (1UL << 4) - 1; +constexpr uint32_t cLowerThreeDigitsBitMask = (1UL << 3) - 1; + +class EncodingException : public TraceableException { +public: + // Constructors + EncodingException( + ErrorCode error_code, + char const* const filename, + int line_number, + std::string message + ) + : TraceableException(error_code, filename, line_number), + m_message(std::move(message)) {} + + // Methods + [[nodiscard]] auto what() const noexcept -> char const* override { return m_message.c_str(); } + +private: + std::string m_message; +}; +} // namespace clp::ffi + +#endif // CLP_FFI_DEFS_HPP diff --git a/components/core/src/clp/ffi/encoding_methods.cpp b/components/core/src/clp/ffi/encoding_methods.cpp index 6113164fe..558b752a5 100644 --- a/components/core/src/clp/ffi/encoding_methods.cpp +++ b/components/core/src/clp/ffi/encoding_methods.cpp @@ -1,6 +1,6 @@ #include "encoding_methods.hpp" -#include +#include #include #include "../ir/types.hpp" @@ -10,9 +10,8 @@ using clp::ir::four_byte_encoded_variable_t; using std::string_view; namespace clp::ffi { -eight_byte_encoded_variable_t encode_four_byte_float_as_eight_byte( - four_byte_encoded_variable_t four_byte_encoded_var -) { +auto encode_four_byte_float_as_eight_byte(four_byte_encoded_variable_t four_byte_encoded_var +) -> eight_byte_encoded_variable_t { uint8_t decimal_point_pos{}; uint8_t num_digits{}; uint32_t digits{}; @@ -33,9 +32,8 @@ eight_byte_encoded_variable_t encode_four_byte_float_as_eight_byte( ); } -eight_byte_encoded_variable_t encode_four_byte_integer_as_eight_byte( - four_byte_encoded_variable_t four_byte_encoded_var -) { +auto encode_four_byte_integer_as_eight_byte(four_byte_encoded_variable_t four_byte_encoded_var +) -> eight_byte_encoded_variable_t { return static_cast(four_byte_encoded_var); } } // namespace clp::ffi diff --git a/components/core/src/clp/ffi/encoding_methods.hpp b/components/core/src/clp/ffi/encoding_methods.hpp index d7f53cfc5..068f1da7d 100644 --- a/components/core/src/clp/ffi/encoding_methods.hpp +++ b/components/core/src/clp/ffi/encoding_methods.hpp @@ -1,62 +1,19 @@ #ifndef CLP_FFI_ENCODING_METHODS_HPP #define CLP_FFI_ENCODING_METHODS_HPP +#include +#include +#include #include +#include +#include #include -#include "../ir/parsing.hpp" #include "../ir/types.hpp" -#include "../TraceableException.hpp" // TODO Some of the methods in this file are mostly duplicated from code that exists elsewhere in // the repo. They should be consolidated in a future commit. namespace clp::ffi { -class EncodingException : public TraceableException { -public: - // Constructors - EncodingException( - ErrorCode error_code, - char const* const filename, - int line_number, - std::string message - ) - : TraceableException(error_code, filename, line_number), - m_message(std::move(message)) {} - - // Methods - [[nodiscard]] char const* what() const noexcept override { return m_message.c_str(); } - -private: - std::string m_message; -}; - -// Constants -/* - * These constants can be used by callers to store the version of the schemas and encoding methods - * they're using. At some point, we may update and/or add built-in schemas/encoding methods. So - * callers must store the versions they used for encoding to ensure that they can choose the same - * versions for decoding. - * - * We use versions which look like package names in anticipation of users writing their own custom - * schemas and encoding methods. - */ -static constexpr char cVariableEncodingMethodsVersion[] - = "com.yscope.clp.VariableEncodingMethodsV1"; -static constexpr char cVariablesSchemaVersion[] = "com.yscope.clp.VariablesSchemaV2"; - -static constexpr char cTooFewDictionaryVarsErrorMessage[] - = "There are fewer dictionary variables than dictionary variable placeholders in the " - "logtype."; -static constexpr char cTooFewEncodedVarsErrorMessage[] - = "There are fewer encoded variables than encoded variable placeholders in the logtype."; -static constexpr char cUnexpectedEscapeCharacterMessage[] - = "Unexpected escape character without escaped value at the end of the logtype."; - -constexpr size_t cMaxDigitsInRepresentableEightByteFloatVar = 16; -constexpr size_t cMaxDigitsInRepresentableFourByteFloatVar = 8; -constexpr uint64_t cEightByteEncodedFloatDigitsBitMask = (1ULL << 54) - 1; -constexpr uint32_t cFourByteEncodedFloatDigitsBitMask = (1UL << 25) - 1; - /** * Encodes the given string into a representable float variable if possible * @tparam encoded_variable_t Type of the encoded variable @@ -65,16 +22,17 @@ constexpr uint32_t cFourByteEncodedFloatDigitsBitMask = (1UL << 25) - 1; * @return true on success, false otherwise */ template -bool encode_float_string(std::string_view str, encoded_variable_t& encoded_var); +[[nodiscard]] auto +encode_float_string(std::string_view str, encoded_variable_t& encoded_var) -> bool; /** * Encodes the given four-byte encoded float using the eight-byte encoding * @param four_byte_encoded_var * @return The float using the eight-byte encoding */ -ir::eight_byte_encoded_variable_t encode_four_byte_float_as_eight_byte( +[[nodiscard]] auto encode_four_byte_float_as_eight_byte( ir::four_byte_encoded_variable_t four_byte_encoded_var -); +) -> ir::eight_byte_encoded_variable_t; /** * Encodes a float value with the given properties into an encoded variable. @@ -87,7 +45,7 @@ ir::eight_byte_encoded_variable_t encode_four_byte_float_as_eight_byte( * @return The encoded variable */ template -encoded_variable_t encode_float_properties( +[[nodiscard]] auto encode_float_properties( bool is_negative, std::conditional_t< std::is_same_v, @@ -95,7 +53,7 @@ encoded_variable_t encode_float_properties( uint64_t> digits, size_t num_digits, size_t decimal_point_pos -); +) -> encoded_variable_t; /** * Decodes an encoded float variable into its properties @@ -107,7 +65,7 @@ encoded_variable_t encode_float_properties( * @param decimal_point_pos Returns the position of the decimal point from the right of the value */ template -void decode_float_properties( +auto decode_float_properties( encoded_variable_t encoded_var, bool& is_negative, std::conditional_t< @@ -116,7 +74,7 @@ void decode_float_properties( uint64_t>& digits, uint8_t& num_digits, uint8_t& decimal_point_pos -); +) -> void; /** * Decodes the given encoded float variable into a string @@ -125,7 +83,7 @@ void decode_float_properties( * @return The decoded value as a string */ template -std::string decode_float_var(encoded_variable_t encoded_var); +[[nodiscard]] auto decode_float_var(encoded_variable_t encoded_var) -> std::string; /** * Encodes the given string into a representable integer variable if possible @@ -135,16 +93,17 @@ std::string decode_float_var(encoded_variable_t encoded_var); * @return true if successfully converted, false otherwise */ template -bool encode_integer_string(std::string_view str, encoded_variable_t& encoded_var); +[[nodiscard]] auto +encode_integer_string(std::string_view str, encoded_variable_t& encoded_var) -> bool; /** * Encodes the given four-byte encoded integer using the eight-byte encoding * @param four_byte_encoded_var * @return The integer using the eight-byte encoding */ -ir::eight_byte_encoded_variable_t encode_four_byte_integer_as_eight_byte( +[[nodiscard]] auto encode_four_byte_integer_as_eight_byte( ir::four_byte_encoded_variable_t four_byte_encoded_var -); +) -> ir::eight_byte_encoded_variable_t; /** * Decodes the given encoded integer variable into a string @@ -153,7 +112,7 @@ ir::eight_byte_encoded_variable_t encode_four_byte_integer_as_eight_byte( * @return The decoded value as a string */ template -std::string decode_integer_var(encoded_variable_t encoded_var); +[[nodiscard]] auto decode_integer_var(encoded_variable_t encoded_var) -> std::string; /** * Encodes the given message and calls the given methods to handle specific components of the @@ -177,13 +136,13 @@ template < typename ConstantHandler, typename EncodedVariableHandler, typename DictionaryVariableHandler> -bool encode_message_generically( +[[nodiscard]] auto encode_message_generically( std::string_view message, std::string& logtype, ConstantHandler constant_handler, EncodedVariableHandler encoded_variable_handler, DictionaryVariableHandler dictionary_variable_handler -); +) -> bool; /** * Encodes the given message. The simplistic interface is to make it efficient to transfer data @@ -197,12 +156,12 @@ bool encode_message_generically( * @return false if the message contains variable placeholders, true otherwise */ template -bool encode_message( +[[nodiscard]] auto encode_message( std::string_view message, std::string& logtype, std::vector& encoded_vars, std::vector& dictionary_var_bounds -); +) -> bool; /** * Decodes the message from the given logtype, encoded variables, and dictionary variables. The @@ -211,23 +170,19 @@ bool encode_message( * @tparam encoded_variable_t Type of the encoded variable * @param logtype * @param encoded_vars - * @param encoded_vars_length * @param all_dictionary_vars The message's dictionary variables, stored back-to-back in a single * byte-array * @param dictionary_var_end_offsets The end-offset of each dictionary variable in * ``all_dictionary_vars`` - * @param dictionary_var_end_offsets_length * @return The decoded message */ template -std::string decode_message( +[[nodiscard]] auto decode_message( std::string_view logtype, - encoded_variable_t* encoded_vars, - size_t encoded_vars_length, + std::span encoded_vars, std::string_view all_dictionary_vars, - int32_t const* dictionary_var_end_offsets, - size_t dictionary_var_end_offsets_length -); + std::span dictionary_var_end_offsets +) -> std::string; /** * Checks if any encoded variable matches the given wildcard query @@ -239,16 +194,14 @@ std::string decode_message( * @param wildcard_query * @param logtype * @param encoded_vars - * @param encoded_vars_length * @return true if a match was found, false otherwise */ template -bool wildcard_query_matches_any_encoded_var( +[[nodiscard]] auto wildcard_query_matches_any_encoded_var( std::string_view wildcard_query, std::string_view logtype, - encoded_variable_t* encoded_vars, - size_t encoded_vars_length -); + std::span encoded_vars +) -> bool; /** * Checks whether the given wildcard strings match the given encoded variables (from a message). @@ -262,7 +215,6 @@ bool wildcard_query_matches_any_encoded_var( * @tparam encoded_variable_t Type of the encoded variable * @param logtype The message's logtype * @param encoded_vars The message's encoded variables - * @param encoded_vars_length The number of encoded variables in \p encoded_vars * @param wildcard_var_placeholders String of variable placeholders, where each one indicates how * the corresponding wildcard string should be interpreted. * @param wildcard_var_queries The wildcard strings to compare with the encoded variables. Callers @@ -271,15 +223,16 @@ bool wildcard_query_matches_any_encoded_var( * @return Whether the wildcard strings match the encoded variables */ template -bool wildcard_match_encoded_vars( +[[nodiscard]] auto wildcard_match_encoded_vars( std::string_view logtype, - encoded_variable_t* encoded_vars, - size_t encoded_vars_length, + std::span encoded_vars, std::string_view wildcard_var_placeholders, std::vector const& wildcard_var_queries -); +) -> bool; } // namespace clp::ffi +// TODO Refactor nested headers +// NOLINTNEXTLINE(misc-include-cleaner) #include "encoding_methods.inc" #endif // CLP_FFI_ENCODING_METHODS_HPP diff --git a/components/core/src/clp/ffi/encoding_methods.inc b/components/core/src/clp/ffi/encoding_methods.inc index c14a3734d..8ae66301c 100644 --- a/components/core/src/clp/ffi/encoding_methods.inc +++ b/components/core/src/clp/ffi/encoding_methods.inc @@ -1,33 +1,42 @@ #ifndef CLP_FFI_ENCODING_METHODS_INC #define CLP_FFI_ENCODING_METHODS_INC -#include +#include +#include +#include +#include +#include +#include +#include #include +#include "../ErrorCode.hpp" #include "../ir/parsing.hpp" #include "../ir/types.hpp" #include "../type_utils.hpp" +#include "defs.hpp" namespace clp::ffi { template -bool encode_float_string(std::string_view str, encoded_variable_t& encoded_var) { +[[nodiscard]] auto +encode_float_string(std::string_view str, encoded_variable_t& encoded_var) -> bool { auto const value_length = str.length(); if (0 == value_length) { // Can't convert an empty string return false; } - size_t pos = 0; + size_t pos{0}; constexpr size_t cMaxDigitsInRepresentableFloatVar = std::is_same_v ? cMaxDigitsInRepresentableFourByteFloatVar : cMaxDigitsInRepresentableEightByteFloatVar; // +1 for decimal point - size_t max_length = cMaxDigitsInRepresentableFloatVar + 1; + size_t max_length{cMaxDigitsInRepresentableFloatVar + 1}; // Check for a negative sign - bool is_negative = false; + bool is_negative{false}; if ('-' == str[pos]) { is_negative = true; ++pos; @@ -40,17 +49,17 @@ bool encode_float_string(std::string_view str, encoded_variable_t& encoded_var) return false; } - size_t num_digits = 0; - size_t decimal_point_pos = std::string::npos; + size_t num_digits{0}; + size_t decimal_point_pos{std::string::npos}; std::conditional_t< std::is_same_v, uint32_t, uint64_t> - digits = 0; + digits{0}; for (; pos < value_length; ++pos) { auto c = str[pos]; if ('0' <= c && c <= '9') { - digits *= 10; + digits *= cDecimalBase; digits += (c - '0'); ++num_digits; } else if (std::string::npos == decimal_point_pos && '.' == c) { @@ -82,7 +91,7 @@ bool encode_float_string(std::string_view str, encoded_variable_t& encoded_var) } template -encoded_variable_t encode_float_properties( +[[nodiscard]] auto encode_float_properties( bool is_negative, std::conditional_t< std::is_same_v, @@ -90,7 +99,7 @@ encoded_variable_t encode_float_properties( uint64_t> digits, size_t num_digits, size_t decimal_point_pos -) { +) -> encoded_variable_t { static_assert( (std::is_same_v || std::is_same_v) @@ -121,12 +130,12 @@ encoded_variable_t encode_float_properties( if (is_negative) { encoded_float = 1; } - encoded_float <<= 55; // 1 unused + 54 for digits of the float + encoded_float <<= (1 + cEightByteEncodedFloatNumDigits); // 1 unused encoded_float |= digits & cEightByteEncodedFloatDigitsBitMask; encoded_float <<= 4; - encoded_float |= (num_digits - 1) & 0x0F; + encoded_float |= (num_digits - 1) & cLowerFourDigitsBitMask; encoded_float <<= 4; - encoded_float |= (decimal_point_pos - 1) & 0x0F; + encoded_float |= (decimal_point_pos - 1) & cLowerFourDigitsBitMask; return bit_cast(encoded_float); } else { // std::is_same_v @@ -154,18 +163,18 @@ encoded_variable_t encode_float_properties( if (is_negative) { encoded_float = 1; } - encoded_float <<= 25; // 25 for digits of the float + encoded_float <<= cFourByteEncodedFloatNumDigits; encoded_float |= digits & cFourByteEncodedFloatDigitsBitMask; encoded_float <<= 3; - encoded_float |= (num_digits - 1) & 0x07; + encoded_float |= (num_digits - 1) & cLowerThreeDigitsBitMask; encoded_float <<= 3; - encoded_float |= (decimal_point_pos - 1) & 0x07; + encoded_float |= (decimal_point_pos - 1) & cLowerThreeDigitsBitMask; return bit_cast(encoded_float); } } template -void decode_float_properties( +auto decode_float_properties( encoded_variable_t encoded_var, bool& is_negative, std::conditional_t< @@ -174,7 +183,7 @@ void decode_float_properties( uint64_t>& digits, uint8_t& num_digits, uint8_t& decimal_point_pos -) { +) -> void { static_assert( (std::is_same_v || std::is_same_v) @@ -183,9 +192,9 @@ void decode_float_properties( auto encoded_float = bit_cast(encoded_var); // Decode according to the format described in encode_float_string - decimal_point_pos = (encoded_float & 0x0F) + 1; + decimal_point_pos = (encoded_float & cLowerFourDigitsBitMask) + 1; encoded_float >>= 4; - num_digits = (encoded_float & 0x0F) + 1; + num_digits = (encoded_float & cLowerFourDigitsBitMask) + 1; encoded_float >>= 4; digits = encoded_float & cEightByteEncodedFloatDigitsBitMask; // This is the maximum base-10 number with cMaxDigitsInRepresentableEightByteFloatVar @@ -199,35 +208,35 @@ void decode_float_properties( "value." ); } - encoded_float >>= 55; + encoded_float >>= (cEightByteEncodedFloatNumDigits + 1); is_negative = encoded_float > 0; } else { // std::is_same_v auto encoded_float = bit_cast(encoded_var); // Decode according to the format in encode_string_as_float_compact_var - decimal_point_pos = (encoded_float & 0x07) + 1; + decimal_point_pos = (encoded_float & cLowerThreeDigitsBitMask) + 1; encoded_float >>= 3; - num_digits = (encoded_float & 0x07) + 1; + num_digits = (encoded_float & cLowerThreeDigitsBitMask) + 1; encoded_float >>= 3; digits = encoded_float & cFourByteEncodedFloatDigitsBitMask; - encoded_float >>= 25; + encoded_float >>= cFourByteEncodedFloatNumDigits; is_negative = encoded_float > 0; } } template -std::string decode_float_var(encoded_variable_t encoded_var) { +[[nodiscard]] auto decode_float_var(encoded_variable_t encoded_var) -> std::string { std::string value; - uint8_t decimal_point_pos; - uint8_t num_digits; + uint8_t decimal_point_pos{0}; + uint8_t num_digits{0}; std::conditional_t< std::is_same_v, uint32_t, uint64_t> digits; - bool is_negative; + bool is_negative{false}; decode_float_properties(encoded_var, is_negative, digits, num_digits, decimal_point_pos); if (num_digits < decimal_point_pos) { @@ -239,7 +248,7 @@ std::string decode_float_var(encoded_variable_t encoded_var) { ); } - size_t value_length = num_digits + 1 + is_negative; + size_t const value_length = num_digits + 1 + is_negative; value.resize(value_length); size_t num_chars_to_process = value_length; @@ -253,20 +262,18 @@ std::string decode_float_var(encoded_variable_t encoded_var) { size_t pos = value_length - 1; auto decimal_point_pos_from_left = value_length - 1 - decimal_point_pos; for (; pos > decimal_point_pos_from_left && digits > 0; --pos) { - value[pos] = (char)('0' + (digits % 10)); - digits /= 10; + value[pos] = (char)('0' + (digits % cDecimalBase)); + digits /= cDecimalBase; --num_chars_to_process; } if (digits > 0) { - constexpr char cTooManyDigitsErrorMsg[] = "Encoded number of digits doesn't match " - "encoded digits in encoded float."; if (0 == num_chars_to_process) { throw EncodingException( ErrorCode_Corrupt, __FILENAME__, __LINE__, - cTooManyDigitsErrorMsg + std::string{cTooManyDigitsErrorMsg} ); } // Skip decimal since it's added at the end @@ -279,12 +286,12 @@ std::string decode_float_var(encoded_variable_t encoded_var) { ErrorCode_Corrupt, __FILENAME__, __LINE__, - cTooManyDigitsErrorMsg + std::string{cTooManyDigitsErrorMsg} ); } - value[pos--] = (char)('0' + (digits % 10)); - digits /= 10; + value[pos--] = (char)('0' + (digits % cDecimalBase)); + digits /= cDecimalBase; --num_chars_to_process; } } @@ -301,8 +308,9 @@ std::string decode_float_var(encoded_variable_t encoded_var) { } template -bool encode_integer_string(std::string_view str, encoded_variable_t& encoded_var) { - size_t length = str.length(); +[[nodiscard]] auto +encode_integer_string(std::string_view str, encoded_variable_t& encoded_var) -> bool { + size_t const length{str.length()}; if (0 == length) { // Empty string cannot be converted return false; @@ -330,15 +338,13 @@ bool encode_integer_string(std::string_view str, encoded_variable_t& encoded_var if (false == string_utils::convert_string_to_int(str, result)) { // Conversion failed return false; - } else { - encoded_var = result; } - + encoded_var = result; return true; } template -std::string decode_integer_var(encoded_variable_t encoded_var) { +[[nodiscard]] auto decode_integer_var(encoded_variable_t encoded_var) -> std::string { return std::to_string(encoded_var); } @@ -347,13 +353,13 @@ template < typename ConstantHandler, typename EncodedVariableHandler, typename DictionaryVariableHandler> -bool encode_message_generically( +[[nodiscard]] auto encode_message_generically( std::string_view message, std::string& logtype, ConstantHandler constant_handler, EncodedVariableHandler encoded_variable_handler, DictionaryVariableHandler dictionary_variable_handler -) { +) -> bool { size_t var_begin_pos = 0; size_t var_end_pos = 0; size_t constant_begin_pos = 0; @@ -393,12 +399,12 @@ bool encode_message_generically( } template -bool encode_message( +[[nodiscard]] auto encode_message( std::string_view message, std::string& logtype, std::vector& encoded_vars, std::vector& dictionary_var_bounds -) { +) -> bool { auto encoded_variable_handler = [&encoded_vars](encoded_variable_t encoded_variable) { encoded_vars.push_back(encoded_variable); }; @@ -429,14 +435,12 @@ bool encode_message( } template -std::string decode_message( +[[nodiscard]] auto decode_message( std::string_view logtype, - encoded_variable_t* encoded_vars, - size_t encoded_vars_length, + std::span encoded_vars, std::string_view all_dictionary_vars, - int32_t const* dictionary_var_end_offsets, - size_t dictionary_var_end_offsets_length -) { + std::span dictionary_var_end_offsets +) -> std::string { std::string message; size_t last_variable_end_pos = 0; size_t dictionary_var_begin_pos = 0; @@ -447,12 +451,12 @@ std::string decode_message( if (enum_to_underlying_type(ir::VariablePlaceholder::Float) == c) { message.append(logtype, last_variable_end_pos, i - last_variable_end_pos); last_variable_end_pos = i + 1; - if (encoded_vars_ix >= encoded_vars_length) { + if (encoded_vars_ix >= encoded_vars.size()) { throw EncodingException( ErrorCode_Corrupt, __FILENAME__, __LINE__, - cTooFewEncodedVarsErrorMessage + std::string{cTooFewEncodedVarsErrorMessage} ); } message.append(decode_float_var(encoded_vars[encoded_vars_ix])); @@ -460,12 +464,12 @@ std::string decode_message( } else if (enum_to_underlying_type(ir::VariablePlaceholder::Integer) == c) { message.append(logtype, last_variable_end_pos, i - last_variable_end_pos); last_variable_end_pos = i + 1; - if (encoded_vars_ix >= encoded_vars_length) { + if (encoded_vars_ix >= encoded_vars.size()) { throw EncodingException( ErrorCode_Corrupt, __FILENAME__, __LINE__, - cTooFewEncodedVarsErrorMessage + std::string{cTooFewEncodedVarsErrorMessage} ); } message.append(decode_integer_var(encoded_vars[encoded_vars_ix])); @@ -473,12 +477,12 @@ std::string decode_message( } else if (enum_to_underlying_type(ir::VariablePlaceholder::Dictionary) == c) { message.append(logtype, last_variable_end_pos, i - last_variable_end_pos); last_variable_end_pos = i + 1; - if (dictionary_var_bounds_ix >= dictionary_var_end_offsets_length) { + if (dictionary_var_bounds_ix >= dictionary_var_end_offsets.size()) { throw EncodingException( ErrorCode_Corrupt, __FILENAME__, __LINE__, - cTooFewDictionaryVarsErrorMessage + std::string{cTooFewDictionaryVarsErrorMessage} ); } auto end_pos = dictionary_var_end_offsets[dictionary_var_bounds_ix]; @@ -500,21 +504,20 @@ std::string decode_message( } template -bool wildcard_query_matches_any_encoded_var( +[[nodiscard]] auto wildcard_query_matches_any_encoded_var( std::string_view wildcard_query, std::string_view logtype, - encoded_variable_t* encoded_vars, - size_t encoded_vars_length -) { + std::span encoded_vars +) -> bool { size_t encoded_vars_ix = 0; for (auto c : logtype) { if (enum_to_underlying_type(ir::VariablePlaceholder::Float) == c) { - if (encoded_vars_ix >= encoded_vars_length) { + if (encoded_vars_ix >= encoded_vars.size()) { throw EncodingException( ErrorCode_Corrupt, __FILENAME__, __LINE__, - cTooFewEncodedVarsErrorMessage + std::string{cTooFewEncodedVarsErrorMessage} ); } @@ -527,12 +530,12 @@ bool wildcard_query_matches_any_encoded_var( ++encoded_vars_ix; } else if (enum_to_underlying_type(ir::VariablePlaceholder::Integer) == c) { - if (encoded_vars_ix >= encoded_vars_length) { + if (encoded_vars_ix >= encoded_vars.size()) { throw EncodingException( ErrorCode_Corrupt, __FILENAME__, __LINE__, - cTooFewEncodedVarsErrorMessage + std::string{cTooFewEncodedVarsErrorMessage} ); } @@ -551,85 +554,57 @@ bool wildcard_query_matches_any_encoded_var( } template -bool wildcard_match_encoded_vars( +[[nodiscard]] auto wildcard_match_encoded_vars( std::string_view logtype, - encoded_variable_t* encoded_vars, - size_t encoded_vars_length, + std::span encoded_vars, std::string_view wildcard_var_placeholders, std::vector const& wildcard_var_queries -) { +) -> bool { // Validate arguments - if (nullptr == encoded_vars) { - throw EncodingException( - ErrorCode_BadParam, - __FILENAME__, - __LINE__, - cTooFewEncodedVarsErrorMessage - ); - } if (wildcard_var_queries.size() != wildcard_var_placeholders.length()) { throw EncodingException( ErrorCode_BadParam, __FILENAME__, __LINE__, - cTooFewEncodedVarsErrorMessage + std::string{cTooFewEncodedVarsErrorMessage} ); } - auto wildcard_var_queries_len = wildcard_var_queries.size(); - size_t var_ix = 0; - size_t wildcard_var_ix = 0; + auto const wildcard_var_queries_len = wildcard_var_queries.size(); + size_t var_ix{0}; + size_t wildcard_var_ix{0}; for (auto c : logtype) { - if (enum_to_underlying_type(ir::VariablePlaceholder::Float) == c) { - if (var_ix >= encoded_vars_length) { - throw EncodingException( - ErrorCode_Corrupt, - __FILENAME__, - __LINE__, - cTooFewEncodedVarsErrorMessage - ); - } + if (enum_to_underlying_type(ir::VariablePlaceholder::Float) != c + && enum_to_underlying_type(ir::VariablePlaceholder::Integer) != c) + { + continue; + } - if (wildcard_var_placeholders[wildcard_var_ix] == c) { - auto decoded_var = decode_float_var(encoded_vars[var_ix]); - if (string_utils::wildcard_match_unsafe( - decoded_var, - wildcard_var_queries[wildcard_var_ix] - )) - { - ++wildcard_var_ix; - if (wildcard_var_ix == wildcard_var_queries_len) { - break; - } - } - } + if (var_ix >= encoded_vars.size()) { + throw EncodingException( + ErrorCode_Corrupt, + __FILENAME__, + __LINE__, + std::string{cTooFewEncodedVarsErrorMessage} + ); + } + if (wildcard_var_placeholders[wildcard_var_ix] != c) { ++var_ix; - } else if (enum_to_underlying_type(ir::VariablePlaceholder::Integer) == c) { - if (var_ix >= encoded_vars_length) { - throw EncodingException( - ErrorCode_Corrupt, - __FILENAME__, - __LINE__, - cTooFewEncodedVarsErrorMessage - ); - } + continue; + } - if (wildcard_var_placeholders[wildcard_var_ix] == c) { - auto decoded_var = decode_integer_var(encoded_vars[var_ix]); - if (string_utils::wildcard_match_unsafe( - decoded_var, - wildcard_var_queries[wildcard_var_ix] - )) - { - ++wildcard_var_ix; - if (wildcard_var_ix == wildcard_var_queries_len) { - break; - } - } - } + auto decoded_var = (enum_to_underlying_type(ir::VariablePlaceholder::Float) == c) + ? decode_float_var(encoded_vars[var_ix]) + : decode_integer_var(encoded_vars[var_ix]); + ++var_ix; - ++var_ix; + if (string_utils::wildcard_match_unsafe(decoded_var, wildcard_var_queries[wildcard_var_ix])) + { + ++wildcard_var_ix; + if (wildcard_var_ix == wildcard_var_queries_len) { + break; + } } } diff --git a/components/core/src/clp/ffi/ir_stream/decoding_methods.inc b/components/core/src/clp/ffi/ir_stream/decoding_methods.inc index 65a72c7a3..34bef18ba 100644 --- a/components/core/src/clp/ffi/ir_stream/decoding_methods.inc +++ b/components/core/src/clp/ffi/ir_stream/decoding_methods.inc @@ -2,6 +2,7 @@ #define CLP_FFI_IR_STREAM_DECODING_METHODS_INC #include +#include #include #include "../../ir/types.hpp" @@ -48,7 +49,7 @@ void generic_decode_message( ErrorCode_Corrupt, __FILENAME__, __LINE__, - cTooFewEncodedVarsErrorMessage + std::string{cTooFewEncodedVarsErrorMessage} ); } encoded_float_handler(encoded_vars[encoded_vars_ix]); @@ -69,7 +70,7 @@ void generic_decode_message( ErrorCode_Corrupt, __FILENAME__, __LINE__, - cTooFewEncodedVarsErrorMessage + std::string{cTooFewEncodedVarsErrorMessage} ); } encoded_int_handler(encoded_vars[encoded_vars_ix]); @@ -90,7 +91,7 @@ void generic_decode_message( ErrorCode_Corrupt, __FILENAME__, __LINE__, - cTooFewDictionaryVarsErrorMessage + std::string{cTooFewDictionaryVarsErrorMessage} ); } dict_var_handler(dict_vars[dictionary_vars_ix]); @@ -106,7 +107,7 @@ void generic_decode_message( ErrorCode_Corrupt, __FILENAME__, __LINE__, - cUnexpectedEscapeCharacterMessage + std::string{cUnexpectedEscapeCharacterMessage} ); } diff --git a/components/core/src/clp/ffi/utils.cpp b/components/core/src/clp/ffi/utils.cpp index c85c47701..93e27a309 100644 --- a/components/core/src/clp/ffi/utils.cpp +++ b/components/core/src/clp/ffi/utils.cpp @@ -1,22 +1,23 @@ #include "utils.hpp" -#include #include #include #include +#include +#include #include +#include #include #include -#include #include "../utf8_utils.hpp" +namespace clp::ffi { using std::string; using std::string_view; -namespace clp::ffi { auto validate_and_escape_utf8_string(string_view raw) -> std::optional { - std::optional ret_val; + std::optional ret_val; auto& escaped{ret_val.emplace()}; escaped.reserve(raw.size() + (raw.size() / 2)); if (false == validate_and_append_escaped_utf8_string(raw, escaped)) { @@ -25,15 +26,11 @@ auto validate_and_escape_utf8_string(string_view raw) -> std::optional { return ret_val; } -auto validate_and_append_escaped_utf8_string(std::string_view src, std::string& dst) -> bool { +auto validate_and_append_escaped_utf8_string(string_view src, string& dst) -> bool { string_view::const_iterator next_char_to_copy_it{src.cbegin()}; auto escape_handler = [&](string_view::const_iterator it) -> void { - // Allocate 6 + 1 size buffer to format control characters as "\u00bb", with the last byte - // used by `snprintf` to append '\0' - constexpr size_t cControlCharacterBufSize{7}; - std::array buf{}; - std::string_view escaped_char; + string_view escaped_char; bool escape_required{true}; switch (*it) { case '\b': @@ -58,11 +55,14 @@ auto validate_and_append_escaped_utf8_string(std::string_view src, std::string& escaped_char = "\\\""; break; default: { + // Format control characters as "\u00bb" + constexpr size_t cControlCharacterMaxSize{6}; constexpr uint8_t cLargestControlCharacter{0x1F}; auto const byte{static_cast(*it)}; if (cLargestControlCharacter >= byte) { - std::ignore = snprintf(buf.data(), buf.size(), "\\u00%02x", byte); - escaped_char = {buf.data(), buf.size() - 1}; + std::stringstream ss; + ss << "\\u00" << std::hex << std::setw(2) << std::setfill('0') << byte; + escaped_char = {ss.str().substr(0, cControlCharacterMaxSize)}; } else { escape_required = false; } diff --git a/components/core/tests/test-encoding_methods.cpp b/components/core/tests/test-encoding_methods.cpp index bd33fb45d..3676bc0e9 100644 --- a/components/core/tests/test-encoding_methods.cpp +++ b/components/core/tests/test-encoding_methods.cpp @@ -1,9 +1,17 @@ +#include +#include +#include +#include +#include + #include +#include "../src/clp/ffi/defs.hpp" #include "../src/clp/ffi/encoding_methods.hpp" #include "../src/clp/ir/types.hpp" using clp::enum_to_underlying_type; +using clp::ffi::cDecimalBase; using clp::ffi::decode_float_var; using clp::ffi::decode_integer_var; using clp::ffi::decode_message; @@ -15,21 +23,28 @@ using clp::ffi::wildcard_match_encoded_vars; using clp::ffi::wildcard_query_matches_any_encoded_var; using clp::ir::eight_byte_encoded_variable_t; using clp::ir::four_byte_encoded_variable_t; -using clp::ir::get_bounds_of_next_var; using clp::ir::VariablePlaceholder; +using std::span; using std::string; using std::string_view; using std::vector; -// Local function prototypes +namespace { /** * Fills a vector of string views from the given vector of strings * @param strings * @param string_views */ -static void -string_views_from_strings(vector const& strings, vector& string_views); +auto string_views_from_strings(vector const& strings, vector& string_views) + -> void { + string_views.reserve(strings.size()); + for (auto const& s : strings) { + string_views.emplace_back(s); + } +} +} // namespace +// NOLINTNEXTLINE(readability-function-cognitive-complexity) TEMPLATE_TEST_CASE( "Encoding integers", "[ffi][encode-integer]", @@ -50,21 +65,21 @@ TEMPLATE_TEST_CASE( value = "0"; REQUIRE(encode_integer_string(value, encoded_var)); decoded_value = decode_integer_var(encoded_var); - REQUIRE(decoded_value == value); + REQUIRE((decoded_value == value)); value = "-1"; REQUIRE(encode_integer_string(value, encoded_var)); decoded_value = decode_integer_var(encoded_var); - REQUIRE(decoded_value == value); + REQUIRE((decoded_value == value)); value = "1"; REQUIRE(encode_integer_string(value, encoded_var)); decoded_value = decode_integer_var(encoded_var); - REQUIRE(decoded_value == value); + REQUIRE((decoded_value == value)); // Test edges of representable range - int64_t min_value; - int64_t max_value; + int64_t min_value{0}; + int64_t max_value{0}; if constexpr (std::is_same_v) { min_value = INT64_MIN; max_value = INT64_MAX; @@ -75,165 +90,81 @@ TEMPLATE_TEST_CASE( value = std::to_string(min_value); REQUIRE(encode_integer_string(value, encoded_var)); decoded_value = decode_integer_var(encoded_var); - REQUIRE(decoded_value == value); + REQUIRE((decoded_value == value)); value = std::to_string(max_value); REQUIRE(encode_integer_string(value, encoded_var)); decoded_value = decode_integer_var(encoded_var); - REQUIRE(decoded_value == value); + REQUIRE((decoded_value == value)); if constexpr (std::is_same_v) { value = "9223372036854775808"; // INT64_MAX + 1 == 2^63 } else { // std::is_same_v value = "2147483648"; // INT32_MAX + 1 == 2^31 } - REQUIRE(false == encode_integer_string(value, encoded_var)); + REQUIRE_FALSE(encode_integer_string(value, encoded_var)); if constexpr (std::is_same_v) { value = "-9223372036854775809"; // INT64_MIN - 1 == -2^63 - 1 } else { // std::is_same_v value = "-2147483649"; // INT32_MIN - 1 == -2^31 - 1 } - REQUIRE(false == encode_integer_string(value, encoded_var)); - - // Test non-integers - value = ""; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "a"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "-"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "+"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "-a"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "+a"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "--"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "++"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - // Test unrepresentable values - value = " 1"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "- 1"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "1 "; - REQUIRE(!encode_integer_string(value, encoded_var)); + REQUIRE_FALSE(encode_integer_string(value, encoded_var)); - value = "01"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "+1"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "1u"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "1U"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "1l"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "1L"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "1ll"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "1LL"; - REQUIRE(!encode_integer_string(value, encoded_var)); - - value = "0.0"; - REQUIRE(!encode_integer_string(value, encoded_var)); + vector const non_integer_values{"", "a", "-", "+", "-a", "+a", "--", "++"}; + for (auto const& value : non_integer_values) { + REQUIRE_FALSE(encode_integer_string(value, encoded_var)); + } - value = "-0"; - REQUIRE(!encode_integer_string(value, encoded_var)); + vector const unrepresentable_values{ + " 1", + "- 1", + "1 ", + "01", + "+1", + "1u", + "1U", + "1l", + "1L", + "1ll", + "1LL", + "0.0", + "-0" + }; + for (auto const& value : unrepresentable_values) { + REQUIRE_FALSE(encode_integer_string(value, encoded_var)); + } } +// NOLINTNEXTLINE(readability-function-cognitive-complexity) TEMPLATE_TEST_CASE( "Encoding floats", "[ffi][encode-float]", eight_byte_encoded_variable_t, four_byte_encoded_variable_t ) { - string value; - string decoded_value; TestType encoded_var; // Test basic conversions - value = "0.0"; - REQUIRE(encode_float_string(value, encoded_var)); - decoded_value = decode_float_var(encoded_var); - REQUIRE(decoded_value == value); - - value = "-1.0"; - REQUIRE(encode_float_string(value, encoded_var)); - decoded_value = decode_float_var(encoded_var); - REQUIRE(decoded_value == value); - - value = "1.0"; - REQUIRE(encode_float_string(value, encoded_var)); - decoded_value = decode_float_var(encoded_var); - REQUIRE(decoded_value == value); - - value = ".1"; - REQUIRE(encode_float_string(value, encoded_var)); - decoded_value = decode_float_var(encoded_var); - REQUIRE(decoded_value == value); - - value = "-00.00"; - REQUIRE(encode_float_string(value, encoded_var)); - decoded_value = decode_float_var(encoded_var); - REQUIRE(decoded_value == value); + vector floats{"0.0", "-1.0", "1.0", ".1", "-00.00"}; // Test edges of representable range if constexpr (std::is_same_v) { - value = "-999999999999999.9"; - } else { // std::is_same_v - value = "-3355443.1"; - } - REQUIRE(encode_float_string(value, encoded_var)); - decoded_value = decode_float_var(encoded_var); - REQUIRE(decoded_value == value); - - if constexpr (std::is_same_v) { - value = "999999999999999.9"; - } else { // std::is_same_v - value = "3355443.1"; - } - REQUIRE(encode_float_string(value, encoded_var)); - decoded_value = decode_float_var(encoded_var); - REQUIRE(decoded_value == value); - - if constexpr (std::is_same_v) { - value = "-.9999999999999999"; + floats.insert( + floats.end(), + {"-999999999999999.9", + "999999999999999.9", + "-.9999999999999999", + ".9999999999999999"} + ); } else { // std::is_same_v - value = "-.33554431"; + floats.insert(floats.end(), {"-3355443.1", "3355443.1", "-.33554431", ".33554431"}); } - REQUIRE(encode_float_string(value, encoded_var)); - decoded_value = decode_float_var(encoded_var); - REQUIRE(decoded_value == value); - if constexpr (std::is_same_v) { - value = ".9999999999999999"; - } else { // std::is_same_v - value = ".33554431"; + for (auto const& value : floats) { + REQUIRE(encode_float_string(value, encoded_var)); + REQUIRE((decode_float_var(encoded_var) == value)); } - REQUIRE(encode_float_string(value, encoded_var)); - decoded_value = decode_float_var(encoded_var); - REQUIRE(decoded_value == value); SECTION("Test unrepresentable floats") { if constexpr (std::is_same_v) { @@ -245,7 +176,7 @@ TEMPLATE_TEST_CASE( "60.000004", "-60.000004" ); - REQUIRE(false == encode_float_string(unrepresentable_values, encoded_var)); + REQUIRE_FALSE(encode_float_string(unrepresentable_values, encoded_var)); } } @@ -271,26 +202,50 @@ TEMPLATE_TEST_CASE( "1.0L", "1.0.0" ); - REQUIRE(false == encode_float_string(non_floating_values, encoded_var)); + REQUIRE_FALSE(encode_float_string(non_floating_values, encoded_var)); } } +// NOLINTNEXTLINE(readability-function-cognitive-complexity) TEMPLATE_TEST_CASE( "encode_float_properties", "[ffi][encode-float]", eight_byte_encoded_variable_t, four_byte_encoded_variable_t ) { - // Test all possible combinations of the properties of the encoded float, except for individual - // values of the 'digits' field, since that takes too long. + using encoded_variable_t = std::conditional_t< + std::is_same_v, + uint32_t, + uint64_t>; + + encoded_variable_t const encoded_float_digits_bit_mask + = std::is_same_v + ? clp::ffi::cFourByteEncodedFloatDigitsBitMask + : clp::ffi::cEightByteEncodedFloatDigitsBitMask; constexpr size_t cMaxDigitsInRepresentableFloatVar = std::is_same_v ? clp::ffi::cMaxDigitsInRepresentableFourByteFloatVar : clp::ffi::cMaxDigitsInRepresentableEightByteFloatVar; - for (size_t num_digits_in_digits_property = 0; + constexpr uint8_t num_high_bits{std::is_same_v ? 1 : 2}; + constexpr uint8_t num_low_bits{62}; + + // Create a value for the `digits` property that has a certain number of digits + encoded_variable_t digits_max{0}; + encoded_variable_t digits{0}; + + // Test all possible combinations of the properties of the encoded float, except for individual + // values of the 'digits' field, since that takes too long. + for (size_t num_digits_in_digits_property{0}; num_digits_in_digits_property <= cMaxDigitsInRepresentableFloatVar + 1; - ++num_digits_in_digits_property) + ++num_digits_in_digits_property, + digits_max = digits_max * cDecimalBase + (cDecimalBase - 1)) { + // Due to the bitmask, the number of digits encoded may be less than + // num_digits_in_digits_property + digits = std::min(encoded_float_digits_bit_mask, digits_max); + auto const num_digits_in_value + = std::min(num_digits_in_digits_property, std::to_string(digits).length()); + // Iterate over the possible values of the `num_digits` property for (uint8_t num_digits = 1; num_digits <= cMaxDigitsInRepresentableFloatVar; ++num_digits) { @@ -299,33 +254,8 @@ TEMPLATE_TEST_CASE( decimal_point_pos <= cMaxDigitsInRepresentableFloatVar; ++decimal_point_pos) { - // Create a value for the `digits` property that has a certain number of digits - std::conditional_t< - std::is_same_v, - uint32_t, - uint64_t> - digits = 0; - for (size_t i = 0; i < num_digits_in_digits_property; ++i) { - digits = digits * 10 + 9; - } - std::conditional_t< - std::is_same_v, - uint32_t, - uint64_t> - cEncodedFloatDigitsBitMask - = std::is_same_v - ? clp::ffi::cFourByteEncodedFloatDigitsBitMask - : clp::ffi::cEightByteEncodedFloatDigitsBitMask; - // Due to the bitmask, the number of digits encoded may be less than - // num_digits_in_digits_property - digits = std::min(cEncodedFloatDigitsBitMask, digits); - auto num_digits_in_value - = std::min(num_digits_in_digits_property, std::to_string(digits).length()); - // Iterate over the possible values for the encoded float's high bits - uint8_t num_high_bits - = std::is_same_v ? 1 : 2; - for (size_t high_bits = 0; high_bits < num_high_bits; ++high_bits) { + for (size_t high_bits{0}; high_bits < num_high_bits; ++high_bits) { TestType test_encoded_var; if (std::is_same_v) { test_encoded_var = encode_float_properties( @@ -336,8 +266,8 @@ TEMPLATE_TEST_CASE( ); // Since encode_float_properties erases the low bit of high_bits, we need to // add it again manually - test_encoded_var - = (high_bits << 62) | (((1ULL << 62) - 1) & test_encoded_var); + test_encoded_var = (high_bits << num_low_bits) + | (((1ULL << num_low_bits) - 1) & test_encoded_var); } else { test_encoded_var = encode_float_properties( high_bits, @@ -368,6 +298,7 @@ TEMPLATE_TEST_CASE( } } +// NOLINTNEXTLINE(readability-function-cognitive-complexity) TEMPLATE_TEST_CASE( "Encoding messages", "[ffi][encode-message]", @@ -390,7 +321,7 @@ TEMPLATE_TEST_CASE( "-00.00", "bin/python2.7.3", "abc123"}; - size_t var_ix = 0; + size_t var_ix{0}; message = "here is a string with a small int " + var_strs[var_ix++]; message += " and a medium int " + var_strs[var_ix++]; message += " and a very large int " + var_strs[var_ix++]; @@ -402,8 +333,8 @@ TEMPLATE_TEST_CASE( REQUIRE(encode_message(message, logtype, encoded_vars, dictionary_var_bounds)); // Concatenate all dictionary variables - size_t all_dictionary_vars_length = 0; - size_t num_dictionary_vars = 0; + size_t all_dictionary_vars_length{0}; + size_t num_dictionary_vars{0}; for (auto current = dictionary_var_bounds.cbegin(); dictionary_var_bounds.cend() != current;) { auto begin_pos = *current; ++current; @@ -421,20 +352,18 @@ TEMPLATE_TEST_CASE( ++current; auto end_pos = *current; ++current; - all_dictionary_vars.append(message.data() + begin_pos, message.data() + end_pos); - dictionary_var_end_offsets.push_back(all_dictionary_vars.length()); + all_dictionary_vars.append(message, begin_pos, end_pos - begin_pos); + dictionary_var_end_offsets.emplace_back(all_dictionary_vars.length()); } // Test decoding auto decoded_message = decode_message( logtype, - encoded_vars.data(), - encoded_vars.size(), + span{encoded_vars}, all_dictionary_vars, - dictionary_var_end_offsets.data(), - dictionary_var_end_offsets.size() + span{dictionary_var_end_offsets} ); - REQUIRE(decoded_message == message); + REQUIRE((decoded_message == message)); // Test encoding a message with a variable placeholder after the variables message = " test var123 "; @@ -446,13 +375,14 @@ TEMPLATE_TEST_CASE( REQUIRE(encode_message(message, logtype, encoded_vars, dictionary_var_bounds)); } +// NOLINTNEXTLINE(readability-function-cognitive-complexity) TEMPLATE_TEST_CASE( "wildcard_query_matches_any_encoded_var", "[ffi][wildcard_query_matches_any_encoded_var]", eight_byte_encoded_variable_t, four_byte_encoded_variable_t ) { - string message = "Static text, dictVar1, 123, 456.7, dictVar2, 987, 654.3"; + string_view const message{"Static text, dictVar1, 123, 456.7, dictVar2, 987, 654.3"}; // Encode string logtype; @@ -464,38 +394,33 @@ TEMPLATE_TEST_CASE( REQUIRE(wildcard_query_matches_any_encoded_var( "1*3", logtype, - encoded_vars.data(), - encoded_vars.size() + span{encoded_vars} + )); + REQUIRE_FALSE(wildcard_query_matches_any_encoded_var( + "4*7", + logtype, + span{encoded_vars} )); - REQUIRE(false - == wildcard_query_matches_any_encoded_var( - "4*7", - logtype, - encoded_vars.data(), - encoded_vars.size() - )); REQUIRE(wildcard_query_matches_any_encoded_var( "4*7", logtype, - encoded_vars.data(), - encoded_vars.size() + span{encoded_vars} + )); + REQUIRE_FALSE(wildcard_query_matches_any_encoded_var( + "1*3", + logtype, + span{encoded_vars} )); - REQUIRE(false - == wildcard_query_matches_any_encoded_var( - "1*3", - logtype, - encoded_vars.data(), - encoded_vars.size() - )); } +// NOLINTNEXTLINE(readability-function-cognitive-complexity) TEMPLATE_TEST_CASE( "wildcard_match_encoded_vars", "[ffi][wildcard_match_encoded_vars]", eight_byte_encoded_variable_t, four_byte_encoded_variable_t ) { - string message = "Static text, dictVar1, 123, 456.7, dictVar2, 987, 654.3"; + string_view const message{"Static text, dictVar1, 123, 456.7, dictVar2, 987, 654.3"}; // Encode a message string logtype; @@ -517,8 +442,7 @@ TEMPLATE_TEST_CASE( REQUIRE(wildcard_match_encoded_vars( logtype, - encoded_vars.data(), - encoded_vars.size(), + span{encoded_vars}, wildcard_var_types, wildcard_var_query_views )); @@ -538,8 +462,7 @@ TEMPLATE_TEST_CASE( REQUIRE(wildcard_match_encoded_vars( logtype, - encoded_vars.data(), - encoded_vars.size(), + span{encoded_vars}, wildcard_var_types, wildcard_var_query_views )); @@ -559,21 +482,11 @@ TEMPLATE_TEST_CASE( string_views_from_strings(wildcard_var_queries, wildcard_var_query_views); - REQUIRE(false - == wildcard_match_encoded_vars( - logtype, - encoded_vars.data(), - encoded_vars.size(), - wildcard_var_types, - wildcard_var_query_views - )); - } -} - -static void -string_views_from_strings(vector const& strings, vector& string_views) { - string_views.reserve(strings.size()); - for (auto const& s : strings) { - string_views.emplace_back(s); + REQUIRE_FALSE(wildcard_match_encoded_vars( + logtype, + span{encoded_vars}, + wildcard_var_types, + wildcard_var_query_views + )); } }