//----------------------------------------------------------------------------- // ___ __ _ _ // / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __ // / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ / // / ___/ (_| | | \__ \ __/ /__| | | | | < // \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ . // //----------------------------------------------------------------------------- // Author: Kurt Sassenrath // Module: Proto // // Session management for the "user" protocol. // // Copyright (c) 2023 Kurt Sassenrath. // // License TBD. //----------------------------------------------------------------------------- #ifndef session_07eae057feface79 #define session_07eae057feface79 #include "parselink/msgpack/token.h" #include "parselink/proto/session_id.h" #include #include #include #include #include #include template <> struct std::hash> { constexpr static std::uint32_t seed_var = 0x811c9dc5; constexpr static std::uint32_t factor = 0x01000193; constexpr auto operator()(std::span data) const noexcept { std::uint32_t digest = seed_var * factor; for (auto byte : data) { digest = (digest ^ static_cast(byte)) * factor; } return digest >> 8; } }; namespace parselink { namespace proto { enum class error { system_error, incomplete, unsupported, bad_data, too_large, }; // Structure containing header information parsed from a buffer. struct header_info { std::uint32_t message_size; // Size of the message, minus the header. std::uint32_t bytes_read; // How many bytes of the buffer were used. std::uint32_t bytes_parsed; // How many bytes were parsed as part of the // header. }; struct connect_info { std::uint32_t version; std::string_view user_id; std::span session_id; }; template struct transparent_hash { using is_transparent = void; using type = T; using hash_type = std::hash; template [[nodiscard]] constexpr auto operator()(Arg&& arg) const { return hash_type{}(std::forward(arg)); } }; class session { public: using close_handle = std::function; session(std::string_view user_id) noexcept; ~session(); session_id id() const noexcept { return id_; } std::string_view user_id() const noexcept { return user_id_; } auto last_activity() const noexcept { return last_activity_; } void update_last_activity( std::chrono::system_clock::time_point = std::chrono::system_clock::now()) noexcept {} private: session_id id_; std::string user_id_; std::chrono::system_clock::time_point last_activity_; }; template <> struct transparent_hash : transparent_hash {}; template <> struct transparent_hash : transparent_hash> { [[nodiscard]] auto operator()(session_id const& s) const { return std::hash>{}(s.raw()); } }; // Parse the protocol header out of a buffer. tl::expected parse_header( std::span buffer) noexcept; tl::expected parse_connect( std::span tokens) noexcept; } // namespace proto } // namespace parselink #endif // session_0c61530748b9f966