From 665e433697247c4a43e055830dee7a72afdb810f Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 1 Jan 2026 12:52:28 +0100 Subject: feat: FIX Checksum API for OCL.FIX. Signed-off-by: Amlal El Mahrouss --- CMakeLists.txt | 2 ++ example/fix_tag_example/CMakeLists.txt | 2 +- example/fix_tag_example/example.cpp | 5 +++- include/ocl/fix/checksum.hpp | 43 +++++++++++++++++++++++++++++++++- test/fix_basic/fix.test.cpp | 2 +- 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 343aee1..1829925 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,8 @@ find_package(Boost REQUIRED) add_library(ocl_fix src/fix/parser_impl.cpp) target_link_libraries(ocl_fix boost_core) + +install(DIRECTORY include/ DESTINATION include) install(TARGETS ocl_fix DESTINATION lib) set_property(TARGET ocl_fix PROPERTY CXX_STANDARD 20) diff --git a/example/fix_tag_example/CMakeLists.txt b/example/fix_tag_example/CMakeLists.txt index 57bec7a..56afa24 100644 --- a/example/fix_tag_example/CMakeLists.txt +++ b/example/fix_tag_example/CMakeLists.txt @@ -12,4 +12,4 @@ add_executable(FixExample example.cpp) set_property(TARGET FixExample PROPERTY CXX_STANDARD 20) target_include_directories(FixExample PUBLIC ../../include/ocl) -target_link_libraries(FixExample PRIVATE Boost) +target_link_libraries(FixExample PRIVATE ocl_fix) diff --git a/example/fix_tag_example/example.cpp b/example/fix_tag_example/example.cpp index f7f3e76..ac4f479 100644 --- a/example/fix_tag_example/example.cpp +++ b/example/fix_tag_example/example.cpp @@ -1,4 +1,5 @@ #include +#include constexpr char default_fix[] = { '8', '=', 'F', 'I', 'X', '.', '4', '.', '2', 0x01, @@ -15,7 +16,7 @@ constexpr char default_fix[] = { int main(int argc, char** argv) { - ocl::fix::visitor basic_visitor; + ocl::fix::visitor basic_visitor; ocl::fix::range_buffer fix = basic_visitor.visit(default_fix); ocl::io::enable_stdio_sync(false); @@ -26,5 +27,7 @@ int main(int argc, char** argv) ocl::io::print(":key=49\n"); ocl::io::print(":value=", fix["49"], "\n"); + ocl::io::print("checksum=", ocl::fix::try_index_checksum(fix), "\n"); + return 0; } diff --git a/include/ocl/fix/checksum.hpp b/include/ocl/fix/checksum.hpp index c075b13..31aee75 100644 --- a/include/ocl/fix/checksum.hpp +++ b/include/ocl/fix/checksum.hpp @@ -9,9 +9,50 @@ #define __OCL_FIX_CHECKSUM #include +#include +#include namespace ocl::fix { -} + + /// \brief Returns the checksum index of a FIX message. + /// \param range the range_buffer containing the message. + /// \throws runtime_error if the FIX message is invalid (missing tag "8"). + inline std::string try_index_checksum(range_buffer& fix) + { + if (fix.is_valid()) + return fix["10"]; + else + detail::throw_runtime_error(); + } + + /// \brief FIX message operators namespace. + namespace operators::fix + { + using checksum_type = long long; + + /// \brief Calculates the FIX protocol checksum for a message. + /// \param in_ Pointer to the message buffer. + /// \param len Length of the message in bytes. + /// \return The checksum value (sum of all bytes modulo 256). + inline checksum_type + checksum(const char* in_, + const long len) + { + if (len < 1) + return 0L; + + long long cks{}; + + for (long idx{}; idx < len; ++idx) + { + cks += static_cast(in_[idx]); + } + + return cks % 256; + } + } // namespace operators::fix + +} // namespace ocl::fix #endif diff --git a/test/fix_basic/fix.test.cpp b/test/fix_basic/fix.test.cpp index 82fb24c..43042b4 100644 --- a/test/fix_basic/fix.test.cpp +++ b/test/fix_basic/fix.test.cpp @@ -22,7 +22,7 @@ constexpr char default_fix[] = { '1', '0', '=', '1', '4', '3', 0x01, 0x00 // CheckSum = 143 }; -static ocl::fix::visitor basic_visitor; +static ocl::fix::visitor basic_visitor; static ocl::fix::range_buffer fix = basic_visitor.visit(default_fix); TEST(FIXTest, FIXGoodPacket) -- cgit v1.2.3