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 : buffers 23 : { 24 : std::size_t n_ = 0; 25 : const_buffer const* p_ = nullptr; 26 : 27 : friend class serializer; 28 : 29 12 : buffers( 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 : buffers() = default; 47 : buffers( 48 : buffers const&) = default; 49 : buffers& operator=( 50 : buffers 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 : serializer:: 71 : serializer( 72 : std::size_t buffer_size, 73 : P0&& p0, 74 : Pn&&... pn) 75 : : serializer(buffer_size) 76 : { 77 : apply_params( 78 : std::forward<P0>(p0), 79 : std::forward<Pn>(pn)...); 80 : } 81 : 82 : //------------------------------------------------ 83 : 84 : template< 85 : class ConstBuffers, 86 : class> 87 : void 88 7 : serializer:: 89 : start( 90 : message_view_base const& m, 91 : ConstBuffers&& body) 92 : { 93 7 : start_init(m); 94 7 : auto const& bs = 95 : ws_.push(std::forward< 96 : ConstBuffers>(body)); 97 7 : std::size_t n = std::distance( 98 : bs.begin(), bs.end()); 99 7 : buf_ = make_array(n); 100 7 : auto p = buf_.data(); 101 14 : for(const_buffer b : bs) 102 7 : *p++ = b; 103 7 : start_buffers(m); 104 7 : } 105 : 106 : template< 107 : class Source, 108 : class> 109 : auto 110 6 : serializer:: 111 : start( 112 : message_view_base const& m, 113 : Source&& src0) -> 114 : typename std::decay< 115 : Source>::type& 116 : { 117 6 : start_init(m); 118 6 : auto& src = ws_.push( 119 : std::forward< 120 : Source>(src0)); 121 6 : start_source( 122 6 : m, std::addressof(src)); 123 6 : return src; 124 : } 125 : 126 : template<class MaybeReserve> 127 : auto 128 : serializer:: 129 : start_stream( 130 : message_view_base const& m, 131 : MaybeReserve&& maybe_reserve) -> 132 : stream 133 : { 134 : // small hack for type-erasing 135 : struct Source : source 136 : { 137 : MaybeReserve&& f; 138 : 139 : void 140 : maybe_reserve( 141 : std::size_t limit, 142 : reserve_fn const& reserve) override 143 : { 144 : f(limit, reserve); 145 : } 146 : 147 : results 148 : read(mutable_buffers_pair) override 149 : { 150 : return {}; 151 : } 152 : }; 153 : Source src{ std::forward< 154 : MaybeReserve>(maybe_reserve) }; 155 : 156 : start_stream(m, src); 157 : return stream{*this}; 158 : } 159 : 160 : //------------------------------------------------ 161 : 162 : inline 163 : auto 164 24 : serializer:: 165 : make_array(std::size_t n) -> 166 : detail::array_of_const_buffers 167 : { 168 : return { 169 : ws_.push_array( 170 48 : n, const_buffer{}), 171 24 : n }; 172 : } 173 : 174 : inline 175 : void 176 : serializer:: 177 : apply_params() noexcept 178 : { 179 : } 180 : 181 : template< 182 : class P0, 183 : class... Pn> 184 : void 185 : serializer:: 186 : apply_params( 187 : P0&& p0, 188 : Pn&&... pn) 189 : { 190 : // If you get an error here it means 191 : // you passed an unknown parameter type. 192 : apply_param(std::forward<P0>(p0)); 193 : 194 : apply_params( 195 : std::forward<Pn>(pn)...); 196 : } 197 : 198 : } // http_proto 199 : } // boost 200 : 201 : #endif