File indexing completed on 2025-01-18 09:29:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_BEAST_HTTP_BUFFER_BODY_HPP
0011 #define BOOST_BEAST_HTTP_BUFFER_BODY_HPP
0012
0013 #include <boost/beast/core/detail/config.hpp>
0014 #include <boost/beast/core/buffer_traits.hpp>
0015 #include <boost/beast/http/error.hpp>
0016 #include <boost/beast/http/message.hpp>
0017 #include <boost/beast/http/type_traits.hpp>
0018 #include <boost/optional.hpp>
0019
0020 #include <cstdint>
0021 #include <type_traits>
0022 #include <utility>
0023
0024 namespace boost {
0025 namespace beast {
0026 namespace http {
0027
0028
0029
0030
0031
0032
0033
0034
0035 struct buffer_body
0036 {
0037
0038 struct value_type
0039 {
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 void* data = nullptr;
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 std::size_t size = 0;
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 bool more = true;
0095 };
0096
0097
0098
0099
0100
0101 #if BOOST_BEAST_DOXYGEN
0102 using reader = __implementation_defined__;
0103 #else
0104 class reader
0105 {
0106 value_type& body_;
0107
0108 public:
0109 template<bool isRequest, class Fields>
0110 explicit
0111 reader(header<isRequest, Fields>&, value_type& b)
0112 : body_(b)
0113 {
0114 }
0115
0116 void
0117 init(boost::optional<std::uint64_t> const&, error_code& ec)
0118 {
0119 ec = {};
0120 }
0121
0122 template<class ConstBufferSequence>
0123 std::size_t
0124 put(ConstBufferSequence const& buffers,
0125 error_code& ec)
0126 {
0127 if(! body_.data)
0128 {
0129 BOOST_BEAST_ASSIGN_EC(ec, error::need_buffer);
0130 return 0;
0131 }
0132 auto const bytes_transferred =
0133 net::buffer_copy(net::buffer(
0134 body_.data, body_.size), buffers);
0135 body_.data = static_cast<char*>(
0136 body_.data) + bytes_transferred;
0137 body_.size -= bytes_transferred;
0138 if(bytes_transferred == buffer_bytes(buffers))
0139 ec = {};
0140 else
0141 {
0142 BOOST_BEAST_ASSIGN_EC(ec, error::need_buffer);
0143 }
0144 return bytes_transferred;
0145 }
0146
0147 void
0148 finish(error_code& ec)
0149 {
0150 ec = {};
0151 }
0152 };
0153 #endif
0154
0155
0156
0157
0158
0159 #if BOOST_BEAST_DOXYGEN
0160 using writer = __implementation_defined__;
0161 #else
0162 class writer
0163 {
0164 bool toggle_ = false;
0165 value_type const& body_;
0166
0167 public:
0168 using const_buffers_type =
0169 net::const_buffer;
0170
0171 template<bool isRequest, class Fields>
0172 explicit
0173 writer(header<isRequest, Fields> const&, value_type const& b)
0174 : body_(b)
0175 {
0176 }
0177
0178 void
0179 init(error_code& ec)
0180 {
0181 ec = {};
0182 }
0183
0184 boost::optional<
0185 std::pair<const_buffers_type, bool>>
0186 get(error_code& ec)
0187 {
0188 if(toggle_)
0189 {
0190 if(body_.more)
0191 {
0192 toggle_ = false;
0193 BOOST_BEAST_ASSIGN_EC(ec, error::need_buffer);
0194 }
0195 else
0196 {
0197 ec = {};
0198 }
0199 return boost::none;
0200 }
0201 if(body_.data)
0202 {
0203 ec = {};
0204 toggle_ = true;
0205 return {{const_buffers_type{
0206 body_.data, body_.size}, body_.more}};
0207 }
0208 if(body_.more)
0209 {
0210 BOOST_BEAST_ASSIGN_EC(ec, error::need_buffer);
0211 }
0212 else
0213 ec = {};
0214 return boost::none;
0215 }
0216 };
0217 #endif
0218 };
0219
0220 #if ! BOOST_BEAST_DOXYGEN
0221
0222 template<bool isRequest, class Fields>
0223 std::ostream&
0224 operator<<(std::ostream& os, message<isRequest,
0225 buffer_body, Fields> const& msg) = delete;
0226 #endif
0227
0228 }
0229 }
0230 }
0231
0232 #endif