diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-12-03 02:36:37 -0500 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2025-12-03 02:36:37 -0500 |
| commit | d43fed8fb9eb369adc70a57bc2a9552d36485241 (patch) | |
| tree | 848f54bb8ab63b1cb1fbbf98f2a0b8a08ea153cf /include | |
| parent | c3b474e38d0f974163cb392626e15f909c5a1b73 (diff) | |
chore: new `unique_socket` example and new public API.
chore: new parser public API.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/ocl/fix/parser.hpp | 81 | ||||
| -rw-r--r-- | include/ocl/net/unique_socket.hpp | 77 |
2 files changed, 81 insertions, 77 deletions
diff --git a/include/ocl/fix/parser.hpp b/include/ocl/fix/parser.hpp index 17fb63c..6455601 100644 --- a/include/ocl/fix/parser.hpp +++ b/include/ocl/fix/parser.hpp @@ -15,14 +15,15 @@ namespace ocl::fix { - class basic_visitor; - - struct basic_range; - - class basic_range_data; + class visitor; + struct range; + class range_buffer; /// @brief Buffer+Length structure - using range_ptr_t = basic_range*; + using range_ptr_type = range*; + + using tag_type = std::string; + using value_type = std::string; namespace detail { @@ -32,7 +33,7 @@ namespace ocl::fix } } // namespace detail - struct basic_range final + struct range final { char* bytes_{nullptr}; size_t length_{}; @@ -48,42 +49,42 @@ namespace ocl::fix } }; - /// @brief Convert basic_range to usable string. - /// @note This function assumes that the basic_range is valid and contains ASCII bytes. - inline std::string to_string(basic_range& basic_range) noexcept + /// @brief Convert range to usable string. + /// @note This function assumes that the range is valid and contains ASCII bytes. + inline std::string to_string(range& range) noexcept { - if (basic_range.length_ < 1) + if (range.length_ < 1) return std::string{}; - return std::string(basic_range.bytes_, basic_range.length_); + return std::string(range.bytes_, range.length_); } - /// @brief a basic_range object containing the FIX packet values. - class basic_range_data final + /// @brief a range object containing the FIX packet values. + class range_buffer final { public: - std::size_t magic_len_{}; - std::string magic_{}; - string_hash_map<std::string> message_{}; + std::size_t magic_len_{}; + std::string magic_{}; + string_hash_map<value_type> message_{}; static inline const char* begin = detail::begin_fix(); - explicit basic_range_data() = default; - ~basic_range_data() = default; + explicit range_buffer() = default; + ~range_buffer() = default; - basic_range_data& operator=(const basic_range_data&) = default; - basic_range_data(const basic_range_data&) = default; + range_buffer& operator=(const range_buffer&) = default; + range_buffer(const range_buffer&) = default; - std::string operator[](const std::string& key) + value_type operator[](const tag_type& key) { if (key.empty()) - return std::string{}; + return value_type{}; auto it = message_.find(key); if (it != message_.end()) return it->second; - return std::string{}; + return value_type{}; } bool is_valid() @@ -97,8 +98,8 @@ namespace ocl::fix } }; - /// @brief basic_visitor object which returns a fix::basic_range_data instance. - class basic_visitor final + /// @brief visitor object which returns a fix::range_buffer instance. + class visitor final { public: /// AMLALE: Yeah... @@ -106,23 +107,23 @@ namespace ocl::fix static constexpr const char eq = '='; static constexpr uint32_t base = 10U; - explicit basic_visitor() = default; - ~basic_visitor() = default; + explicit visitor() = default; + ~visitor() = default; - basic_visitor& operator=(const basic_visitor&) = default; - basic_visitor(const basic_visitor&) = default; + visitor& operator=(const visitor&) = default; + visitor(const visitor&) = default; - basic_range_data operator()(const std::string& in) + range_buffer operator()(const std::string& in) { return this->visit(in); } - /// @brief Visit a FIX message and parse it into a basic_range_data object. + /// @brief Visit 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. - basic_range_data visit(const std::string& in) + range_buffer visit(const std::string& in) { - basic_range_data ret{}; + range_buffer ret{}; if (in.empty()) return ret; @@ -133,44 +134,32 @@ namespace ocl::fix while (off < in.size()) { - // Find the '=' separator std::size_t eq_pos = in.find(eq, off); if (eq_pos == std::string::npos) break; - // Extract tag (everything from current position to '=') std::string tag = in.substr(off, eq_pos - off); - // Find the SOH delimiter after the value (or end of string) std::size_t soh_pos = in.find(soh, eq_pos + 1); if (soh_pos == std::string::npos) soh_pos = in.size(); - // Extract value (everything from after '=' to SOH) std::string value = in.substr(eq_pos + 1, soh_pos - eq_pos - 1); - // Store first value as magic (should be BeginString) if (ret.magic_.empty()) { ret.magic_ = value; ret.magic_len_ = value.size(); } - // Store tag-value pair ret.message_[tag] = value; - // Move to position after the SOH off = soh_pos + 1; } return ret; } }; - - using fix_tag_type = std::string; - - using range_data = basic_range_data; - using visitor = basic_visitor; } // namespace ocl::fix #endif // ifndef _OCL_FIX_PARSER_HPP
\ No newline at end of file diff --git a/include/ocl/net/unique_socket.hpp b/include/ocl/net/unique_socket.hpp index 5e74af0..d5b8b49 100644 --- a/include/ocl/net/unique_socket.hpp +++ b/include/ocl/net/unique_socket.hpp @@ -21,8 +21,12 @@ #error !!! "Windows is not supported yet for <unique_socket>" !!! #endif // _WIN32 -namespace ocl::net +namespace ocl { + class unique_socket; + + inline constexpr auto socket_null = 0; + class unique_socket final { public: @@ -51,10 +55,12 @@ namespace ocl::net { if (this != &other) { - destroy(); - socket_ = other.socket_; - is_server_ = other.is_server_; - bad_ = other.bad_; + this->destroy(); + + socket_ = other.socket_; + is_server_ = other.is_server_; + bad_ = other.bad_; + other.socket_ = 0; other.bad_ = true; } @@ -69,8 +75,8 @@ namespace ocl::net other.bad_ = true; } - static constexpr auto local_address_ip4 = "127.0.0.1"; - static constexpr auto backlog_count = 5U; + static constexpr auto any_address = "0.0.0.0"; + static constexpr auto backlog_count = 20U; const error_type& bad() { @@ -99,36 +105,34 @@ namespace ocl::net return std::move(ret_sock); } - unique_socket read_server_buffer(char* out, std::size_t len) + unique_socket read_server_buffer(char* in, std::size_t len) { - if (!out || !len) + if (!in || !len) return {}; if (!is_server_) - { return {}; - } auto ret_sock = accept(); if (ret_sock.socket_ == -1) throw std::invalid_argument("no connection to accept."); - auto ret = ::recv(ret_sock.socket_, static_cast<void*>(out), len, 0); + auto ret = ::recv(ret_sock.socket_, in, len, 0); ret_sock.bad_ = ret < 0L; return ret_sock; } - void read_client_buffer(char* out, std::size_t len) + void read_client_buffer(char* in, std::size_t len) { - if (!out || !len) + if (!in || !len) return; if (is_server_) return; - auto ret = ::recv(this->socket_, static_cast<void*>(out), len, 0); + auto ret = ::recv(this->socket_, in, len, 0); this->bad_ = ret < 0L; } @@ -140,25 +144,22 @@ namespace ocl::net if (!len) return; - auto ret = ::send(socket_, out, len, 0); - - bad_ = ret < 0L; + auto ret = ::send(this->socket_, out, len, 0); + this->bad_ = ret < 0L; } template <uint16_t port> static unique_socket make_socket(const std::string& address, const bool is_server) { - unique_socket sock; + if (unique_socket sock; sock.construct<AF_INET, SOCK_STREAM, port>(address.c_str(), is_server)) + return sock; - if (!sock.construct<AF_INET, SOCK_STREAM, port>(address.c_str(), is_server)) - throw std::invalid_argument("invalid socket argument"); - - return sock; + throw std::invalid_argument("invalid socket argument"); } private: template <uint16_t af, uint16_t kind, uint16_t port> - bool construct(const char* addr = unique_socket::local_address_ip4, const bool& is_server = false) noexcept + bool construct(const char* addr = unique_socket::any_address, const bool& is_server = false) noexcept { static_assert(af != 0, "Address family is zero"); static_assert(kind != 0, "Kind is zero"); @@ -172,21 +173,31 @@ namespace ocl::net struct sockaddr_in addr_; std::memset(&addr_, 0, sizeof(struct sockaddr_in)); - addr_.sin_addr.s_addr = ::inet_addr(addr); - addr_.sin_port = htons(port); - addr_.sin_family = af; + if (addr == unique_socket::any_address) + addr_.sin_addr.s_addr = INADDR_ANY; + else + addr_.sin_addr.s_addr = ::inet_addr(addr); + + addr_.sin_port = htons(port); + addr_.sin_family = af; if (!is_server) { const auto ret = ::connect(socket_, reinterpret_cast<struct sockaddr*>(&addr_), sizeof(addr_)); - return ret == 0L; + bad_ = ret == -1; + return bad_ == false; } int ret = ::bind(socket_, (struct sockaddr*)&addr_, sizeof(addr_)); bad_ = ret == -1; - ::listen(socket_, unique_socket::backlog_count); + if (bad_) + return false; + + ret = ::listen(socket_, unique_socket::backlog_count); + + bad_ = ret == -1; return bad_ == false; } @@ -196,7 +207,6 @@ namespace ocl::net if (!socket_) return false; - ::shutdown(socket_, SHUT_RDWR); ::close(socket_); socket_ = 0L; @@ -204,4 +214,9 @@ namespace ocl::net return true; } }; -} // namespace ocl::net + + template <typename TS> + concept IsValidSocket = requires(TS& sock) { + { sock.bad() }; + }; +} // namespace ocl |
