diff options
Diffstat (limited to 'dev')
| -rw-r--r-- | dev/examples/fix/fix.cc | 2 | ||||
| -rw-r--r-- | dev/lib/core/includes.hpp | 16 | ||||
| -rw-r--r-- | dev/lib/except/error.hpp | 2 | ||||
| -rw-r--r-- | dev/lib/fix/network.hpp | 117 | ||||
| -rw-r--r-- | dev/lib/fix/parser.hpp | 20 | ||||
| -rw-r--r-- | dev/lib/io/print.hpp | 27 | ||||
| -rw-r--r-- | dev/lib/memory/tracked_ptr.hpp | 2 | ||||
| -rw-r--r-- | dev/lib/net/network.hpp | 137 | ||||
| -rw-r--r-- | dev/lib/net/url.hpp | 64 | ||||
| -rw-r--r-- | dev/lib/tests/gtest.hpp | 8 | ||||
| -rw-r--r-- | dev/lib/tests/hpptest.hpp | 22 | ||||
| -rw-r--r-- | dev/lib/utility/cgi.hpp | 22 | ||||
| -rw-r--r-- | dev/lib/utility/embfs.hpp | 8 | ||||
| -rw-r--r-- | dev/tests/fix_basic/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | dev/tests/fix_basic/fix_test.cc | 2 | ||||
| -rw-r--r-- | dev/tests/network_basic/CMakeLists.txt | 23 | ||||
| -rw-r--r-- | dev/tests/network_basic/net_test.cc | 36 | ||||
| -rw-r--r-- | dev/tests/tracked_ptr_basic/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | dev/tests/tracked_ptr_leak/CMakeLists.txt | 2 |
19 files changed, 358 insertions, 156 deletions
diff --git a/dev/examples/fix/fix.cc b/dev/examples/fix/fix.cc index 3656c0c..ce48186 100644 --- a/dev/examples/fix/fix.cc +++ b/dev/examples/fix/fix.cc @@ -4,7 +4,7 @@ licensed under the MIT license */ -#include <lib/fix/network.hpp> +#include <lib/net/network.hpp> #include <lib/fix/parser.hpp> #include <iostream> #include <unistd.h> diff --git a/dev/lib/core/includes.hpp b/dev/lib/core/includes.hpp new file mode 100644 index 0000000..e482a7c --- /dev/null +++ b/dev/lib/core/includes.hpp @@ -0,0 +1,16 @@ +/* + * File: core/includes.hpp + * Purpose: Core includes for the SOCL library. + * Author: Amlal El Mahrouss (founder@snu.systems) + * Copyright 2025, Amlal El Mahrouss and SNU Systems Corp. + */ + +#pragma once + +#include <boost/config.hpp> +#include <boost/core/nvp.hpp> +#include <boost/core/demangle.hpp> +#include <boost/core/null_deleter.hpp> +#include <memory> +#include <utility> +#include <filesystem> diff --git a/dev/lib/except/error.hpp b/dev/lib/except/error.hpp index 6e75f16..486d2e6 100644 --- a/dev/lib/except/error.hpp +++ b/dev/lib/except/error.hpp @@ -14,7 +14,7 @@ namespace snu::except using runtime_error = std::runtime_error; using fix_error = runtime_error; using math_error = runtime_error; - using cgi_error = runtime_error; + using cgi_error = runtime_error; } // namespace snu::except #endif // _SNU_ERR_HPP
\ No newline at end of file diff --git a/dev/lib/fix/network.hpp b/dev/lib/fix/network.hpp deleted file mode 100644 index edd4c26..0000000 --- a/dev/lib/fix/network.hpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * File: fix/network.hpp - * Purpose: Financial Information Exchange in C++ - * Author: Amlal El Mahrouss (founder@snu.systems) - * Copyright 2025, Amlal El Mahrouss and SNU Systems Corp. - */ - -#ifndef _SNU_FIX_NETWORK_HPP -#define _SNU_FIX_NETWORK_HPP - -#include <arpa/inet.h> -#include <sys/socket.h> -#include <utility> -#include <cstddef> - -#define SNU_MODEM : protected snu::fix::basic_delivery_modem - -namespace snu::fix -{ - class basic_delivery_modem; - - typedef int32_t delivery_socket_type; - - /// @brief a delivery modem is a container which establishes a comm. channel between the FIX session and application. - class basic_delivery_modem - { - public: - explicit basic_delivery_modem() = default; - virtual ~basic_delivery_modem() = default; - - basic_delivery_modem& operator=(const basic_delivery_modem&) = default; - basic_delivery_modem(const basic_delivery_modem&) = default; - - public: - static constexpr auto local_address = "127.0.0.1"; - static constexpr auto backlog_count = 18U; - - public: - delivery_socket_type fd_{}; - - template <typename T> - bool receive(T& out, std::size_t len) noexcept - { - static_assert(std::is_pointer<T>::value, "T is not a pointer!"); - - if (!out) - return false; - - if (!len) - return false; - - auto ret = ::recv(fd_, out, len, MSG_WAITALL); - - return ret > 0; - } - - template <typename T> - bool transmit(T& out, std::size_t len) noexcept - { - static_assert(std::is_pointer<T>::value, "T is not a pointer!"); - - if (!out) - return false; - - if (!len) - return false; - - auto ret = ::send(fd_, out, len, 0); - - return ret > 0; - } - - template <int32_t AF, int32_t Kind, int32_t IPProto, int32_t Port> - bool construct(const char* addr = basic_delivery_modem::local_address, const bool& is_server = false) noexcept - { - static_assert(AF != 0, "AF is zero"); - static_assert(Kind != 0, "Kind is zero"); - static_assert(IPProto != 0, "IPProto is zero"); - - fd_ = ::socket(AF, Kind, IPProto); - - if (fd_ < 1) - return false; - - struct sockaddr_in addr_ - { - }; - - addr_.sin_addr.s_addr = ::inet_addr(addr); - addr_.sin_port = Port; - - if (!is_server) - { - auto ret = ::connect(fd_, (struct sockaddr*)&addr_, sizeof(decltype(addr_))); - return ret == 0; - } - - ::listen(fd_, basic_delivery_modem::backlog_count); - - return true; - } - - bool destroy() noexcept - { - if (!fd_) - return false; - - ::shutdown(fd_, SHUT_RDWR); - - fd_ = 0U; - - return true; - } - }; -} // namespace snu::fix - -#endif // ifndef _SNU_FIX_NETWORK_HPP
\ No newline at end of file diff --git a/dev/lib/fix/parser.hpp b/dev/lib/fix/parser.hpp index 5701783..8181359 100644 --- a/dev/lib/fix/parser.hpp +++ b/dev/lib/fix/parser.hpp @@ -13,7 +13,7 @@ #include <utility> #include <string> #include <vector> - +#include <cstdint> #include <sys/types.h> #include <unistd.h> #include <signal.h> @@ -21,13 +21,13 @@ namespace snu::fix { template <typename char_type> - struct basic_visitor; + class basic_visitor; template <typename char_type> struct basic_range; template <typename char_type> - struct basic_range_data; + class basic_range_data; /// @brief Buffer+Length structure template <typename char_type = char> @@ -63,12 +63,12 @@ namespace snu::fix char_type* bytes_; size_t length_; - bool is_valid() + bool is_valid() noexcept { - return bytes_ && length_ > 0; + return this->bytes_ && this->length_ > 0; } - operator bool() + explicit operator bool() { return this->is_valid(); } @@ -77,7 +77,7 @@ namespace snu::fix /// @brief Convert basic_range to usable string. /// @note This function assumes that the basic_range is valid and contains ASCII bytes. template <typename char_type = char> - inline std::basic_string<char_type> to_string(basic_range<char_type>& basic_range) noexcept + std::basic_string<char_type> to_string(basic_range<char_type>& basic_range) noexcept { if (basic_range.length_ < 0) return std::basic_string<char_type>{}; @@ -98,7 +98,7 @@ namespace snu::fix static inline const char_type* begin = detail::begin_fix<char_type>(); explicit basic_range_data() = default; - ~basic_range_data() = default; + ~basic_range_data() = default; basic_range_data& operator=(const basic_range_data&) = default; basic_range_data(const basic_range_data&) = default; @@ -126,7 +126,7 @@ namespace snu::fix return magic_.starts_with(basic_range_data<char_type>::begin); } - operator bool() + explicit operator bool() { return this->is_valid(); } @@ -159,7 +159,7 @@ namespace snu::fix if (in.empty()) return ret; - thread_local std::basic_string<char_type> in_tmp{}; + static thread_local std::basic_string<char_type> in_tmp{}; in_tmp.reserve(in.size()); diff --git a/dev/lib/io/print.hpp b/dev/lib/io/print.hpp index e326845..eb425c1 100644 --- a/dev/lib/io/print.hpp +++ b/dev/lib/io/print.hpp @@ -8,22 +8,35 @@ #ifndef _SNU_PRINT_HPP #define _SNU_PRINT_HPP +#include <initializer_list> #include <iostream> +#include <ostream> namespace snu::io { - template <typename... T> - inline void print(T... fmt) + template <typename T, typename... Args> + inline void print(T fmt, Args... other) noexcept { - std::cout << std::move(fmt...); + std::cout << fmt; + print(other...); } - template <typename... T> - inline void println(T... fmt) + template <typename T> + inline void print(T fmt) noexcept + { + std::cout << fmt; + } + + inline void print() noexcept { - std::cout << std::move(fmt...); std::cout << std::endl; } + + template <typename... T> + inline void println(T... fmt) noexcept + { + print(fmt...); + } } // namespace snu::io -#endif // ifndef _SNU_PRINT_HPP
\ No newline at end of file +#endif // ifndef _SNU_PRINT_HPP diff --git a/dev/lib/memory/tracked_ptr.hpp b/dev/lib/memory/tracked_ptr.hpp index 2607b5b..c767b67 100644 --- a/dev/lib/memory/tracked_ptr.hpp +++ b/dev/lib/memory/tracked_ptr.hpp @@ -128,7 +128,7 @@ namespace snu::memory this->reset(); } - tracked_ptr(const tracked_ptr&) = delete; + tracked_ptr(const tracked_ptr&) = delete; tracked_ptr& operator=(const tracked_ptr&) = delete; public: diff --git a/dev/lib/net/network.hpp b/dev/lib/net/network.hpp new file mode 100644 index 0000000..67f3740 --- /dev/null +++ b/dev/lib/net/network.hpp @@ -0,0 +1,137 @@ +/* + * File: net/network.hpp + * Purpose: Modem concept in modern C++ + * Author: Amlal El Mahrouss (founder@snu.systems) + * Copyright 2025, Amlal El Mahrouss and SNU Systems Corp. + */ + +#ifndef _SNU_NET_NETWORK_HPP +#define _SNU_NET_NETWORK_HPP + +#include <unistd.h> +#include <arpa/inet.h> +#include <sys/socket.h> +#include <string> +#include <utility> +#include <cstddef> + +#define SNU_MODEM_INTERFACE : protected snu::net::basic_modem + +namespace snu::net +{ + template <typename char_type> + class basic_modem; + + typedef int64_t socket_type; + + /// @brief Delivery modem concept, a container to read and write on a network stream. + template <typename char_type> + class basic_modem + { + public: + explicit basic_modem() = default; + virtual ~basic_modem() = default; + + basic_modem& operator=(const basic_modem&) = default; + basic_modem(const basic_modem&) = default; + + static constexpr auto local_address_ip6 = "127.0.0.1"; + static constexpr auto local_address_ip4 = "::1"; + + static constexpr auto backlog_count = 18U; + + socket_type fd_{}; + + bool is_valid() const noexcept + { + return this->fd_ != -1; + } + + template <typename ptr_type> + bool receive(ptr_type& out, std::size_t len) noexcept + { + static_assert(std::is_pointer<ptr_type>::value, "ptr_type is not a pointer!"); + + if (!out) + return false; + + if (!len) + return false; + + auto ret = ::recv(fd_, out, len, 0); + + return ret > 0; + } + + template <typename ptr_type> + bool transmit(ptr_type& out, std::size_t len) noexcept + { + static_assert(std::is_pointer<ptr_type>::value, "char_type is not a pointer!"); + + if (!out) + return false; + + if (!len) + return false; + + auto ret = ::send(fd_, out, len, 0); + + return ret > 0; + } + + template <typename ptr_type> + bool transmit(std::basic_string<ptr_type> out) noexcept + { + if (out.empty()) + return false; + + auto ret = ::send(fd_, out.data(), out.size(), 0); + + return ret > 0; + } + + template <int32_t af, int32_t kind, int32_t ip_proto, int32_t port> + bool construct(const char* addr = basic_modem::local_address_ip4, const bool& is_server = false) noexcept + { + static_assert(af != 0, "Address family is zero"); + static_assert(kind != 0, "Type is zero"); + + fd_ = ::socket(af, kind, ip_proto); + + if (fd_ == -1) + return false; + + struct sockaddr_in addr_ + { + }; + + addr_.sin_addr.s_addr = ::inet_addr(addr); + addr_.sin_port = port; + + if (!is_server) + { + const auto ret = ::connect(fd_, reinterpret_cast<struct sockaddr*>(&addr_), sizeof(decltype(addr_))); + return ret == 0; + } + + ::listen(fd_, basic_modem::backlog_count); + + return true; + } + + bool destroy() noexcept + { + if (!fd_) + return false; + + ::shutdown(fd_, SHUT_RDWR); + ::close(fd_); + + fd_ = 0U; + + return true; + } + }; +} // namespace snu::net + +#endif // ifndef _SNU_NET_NETWORK_HPP diff --git a/dev/lib/net/url.hpp b/dev/lib/net/url.hpp new file mode 100644 index 0000000..f6dba95 --- /dev/null +++ b/dev/lib/net/url.hpp @@ -0,0 +1,64 @@ +/* + * File: net/url.hpp + * Purpose: URL container in modern C++ + * Author: Amlal El Mahrouss (founder@snu.systems) + * Copyright 2025, Amlal El Mahrouss and SNU Systems Corp. + */ + +#pragma once + +#include <string> +#include <iostream> +#include <sstream> + +/// @author Amlal El Mahrouss (founder@snu.systems) + +namespace snu::net +{ + template <typename char_type> + class basic_url; + + template <typename char_type> + class basic_url_traits; + + /// @brief Basic URL parser container. + template <typename char_type> + class basic_url final + { + friend basic_url_traits<char_type>; + + std::basic_stringstream<char_type> ss_{}; + + public: + explicit basic_url() = default; + ~basic_url() = default; + + basic_url& operator=(const basic_url&) = default; + basic_url(const basic_url&) = default; + + basic_url& operator/=(const std::basic_string<char_type>& in) + { + if (in.empty()) + return *this; + + ss_ += in; + return *this; + } + + basic_url& operator/=(const char_type& in) + { + ss_ += in; + return *this; + } + + explicit operator bool() + { + return this->is_valid(); + } + + bool is_valid() + { + return ss_.size() > 0; + } + }; +} // namespace snu::net diff --git a/dev/lib/tests/gtest.hpp b/dev/lib/tests/gtest.hpp new file mode 100644 index 0000000..14474c0 --- /dev/null +++ b/dev/lib/tests/gtest.hpp @@ -0,0 +1,8 @@ +/* + * File: tests/gtest.hpp + * Purpose: Google Test wrapper for the SOCL library. + * Author: Amlal El Mahrouss (founder@snu.systems) + * Copyright 2025, Amlal El Mahrouss and SNU Systems Corp. + */ + +#include <gtest/gtest.h> diff --git a/dev/lib/tests/hpptest.hpp b/dev/lib/tests/hpptest.hpp new file mode 100644 index 0000000..4c99ce6 --- /dev/null +++ b/dev/lib/tests/hpptest.hpp @@ -0,0 +1,22 @@ +/* + * File: tests/hpptest.hpp + * Purpose: HPP Test wrapper for the SOCL library. + * Author: Amlal El Mahrouss (founder@snu.systems) + * Copyright 2025, Amlal El Mahrouss and SNU Systems Corp. + */ + +#pragma once + + +#ifdef SOCL_HPPTEST +namespace snu::hpptest +{ + typedef bool condition_type; + + template <condition_type expr = true> + consteval inline void must_pass() + { + SOCL_HPPTEST_ASSERT(expr); + } +} // namespace snu::hpptest +#endif diff --git a/dev/lib/utility/cgi.hpp b/dev/lib/utility/cgi.hpp index 8e2170e..57625b8 100644 --- a/dev/lib/utility/cgi.hpp +++ b/dev/lib/utility/cgi.hpp @@ -32,35 +32,35 @@ namespace snu public: explicit basic_writer() = default; - ~basic_writer() = default; + ~basic_writer() = default; basic_writer& operator=(const basic_writer&) = default; basic_writer(const basic_writer&) = default; public: - basic_writer& binary(const std::basic_stringstream<char_type>& ss_html) + basic_writer& binary(const std::basic_stringstream<char_type>& ss_in) { - return this->eval_("application/octet-stream", ss_html); + return this->eval_("application/octet-stream", ss_in); } - basic_writer& html(const std::basic_stringstream<char_type>& ss_html) + basic_writer& html(const std::basic_stringstream<char_type>& ss_in) { - return this->eval_("text/html", ss_html); + return this->eval_("text/html", ss_in); } - basic_writer& xml(const std::basic_stringstream<char_type>& ss_html) + basic_writer& xml(const std::basic_stringstream<char_type>& ss_in) { - return this->eval_("application/xml", ss_html); + return this->eval_("application/xml", ss_in); } - basic_writer& json(const std::basic_stringstream<char_type>& ss_html) + basic_writer& json(const std::basic_stringstream<char_type>& ss_in) { - return this->eval_("application/json", ss_html); + return this->eval_("application/json", ss_in); } - basic_writer& js(const std::basic_stringstream<char_type>& ss_html) + basic_writer& js(const std::basic_stringstream<char_type>& ss_in) { - return this->eval_("text/javascript", ss_html); + return this->eval_("text/javascript", ss_in); } }; } // namespace cgi diff --git a/dev/lib/utility/embfs.hpp b/dev/lib/utility/embfs.hpp index fea379c..3acc867 100644 --- a/dev/lib/utility/embfs.hpp +++ b/dev/lib/utility/embfs.hpp @@ -23,10 +23,10 @@ namespace snu::embfs inline constexpr const size_t _superblock_name_len = 16; inline constexpr const size_t _superblock_reserve_len = 462; - - inline constexpr const size_t _inode_name_len = 128; - inline constexpr const size_t _inode_arr_len = 12; - inline constexpr const size_t _inode_lookup_len = 8; + + inline constexpr const size_t _inode_name_len = 128; + inline constexpr const size_t _inode_arr_len = 12; + inline constexpr const size_t _inode_lookup_len = 8; #ifdef EMBFS_28BIT_LBA typedef std::uint32_t lba_t; diff --git a/dev/tests/fix_basic/CMakeLists.txt b/dev/tests/fix_basic/CMakeLists.txt index 3a2542d..f792277 100644 --- a/dev/tests/fix_basic/CMakeLists.txt +++ b/dev/tests/fix_basic/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(TrackedPtrTests) +project(SOCLTests) include(FetchContent) FetchContent_Declare( diff --git a/dev/tests/fix_basic/fix_test.cc b/dev/tests/fix_basic/fix_test.cc index 1ce128f..bd04d07 100644 --- a/dev/tests/fix_basic/fix_test.cc +++ b/dev/tests/fix_basic/fix_test.cc @@ -13,6 +13,6 @@ TEST(FIXTest, BasicFIXUsage) snu::fix::basic_visitor<char> basic_visitor; snu::fix::basic_range_data<char> fix = basic_visitor.visit("8=FIX.4.2|9=65|35=A|49=SERVER|56=CLIENT|34=177|52=20090107-18:15:16|98=0|108=30|10=062|"); - EXPECT_EQ(fix.magic_, "FIX.4.2"); + EXPECT_EQ(fix.magic_, snu::fix::detail::begin_fix()); EXPECT_TRUE(fix.is_valid()); }
\ No newline at end of file diff --git a/dev/tests/network_basic/CMakeLists.txt b/dev/tests/network_basic/CMakeLists.txt new file mode 100644 index 0000000..a5704fc --- /dev/null +++ b/dev/tests/network_basic/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.28) +project(SOCLTests LANGUAGES CXX) + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip +) + +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +enable_testing() + +add_executable(NetworkTestBasic net_test.cc) +target_link_libraries(NetworkTestBasic gtest_main) + +set_property(TARGET NetworkTestBasic PROPERTY CXX_STANDARD 20) +target_include_directories(NetworkTestBasic PUBLIC ../../) + +include(GoogleTest) +gtest_discover_tests(NetworkTestBasic) diff --git a/dev/tests/network_basic/net_test.cc b/dev/tests/network_basic/net_test.cc new file mode 100644 index 0000000..634048e --- /dev/null +++ b/dev/tests/network_basic/net_test.cc @@ -0,0 +1,36 @@ +/* + * File: tests/net_test.cc + * Purpose: Network unit tests in C++ + * Author: Amlal El Mahrouss (founder@snu.systems) + * Copyright 2025, Amlal El Mahrouss and SNU Systems Corp. + */ + +#include <lib/net/network.hpp> +#include <lib/io/print.hpp> +#include <lib/tests/gtest.hpp> +#include <cstring> + +TEST(NetworkTest, BasicNetworkUsage) +{ + snu::net::basic_modem<char> modem; + modem.construct<AF_INET, SOCK_STREAM, IPPROTO_IP, 80>(snu::net::basic_modem<char>::local_address_ip4, true); + + snu::net::basic_modem<char> modem_cl; + modem_cl.construct<AF_INET, SOCK_STREAM, IPPROTO_IP, 80>(snu::net::basic_modem<char>::local_address_ip4, false); + + EXPECT_TRUE(modem_cl.is_valid()); + EXPECT_TRUE(modem.is_valid()); + + std::basic_string<char> buf_dst = "HELLO, NET!"; + char* buf = new char[buf_dst.size()]; + + modem_cl.transmit(buf_dst); + modem.receive<char*>(buf, buf_dst.size()); + + snu::io::print(buf_dst); + snu::io::print(buf); + snu::io::print(); + + delete[] buf; + buf = nullptr; +} diff --git a/dev/tests/tracked_ptr_basic/CMakeLists.txt b/dev/tests/tracked_ptr_basic/CMakeLists.txt index 97f7204..9100e9a 100644 --- a/dev/tests/tracked_ptr_basic/CMakeLists.txt +++ b/dev/tests/tracked_ptr_basic/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(TrackedPtrTests) +project(SOCLTests) include(FetchContent) FetchContent_Declare( diff --git a/dev/tests/tracked_ptr_leak/CMakeLists.txt b/dev/tests/tracked_ptr_leak/CMakeLists.txt index 17df8f1..625a1dc 100644 --- a/dev/tests/tracked_ptr_leak/CMakeLists.txt +++ b/dev/tests/tracked_ptr_leak/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(TrackedPtrTests) +project(SOCLTests) include(FetchContent) FetchContent_Declare( |
