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_BUFFERS_ADAPTOR_HPP 11 #define BOOST_BEAST_BUFFERS_ADAPTOR_HPP 12 13 #include <boost/beast/core/detail/config.hpp> 14 #include <boost/beast/core/buffer_traits.hpp> 15 #include <boost/optional.hpp> 16 #include <type_traits> 17 18 namespace boost { 19 namespace beast { 20 21 /** Adapts a <em>MutableBufferSequence</em> into a <em>DynamicBuffer</em>. 22 23 This class wraps a <em>MutableBufferSequence</em> to meet the requirements 24 of <em>DynamicBuffer</em>. Upon construction the input and output sequences 25 are empty. A copy of the mutable buffer sequence object is stored; however, 26 ownership of the underlying memory is not transferred. The caller is 27 responsible for making sure that referenced memory remains valid 28 for the duration of any operations. 29 30 The size of the mutable buffer sequence determines the maximum 31 number of bytes which may be prepared and committed. 32 33 @tparam MutableBufferSequence The type of mutable buffer sequence to adapt. 34 */ 35 template<class MutableBufferSequence> 36 class buffers_adaptor 37 { 38 static_assert(net::is_mutable_buffer_sequence< 39 MutableBufferSequence>::value, 40 "MutableBufferSequence type requirements not met"); 41 42 using iter_type = 43 buffers_iterator_type<MutableBufferSequence>; 44 45 template<bool> 46 class subrange; 47 48 MutableBufferSequence bs_; 49 iter_type begin_; 50 iter_type out_; 51 iter_type end_; 52 std::size_t max_size_; 53 std::size_t in_pos_ = 0; // offset in *begin_ 54 std::size_t in_size_ = 0; // size of input sequence 55 std::size_t out_pos_ = 0; // offset in *out_ 56 std::size_t out_end_ = 0; // output end offset 57 58 iter_type end_impl() const; 59 60 buffers_adaptor( 61 buffers_adaptor const& other, 62 std::size_t nbegin, 63 std::size_t nout, 64 std::size_t nend); 65 66 public: 67 /// The type of the underlying mutable buffer sequence 68 using value_type = MutableBufferSequence; 69 70 /** Construct a buffers adaptor. 71 72 @param buffers The mutable buffer sequence to wrap. A copy of 73 the object will be made, but ownership of the memory is not 74 transferred. 75 */ 76 explicit 77 buffers_adaptor(MutableBufferSequence const& buffers); 78 79 /** Constructor 80 81 This constructs the buffer adaptor in-place from 82 a list of arguments. 83 84 @param args Arguments forwarded to the buffers constructor. 85 */ 86 template<class... Args> 87 explicit 88 buffers_adaptor(boost::in_place_init_t, Args&&... args); 89 90 /// Copy Constructor 91 buffers_adaptor(buffers_adaptor const& other); 92 93 /// Copy Assignment 94 buffers_adaptor& operator=(buffers_adaptor const&); 95 96 /// Returns the original mutable buffer sequence 97 value_type const& value() const98 value() const 99 { 100 return bs_; 101 } 102 103 //-------------------------------------------------------------------------- 104 105 #if BOOST_BEAST_DOXYGEN 106 /// The ConstBufferSequence used to represent the readable bytes. 107 using const_buffers_type = __implementation_defined__; 108 109 /// The MutableBufferSequence used to represent the writable bytes. 110 using mutable_buffers_type = __implementation_defined__; 111 112 #else 113 using const_buffers_type = subrange<false>; 114 115 using mutable_buffers_type = subrange<true>; 116 #endif 117 118 /// Returns the number of readable bytes. 119 std::size_t size() const120 size() const noexcept 121 { 122 return in_size_; 123 } 124 125 /// Return the maximum number of bytes, both readable and writable, that can ever be held. 126 std::size_t max_size() const127 max_size() const noexcept 128 { 129 return max_size_; 130 } 131 132 /// Return the maximum number of bytes, both readable and writable, that can be held without requiring an allocation. 133 std::size_t capacity() const134 capacity() const noexcept 135 { 136 return max_size_; 137 } 138 139 /// Returns a constant buffer sequence representing the readable bytes 140 const_buffers_type 141 data() const noexcept; 142 143 /// Returns a constant buffer sequence representing the readable bytes 144 const_buffers_type cdata() const145 cdata() const noexcept 146 { 147 return data(); 148 } 149 150 /// Returns a mutable buffer sequence representing the readable bytes. 151 mutable_buffers_type 152 data() noexcept; 153 154 /** Returns a mutable buffer sequence representing writable bytes. 155 156 Returns a mutable buffer sequence representing the writable 157 bytes containing exactly `n` bytes of storage. This function 158 does not allocate memory. Instead, the storage comes from 159 the underlying mutable buffer sequence. 160 161 All buffer sequences previously obtained using @ref prepare are 162 invalidated. Buffer sequences previously obtained using @ref data 163 remain valid. 164 165 @param n The desired number of bytes in the returned buffer 166 sequence. 167 168 @throws std::length_error if `size() + n` exceeds `max_size()`. 169 170 @esafe 171 172 Strong guarantee. 173 */ 174 mutable_buffers_type 175 prepare(std::size_t n); 176 177 /** Append writable bytes to the readable bytes. 178 179 Appends n bytes from the start of the writable bytes to the 180 end of the readable bytes. The remainder of the writable bytes 181 are discarded. If n is greater than the number of writable 182 bytes, all writable bytes are appended to the readable bytes. 183 184 All buffer sequences previously obtained using @ref prepare are 185 invalidated. Buffer sequences previously obtained using @ref data 186 remain valid. 187 188 @param n The number of bytes to append. If this number 189 is greater than the number of writable bytes, all 190 writable bytes are appended. 191 192 @esafe 193 194 No-throw guarantee. 195 */ 196 void 197 commit(std::size_t n) noexcept; 198 199 /** Remove bytes from beginning of the readable bytes. 200 201 Removes n bytes from the beginning of the readable bytes. 202 203 All buffers sequences previously obtained using 204 @ref data or @ref prepare are invalidated. 205 206 @param n The number of bytes to remove. If this number 207 is greater than the number of readable bytes, all 208 readable bytes are removed. 209 210 @esafe 211 212 No-throw guarantee. 213 */ 214 void 215 consume(std::size_t n) noexcept; 216 217 private: 218 219 subrange<true> 220 make_subrange(std::size_t pos, std::size_t n); 221 222 subrange<false> 223 make_subrange(std::size_t pos, std::size_t n) const; 224 225 friend struct buffers_adaptor_test_hook; 226 227 }; 228 229 } // beast 230 } // boost 231 232 #include <boost/beast/core/impl/buffers_adaptor.hpp> 233 234 #endif 235