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