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_SUFFIX_HPP 11 #define BOOST_BEAST_BUFFERS_SUFFIX_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 <cstdint> 17 #include <iterator> 18 #include <utility> 19 20 namespace boost { 21 namespace beast { 22 23 /** Adaptor to progressively trim the front of a <em>BufferSequence</em>. 24 25 This adaptor wraps a buffer sequence to create a new sequence 26 which may be incrementally consumed. Bytes consumed are removed 27 from the front of the buffer. The underlying memory is not changed, 28 instead the adaptor efficiently iterates through a subset of 29 the buffers wrapped. 30 31 The wrapped buffer is not modified, a copy is made instead. 32 Ownership of the underlying memory is not transferred, the application 33 is still responsible for managing its lifetime. 34 35 @tparam BufferSequence The buffer sequence to wrap. 36 37 @par Example 38 39 This function writes the entire contents of a buffer sequence 40 to the specified stream. 41 42 @code 43 template<class SyncWriteStream, class ConstBufferSequence> 44 void send(SyncWriteStream& stream, ConstBufferSequence const& buffers) 45 { 46 buffers_suffix<ConstBufferSequence> bs{buffers}; 47 while(buffer_bytes(bs) > 0) 48 bs.consume(stream.write_some(bs)); 49 } 50 @endcode 51 */ 52 template<class BufferSequence> 53 class buffers_suffix 54 { 55 using iter_type = 56 buffers_iterator_type<BufferSequence>; 57 58 BufferSequence bs_; 59 iter_type begin_{}; 60 std::size_t skip_ = 0; 61 62 template<class Deduced> buffers_suffix(Deduced && other,std::size_t dist)63 buffers_suffix(Deduced&& other, std::size_t dist) 64 : bs_(std::forward<Deduced>(other).bs_) 65 , begin_(std::next( 66 net::buffer_sequence_begin(bs_), 67 dist)) 68 , skip_(other.skip_) 69 { 70 } 71 72 public: 73 /** The type for each element in the list of buffers. 74 75 If <em>BufferSequence</em> meets the requirements of 76 <em>MutableBufferSequence</em>, then this type will be 77 `net::mutable_buffer`, otherwise this type will be 78 `net::const_buffer`. 79 */ 80 #if BOOST_BEAST_DOXYGEN 81 using value_type = __see_below__; 82 #else 83 using value_type = buffers_type<BufferSequence>; 84 #endif 85 86 #if BOOST_BEAST_DOXYGEN 87 /// A bidirectional iterator type that may be used to read elements. 88 using const_iterator = __implementation_defined__; 89 90 #else 91 class const_iterator; 92 93 #endif 94 95 /// Constructor 96 buffers_suffix(); 97 98 /// Copy Constructor 99 buffers_suffix(buffers_suffix const&); 100 101 /** Constructor 102 103 A copy of the buffer sequence is made. Ownership of the 104 underlying memory is not transferred or copied. 105 */ 106 explicit 107 buffers_suffix(BufferSequence const& buffers); 108 109 /** Constructor 110 111 This constructs the buffer sequence in-place from 112 a list of arguments. 113 114 @param args Arguments forwarded to the buffers constructor. 115 */ 116 template<class... Args> 117 explicit 118 buffers_suffix(boost::in_place_init_t, Args&&... args); 119 120 /// Copy Assignment 121 buffers_suffix& operator=(buffers_suffix const&); 122 123 /// Get a bidirectional iterator to the first element. 124 const_iterator 125 begin() const; 126 127 /// Get a bidirectional iterator to one past the last element. 128 const_iterator 129 end() const; 130 131 /** Remove bytes from the beginning of the sequence. 132 133 @param amount The number of bytes to remove. If this is 134 larger than the number of bytes remaining, all the 135 bytes remaining are removed. 136 */ 137 void 138 consume(std::size_t amount); 139 }; 140 141 } // beast 142 } // boost 143 144 #include <boost/beast/core/impl/buffers_suffix.hpp> 145 146 #endif 147