2 // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
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)
8 #ifndef BEAST_TEST_FAIL_STREAM_HPP
9 #define BEAST_TEST_FAIL_STREAM_HPP
11 #include <beast/core/async_completion.hpp>
12 #include <beast/core/bind_handler.hpp>
13 #include <beast/core/error.hpp>
14 #include <beast/core/detail/get_lowest_layer.hpp>
15 #include <beast/websocket/teardown.hpp>
16 #include <beast/test/fail_counter.hpp>
17 #include <boost/optional.hpp>
22 /** A stream wrapper that fails.
24 On the Nth operation, the stream will fail with the specified
25 error code, or the default error code of invalid_argument.
27 template<class NextLayer>
30 boost::optional<fail_counter> fc_;
32 NextLayer next_layer_;
35 using next_layer_type =
36 typename std::remove_reference<NextLayer>::type;
38 using lowest_layer_type =
39 typename beast::detail::get_lowest_layer<
40 next_layer_type>::type;
42 fail_stream(fail_stream&&) = delete;
43 fail_stream(fail_stream const&) = delete;
44 fail_stream& operator=(fail_stream&&) = delete;
45 fail_stream& operator=(fail_stream const&) = delete;
47 template<class... Args>
49 fail_stream(std::size_t n, Args&&... args)
52 , next_layer_(std::forward<Args>(args)...)
56 template<class... Args>
58 fail_stream(fail_counter& fc, Args&&... args)
60 , next_layer_(std::forward<Args>(args)...)
73 return next_layer_.lowest_layer();
76 lowest_layer_type const&
79 return next_layer_.lowest_layer();
82 boost::asio::io_service&
85 return next_layer_.get_io_service();
88 template<class MutableBufferSequence>
90 read_some(MutableBufferSequence const& buffers)
93 return next_layer_.read_some(buffers);
96 template<class MutableBufferSequence>
98 read_some(MutableBufferSequence const& buffers, error_code& ec)
102 return next_layer_.read_some(buffers, ec);
105 template<class MutableBufferSequence, class ReadHandler>
106 typename async_completion<
107 ReadHandler, void(error_code)>::result_type
108 async_read_some(MutableBufferSequence const& buffers,
109 ReadHandler&& handler)
115 ReadHandler, void(error_code, std::size_t)
116 > completion{handler};
117 next_layer_.get_io_service().post(
118 bind_handler(completion.handler, ec, 0));
119 return completion.result.get();
121 return next_layer_.async_read_some(buffers,
122 std::forward<ReadHandler>(handler));
125 template<class ConstBufferSequence>
127 write_some(ConstBufferSequence const& buffers)
130 return next_layer_.write_some(buffers);
133 template<class ConstBufferSequence>
135 write_some(ConstBufferSequence const& buffers, error_code& ec)
139 return next_layer_.write_some(buffers, ec);
142 template<class ConstBufferSequence, class WriteHandler>
143 typename async_completion<
144 WriteHandler, void(error_code)>::result_type
145 async_write_some(ConstBufferSequence const& buffers,
146 WriteHandler&& handler)
152 WriteHandler, void(error_code, std::size_t)
153 > completion{handler};
154 next_layer_.get_io_service().post(
155 bind_handler(completion.handler, ec, 0));
156 return completion.result.get();
158 return next_layer_.async_write_some(buffers,
159 std::forward<WriteHandler>(handler));
164 teardown(websocket::teardown_tag,
165 fail_stream<NextLayer>& stream,
166 boost::system::error_code& ec)
168 if(stream.pfc_->fail(ec))
170 beast::websocket_helpers::call_teardown(stream.next_layer(), ec);
173 template<class TeardownHandler>
176 async_teardown(websocket::teardown_tag,
177 fail_stream<NextLayer>& stream,
178 TeardownHandler&& handler)
181 if(stream.pfc_->fail(ec))
183 stream.get_io_service().post(
184 bind_handler(std::move(handler), ec));
187 beast::websocket_helpers::call_async_teardown(
188 stream.next_layer(), std::forward<TeardownHandler>(handler));