1 // 2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 // 7 // Official repository: https://github.com/boostorg/beast 8 // 9 10 #ifndef BOOST_BEAST_CORE_RATE_POLICY_HPP 11 #define BOOST_BEAST_CORE_RATE_POLICY_HPP 12 13 #include <boost/beast/core/detail/config.hpp> 14 #include <cstdint> 15 #include <limits> 16 17 namespace boost { 18 namespace beast { 19 20 /** Helper class to assist implementing a <em>RatePolicy</em>. 21 22 This class is used by the implementation to gain access to the 23 private members of a user-defined object meeting the requirements 24 of <em>RatePolicy</em>. To use it, simply declare it as a friend 25 in your class: 26 27 @par Example 28 @code 29 class custom_rate_policy 30 { 31 friend class beast::rate_policy_access; 32 ... 33 @endcode 34 35 @par Concepts 36 37 @li <em>RatePolicy</em> 38 39 @see beast::basic_stream 40 */ 41 class rate_policy_access 42 { 43 private: 44 template<class, class, class> 45 friend class basic_stream; 46 47 template<class Policy> 48 static 49 std::size_t available_read_bytes(Policy & policy)50 available_read_bytes(Policy& policy) 51 { 52 return policy.available_read_bytes(); 53 } 54 55 template<class Policy> 56 static 57 std::size_t available_write_bytes(Policy & policy)58 available_write_bytes(Policy& policy) 59 { 60 return policy.available_write_bytes(); 61 } 62 63 template<class Policy> 64 static 65 void transfer_read_bytes(Policy & policy,std::size_t n)66 transfer_read_bytes( 67 Policy& policy, std::size_t n) 68 { 69 return policy.transfer_read_bytes(n); 70 } 71 72 template<class Policy> 73 static 74 void transfer_write_bytes(Policy & policy,std::size_t n)75 transfer_write_bytes( 76 Policy& policy, std::size_t n) 77 { 78 return policy.transfer_write_bytes(n); 79 } 80 81 template<class Policy> 82 static 83 void on_timer(Policy & policy)84 on_timer(Policy& policy) 85 { 86 return policy.on_timer(); 87 } 88 }; 89 90 //------------------------------------------------------------------------------ 91 92 /** A rate policy with unlimited throughput. 93 94 This rate policy object does not apply any rate limit. 95 96 @par Concepts 97 98 @li <em>RatePolicy</em> 99 100 @see beast::basic_stream, beast::tcp_stream 101 */ 102 class unlimited_rate_policy 103 { 104 friend class rate_policy_access; 105 106 static std::size_t constexpr all = 107 (std::numeric_limits<std::size_t>::max)(); 108 109 std::size_t available_read_bytes() const110 available_read_bytes() const noexcept 111 { 112 return all; 113 } 114 115 std::size_t available_write_bytes() const116 available_write_bytes() const noexcept 117 { 118 return all; 119 } 120 121 void transfer_read_bytes(std::size_t) const122 transfer_read_bytes(std::size_t) const noexcept 123 { 124 } 125 126 void transfer_write_bytes(std::size_t) const127 transfer_write_bytes(std::size_t) const noexcept 128 { 129 } 130 131 void on_timer() const132 on_timer() const noexcept 133 { 134 } 135 }; 136 137 //------------------------------------------------------------------------------ 138 139 /** A rate policy with simple, configurable limits on reads and writes. 140 141 This rate policy allows for simple individual limits on the amount 142 of bytes per second allowed for reads and writes. 143 144 @par Concepts 145 146 @li <em>RatePolicy</em> 147 148 @see beast::basic_stream 149 */ 150 class simple_rate_policy 151 { 152 friend class rate_policy_access; 153 154 static std::size_t constexpr all = 155 (std::numeric_limits<std::size_t>::max)(); 156 157 std::size_t rd_remain_ = all; 158 std::size_t wr_remain_ = all; 159 std::size_t rd_limit_ = all; 160 std::size_t wr_limit_ = all; 161 162 std::size_t available_read_bytes() const163 available_read_bytes() const noexcept 164 { 165 return rd_remain_; 166 } 167 168 std::size_t available_write_bytes() const169 available_write_bytes() const noexcept 170 { 171 return wr_remain_; 172 } 173 174 void transfer_read_bytes(std::size_t n)175 transfer_read_bytes(std::size_t n) noexcept 176 { 177 if( rd_remain_ != all) 178 rd_remain_ = 179 (n < rd_remain_) ? rd_remain_ - n : 0; 180 } 181 182 void transfer_write_bytes(std::size_t n)183 transfer_write_bytes(std::size_t n) noexcept 184 { 185 if( wr_remain_ != all) 186 wr_remain_ = 187 (n < wr_remain_) ? wr_remain_ - n : 0; 188 } 189 190 void on_timer()191 on_timer() noexcept 192 { 193 rd_remain_ = rd_limit_; 194 wr_remain_ = wr_limit_; 195 } 196 197 public: 198 /// Set the limit of bytes per second to read 199 void read_limit(std::size_t bytes_per_second)200 read_limit(std::size_t bytes_per_second) noexcept 201 { 202 rd_limit_ = bytes_per_second; 203 if( rd_remain_ > bytes_per_second) 204 rd_remain_ = bytes_per_second; 205 } 206 207 /// Set the limit of bytes per second to write 208 void write_limit(std::size_t bytes_per_second)209 write_limit(std::size_t bytes_per_second) noexcept 210 { 211 wr_limit_ = bytes_per_second; 212 if( wr_remain_ > bytes_per_second) 213 wr_remain_ = bytes_per_second; 214 } 215 }; 216 217 } // beast 218 } // boost 219 220 #endif 221