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_SYMBOL_VISIBLE 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 : BOOST_HTTP_PROTO_DECL 126 : virtual 127 : results 128 : on_read( 129 : buffers::mutable_buffer b) = 0; 130 : 131 : /** Derived class override. 132 : 133 : This pure virtual function is called by 134 : the implementation and must be overriden. 135 : The callee should attempt to place data 136 : into the given mutable buffer sequence. 137 : The return value must be set to indicate 138 : the number of bytes placed into the 139 : buffers, the error if any occurred, 140 : and a `bool` indicating whether or 141 : not there is more data remaining 142 : in the source. 143 : 144 : @par Preconditions 145 : @li @ref init was called, and 146 : @li There is more data remaining. 147 : 148 : @return The result of the operation. 149 : 150 : @param bs The buffer sequence to use. 151 : Each buffer in the sequence must 152 : be filled completely before data 153 : is placed in the next buffer. 154 : If the buffers are not filled 155 : completely, then the result must 156 : indicate failure or that no more 157 : data remains (or both). 158 : */ 159 : BOOST_HTTP_PROTO_DECL 160 : virtual 161 : results 162 : on_read( 163 : buffers::mutable_buffer_span bs); 164 : 165 : private: 166 : results 167 2 : read_impl( 168 : buffers::mutable_buffer const& b) 169 : { 170 2 : return on_read(b); 171 : } 172 : 173 : results 174 5 : read_impl( 175 : buffers::mutable_buffer_span const& bs) 176 : { 177 5 : return on_read(bs); 178 : } 179 : 180 : template<class T> 181 : results 182 : read_impl(T const&); 183 : }; 184 : 185 : //------------------------------------------------ 186 : 187 : /** Metafunction which determines if T is a source 188 : 189 : @see 190 : @ref source. 191 : */ 192 : #ifdef BOOST_HTTP_PROTO_DOCS 193 : template<class T> 194 : using is_source = __see_below__; 195 : #else 196 : template<class T> 197 : using is_source = 198 : std::is_convertible< 199 : typename std::decay<T>::type*, 200 : source*>; 201 : #endif 202 : 203 : } // http_proto 204 : } // boost 205 : 206 : #include <boost/http_proto/impl/source.hpp> 207 : 208 : #endif