Line data Source code
1 : // 2 : // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.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/CPPAlliance/http_proto 8 : // 9 : 10 : #ifndef BOOST_HTTP_PROTO_SINK_HPP 11 : #define BOOST_HTTP_PROTO_SINK_HPP 12 : 13 : #include <boost/http_proto/detail/config.hpp> 14 : #include <boost/http_proto/buffered_base.hpp> 15 : #include <boost/buffers/const_buffer_span.hpp> 16 : #include <boost/buffers/type_traits.hpp> 17 : #include <boost/system/error_code.hpp> 18 : #include <cstddef> 19 : #include <type_traits> 20 : 21 : namespace boost { 22 : namespace http_proto { 23 : 24 : /** An algorithm for consuming buffers of data. 25 : 26 : This interface abstracts the consumption of 27 : a finite stream of data, passed by reading 28 : from caller-provided buffers until there 29 : is no more input data. 30 : 31 : @par Thread Safety 32 : Non-const member functions may not be 33 : called concurrently on the same instance. 34 : */ 35 : struct BOOST_SYMBOL_VISIBLE 36 : sink 37 : : buffered_base 38 : { 39 : /** The results of consuming data. 40 : */ 41 : struct results 42 : { 43 : /** The error, if any occurred. 44 : */ 45 : system::error_code ec; 46 : 47 : /** The number of bytes consumed in the input. 48 : */ 49 : std::size_t bytes = 0; 50 : 51 : /** Accumulate results. 52 : */ 53 : results& 54 : operator+=( 55 : results const& rv) noexcept; 56 : }; 57 : 58 : /** Consume data. 59 : 60 : This function attempts to write to the 61 : sink, by transferring data from the given 62 : constant buffer sequence. 63 : The return value indicates the number of 64 : bytes consumed from the buffers and the 65 : error if any occurred. 66 : 67 : @par Preconditions 68 : @li @ref init was called, and 69 : @li This is the first call to @ref write, 70 : or the last value of `more` was `true`. 71 : 72 : @return The result of the operation. 73 : 74 : @param bs The buffers to use. 75 : Each buffer in the sequence will be 76 : consumed completely before the next 77 : buffer is accessed. 78 : 79 : @param more `true` if there will be one 80 : or more subsequent calls to @ref write. 81 : */ 82 : template<class ConstBufferSequence> 83 : results 84 9 : write( 85 : ConstBufferSequence const& bs, 86 : bool more) 87 : { 88 : static_assert( 89 : buffers::is_const_buffer_sequence< 90 : ConstBufferSequence>::value, 91 : "Type requirements not met"); 92 : 93 9 : return write_impl(bs, more); 94 : } 95 : 96 : #ifdef BOOST_HTTP_PROTO_DOCS 97 : protected: 98 : #else 99 : private: 100 : #endif 101 : /** Derived class override. 102 : 103 : This pure virtual function is called by 104 : the implementation and must be overriden. 105 : The callee should attempt to consume data 106 : from the given constant buffer. 107 : The return value must be set to indicate 108 : the number of bytes consumed from the 109 : buffers, and the error if any occurred. 110 : 111 : @par Preconditions 112 : @li @ref init was called, and 113 : @li This is the first call to @ref on_write, 114 : or the last value of `more` was `true`. 115 : 116 : @return The result of the operation. 117 : 118 : @param b The buffer to use. 119 : If `more` is true then the results 120 : must indicate that the buffer was 121 : consumed completely, or that an error 122 : occurred. 123 : 124 : @param more `true` if there will be one 125 : or more subsequent calls to @ref write. 126 : */ 127 : BOOST_HTTP_PROTO_DECL 128 : virtual 129 : results 130 : on_write( 131 : buffers::const_buffer b, 132 : bool more) = 0; 133 : 134 : /** Derived class override. 135 : 136 : This pure virtual function is called by 137 : the implementation and must be overriden. 138 : The callee should attempt to consume data 139 : from the given constant buffer sequence. 140 : The return value must be set to indicate 141 : the number of bytes consumed from the 142 : buffers, and the error if any occurred. 143 : 144 : @par Preconditions 145 : @li @ref init was called, and 146 : @li This is the first call to @ref on_write, 147 : or the last value of `more` was `true`. 148 : 149 : @return The result of the operation. 150 : 151 : @param bs The buffer sequence to use. 152 : Each buffer in the sequence must 153 : be completely consumed before data 154 : is consumed from the next buffer. 155 : If `more` is true then the results 156 : must indicate that the buffer was 157 : consumed completely, or that an error 158 : occurred. 159 : 160 : @param more `true` if there will be one 161 : or more subsequent calls to @ref write. 162 : */ 163 : BOOST_HTTP_PROTO_DECL 164 : virtual 165 : results 166 : on_write( 167 : buffers::const_buffer_span bs, 168 : bool more); 169 : 170 : private: 171 : results 172 2 : write_impl( 173 : buffers::const_buffer const& b, 174 : bool more) 175 : { 176 2 : return on_write(b, more); 177 : } 178 : 179 : results 180 2 : write_impl( 181 : buffers::mutable_buffer const& b, 182 : bool more) 183 : { 184 2 : return on_write(b, more); 185 : } 186 : 187 : results 188 5 : write_impl( 189 : buffers::const_buffer_span const& bs, 190 : bool more) 191 : { 192 5 : return on_write(bs, more); 193 : } 194 : 195 : template<class T> 196 : results 197 : write_impl(T const&, bool); 198 : }; 199 : 200 : //------------------------------------------------ 201 : 202 : /** Metafunction which determines if T is a sink 203 : 204 : @see 205 : @ref sink. 206 : */ 207 : #ifdef BOOST_HTTP_PROTO_DOCS 208 : template<class T> 209 : using is_sink = __see_below__; 210 : #else 211 : template<class T> 212 : using is_sink = 213 : std::is_convertible< 214 : typename std::decay<T>::type*, 215 : sink*>; 216 : #endif 217 : 218 : } // http_proto 219 : } // boost 220 : 221 : #include <boost/http_proto/impl/sink.hpp> 222 : 223 : #endif