Warning, file /include/boost/beast/core/impl/flat_stream.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_BEAST_CORE_IMPL_FLAT_STREAM_HPP
0011 #define BOOST_BEAST_CORE_IMPL_FLAT_STREAM_HPP
0012
0013 #include <boost/beast/core/async_base.hpp>
0014 #include <boost/beast/core/buffers_prefix.hpp>
0015 #include <boost/beast/core/static_buffer.hpp>
0016 #include <boost/beast/core/stream_traits.hpp>
0017 #include <boost/beast/websocket/teardown.hpp>
0018 #include <boost/asio/buffer.hpp>
0019 #include <memory>
0020
0021 namespace boost {
0022 namespace beast {
0023
0024 template<class NextLayer>
0025 struct flat_stream<NextLayer>::ops
0026 {
0027
0028 template<class Handler>
0029 class write_op
0030 : public async_base<Handler,
0031 beast::executor_type<flat_stream>>
0032 {
0033 public:
0034 template<
0035 class ConstBufferSequence,
0036 class Handler_>
0037 write_op(
0038 Handler_&& h,
0039 flat_stream<NextLayer>& s,
0040 ConstBufferSequence const& b)
0041 : async_base<Handler,
0042 beast::executor_type<flat_stream>>(
0043 std::forward<Handler_>(h),
0044 s.get_executor())
0045 {
0046 auto const result =
0047 flatten(b, max_size);
0048 if(result.flatten)
0049 {
0050 s.buffer_.clear();
0051 s.buffer_.commit(net::buffer_copy(
0052 s.buffer_.prepare(result.size),
0053 b, result.size));
0054
0055 BOOST_ASIO_HANDLER_LOCATION((
0056 __FILE__, __LINE__,
0057 "flat_stream::async_write_some"));
0058
0059 s.stream_.async_write_some(
0060 s.buffer_.data(), std::move(*this));
0061 }
0062 else
0063 {
0064 s.buffer_.clear();
0065 s.buffer_.shrink_to_fit();
0066
0067 BOOST_ASIO_HANDLER_LOCATION((
0068 __FILE__, __LINE__,
0069 "flat_stream::async_write_some"));
0070
0071 s.stream_.async_write_some(
0072 beast::buffers_prefix(
0073 result.size, b), std::move(*this));
0074 }
0075 }
0076
0077 void
0078 operator()(
0079 boost::system::error_code ec,
0080 std::size_t bytes_transferred)
0081 {
0082 this->complete_now(ec, bytes_transferred);
0083 }
0084 };
0085
0086 struct run_write_op
0087 {
0088 flat_stream* self;
0089
0090 using executor_type = typename flat_stream::executor_type;
0091
0092 executor_type
0093 get_executor() const noexcept
0094 {
0095 return self->get_executor();
0096 }
0097
0098 template<class WriteHandler, class Buffers>
0099 void
0100 operator()(
0101 WriteHandler&& h,
0102 Buffers const& b)
0103 {
0104
0105
0106
0107
0108 static_assert(
0109 beast::detail::is_invocable<WriteHandler,
0110 void(error_code, std::size_t)>::value,
0111 "WriteHandler type requirements not met");
0112
0113 write_op<
0114 typename std::decay<WriteHandler>::type>(
0115 std::forward<WriteHandler>(h), *self, b);
0116 }
0117 };
0118
0119 };
0120
0121
0122
0123 template<class NextLayer>
0124 template<class... Args>
0125 flat_stream<NextLayer>::
0126 flat_stream(Args&&... args)
0127 : stream_(std::forward<Args>(args)...)
0128 {
0129 }
0130
0131 template<class NextLayer>
0132 template<class MutableBufferSequence>
0133 std::size_t
0134 flat_stream<NextLayer>::
0135 read_some(MutableBufferSequence const& buffers)
0136 {
0137 static_assert(boost::beast::is_sync_read_stream<next_layer_type>::value,
0138 "SyncReadStream type requirements not met");
0139 static_assert(net::is_mutable_buffer_sequence<
0140 MutableBufferSequence>::value,
0141 "MutableBufferSequence type requirements not met");
0142 error_code ec;
0143 auto n = read_some(buffers, ec);
0144 if(ec)
0145 BOOST_THROW_EXCEPTION(boost::system::system_error{ec});
0146 return n;
0147 }
0148
0149 template<class NextLayer>
0150 template<class MutableBufferSequence>
0151 std::size_t
0152 flat_stream<NextLayer>::
0153 read_some(MutableBufferSequence const& buffers, error_code& ec)
0154 {
0155 static_assert(boost::beast::is_sync_read_stream<next_layer_type>::value,
0156 "SyncReadStream type requirements not met");
0157 static_assert(net::is_mutable_buffer_sequence<
0158 MutableBufferSequence>::value,
0159 "MutableBufferSequence type requirements not met");
0160 return stream_.read_some(buffers, ec);
0161 }
0162
0163 template<class NextLayer>
0164 template<
0165 class MutableBufferSequence,
0166 BOOST_BEAST_ASYNC_TPARAM2 ReadHandler>
0167 BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
0168 flat_stream<NextLayer>::
0169 async_read_some(
0170 MutableBufferSequence const& buffers,
0171 ReadHandler&& handler)
0172 {
0173 static_assert(boost::beast::is_async_read_stream<next_layer_type>::value,
0174 "AsyncReadStream type requirements not met");
0175 static_assert(net::is_mutable_buffer_sequence<
0176 MutableBufferSequence >::value,
0177 "MutableBufferSequence type requirements not met");
0178 return stream_.async_read_some(
0179 buffers, std::forward<ReadHandler>(handler));
0180 }
0181
0182 template<class NextLayer>
0183 template<class ConstBufferSequence>
0184 std::size_t
0185 flat_stream<NextLayer>::
0186 write_some(ConstBufferSequence const& buffers)
0187 {
0188 static_assert(boost::beast::is_sync_write_stream<next_layer_type>::value,
0189 "SyncWriteStream type requirements not met");
0190 static_assert(net::is_const_buffer_sequence<
0191 ConstBufferSequence>::value,
0192 "ConstBufferSequence type requirements not met");
0193 error_code ec;
0194 auto n = write_some(buffers, ec);
0195 if(ec)
0196 BOOST_THROW_EXCEPTION(boost::system::system_error{ec});
0197 return n;
0198 }
0199
0200 template<class NextLayer>
0201 template<class ConstBufferSequence>
0202 std::size_t
0203 flat_stream<NextLayer>::
0204 stack_write_some(
0205 std::size_t size,
0206 ConstBufferSequence const& buffers,
0207 error_code& ec)
0208 {
0209 static_buffer<max_stack> b;
0210 b.commit(net::buffer_copy(
0211 b.prepare(size), buffers));
0212 return stream_.write_some(b.data(), ec);
0213 }
0214
0215 template<class NextLayer>
0216 template<class ConstBufferSequence>
0217 std::size_t
0218 flat_stream<NextLayer>::
0219 write_some(ConstBufferSequence const& buffers, error_code& ec)
0220 {
0221 static_assert(boost::beast::is_sync_write_stream<next_layer_type>::value,
0222 "SyncWriteStream type requirements not met");
0223 static_assert(net::is_const_buffer_sequence<
0224 ConstBufferSequence>::value,
0225 "ConstBufferSequence type requirements not met");
0226 auto const result = flatten(buffers, max_size);
0227 if(result.flatten)
0228 {
0229 if(result.size <= max_stack)
0230 return stack_write_some(result.size, buffers, ec);
0231
0232 buffer_.clear();
0233 buffer_.commit(net::buffer_copy(
0234 buffer_.prepare(result.size),
0235 buffers));
0236 return stream_.write_some(buffer_.data(), ec);
0237 }
0238 buffer_.clear();
0239 buffer_.shrink_to_fit();
0240 return stream_.write_some(
0241 boost::beast::buffers_prefix(result.size, buffers), ec);
0242 }
0243
0244 template<class NextLayer>
0245 template<
0246 class ConstBufferSequence,
0247 BOOST_BEAST_ASYNC_TPARAM2 WriteHandler>
0248 BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
0249 flat_stream<NextLayer>::
0250 async_write_some(
0251 ConstBufferSequence const& buffers,
0252 WriteHandler&& handler)
0253 {
0254 static_assert(boost::beast::is_async_write_stream<next_layer_type>::value,
0255 "AsyncWriteStream type requirements not met");
0256 static_assert(net::is_const_buffer_sequence<
0257 ConstBufferSequence>::value,
0258 "ConstBufferSequence type requirements not met");
0259 return net::async_initiate<
0260 WriteHandler,
0261 void(error_code, std::size_t)>(
0262 typename ops::run_write_op{this},
0263 handler,
0264 buffers);
0265 }
0266
0267 template<class NextLayer>
0268 void
0269 teardown(
0270 boost::beast::role_type role,
0271 flat_stream<NextLayer>& s,
0272 error_code& ec)
0273 {
0274 using boost::beast::websocket::teardown;
0275 teardown(role, s.next_layer(), ec);
0276 }
0277
0278 template<class NextLayer, class TeardownHandler>
0279 void
0280 async_teardown(
0281 boost::beast::role_type role,
0282 flat_stream<NextLayer>& s,
0283 TeardownHandler&& handler)
0284 {
0285 using boost::beast::websocket::async_teardown;
0286 async_teardown(role, s.next_layer(), std::move(handler));
0287 }
0288
0289 }
0290 }
0291
0292 #endif