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 --- src/fix/parser.cpp | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/fix/parser.cpp (limited to 'src/fix/parser.cpp') 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 -- cgit v1.2.3