// // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // Official repository: https://github.com/boostorg/beast // #ifndef BOOST_BEAST_CORE_RATE_POLICY_HPP #define BOOST_BEAST_CORE_RATE_POLICY_HPP #include #include #include namespace boost { namespace beast { /** Helper class to assist implementing a RatePolicy. This class is used by the implementation to gain access to the private members of a user-defined object meeting the requirements of RatePolicy. To use it, simply declare it as a friend in your class: @par Example @code class custom_rate_policy { friend class beast::rate_policy_access; ... @endcode @par Concepts @li RatePolicy @see beast::basic_stream */ class rate_policy_access { private: template friend class basic_stream; template static std::size_t available_read_bytes(Policy& policy) { return policy.available_read_bytes(); } template static std::size_t available_write_bytes(Policy& policy) { return policy.available_write_bytes(); } template static void transfer_read_bytes( Policy& policy, std::size_t n) { return policy.transfer_read_bytes(n); } template static void transfer_write_bytes( Policy& policy, std::size_t n) { return policy.transfer_write_bytes(n); } template static void on_timer(Policy& policy) { return policy.on_timer(); } }; //------------------------------------------------------------------------------ /** A rate policy with unlimited throughput. This rate policy object does not apply any rate limit. @par Concepts @li RatePolicy @see beast::basic_stream, beast::tcp_stream */ class unlimited_rate_policy { friend class rate_policy_access; static std::size_t constexpr all = (std::numeric_limits::max)(); std::size_t available_read_bytes() const noexcept { return all; } std::size_t available_write_bytes() const noexcept { return all; } void transfer_read_bytes(std::size_t) const noexcept { } void transfer_write_bytes(std::size_t) const noexcept { } void on_timer() const noexcept { } }; //------------------------------------------------------------------------------ /** A rate policy with simple, configurable limits on reads and writes. This rate policy allows for simple individual limits on the amount of bytes per second allowed for reads and writes. @par Concepts @li RatePolicy @see beast::basic_stream */ class simple_rate_policy { friend class rate_policy_access; static std::size_t constexpr all = (std::numeric_limits::max)(); std::size_t rd_remain_ = all; std::size_t wr_remain_ = all; std::size_t rd_limit_ = all; std::size_t wr_limit_ = all; std::size_t available_read_bytes() const noexcept { return rd_remain_; } std::size_t available_write_bytes() const noexcept { return wr_remain_; } void transfer_read_bytes(std::size_t n) noexcept { if( rd_remain_ != all) rd_remain_ = (n < rd_remain_) ? rd_remain_ - n : 0; } void transfer_write_bytes(std::size_t n) noexcept { if( wr_remain_ != all) wr_remain_ = (n < wr_remain_) ? wr_remain_ - n : 0; } void on_timer() noexcept { rd_remain_ = rd_limit_; wr_remain_ = wr_limit_; } public: /// Set the limit of bytes per second to read void read_limit(std::size_t bytes_per_second) noexcept { rd_limit_ = bytes_per_second; if( rd_remain_ > bytes_per_second) rd_remain_ = bytes_per_second; } /// Set the limit of bytes per second to write void write_limit(std::size_t bytes_per_second) noexcept { wr_limit_ = bytes_per_second; if( wr_remain_ > bytes_per_second) wr_remain_ = bytes_per_second; } }; } // beast } // boost #endif