Line data Source code
1 : // 2 : // Copyright (c) 2019 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_SOURCE_HPP 11 : #define BOOST_HTTP_PROTO_SOURCE_HPP 12 : 13 : #include <boost/http_proto/detail/config.hpp> 14 : #include <boost/http_proto/buffered_base.hpp> 15 : #include <boost/buffers/mutable_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 producing buffers of data. 25 : 26 : This interface abstracts the production of 27 : a finite stream of data, returned by writing 28 : into caller-provided buffers until there 29 : is no more output 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_HTTP_PROTO_DECL 36 : source 37 : : buffered_base 38 : { 39 : /** The results of producing data. 40 : */ 41 : struct results 42 : { 43 : /** The error, if any occurred. 44 : */ 45 : system::error_code ec; 46 : 47 : /** The number of bytes produced in the output. 48 : */ 49 : std::size_t bytes = 0; 50 : 51 : /** True if there will be no more output. 52 : */ 53 : bool finished = false; 54 : 55 : /** Accumulate results. 56 : */ 57 : results& 58 : operator+=( 59 : results const& rv) noexcept; 60 : }; 61 : 62 : /** Produce data. 63 : 64 : This function attempts to read from the 65 : source, placing the data into the given 66 : mutable buffer sequence. 67 : The return value indicates the number of 68 : bytes placed into the buffers, the error 69 : if any occurred, and a `bool` indicating 70 : whether or not there is more data 71 : remaining in the source. 72 : 73 : @par Preconditions 74 : @li @ref init was called, and 75 : @li There is more data remaining. 76 : 77 : @return The result of the operation. 78 : 79 : @param bs The buffers to use. 80 : Each buffer in the sequence will 81 : be filled completely before data 82 : is placed in the next buffer. 83 : */ 84 : template<class MutableBufferSequence> 85 : results 86 11 : read(MutableBufferSequence const& bs) 87 : { 88 : static_assert( 89 : buffers::is_mutable_buffer_sequence< 90 : MutableBufferSequence>::value, 91 : "Type requirements not met"); 92 : 93 11 : return read_impl(bs); 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 place data 106 : into the given mutable buffer. 107 : The return value must be set to indicate 108 : the number of bytes placed into the 109 : buffers, the error if any occurred, 110 : and a `bool` indicating whether or 111 : not there is more data remaining 112 : in the source. 113 : 114 : @par Preconditions 115 : @li @ref init was called, and 116 : @li There is more data remaining. 117 : 118 : @return The result of the operation. 119 : 120 : @param b The buffer to use. 121 : If this is not filled completely, 122 : then the result must indicate failure 123 : or that no more data remains (or both). 124 : */ 125 : virtual 126 : results 127 : on_read( 128 : buffers::mutable_buffer b) = 0; 129 : 130 : /** Derived class override. 131 : 132 : This pure virtual function is called by 133 : the implementation and must be overriden. 134 : The callee should attempt to place data 135 : into the given mutable buffer sequence. 136 : The return value must be set to indicate 137 : the number of bytes placed into the 138 : buffers, the error if any occurred, 139 : and a `bool` indicating whether or 140 : not there is more data remaining 141 : in the source. 142 : 143 : @par Preconditions 144 : @li @ref init was called, and 145 : @li There is more data remaining. 146 : 147 : @return The result of the operation. 148 : 149 : @param bs The buffer sequence to use. 150 : Each buffer in the sequence must 151 : be filled completely before data 152 : is placed in the next buffer. 153 : If the buffers are not filled 154 : completely, then the result must 155 : indicate failure or that no more 156 : data remains (or both). 157 : */ 158 : virtual 159 : results 160 : on_read( 161 : buffers::mutable_buffer_span bs); 162 : 163 : private: 164 : results 165 2 : read_impl( 166 : buffers::mutable_buffer const& b) 167 : { 168 2 : return on_read(b); 169 : } 170 : 171 : results 172 5 : read_impl( 173 : buffers::mutable_buffer_span const& bs) 174 : { 175 5 : return on_read(bs); 176 : } 177 : 178 : template<class T> 179 : results 180 : read_impl(T const&); 181 : }; 182 : 183 : //------------------------------------------------ 184 : 185 : /** Metafunction which determines if T is a source 186 : 187 : @see 188 : @ref source. 189 : */ 190 : #ifdef BOOST_HTTP_PROTO_DOCS 191 : template<class T> 192 : using is_source = __see_below__; 193 : #else 194 : template<class T> 195 : using is_source = 196 : std::is_convertible< 197 : typename std::decay<T>::type*, 198 : source*>; 199 : #endif 200 : 201 : } // http_proto 202 : } // boost 203 : 204 : #include <boost/http_proto/impl/source.hpp> 205 : 206 : #endif