summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-12-03 02:36:37 -0500
committerAmlal El Mahrouss <amlal@nekernel.org>2025-12-03 02:36:37 -0500
commitd43fed8fb9eb369adc70a57bc2a9552d36485241 (patch)
tree848f54bb8ab63b1cb1fbbf98f2a0b8a08ea153cf /include
parentc3b474e38d0f974163cb392626e15f909c5a1b73 (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.hpp81
-rw-r--r--include/ocl/net/unique_socket.hpp77
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