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_IMPL_SERIALIZER_HPP 11 : #define BOOST_HTTP_PROTO_IMPL_SERIALIZER_HPP 12 : 13 : #include <boost/http_proto/detail/except.hpp> 14 : #include <iterator> 15 : #include <new> 16 : #include <utility> 17 : 18 : namespace boost { 19 : namespace http_proto { 20 : 21 : class serializer:: 22 : output 23 : { 24 : std::size_t n_ = 0; 25 : const_buffer const* p_ = nullptr; 26 : 27 : friend class serializer; 28 : 29 12 : output( 30 : const_buffer const* p, 31 : std::size_t n) noexcept 32 12 : : n_(n) 33 12 : , p_(p) 34 : { 35 12 : } 36 : 37 : public: 38 : using iterator = const_buffer const*; 39 : using const_iterator = iterator; 40 : using value_type = const_buffer; 41 : using reference = const_buffer; 42 : using const_reference = const_buffer; 43 : using size_type = std::size_t; 44 : using difference_type = std::ptrdiff_t; 45 : 46 : output() = default; 47 : output( 48 : output const&) = default; 49 : output& operator=( 50 : output const&) = default; 51 : 52 : iterator 53 23 : begin() const noexcept 54 : { 55 23 : return p_; 56 : } 57 : 58 : iterator 59 23 : end() const noexcept 60 : { 61 23 : return p_ + n_; 62 : } 63 : }; 64 : 65 : //------------------------------------------------ 66 : 67 : template< 68 : class P0, 69 : class... Pn> 70 3 : serializer:: 71 : serializer( 72 : std::size_t buffer_size, 73 : P0&& p0, 74 : Pn&&... pn) 75 3 : : serializer(buffer_size) 76 : { 77 3 : apply_params( 78 : std::forward<P0>(p0), 79 : std::forward<Pn>(pn)...); 80 3 : } 81 : 82 : //------------------------------------------------ 83 : 84 : template< 85 : class ConstBuffers, 86 : class> 87 : void 88 11 : serializer:: 89 : reset( 90 : message_view_base const& m, 91 : ConstBuffers&& body) 92 : { 93 11 : ws_.clear(); 94 11 : auto& bs = ws_.push( 95 4 : (make_buffers)(std::forward< 96 2 : ConstBuffers>(body))); 97 11 : std::size_t const pn = 98 : 1 + 99 : 1 + // chunk header 100 11 : std::distance( 101 11 : bs.begin(), bs.end()) + 102 : 1; // final chunk 103 11 : auto const pp = ws_.push_array( 104 : pn, const_buffer{}); 105 11 : auto p = pp + 2; 106 22 : for(const_buffer b : bs) 107 11 : *p++ = b; 108 11 : reset_buffers_impl(m, pp, pn); 109 11 : } 110 : 111 : template< 112 : class Source, 113 : class> 114 : auto 115 6 : serializer:: 116 : reset( 117 : message_view_base const& m, 118 : Source&& source) -> 119 : typename std::decay< 120 : Source>::type& 121 : { 122 6 : ws_.clear(); 123 6 : auto& rv = ws_.push( 124 : std::forward< 125 : Source>(source)); 126 6 : reset_source_impl( 127 6 : m, std::addressof(rv)); 128 6 : return rv; 129 : } 130 : 131 : template<class MaybeReserve> 132 : auto 133 : serializer:: 134 : reset_stream( 135 : message_view_base const& m, 136 : MaybeReserve&& maybe_reserve) -> 137 : stream 138 : { 139 : // small hack for type-erasing 140 : struct Source : source 141 : { 142 : MaybeReserve&& f; 143 : 144 : void 145 : maybe_reserve( 146 : std::size_t limit, 147 : reserve_fn const& reserve) override 148 : { 149 : f(limit, reserve); 150 : } 151 : 152 : results 153 : read(mutable_buffers_pair) override 154 : { 155 : return {}; 156 : } 157 : }; 158 : Source src{ std::forward< 159 : MaybeReserve>(maybe_reserve) }; 160 : 161 : ws_.clear(); 162 : reset_stream_impl(m, src); 163 : return stream{*this}; 164 : } 165 : 166 : //------------------------------------------------ 167 : 168 : inline 169 : void 170 3 : serializer:: 171 : apply_params() noexcept 172 : { 173 3 : } 174 : 175 : template< 176 : class P0, 177 : class... Pn> 178 : void 179 4 : serializer:: 180 : apply_params( 181 : P0&& p0, 182 : Pn&&... pn) 183 : { 184 : // If you get an error here it means 185 : // you passed an unknown parameter type. 186 4 : apply_param(std::forward<P0>(p0)); 187 : 188 4 : apply_params( 189 : std::forward<Pn>(pn)...); 190 4 : } 191 : 192 : } // http_proto 193 : } // boost 194 : 195 : #endif