From f7a6fd9a6efd7a603e534242f3aa21e782a61958 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Fri, 27 Feb 2026 22:37:31 +0100 Subject: feat: moving checksum to sources directory, update file structure. Signed-off-by: Amlal El Mahrouss --- CMakeLists.txt | 4 +- example/fix_tag_example/CMakeLists.txt | 2 +- example/fix_tag_example/example.cpp | 2 +- include/ocl/fix/checksum.hpp | 30 ++-------- src/fix/checksum.cpp | 44 ++++++++++++++ src/fix/parser.cpp | 101 +++++++++++++++++++++++++++++++++ src/fix/parser_impl.cpp | 101 --------------------------------- src/test/.keep | 0 8 files changed, 153 insertions(+), 131 deletions(-) create mode 100644 src/fix/checksum.cpp create mode 100644 src/fix/parser.cpp delete mode 100644 src/fix/parser_impl.cpp create mode 100644 src/test/.keep diff --git a/CMakeLists.txt b/CMakeLists.txt index 66d9997..ddc301a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,11 +5,11 @@ project(ocl_fix) find_package(Boost REQUIRED core) -add_library(ocl_fix src/fix/parser_impl.cpp) +add_library(ocl_fix src/fix/parser.cpp src/fix/checksum.cpp) target_link_libraries(ocl_fix Boost::core) target_include_directories(ocl_fix PUBLIC ${BOOST_INCLUDE_DIRS}) -install(DIRECTORY include/ DESTINATION include) +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 967ca07..ebf3e6f 100644 --- a/example/fix_tag_example/CMakeLists.txt +++ b/example/fix_tag_example/CMakeLists.txt @@ -13,4 +13,4 @@ target_include_directories(FixExample PUBLIC ${BOOST_INCLUDE_DIRS}) set_property(TARGET FixExample PROPERTY CXX_STANDARD 20) target_include_directories(FixExample PUBLIC ../../include/ocl) -target_link_libraries(FixExample PRIVATE ocl_fix.a) +target_link_libraries(FixExample PUBLIC ocl_fix.a) diff --git a/example/fix_tag_example/example.cpp b/example/fix_tag_example/example.cpp index efd66f8..42b859f 100644 --- a/example/fix_tag_example/example.cpp +++ b/example/fix_tag_example/example.cpp @@ -45,7 +45,7 @@ int main(int argc, char** argv) ocl::io::print(":value=", fix["49"], "\n"); ocl::io::print(":checksum=", ocl::fix::try_index_checksum(fix), "\n"); - ocl::io::print(":checksum=", ocl::fix::operators::checksum(default_fix_unchecked), "\n"); + //ocl::io::print(":checksum=", ocl::fix::operators::checksum(default_fix_unchecked), "\n"); return 0; } diff --git a/include/ocl/fix/checksum.hpp b/include/ocl/fix/checksum.hpp index 2672996..5d9fa8b 100644 --- a/include/ocl/fix/checksum.hpp +++ b/include/ocl/fix/checksum.hpp @@ -18,42 +18,20 @@ 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 - ::ocl::fix::detail::throw_runtime_error(); - - ::ocl::fix::detail::unreachable(); - - return {}; - } + std::string try_index_checksum(range_buffer& fix); /// \brief FIX message operators namespace. namespace operators { - + 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). - constexpr inline checksum_type - checksum(const std::string_view& in_) noexcept - { - checksum_type cks{}; - - for (std::size_t idx{}; - idx < in_.size(); ++idx) - cks += static_cast(in_[idx]); - - // add \0 - cks += 1; - return cks % 256; - } + checksum_type + checksum(const boost::string_view& in_) noexcept; } // namespace operators diff --git a/src/fix/checksum.cpp b/src/fix/checksum.cpp new file mode 100644 index 0000000..e8e155f --- /dev/null +++ b/src/fix/checksum.cpp @@ -0,0 +1,44 @@ +/* + * File: fix/checksum.cpp + * Purpose: Financial Information Exchange parser in C++ + * Author: Amlal El Mahrouss (amlal@nekernel.org) + * Copyright 2026, Amlal El Mahrouss, licensed under the Boost Software License. + */ + +#include + +namespace ocl::fix +{ + + std::string try_index_checksum(range_buffer& fix) + { + if (fix.is_valid()) + return fix["10"]; + else + detail::throw_runtime_error(); + + detail::unreachable(); + + return {}; + } + + namespace operators + { + + checksum_type + checksum(const boost::string_view& in_) noexcept + { + checksum_type cks{}; + + for (std::size_t idx{}; + idx < in_.size(); ++idx) + cks += static_cast(in_[idx]); + + // add \0 + cks += 1; + return cks % 256; + } + + } // namespace operators + +} // namespace ocl::fix diff --git a/src/fix/parser.cpp b/src/fix/parser.cpp new file mode 100644 index 0000000..d12056b --- /dev/null +++ b/src/fix/parser.cpp @@ -0,0 +1,101 @@ +/* + * File: fix/parser.cpp + * Purpose: Financial Information Exchange parser in C++ + * Author: Amlal El Mahrouss (amlal@nekernel.org) + * Copyright 2025-2026, Amlal El Mahrouss, licensed under the Boost Software License. + */ + +#define OCL_FIX_HAS_IMPL +#include +#include + +namespace ocl::fix +{ + + namespace detail + { + + inline boost::string_view& begin_fix() noexcept + { + static boost::string_view begin_fix{"FIX.4.2"}; + return begin_fix; + } + + } // namespace detail + + boost::string_view& range_buffer::begin = detail::begin_fix(); + + struct visitor::impl final + { + public: + static constexpr int soh = '\x01'; + static constexpr char eq = '='; + static constexpr unsigned base = 10U; + + explicit impl() = default; + ~impl() = default; + + impl& operator=(const impl&) = delete; + impl(const impl&) = delete; + + /// @brief Visits a FIX message and parse it into a range_buffer object. + /// @param in The input FIX message as a string. + /// @warning This function may throw exceptions. + range_buffer visit(const boost::string_view& in) + { + range_buffer ret{}; + + if (in.empty()) + return ret; + + std::string key, tag, value; + std::size_t off = 0UL; + std::size_t soh_pos = 0UL; + + while (off < in.size()) + { + std::size_t eq_pos = in.find(eq, off); + if (eq_pos == std::string::npos) + break; + + tag = in.substr(off, eq_pos - off).to_string(); + + soh_pos = in.find(soh, eq_pos + 1); + if (soh_pos == std::string::npos) + soh_pos = in.size(); + + value = in.substr(eq_pos + 1, soh_pos - eq_pos - 1).to_string(); + + if (ret.magic_.empty()) + { + ret.magic_ = value; + ret.magic_len_ = value.size(); + } + + ret.message_[tag] = value; + + off = soh_pos + 1; + } + + return ret; + } + }; + + visitor::visitor() = default; + visitor::~visitor() = default; + + /// @brief Alias of visit. + range_buffer visitor::operator()(const std::string& in) + { + return impl_->visit(in.data()); + } + + /// @brief Visits a FIX message and parse it into a range_buffer object. + /// @param in The input FIX message as a string. + /// @warning This function may throw exceptions. + range_buffer visitor::visit(const std::string& in) + { + return impl_->visit(in.data()); + } + +} // namespace ocl::fix diff --git a/src/fix/parser_impl.cpp b/src/fix/parser_impl.cpp deleted file mode 100644 index 4db9873..0000000 --- a/src/fix/parser_impl.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * File: fix/parser_impl.cpp - * Purpose: Financial Information Exchange parser in C++ - * Author: Amlal El Mahrouss (amlal@nekernel.org) - * Copyright 2025-2026, Amlal El Mahrouss, licensed under the Boost Software License. - */ - -#define OCL_FIX_HAS_IMPL -#include -#include - -namespace ocl::fix -{ - - namespace detail - { - - inline boost::string_view& begin_fix() noexcept - { - static boost::string_view begin_fix{"FIX.4.2"}; - return begin_fix; - } - - } // namespace detail - - boost::string_view& range_buffer::begin = detail::begin_fix(); - - struct visitor::impl final - { - public: - static constexpr int soh = '\x01'; - static constexpr char eq = '='; - static constexpr unsigned base = 10U; - - explicit impl() = default; - ~impl() = default; - - impl& operator=(const impl&) = delete; - impl(const impl&) = delete; - - /// @brief Visits a FIX message and parse it into a range_buffer object. - /// @param in The input FIX message as a string. - /// @warning This function may throw exceptions. - range_buffer visit(const boost::string_view& in) - { - range_buffer ret{}; - - if (in.empty()) - return ret; - - std::string key, tag, value; - std::size_t off = 0UL; - std::size_t soh_pos = 0UL; - - while (off < in.size()) - { - std::size_t eq_pos = in.find(eq, off); - if (eq_pos == std::string::npos) - break; - - tag = in.substr(off, eq_pos - off).to_string(); - - soh_pos = in.find(soh, eq_pos + 1); - if (soh_pos == std::string::npos) - soh_pos = in.size(); - - value = in.substr(eq_pos + 1, soh_pos - eq_pos - 1).to_string(); - - if (ret.magic_.empty()) - { - ret.magic_ = value; - ret.magic_len_ = value.size(); - } - - ret.message_[tag] = value; - - off = soh_pos + 1; - } - - return ret; - } - }; - - visitor::visitor() = default; - visitor::~visitor() = default; - - /// \brief Alias of visit. - range_buffer visitor::operator()(const std::string& in) - { - return impl_->visit(in.data()); - } - - /// @brief Visits a FIX message and parse it into a range_buffer object. - /// @param in The input FIX message as a string. - /// @warning This function may throw exceptions. - range_buffer visitor::visit(const std::string& in) - { - return impl_->visit(in.data()); - } - -} // namespace ocl::fix diff --git a/src/test/.keep b/src/test/.keep new file mode 100644 index 0000000..e69de29 -- cgit v1.2.3