Rename to multi_buffer, basic_multi_buffer (API Change):

These classes are renamed:

* streambuf to multi_buffer
* basic_streambuf to basic_multi_buffer
This commit is contained in:
Vinnie Falco
2017-05-04 15:40:07 -07:00
parent 38b473902a
commit 24fd254690
45 changed files with 744 additions and 745 deletions

View File

@ -10,6 +10,7 @@ API Changes:
* Refactor http::header contents * Refactor http::header contents
* New ostream() returns dynamic buffer output stream * New ostream() returns dynamic buffer output stream
* New buffers() replaces to_string() * New buffers() replaces to_string()
* Rename to multi_buffer, basic_multi_buffer
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@ -419,7 +419,7 @@ start. Other design goals:
[``` [```
beast::async_completion<ReadHandler, void(error_code)> completion(handler); beast::async_completion<ReadHandler, void(error_code)> completion(handler);
read_op<DynamicBuffer, decltype(completion.handler)>{ read_op<DynamicBuffer, decltype(completion.handler)>{
completion.handler, *this, op, streambuf}; completion.handler, *this, op, buffer};
return completion.result.get(); return completion.result.get();
```] ```]
[ [
@ -442,13 +442,13 @@ start. Other design goals:
or frame data, which is of any type meeting the requirements of or frame data, which is of any type meeting the requirements of
__DynamicBuffer__ (modeled after `boost::asio::streambuf`). __DynamicBuffer__ (modeled after `boost::asio::streambuf`).
Beast comes with the class __basic_streambuf__, an efficient Beast comes with the class __basic_multi_buffer__, an efficient
implementation of the __DynamicBuffer__ concept which makes use of multiple implementation of the __DynamicBuffer__ concept which makes use of multiple
allocated octet arrays. If an incoming message is broken up into allocated octet arrays. If an incoming message is broken up into
multiple pieces, no reallocation occurs. Instead, new allocations are multiple pieces, no reallocation occurs. Instead, new allocations are
appended to the sequence when existing allocations are filled. Beast appended to the sequence when existing allocations are filled. Beast
does not impose any particular memory management model on callers. The does not impose any particular memory management model on callers. The
__basic_streambuf__ provided by beast supports standard allocators through __basic_multi_buffer__ provided by beast supports standard allocators through
a template argument. Use the __DynamicBuffer__ that comes with beast, a template argument. Use the __DynamicBuffer__ that comes with beast,
customize the allocator if you desire, or provide your own type that customize the allocator if you desire, or provide your own type that
meets the requirements. meets the requirements.

View File

@ -45,17 +45,17 @@ int main()
beast::http::write(sock, req); beast::http::write(sock, req);
// Receive and print HTTP response using beast // Receive and print HTTP response using beast
beast::streambuf sb; beast::multi_buffer b;
beast::http::response<beast::http::dynamic_body> resp; beast::http::response<beast::http::dynamic_body> res;
beast::http::read(sock, sb, resp); beast::http::read(sock, b, res);
std::cout << resp; std::cout << res;
} }
``` ```
[heading WebSocket] [heading WebSocket]
Establish a WebSocket connection, send a message and receive the reply: Establish a WebSocket connection, send a message and receive the reply:
``` ```
#include <beast/core/to_string.hpp> #include <beast/core.hpp>
#include <beast/websocket.hpp> #include <beast/websocket.hpp>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <iostream> #include <iostream>
@ -77,11 +77,11 @@ int main()
ws.write(boost::asio::buffer(std::string("Hello, world!"))); ws.write(boost::asio::buffer(std::string("Hello, world!")));
// Receive WebSocket message, print and close using beast // Receive WebSocket message, print and close using beast
beast::streambuf sb; beast::multi_buffer b;
beast::websocket::opcode op; beast::websocket::opcode op;
ws.read(op, sb); ws.read(op, b);
ws.close(beast::websocket::close_code::normal); ws.close(beast::websocket::close_code::normal);
std::cout << beast::to_string(sb.data()) << "\n"; std::cout << beast::buffers(b.data()) << "\n";
} }
``` ```

View File

@ -40,17 +40,17 @@
[def __SyncReadStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/SyncReadStream.html [*SyncReadStream]]] [def __SyncReadStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/SyncReadStream.html [*SyncReadStream]]]
[def __SyncWriteStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/SyncWriteStream.html [*SyncWriteStream]]] [def __SyncWriteStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/SyncWriteStream.html [*SyncWriteStream]]]
[def __Body__ [link beast.ref.Body [*`Body`]]] [def __Body__ [link beast.ref.Body [*`Body`]]]
[def __DynamicBuffer__ [link beast.ref.DynamicBuffer [*DynamicBuffer]]] [def __DynamicBuffer__ [link beast.ref.DynamicBuffer [*DynamicBuffer]]]
[def __FieldSequence__ [link beast.ref.FieldSequence [*FieldSequence]]] [def __FieldSequence__ [link beast.ref.FieldSequence [*FieldSequence]]]
[def __Parser__ [link beast.ref.Parser [*`Parser`]]] [def __Parser__ [link beast.ref.Parser [*`Parser`]]]
[def __basic_fields__ [link beast.ref.http__basic_fields `basic_fields`]] [def __basic_fields__ [link beast.ref.http__basic_fields `basic_fields`]]
[def __fields__ [link beast.ref.http__fields `fields`]] [def __fields__ [link beast.ref.http__fields `fields`]]
[def __header__ [link beast.ref.http__header `header`]] [def __header__ [link beast.ref.http__header `header`]]
[def __message__ [link beast.ref.http__message `message`]] [def __message__ [link beast.ref.http__message `message`]]
[def __streambuf__ [link beast.ref.streambuf `streambuf`]] [def __streambuf__ [link beast.ref.streambuf `streambuf`]]
[def __basic_streambuf__ [link beast.ref.basic_streambuf `basic_streambuf`]] [def __basic_multi_buffer__ [link beast.ref.basic_multi_buffer `basic_multi_buffer`]]
Beast is a cross-platform, header-only C++ library built on Boost.Asio that Beast is a cross-platform, header-only C++ library built on Boost.Asio that
provides implementations of the HTTP and WebSocket protocols. provides implementations of the HTTP and WebSocket protocols.

View File

@ -153,7 +153,7 @@
<simplelist type="vert" columns="1"> <simplelist type="vert" columns="1">
<member><link linkend="beast.ref.async_completion">async_completion</link></member> <member><link linkend="beast.ref.async_completion">async_completion</link></member>
<member><link linkend="beast.ref.basic_flat_streambuf">basic_flat_streambuf</link></member> <member><link linkend="beast.ref.basic_flat_streambuf">basic_flat_streambuf</link></member>
<member><link linkend="beast.ref.basic_streambuf">basic_streambuf</link></member> <member><link linkend="beast.ref.basic_multi_buffer">basic_multi_buffer</link></member>
<member><link linkend="beast.ref.buffers_adapter">buffers_adapter</link></member> <member><link linkend="beast.ref.buffers_adapter">buffers_adapter</link></member>
<member><link linkend="beast.ref.consuming_buffers">consuming_buffers</link></member> <member><link linkend="beast.ref.consuming_buffers">consuming_buffers</link></member>
<member><link linkend="beast.ref.dynabuf_readstream">dynabuf_readstream</link></member> <member><link linkend="beast.ref.dynabuf_readstream">dynabuf_readstream</link></member>
@ -164,10 +164,10 @@
<member><link linkend="beast.ref.flat_streambuf">flat_streambuf</link></member> <member><link linkend="beast.ref.flat_streambuf">flat_streambuf</link></member>
<member><link linkend="beast.ref.handler_alloc">handler_alloc</link></member> <member><link linkend="beast.ref.handler_alloc">handler_alloc</link></member>
<member><link linkend="beast.ref.handler_ptr">handler_ptr</link></member> <member><link linkend="beast.ref.handler_ptr">handler_ptr</link></member>
<member><link linkend="beast.ref.multi_buffer">multi_buffer</link></member>
<member><link linkend="beast.ref.static_streambuf">static_streambuf</link></member> <member><link linkend="beast.ref.static_streambuf">static_streambuf</link></member>
<member><link linkend="beast.ref.static_streambuf_n">static_streambuf_n</link></member> <member><link linkend="beast.ref.static_streambuf_n">static_streambuf_n</link></member>
<member><link linkend="beast.ref.static_string">static_string</link></member> <member><link linkend="beast.ref.static_string">static_string</link></member>
<member><link linkend="beast.ref.streambuf">streambuf</link></member>
<member><link linkend="beast.ref.system_error">system_error</link></member> <member><link linkend="beast.ref.system_error">system_error</link></member>
</simplelist> </simplelist>
</entry> </entry>

View File

@ -294,13 +294,13 @@ all of the buffers representing the message are known ahead of time:
``` ```
void echo(beast::websocket::stream<boost::asio::ip::tcp::socket>& ws) void echo(beast::websocket::stream<boost::asio::ip::tcp::socket>& ws)
{ {
beast::streambuf sb; beast::multi_buffer b;
beast::websocket::opcode::value op; beast::websocket::opcode::value op;
ws.read(op, sb); ws.read(op, b);
ws.set_option(beast::websocket::message_type{op}); ws.set_option(beast::websocket::message_type{op});
ws.write(sb.data()); ws.write(b.data());
sb.consume(sb.size()); sb.consume(b.size());
} }
``` ```
@ -328,17 +328,17 @@ example reads and echoes a complete message using this interface:
``` ```
void echo(beast::websocket::stream<boost::asio::ip::tcp::socket>& ws) void echo(beast::websocket::stream<boost::asio::ip::tcp::socket>& ws)
{ {
beast::streambuf sb; beast::multi_buffer b;
beast::websocket::frame_info fi; beast::websocket::frame_info fi;
for(;;) for(;;)
{ {
ws.read_frame(fi, sb); ws.read_frame(fi, b);
if(fi.fin) if(fi.fin)
break; break;
} }
ws.set_option(beast::websocket::message_type{fi.op}); ws.set_option(beast::websocket::message_type{fi.op});
beast::consuming_buffers< beast::consuming_buffers<
beast::streambuf::const_buffers_type> cb{sb.data()}; beast::streambuf::const_buffers_type> cb{b.data()};
for(;;) for(;;)
{ {
using boost::asio::buffer_size; using boost::asio::buffer_size;

View File

@ -15,7 +15,7 @@
#include <beast/core/handler_helpers.hpp> #include <beast/core/handler_helpers.hpp>
#include <beast/core/handler_ptr.hpp> #include <beast/core/handler_ptr.hpp>
#include <beast/core/placeholders.hpp> #include <beast/core/placeholders.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <cstddef> #include <cstddef>
#include <cstdio> #include <cstdio>
@ -181,7 +181,7 @@ private:
class peer : public std::enable_shared_from_this<peer> class peer : public std::enable_shared_from_this<peer>
{ {
int id_; int id_;
streambuf sb_; multi_buffer sb_;
socket_type sock_; socket_type sock_;
http_async_server& server_; http_async_server& server_;
boost::asio::io_service::strand strand_; boost::asio::io_service::strand strand_;

View File

@ -7,7 +7,7 @@
#include "urls_large_data.hpp" #include "urls_large_data.hpp"
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/http.hpp> #include <beast/http.hpp>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
@ -46,8 +46,8 @@ int main(int, char const*[])
prepare(req); prepare(req);
write(sock, req); write(sock, req);
response<string_body> res; response<string_body> res;
streambuf sb; beast::multi_buffer b;
beast::http::read(sock, sb, res); beast::http::read(sock, b, res);
std::cout << res; std::cout << res;
} }
catch(beast::system_error const& ec) catch(beast::system_error const& ec)

View File

@ -5,6 +5,7 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// //
#include <beast/core.hpp>
#include <beast/http.hpp> #include <beast/http.hpp>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
@ -33,8 +34,8 @@ int main()
beast::http::write(sock, req); beast::http::write(sock, req);
// Receive and print HTTP response using beast // Receive and print HTTP response using beast
beast::streambuf sb; beast::multi_buffer b;
beast::http::response<beast::http::dynamic_body> resp; beast::http::response<beast::http::dynamic_body> res;
beast::http::read(sock, sb, resp); beast::http::read(sock, b, res);
std::cout << resp; std::cout << res;
} }

View File

@ -13,7 +13,7 @@
#include <beast/http.hpp> #include <beast/http.hpp>
#include <beast/core/placeholders.hpp> #include <beast/core/placeholders.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <cstdint> #include <cstdint>
#include <cstdio> #include <cstdio>
@ -150,12 +150,12 @@ private:
do_peer(int id, socket_type&& sock0) do_peer(int id, socket_type&& sock0)
{ {
socket_type sock(std::move(sock0)); socket_type sock(std::move(sock0));
streambuf sb; multi_buffer b;
error_code ec; error_code ec;
for(;;) for(;;)
{ {
req_type req; req_type req;
http::read(sock, sb, req, ec); http::read(sock, b, req, ec);
if(ec) if(ec)
break; break;
auto path = req.target().to_string(); auto path = req.target().to_string();

View File

@ -45,9 +45,9 @@ int main()
beast::http::write(stream, req); beast::http::write(stream, req);
// Receive and print HTTP response using Beast // Receive and print HTTP response using Beast
beast::streambuf sb; beast::multi_buffer b;
beast::http::response<beast::http::dynamic_body> resp; beast::http::response<beast::http::dynamic_body> resp;
beast::http::read(stream, sb, resp); beast::http::read(stream, b, resp);
std::cout << resp; std::cout << resp;
// Shut down SSL on the stream // Shut down SSL on the stream

View File

@ -41,9 +41,9 @@ int main()
ws.write(boost::asio::buffer("Hello, world!")); ws.write(boost::asio::buffer("Hello, world!"));
// Receive Secure WebSocket message, print and close using Beast // Receive Secure WebSocket message, print and close using Beast
beast::streambuf sb; beast::multi_buffer b;
beast::websocket::opcode op; beast::websocket::opcode op;
ws.read(op, sb); ws.read(op, b);
ws.close(beast::websocket::close_code::normal); ws.close(beast::websocket::close_code::normal);
std::cout << beast::buffers(sb.data()) << "\n"; std::cout << beast::buffers(b.data()) << "\n";
} }

View File

@ -9,7 +9,7 @@
#define WEBSOCKET_ASYNC_ECHO_SERVER_HPP #define WEBSOCKET_ASYNC_ECHO_SERVER_HPP
#include <beast/core/placeholders.hpp> #include <beast/core/placeholders.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/websocket/stream.hpp> #include <beast/websocket/stream.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/optional.hpp> #include <boost/optional.hpp>
@ -216,7 +216,7 @@ private:
beast::websocket::stream<socket_type> ws; beast::websocket::stream<socket_type> ws;
boost::asio::io_service::strand strand; boost::asio::io_service::strand strand;
beast::websocket::opcode op; beast::websocket::opcode op;
beast::streambuf db; beast::multi_buffer db;
std::size_t id; std::size_t id;
data(async_echo_server& server_, data(async_echo_server& server_,

View File

@ -5,7 +5,7 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// //
#include <beast/core/ostream.hpp> #include <beast/core.hpp>
#include <beast/websocket.hpp> #include <beast/websocket.hpp>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <iostream> #include <iostream>
@ -27,9 +27,9 @@ int main()
ws.write(boost::asio::buffer(std::string("Hello, world!"))); ws.write(boost::asio::buffer(std::string("Hello, world!")));
// Receive WebSocket message, print and close using beast // Receive WebSocket message, print and close using beast
beast::streambuf sb; beast::multi_buffer b;
beast::websocket::opcode op; beast::websocket::opcode op;
ws.read(op, sb); ws.read(op, b);
ws.close(beast::websocket::close_code::normal); ws.close(beast::websocket::close_code::normal);
std::cout << beast::buffers(sb.data()) << "\n"; std::cout << beast::buffers(b.data()) << "\n";
} }

View File

@ -9,7 +9,7 @@
#define WEBSOCKET_SYNC_ECHO_SERVER_HPP #define WEBSOCKET_SYNC_ECHO_SERVER_HPP
#include <beast/core/placeholders.hpp> #include <beast/core/placeholders.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/websocket.hpp> #include <beast/websocket.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/optional.hpp> #include <boost/optional.hpp>
@ -287,15 +287,15 @@ private:
for(;;) for(;;)
{ {
beast::websocket::opcode op; beast::websocket::opcode op;
beast::streambuf sb; beast::multi_buffer b;
ws.read(op, sb, ec); ws.read(op, b, ec);
if(ec) if(ec)
{ {
auto const s = ec.message(); auto const s = ec.message();
break; break;
} }
ws.set_option(beast::websocket::message_type{op}); ws.set_option(beast::websocket::message_type{op});
ws.write(sb.data(), ec); ws.write(b.data(), ec);
if(ec) if(ec)
break; break;
} }

View File

@ -23,12 +23,12 @@
#include <beast/core/handler_concepts.hpp> #include <beast/core/handler_concepts.hpp>
#include <beast/core/handler_helpers.hpp> #include <beast/core/handler_helpers.hpp>
#include <beast/core/handler_ptr.hpp> #include <beast/core/handler_ptr.hpp>
#include <beast/core/multi_buffer.hpp>
#include <beast/core/ostream.hpp> #include <beast/core/ostream.hpp>
#include <beast/core/placeholders.hpp> #include <beast/core/placeholders.hpp>
#include <beast/core/prepare_buffers.hpp> #include <beast/core/prepare_buffers.hpp>
#include <beast/core/static_streambuf.hpp> #include <beast/core/static_streambuf.hpp>
#include <beast/core/static_string.hpp> #include <beast/core/static_string.hpp>
#include <beast/core/stream_concepts.hpp> #include <beast/core/stream_concepts.hpp>
#include <beast/core/streambuf.hpp>
#endif #endif

View File

@ -13,7 +13,7 @@
#include <beast/core/buffer_concepts.hpp> #include <beast/core/buffer_concepts.hpp>
#include <beast/core/error.hpp> #include <beast/core/error.hpp>
#include <beast/core/stream_concepts.hpp> #include <beast/core/stream_concepts.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/core/detail/get_lowest_layer.hpp> #include <beast/core/detail/get_lowest_layer.hpp>
#include <boost/asio/buffer.hpp> #include <boost/asio/buffer.hpp>
#include <boost/asio/io_service.hpp> #include <boost/asio/io_service.hpp>

View File

@ -5,8 +5,8 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// //
#ifndef BEAST_IMPL_STREAMBUF_IPP #ifndef BEAST_IMPL_MULTI_BUFFER_IPP
#define BEAST_IMPL_STREAMBUF_IPP #define BEAST_IMPL_MULTI_BUFFER_IPP
#include <beast/core/detail/type_traits.hpp> #include <beast/core/detail/type_traits.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
@ -83,7 +83,7 @@ namespace beast {
*/ */
template<class Allocator> template<class Allocator>
class basic_streambuf<Allocator>::element class basic_multi_buffer<Allocator>::element
: public boost::intrusive::list_base_hook< : public boost::intrusive::list_base_hook<
boost::intrusive::link_mode< boost::intrusive::link_mode<
boost::intrusive::normal_link>> boost::intrusive::normal_link>>
@ -117,14 +117,14 @@ public:
}; };
template<class Allocator> template<class Allocator>
class basic_streambuf<Allocator>::const_buffers_type class basic_multi_buffer<Allocator>::const_buffers_type
{ {
basic_streambuf const* sb_; basic_multi_buffer const* sb_;
friend class basic_streambuf; friend class basic_multi_buffer;
explicit explicit
const_buffers_type(basic_streambuf const& sb); const_buffers_type(basic_multi_buffer const& b);
public: public:
// Why? // Why?
@ -144,14 +144,14 @@ public:
}; };
template<class Allocator> template<class Allocator>
class basic_streambuf<Allocator>::mutable_buffers_type class basic_multi_buffer<Allocator>::mutable_buffers_type
{ {
basic_streambuf const* sb_; basic_multi_buffer const* sb_;
friend class basic_streambuf; friend class basic_multi_buffer;
explicit explicit
mutable_buffers_type(basic_streambuf const& sb); mutable_buffers_type(basic_multi_buffer const& b);
public: public:
using value_type = mutable_buffer; using value_type = mutable_buffer;
@ -172,9 +172,9 @@ public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template<class Allocator> template<class Allocator>
class basic_streambuf<Allocator>::const_buffers_type::const_iterator class basic_multi_buffer<Allocator>::const_buffers_type::const_iterator
{ {
basic_streambuf const* sb_ = nullptr; basic_multi_buffer const* sb_ = nullptr;
typename list_type::const_iterator it_; typename list_type::const_iterator it_;
public: public:
@ -192,9 +192,9 @@ public:
const_iterator& operator=(const_iterator&& other) = default; const_iterator& operator=(const_iterator&& other) = default;
const_iterator& operator=(const_iterator const& other) = default; const_iterator& operator=(const_iterator const& other) = default;
const_iterator(basic_streambuf const& sb, const_iterator(basic_multi_buffer const& b,
typename list_type::const_iterator const& it) typename list_type::const_iterator const& it)
: sb_(&sb) : sb_(&b)
, it_(it) , it_(it)
{ {
} }
@ -256,15 +256,15 @@ public:
}; };
template<class Allocator> template<class Allocator>
basic_streambuf<Allocator>::const_buffers_type::const_buffers_type( basic_multi_buffer<Allocator>::const_buffers_type::const_buffers_type(
basic_streambuf const& sb) basic_multi_buffer const& b)
: sb_(&sb) : sb_(&b)
{ {
} }
template<class Allocator> template<class Allocator>
auto auto
basic_streambuf<Allocator>::const_buffers_type::begin() const -> basic_multi_buffer<Allocator>::const_buffers_type::begin() const ->
const_iterator const_iterator
{ {
return const_iterator{*sb_, sb_->list_.begin()}; return const_iterator{*sb_, sb_->list_.begin()};
@ -272,7 +272,7 @@ basic_streambuf<Allocator>::const_buffers_type::begin() const ->
template<class Allocator> template<class Allocator>
auto auto
basic_streambuf<Allocator>::const_buffers_type::end() const -> basic_multi_buffer<Allocator>::const_buffers_type::end() const ->
const_iterator const_iterator
{ {
return const_iterator{*sb_, sb_->out_ == return const_iterator{*sb_, sb_->out_ ==
@ -283,9 +283,9 @@ basic_streambuf<Allocator>::const_buffers_type::end() const ->
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template<class Allocator> template<class Allocator>
class basic_streambuf<Allocator>::mutable_buffers_type::const_iterator class basic_multi_buffer<Allocator>::mutable_buffers_type::const_iterator
{ {
basic_streambuf const* sb_ = nullptr; basic_multi_buffer const* sb_ = nullptr;
typename list_type::const_iterator it_; typename list_type::const_iterator it_;
public: public:
@ -303,9 +303,9 @@ public:
const_iterator& operator=(const_iterator&& other) = default; const_iterator& operator=(const_iterator&& other) = default;
const_iterator& operator=(const_iterator const& other) = default; const_iterator& operator=(const_iterator const& other) = default;
const_iterator(basic_streambuf const& sb, const_iterator(basic_multi_buffer const& b,
typename list_type::const_iterator const& it) typename list_type::const_iterator const& it)
: sb_(&sb) : sb_(&b)
, it_(it) , it_(it)
{ {
} }
@ -367,15 +367,15 @@ public:
}; };
template<class Allocator> template<class Allocator>
basic_streambuf<Allocator>::mutable_buffers_type::mutable_buffers_type( basic_multi_buffer<Allocator>::mutable_buffers_type::mutable_buffers_type(
basic_streambuf const& sb) basic_multi_buffer const& b)
: sb_(&sb) : sb_(&b)
{ {
} }
template<class Allocator> template<class Allocator>
auto auto
basic_streambuf<Allocator>::mutable_buffers_type::begin() const -> basic_multi_buffer<Allocator>::mutable_buffers_type::begin() const ->
const_iterator const_iterator
{ {
return const_iterator{*sb_, sb_->out_}; return const_iterator{*sb_, sb_->out_};
@ -383,7 +383,7 @@ basic_streambuf<Allocator>::mutable_buffers_type::begin() const ->
template<class Allocator> template<class Allocator>
auto auto
basic_streambuf<Allocator>::mutable_buffers_type::end() const -> basic_multi_buffer<Allocator>::mutable_buffers_type::end() const ->
const_iterator const_iterator
{ {
return const_iterator{*sb_, sb_->list_.end()}; return const_iterator{*sb_, sb_->list_.end()};
@ -392,14 +392,14 @@ basic_streambuf<Allocator>::mutable_buffers_type::end() const ->
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template<class Allocator> template<class Allocator>
basic_streambuf<Allocator>::~basic_streambuf() basic_multi_buffer<Allocator>::~basic_multi_buffer()
{ {
delete_list(); delete_list();
} }
template<class Allocator> template<class Allocator>
basic_streambuf<Allocator>:: basic_multi_buffer<Allocator>::
basic_streambuf(basic_streambuf&& other) basic_multi_buffer(basic_multi_buffer&& other)
: detail::empty_base_optimization<allocator_type>( : detail::empty_base_optimization<allocator_type>(
std::move(other.member())) std::move(other.member()))
, alloc_size_(other.alloc_size_) , alloc_size_(other.alloc_size_)
@ -420,10 +420,10 @@ basic_streambuf(basic_streambuf&& other)
} }
template<class Allocator> template<class Allocator>
basic_streambuf<Allocator>:: basic_multi_buffer<Allocator>::
basic_streambuf(basic_streambuf&& other, basic_multi_buffer(basic_multi_buffer&& other,
allocator_type const& alloc) allocator_type const& alloc)
: basic_streambuf(other.alloc_size_, alloc) : basic_multi_buffer(other.alloc_size_, alloc)
{ {
using boost::asio::buffer_copy; using boost::asio::buffer_copy;
if(this->member() != other.member()) if(this->member() != other.member())
@ -434,8 +434,8 @@ basic_streambuf(basic_streambuf&& other,
template<class Allocator> template<class Allocator>
auto auto
basic_streambuf<Allocator>::operator=( basic_multi_buffer<Allocator>::operator=(
basic_streambuf&& other) -> basic_streambuf& basic_multi_buffer&& other) -> basic_multi_buffer&
{ {
if(this == &other) if(this == &other)
return *this; return *this;
@ -448,28 +448,28 @@ basic_streambuf<Allocator>::operator=(
} }
template<class Allocator> template<class Allocator>
basic_streambuf<Allocator>:: basic_multi_buffer<Allocator>::
basic_streambuf(basic_streambuf const& other) basic_multi_buffer(basic_multi_buffer const& other)
: basic_streambuf(other.alloc_size_, : basic_multi_buffer(other.alloc_size_,
alloc_traits::select_on_container_copy_construction(other.member())) alloc_traits::select_on_container_copy_construction(other.member()))
{ {
commit(boost::asio::buffer_copy(prepare(other.size()), other.data())); commit(boost::asio::buffer_copy(prepare(other.size()), other.data()));
} }
template<class Allocator> template<class Allocator>
basic_streambuf<Allocator>:: basic_multi_buffer<Allocator>::
basic_streambuf(basic_streambuf const& other, basic_multi_buffer(basic_multi_buffer const& other,
allocator_type const& alloc) allocator_type const& alloc)
: basic_streambuf(other.alloc_size_, alloc) : basic_multi_buffer(other.alloc_size_, alloc)
{ {
commit(boost::asio::buffer_copy(prepare(other.size()), other.data())); commit(boost::asio::buffer_copy(prepare(other.size()), other.data()));
} }
template<class Allocator> template<class Allocator>
auto auto
basic_streambuf<Allocator>::operator=( basic_multi_buffer<Allocator>::operator=(
basic_streambuf const& other) -> basic_multi_buffer const& other) ->
basic_streambuf& basic_multi_buffer&
{ {
if(this == &other) if(this == &other)
return *this; return *this;
@ -483,9 +483,9 @@ basic_streambuf<Allocator>::operator=(
template<class Allocator> template<class Allocator>
template<class OtherAlloc> template<class OtherAlloc>
basic_streambuf<Allocator>::basic_streambuf( basic_multi_buffer<Allocator>::basic_multi_buffer(
basic_streambuf<OtherAlloc> const& other) basic_multi_buffer<OtherAlloc> const& other)
: basic_streambuf(other.alloc_size_) : basic_multi_buffer(other.alloc_size_)
{ {
using boost::asio::buffer_copy; using boost::asio::buffer_copy;
commit(buffer_copy(prepare(other.size()), other.data())); commit(buffer_copy(prepare(other.size()), other.data()));
@ -493,10 +493,10 @@ basic_streambuf<Allocator>::basic_streambuf(
template<class Allocator> template<class Allocator>
template<class OtherAlloc> template<class OtherAlloc>
basic_streambuf<Allocator>::basic_streambuf( basic_multi_buffer<Allocator>::basic_multi_buffer(
basic_streambuf<OtherAlloc> const& other, basic_multi_buffer<OtherAlloc> const& other,
allocator_type const& alloc) allocator_type const& alloc)
: basic_streambuf(other.alloc_size_, alloc) : basic_multi_buffer(other.alloc_size_, alloc)
{ {
using boost::asio::buffer_copy; using boost::asio::buffer_copy;
commit(buffer_copy(prepare(other.size()), other.data())); commit(buffer_copy(prepare(other.size()), other.data()));
@ -505,9 +505,9 @@ basic_streambuf<Allocator>::basic_streambuf(
template<class Allocator> template<class Allocator>
template<class OtherAlloc> template<class OtherAlloc>
auto auto
basic_streambuf<Allocator>::operator=( basic_multi_buffer<Allocator>::operator=(
basic_streambuf<OtherAlloc> const& other) -> basic_multi_buffer<OtherAlloc> const& other) ->
basic_streambuf& basic_multi_buffer&
{ {
using boost::asio::buffer_copy; using boost::asio::buffer_copy;
clear(); clear();
@ -516,7 +516,7 @@ basic_streambuf<Allocator>::operator=(
} }
template<class Allocator> template<class Allocator>
basic_streambuf<Allocator>::basic_streambuf( basic_multi_buffer<Allocator>::basic_multi_buffer(
std::size_t alloc_size, Allocator const& alloc) std::size_t alloc_size, Allocator const& alloc)
: detail::empty_base_optimization<allocator_type>(alloc) : detail::empty_base_optimization<allocator_type>(alloc)
, out_(list_.end()) , out_(list_.end())
@ -529,7 +529,7 @@ basic_streambuf<Allocator>::basic_streambuf(
template<class Allocator> template<class Allocator>
std::size_t std::size_t
basic_streambuf<Allocator>::capacity() const basic_multi_buffer<Allocator>::capacity() const
{ {
auto pos = out_; auto pos = out_;
if(pos == list_.end()) if(pos == list_.end())
@ -542,7 +542,7 @@ basic_streambuf<Allocator>::capacity() const
template<class Allocator> template<class Allocator>
auto auto
basic_streambuf<Allocator>:: basic_multi_buffer<Allocator>::
data() const -> data() const ->
const_buffers_type const_buffers_type
{ {
@ -551,7 +551,7 @@ data() const ->
template<class Allocator> template<class Allocator>
auto auto
basic_streambuf<Allocator>::prepare(size_type n) -> basic_multi_buffer<Allocator>::prepare(size_type n) ->
mutable_buffers_type mutable_buffers_type
{ {
list_type reuse; list_type reuse;
@ -630,7 +630,7 @@ basic_streambuf<Allocator>::prepare(size_type n) ->
template<class Allocator> template<class Allocator>
void void
basic_streambuf<Allocator>::commit(size_type n) basic_multi_buffer<Allocator>::commit(size_type n)
{ {
if(list_.empty()) if(list_.empty())
return; return;
@ -670,7 +670,7 @@ basic_streambuf<Allocator>::commit(size_type n)
template<class Allocator> template<class Allocator>
void void
basic_streambuf<Allocator>::consume(size_type n) basic_multi_buffer<Allocator>::consume(size_type n)
{ {
if(list_.empty()) if(list_.empty())
return; return;
@ -731,7 +731,7 @@ basic_streambuf<Allocator>::consume(size_type n)
template<class Allocator> template<class Allocator>
void void
basic_streambuf<Allocator>:: basic_multi_buffer<Allocator>::
clear() clear()
{ {
delete_list(); delete_list();
@ -745,8 +745,8 @@ clear()
template<class Allocator> template<class Allocator>
void void
basic_streambuf<Allocator>:: basic_multi_buffer<Allocator>::
move_assign(basic_streambuf& other, std::false_type) move_assign(basic_multi_buffer& other, std::false_type)
{ {
using boost::asio::buffer_copy; using boost::asio::buffer_copy;
if(this->member() != other.member()) if(this->member() != other.member())
@ -760,8 +760,8 @@ move_assign(basic_streambuf& other, std::false_type)
template<class Allocator> template<class Allocator>
void void
basic_streambuf<Allocator>:: basic_multi_buffer<Allocator>::
move_assign(basic_streambuf& other, std::true_type) move_assign(basic_multi_buffer& other, std::true_type)
{ {
this->member() = std::move(other.member()); this->member() = std::move(other.member());
auto const at_end = auto const at_end =
@ -783,23 +783,23 @@ move_assign(basic_streambuf& other, std::true_type)
template<class Allocator> template<class Allocator>
void void
basic_streambuf<Allocator>:: basic_multi_buffer<Allocator>::
copy_assign(basic_streambuf const& other, std::false_type) copy_assign(basic_multi_buffer const& other, std::false_type)
{ {
beast::detail::ignore_unused(other); beast::detail::ignore_unused(other);
} }
template<class Allocator> template<class Allocator>
void void
basic_streambuf<Allocator>:: basic_multi_buffer<Allocator>::
copy_assign(basic_streambuf const& other, std::true_type) copy_assign(basic_multi_buffer const& other, std::true_type)
{ {
this->member() = other.member(); this->member() = other.member();
} }
template<class Allocator> template<class Allocator>
void void
basic_streambuf<Allocator>::delete_list() basic_multi_buffer<Allocator>::delete_list()
{ {
for(auto iter = list_.begin(); iter != list_.end();) for(auto iter = list_.begin(); iter != list_.end();)
{ {
@ -813,7 +813,7 @@ basic_streambuf<Allocator>::delete_list()
template<class Allocator> template<class Allocator>
void void
basic_streambuf<Allocator>::debug_check() const basic_multi_buffer<Allocator>::debug_check() const
{ {
#ifndef NDEBUG #ifndef NDEBUG
using boost::asio::buffer_size; using boost::asio::buffer_size;
@ -853,19 +853,19 @@ basic_streambuf<Allocator>::debug_check() const
template<class Allocator> template<class Allocator>
std::size_t std::size_t
read_size_helper(basic_streambuf< read_size_helper(basic_multi_buffer<
Allocator> const& streambuf, std::size_t max_size) Allocator> const& multi_buffer, std::size_t max_size)
{ {
BOOST_ASSERT(max_size >= 1); BOOST_ASSERT(max_size >= 1);
// If we already have an allocated // If we already have an allocated
// buffer, try to fill that up first // buffer, try to fill that up first
auto const avail = streambuf.capacity() - streambuf.size(); auto const avail = multi_buffer.capacity() - multi_buffer.size();
if (avail > 0) if (avail > 0)
return (std::min)(avail, max_size); return (std::min)(avail, max_size);
// Try to have just one new block allocated // Try to have just one new block allocated
constexpr std::size_t low = 512; constexpr std::size_t low = 512;
if (streambuf.alloc_size_ > low) if (multi_buffer.alloc_size_ > low)
return (std::min)(max_size, streambuf.alloc_size_); return (std::min)(max_size, multi_buffer.alloc_size_);
// ...but enforce a 512 byte minimum. // ...but enforce a 512 byte minimum.
return (std::min)(max_size, low); return (std::min)(max_size, low);
} }

View File

@ -297,7 +297,7 @@ static_streambuf::prepare(std::size_t n) ->
{ {
if(n > static_cast<std::size_t>(end_ - out_)) if(n > static_cast<std::size_t>(end_ - out_))
throw detail::make_exception<std::length_error>( throw detail::make_exception<std::length_error>(
"no space in streambuf", __FILE__, __LINE__); "no space in static_buffer", __FILE__, __LINE__);
last_ = out_ + n; last_ = out_ + n;
return mutable_buffers_type{out_, n}; return mutable_buffers_type{out_, n};
} }

View File

@ -5,8 +5,8 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// //
#ifndef BEAST_STREAMBUF_HPP #ifndef BEAST_MULTI_BUFFER_HPP
#define BEAST_STREAMBUF_HPP #define BEAST_MULTI_BUFFER_HPP
#include <beast/config.hpp> #include <beast/config.hpp>
#include <beast/core/detail/empty_base_optimization.hpp> #include <beast/core/detail/empty_base_optimization.hpp>
@ -31,7 +31,7 @@ namespace beast {
@tparam Allocator The allocator to use for managing memory. @tparam Allocator The allocator to use for managing memory.
*/ */
template<class Allocator> template<class Allocator>
class basic_streambuf class basic_multi_buffer
#if ! BEAST_DOXYGEN #if ! BEAST_DOXYGEN
: private detail::empty_base_optimization< : private detail::empty_base_optimization<
typename std::allocator_traits<Allocator>:: typename std::allocator_traits<Allocator>::
@ -96,7 +96,7 @@ public:
#endif #endif
/// Destructor. /// Destructor.
~basic_streambuf(); ~basic_multi_buffer();
/** Move constructor. /** Move constructor.
@ -107,7 +107,7 @@ public:
an empty input and output sequence, with no internal an empty input and output sequence, with no internal
buffers allocated. buffers allocated.
*/ */
basic_streambuf(basic_streambuf&&); basic_multi_buffer(basic_multi_buffer&&);
/** Move constructor. /** Move constructor.
@ -121,7 +121,7 @@ public:
@param alloc The allocator to associate with the @param alloc The allocator to associate with the
stream buffer. stream buffer.
*/ */
basic_streambuf(basic_streambuf&&, basic_multi_buffer(basic_multi_buffer&&,
allocator_type const& alloc); allocator_type const& alloc);
/** Move assignment. /** Move assignment.
@ -133,15 +133,15 @@ public:
an empty input and output sequence, with no internal an empty input and output sequence, with no internal
buffers allocated. buffers allocated.
*/ */
basic_streambuf& basic_multi_buffer&
operator=(basic_streambuf&&); operator=(basic_multi_buffer&&);
/** Copy constructor. /** Copy constructor.
This object will have a copy of the other stream This object will have a copy of the other stream
buffer's input sequence, and an empty output sequence. buffer's input sequence, and an empty output sequence.
*/ */
basic_streambuf(basic_streambuf const&); basic_multi_buffer(basic_multi_buffer const&);
/** Copy constructor. /** Copy constructor.
@ -151,7 +151,7 @@ public:
@param alloc The allocator to associate with the @param alloc The allocator to associate with the
stream buffer. stream buffer.
*/ */
basic_streambuf(basic_streambuf const&, basic_multi_buffer(basic_multi_buffer const&,
allocator_type const& alloc); allocator_type const& alloc);
/** Copy assignment. /** Copy assignment.
@ -159,7 +159,7 @@ public:
This object will have a copy of the other stream This object will have a copy of the other stream
buffer's input sequence, and an empty output sequence. buffer's input sequence, and an empty output sequence.
*/ */
basic_streambuf& operator=(basic_streambuf const&); basic_multi_buffer& operator=(basic_multi_buffer const&);
/** Copy constructor. /** Copy constructor.
@ -167,7 +167,7 @@ public:
buffer's input sequence, and an empty output sequence. buffer's input sequence, and an empty output sequence.
*/ */
template<class OtherAlloc> template<class OtherAlloc>
basic_streambuf(basic_streambuf<OtherAlloc> const&); basic_multi_buffer(basic_multi_buffer<OtherAlloc> const&);
/** Copy constructor. /** Copy constructor.
@ -178,7 +178,7 @@ public:
stream buffer. stream buffer.
*/ */
template<class OtherAlloc> template<class OtherAlloc>
basic_streambuf(basic_streambuf<OtherAlloc> const&, basic_multi_buffer(basic_multi_buffer<OtherAlloc> const&,
allocator_type const& alloc); allocator_type const& alloc);
/** Copy assignment. /** Copy assignment.
@ -187,7 +187,7 @@ public:
buffer's input sequence, and an empty output sequence. buffer's input sequence, and an empty output sequence.
*/ */
template<class OtherAlloc> template<class OtherAlloc>
basic_streambuf& operator=(basic_streambuf<OtherAlloc> const&); basic_multi_buffer& operator=(basic_multi_buffer<OtherAlloc> const&);
/** Construct a stream buffer. /** Construct a stream buffer.
@ -200,7 +200,7 @@ public:
unspecified, a default constructed allocator will be used. unspecified, a default constructed allocator will be used.
*/ */
explicit explicit
basic_streambuf(std::size_t alloc_size = 1024, basic_multi_buffer(std::size_t alloc_size = 1024,
Allocator const& alloc = allocator_type{}); Allocator const& alloc = allocator_type{});
/// Returns a copy of the associated allocator. /// Returns a copy of the associated allocator.
@ -289,24 +289,24 @@ public:
template<class OtherAllocator> template<class OtherAllocator>
friend friend
std::size_t std::size_t
read_size_helper(basic_streambuf< read_size_helper(basic_multi_buffer<
OtherAllocator> const& streambuf, std::size_t max_size); OtherAllocator> const& multi_buffer, std::size_t max_size);
private: private:
void void
clear(); clear();
void void
move_assign(basic_streambuf& other, std::false_type); move_assign(basic_multi_buffer& other, std::false_type);
void void
move_assign(basic_streambuf& other, std::true_type); move_assign(basic_multi_buffer& other, std::true_type);
void void
copy_assign(basic_streambuf const& other, std::false_type); copy_assign(basic_multi_buffer const& other, std::false_type);
void void
copy_assign(basic_streambuf const& other, std::true_type); copy_assign(basic_multi_buffer const& other, std::true_type);
void void
delete_list(); delete_list();
@ -324,10 +324,10 @@ private:
@note Meets the requirements of @b `DynamicBuffer`. @note Meets the requirements of @b `DynamicBuffer`.
*/ */
using streambuf = basic_streambuf<std::allocator<char>>; using multi_buffer = basic_multi_buffer<std::allocator<char>>;
} // beast } // beast
#include <beast/core/impl/streambuf.ipp> #include <beast/core/impl/multi_buffer.ipp>
#endif #endif

View File

@ -28,9 +28,9 @@ namespace beast {
@par Example @par Example
@code @code
streambuf sb; multi_buffer b;
... ...
std::cout << buffers(sb.data()) << std::endl; std::cout << buffers(b.data()) << std::endl;
@endcode @endcode
@param b An object meeting the requirements of @b ConstBufferSequence @param b An object meeting the requirements of @b ConstBufferSequence

View File

@ -10,7 +10,7 @@
#include <beast/config.hpp> #include <beast/config.hpp>
#include <beast/core/error.hpp> #include <beast/core/error.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/http/message.hpp> #include <beast/http/message.hpp>
namespace beast { namespace beast {
@ -111,11 +111,11 @@ private:
}; };
}; };
/** A dynamic message body represented by a @ref streambuf /** A dynamic message body represented by a @ref multi_buffer
Meets the requirements of @b `Body`. Meets the requirements of @b `Body`.
*/ */
using dynamic_body = basic_dynamic_body<streambuf>; using dynamic_body = basic_dynamic_body<multi_buffer>;
} // http } // http
} // beast } // beast

View File

@ -17,7 +17,7 @@
#include <beast/core/handler_helpers.hpp> #include <beast/core/handler_helpers.hpp>
#include <beast/core/handler_ptr.hpp> #include <beast/core/handler_ptr.hpp>
#include <beast/core/stream_concepts.hpp> #include <beast/core/stream_concepts.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/core/detail/sync_ostream.hpp> #include <beast/core/detail/sync_ostream.hpp>
#include <boost/asio/write.hpp> #include <boost/asio/write.hpp>
#include <condition_variable> #include <condition_variable>
@ -89,15 +89,15 @@ class write_streambuf_op
{ {
bool cont; bool cont;
Stream& s; Stream& s;
streambuf sb; multi_buffer b;
int state = 0; int state = 0;
data(Handler& handler, Stream& s_, data(Handler& handler, Stream& s_,
streambuf&& sb_) multi_buffer&& sb_)
: cont(beast_asio_helpers:: : cont(beast_asio_helpers::
is_continuation(handler)) is_continuation(handler))
, s(s_) , s(s_)
, sb(std::move(sb_)) , b(std::move(sb_))
{ {
} }
}; };
@ -167,7 +167,7 @@ operator()(error_code ec, std::size_t, bool again)
{ {
d.state = 99; d.state = 99;
boost::asio::async_write(d.s, boost::asio::async_write(d.s,
d.sb.data(), std::move(*this)); d.b.data(), std::move(*this));
return; return;
} }
} }
@ -200,14 +200,14 @@ write(SyncWriteStream& stream,
{ {
static_assert(is_SyncWriteStream<SyncWriteStream>::value, static_assert(is_SyncWriteStream<SyncWriteStream>::value,
"SyncWriteStream requirements not met"); "SyncWriteStream requirements not met");
streambuf sb; multi_buffer b;
{ {
auto os = ostream(sb); auto os = ostream(b);
detail::write_start_line(os, msg); detail::write_start_line(os, msg);
detail::write_fields(os, msg.fields); detail::write_fields(os, msg.fields);
os << "\r\n"; os << "\r\n";
} }
boost::asio::write(stream, sb.data(), ec); boost::asio::write(stream, b.data(), ec);
} }
template<class AsyncWriteStream, template<class AsyncWriteStream,
@ -223,16 +223,16 @@ async_write(AsyncWriteStream& stream,
"AsyncWriteStream requirements not met"); "AsyncWriteStream requirements not met");
beast::async_completion<WriteHandler, beast::async_completion<WriteHandler,
void(error_code)> completion{handler}; void(error_code)> completion{handler};
streambuf sb; multi_buffer b;
{ {
auto os = ostream(sb); auto os = ostream(b);
detail::write_start_line(os, msg); detail::write_start_line(os, msg);
detail::write_fields(os, msg.fields); detail::write_fields(os, msg.fields);
os << "\r\n"; os << "\r\n";
} }
detail::write_streambuf_op<AsyncWriteStream, detail::write_streambuf_op<AsyncWriteStream,
decltype(completion.handler)>{ decltype(completion.handler)>{
completion.handler, stream, std::move(sb)}; completion.handler, stream, std::move(b)};
return completion.result.get(); return completion.result.get();
} }
@ -245,7 +245,7 @@ struct write_preparation
{ {
message<isRequest, Body, Fields> const& msg; message<isRequest, Body, Fields> const& msg;
typename Body::writer w; typename Body::writer w;
streambuf sb; multi_buffer b;
bool chunked; bool chunked;
bool close; bool close;
@ -270,7 +270,7 @@ struct write_preparation
if(ec) if(ec)
return; return;
auto os = ostream(sb); auto os = ostream(b);
write_start_line(os, msg); write_start_line(os, msg);
write_fields(os, msg.fields); write_fields(os, msg.fields);
os << "\r\n"; os << "\r\n";
@ -318,12 +318,12 @@ class write_op
// write header and body // write header and body
if(d.wp.chunked) if(d.wp.chunked)
boost::asio::async_write(d.s, boost::asio::async_write(d.s,
buffer_cat(d.wp.sb.data(), buffer_cat(d.wp.b.data(),
chunk_encode(false, buffers)), chunk_encode(false, buffers)),
std::move(self_)); std::move(self_));
else else
boost::asio::async_write(d.s, boost::asio::async_write(d.s,
buffer_cat(d.wp.sb.data(), buffer_cat(d.wp.b.data(),
buffers), std::move(self_)); buffers), std::move(self_));
} }
}; };
@ -452,7 +452,7 @@ operator()(error_code ec, std::size_t, bool again)
// sent header and body // sent header and body
case 2: case 2:
d.wp.sb.consume(d.wp.sb.size()); d.wp.b.consume(d.wp.b.size());
d.state = 3; d.state = 3;
break; break;
@ -508,8 +508,8 @@ class writef0_lambda
public: public:
writef0_lambda(SyncWriteStream& stream, writef0_lambda(SyncWriteStream& stream,
DynamicBuffer const& sb, bool chunked, error_code& ec) DynamicBuffer const& b, bool chunked, error_code& ec)
: sb_(sb) : sb_(b)
, stream_(stream) , stream_(stream)
, chunked_(chunked) , chunked_(chunked)
, ec_(ec) , ec_(ec)
@ -602,11 +602,11 @@ write(SyncWriteStream& stream,
return; return;
auto result = wp.w.write( auto result = wp.w.write(
ec, detail::writef0_lambda< ec, detail::writef0_lambda<
SyncWriteStream, decltype(wp.sb)>{ SyncWriteStream, decltype(wp.b)>{
stream, wp.sb, wp.chunked, ec}); stream, wp.b, wp.chunked, ec});
if(ec) if(ec)
return; return;
wp.sb.consume(wp.sb.size()); wp.b.consume(wp.b.size());
if(! result) if(! result)
{ {
detail::writef_lambda<SyncWriteStream> wf{ detail::writef_lambda<SyncWriteStream> wf{

View File

@ -98,7 +98,7 @@ class stream : public detail::stream_base
{ {
friend class stream_test; friend class stream_test;
dynabuf_readstream<NextLayer, streambuf> stream_; dynabuf_readstream<NextLayer, multi_buffer> stream_;
public: public:
/// The type of the next layer. /// The type of the next layer.

View File

@ -29,6 +29,7 @@ unit-test core-tests :
core/handler_alloc.cpp core/handler_alloc.cpp
core/handler_concepts.cpp core/handler_concepts.cpp
core/handler_ptr.cpp core/handler_ptr.cpp
core/multi_buffer.cpp
core/ostream.cpp core/ostream.cpp
core/placeholders.cpp core/placeholders.cpp
core/prepare_buffer.cpp core/prepare_buffer.cpp
@ -36,7 +37,6 @@ unit-test core-tests :
core/static_streambuf.cpp core/static_streambuf.cpp
core/static_string.cpp core/static_string.cpp
core/stream_concepts.cpp core/stream_concepts.cpp
core/streambuf.cpp
core/base64.cpp core/base64.cpp
core/empty_base_optimization.cpp core/empty_base_optimization.cpp
core/get_lowest_layer.cpp core/get_lowest_layer.cpp

View File

@ -22,6 +22,7 @@ add_executable (core-tests
handler_alloc.cpp handler_alloc.cpp
handler_concepts.cpp handler_concepts.cpp
handler_ptr.cpp handler_ptr.cpp
multi_buffer.cpp
ostream.cpp ostream.cpp
placeholders.cpp placeholders.cpp
prepare_buffer.cpp prepare_buffer.cpp
@ -29,7 +30,6 @@ add_executable (core-tests
static_streambuf.cpp static_streambuf.cpp
static_string.cpp static_string.cpp
stream_concepts.cpp stream_concepts.cpp
streambuf.cpp
base64.cpp base64.cpp
empty_base_optimization.cpp empty_base_optimization.cpp
get_lowest_layer.cpp get_lowest_layer.cpp

View File

@ -9,7 +9,7 @@
#include <beast/core/buffers_adapter.hpp> #include <beast/core/buffers_adapter.hpp>
#include <beast/core/ostream.hpp> #include <beast/core/ostream.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/unit_test/suite.hpp> #include <beast/unit_test/suite.hpp>
#include <boost/asio/buffer.hpp> #include <boost/asio/buffer.hpp>
#include <boost/asio/streambuf.hpp> #include <boost/asio/streambuf.hpp>
@ -151,19 +151,19 @@ public:
using boost::asio::buffer_size; using boost::asio::buffer_size;
{ {
using sb_type = boost::asio::streambuf; using sb_type = boost::asio::streambuf;
sb_type sb; sb_type b;
buffers_adapter< buffers_adapter<
sb_type::mutable_buffers_type> ba(sb.prepare(3)); sb_type::mutable_buffers_type> ba(b.prepare(3));
BEAST_EXPECT(buffer_size(ba.prepare(3)) == 3); BEAST_EXPECT(buffer_size(ba.prepare(3)) == 3);
ba.commit(2); ba.commit(2);
BEAST_EXPECT(buffer_size(ba.data()) == 2); BEAST_EXPECT(buffer_size(ba.data()) == 2);
} }
{ {
using sb_type = beast::streambuf; using sb_type = beast::multi_buffer;
sb_type sb(2); sb_type b(2);
sb.prepare(3); b.prepare(3);
buffers_adapter< buffers_adapter<
sb_type::mutable_buffers_type> ba(sb.prepare(8)); sb_type::mutable_buffers_type> ba(b.prepare(8));
BEAST_EXPECT(buffer_size(ba.prepare(8)) == 8); BEAST_EXPECT(buffer_size(ba.prepare(8)) == 8);
ba.commit(2); ba.commit(2);
BEAST_EXPECT(buffer_size(ba.data()) == 2); BEAST_EXPECT(buffer_size(ba.data()) == 2);

View File

@ -8,7 +8,7 @@
// Test that header file is self-contained. // Test that header file is self-contained.
#include <beast/core/dynabuf_readstream.hpp> #include <beast/core/dynabuf_readstream.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/test/fail_stream.hpp> #include <beast/test/fail_stream.hpp>
#include <beast/test/string_istream.hpp> #include <beast/test/string_istream.hpp>
#include <beast/test/yield_to.hpp> #include <beast/test/yield_to.hpp>
@ -29,16 +29,16 @@ public:
using socket_type = boost::asio::ip::tcp::socket; using socket_type = boost::asio::ip::tcp::socket;
boost::asio::io_service ios; boost::asio::io_service ios;
{ {
dynabuf_readstream<socket_type, streambuf> srs(ios); dynabuf_readstream<socket_type, multi_buffer> srs(ios);
dynabuf_readstream<socket_type, streambuf> srs2(std::move(srs)); dynabuf_readstream<socket_type, multi_buffer> srs2(std::move(srs));
srs = std::move(srs2); srs = std::move(srs2);
BEAST_EXPECT(&srs.get_io_service() == &ios); BEAST_EXPECT(&srs.get_io_service() == &ios);
BEAST_EXPECT(&srs.get_io_service() == &srs2.get_io_service()); BEAST_EXPECT(&srs.get_io_service() == &srs2.get_io_service());
} }
{ {
socket_type sock(ios); socket_type sock(ios);
dynabuf_readstream<socket_type&, streambuf> srs(sock); dynabuf_readstream<socket_type&, multi_buffer> srs(sock);
dynabuf_readstream<socket_type&, streambuf> srs2(std::move(srs)); dynabuf_readstream<socket_type&, multi_buffer> srs2(std::move(srs));
} }
} }
@ -56,7 +56,7 @@ public:
test::fail_stream< test::fail_stream<
test::string_istream> fs(n, ios_, ", world!"); test::string_istream> fs(n, ios_, ", world!");
dynabuf_readstream< dynabuf_readstream<
decltype(fs)&, streambuf> srs(fs); decltype(fs)&, multi_buffer> srs(fs);
srs.buffer().commit(buffer_copy( srs.buffer().commit(buffer_copy(
srs.buffer().prepare(5), buffer("Hello", 5))); srs.buffer().prepare(5), buffer("Hello", 5)));
error_code ec; error_code ec;
@ -74,7 +74,7 @@ public:
test::fail_stream< test::fail_stream<
test::string_istream> fs(n, ios_, ", world!"); test::string_istream> fs(n, ios_, ", world!");
dynabuf_readstream< dynabuf_readstream<
decltype(fs)&, streambuf> srs(fs); decltype(fs)&, multi_buffer> srs(fs);
srs.capacity(3); srs.capacity(3);
srs.buffer().commit(buffer_copy( srs.buffer().commit(buffer_copy(
srs.buffer().prepare(5), buffer("Hello", 5))); srs.buffer().prepare(5), buffer("Hello", 5)));
@ -93,7 +93,7 @@ public:
test::fail_stream< test::fail_stream<
test::string_istream> fs(n, ios_, ", world!"); test::string_istream> fs(n, ios_, ", world!");
dynabuf_readstream< dynabuf_readstream<
decltype(fs)&, streambuf> srs(fs); decltype(fs)&, multi_buffer> srs(fs);
srs.buffer().commit(buffer_copy( srs.buffer().commit(buffer_copy(
srs.buffer().prepare(5), buffer("Hello", 5))); srs.buffer().prepare(5), buffer("Hello", 5)));
error_code ec; error_code ec;
@ -112,7 +112,7 @@ public:
test::fail_stream< test::fail_stream<
test::string_istream> fs(n, ios_, ", world!"); test::string_istream> fs(n, ios_, ", world!");
dynabuf_readstream< dynabuf_readstream<
decltype(fs)&, streambuf> srs(fs); decltype(fs)&, multi_buffer> srs(fs);
srs.capacity(3); srs.capacity(3);
srs.buffer().commit(buffer_copy( srs.buffer().commit(buffer_copy(
srs.buffer().prepare(5), buffer("Hello", 5))); srs.buffer().prepare(5), buffer("Hello", 5)));

361
test/core/multi_buffer.cpp Normal file
View File

@ -0,0 +1,361 @@
//
// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Test that header file is self-contained.
#include <beast/core/multi_buffer.hpp>
#include "buffer_test.hpp"
#include <beast/core/buffer_concepts.hpp>
#include <beast/core/ostream.hpp>
#include <beast/test/test_allocator.hpp>
#include <beast/unit_test/suite.hpp>
#include <boost/asio/buffer.hpp>
#include <algorithm>
#include <atomic>
#include <memory>
#include <string>
namespace beast {
static_assert(is_DynamicBuffer<multi_buffer>::value, "");
class multi_buffer_test : public beast::unit_test::suite
{
public:
template<class ConstBufferSequence>
static
std::string
to_string(ConstBufferSequence const& bs)
{
return boost::lexical_cast<
std::string>(buffers(bs));
}
template<class Alloc1, class Alloc2>
static
bool
eq(basic_multi_buffer<Alloc1> const& sb1,
basic_multi_buffer<Alloc2> const& sb2)
{
return to_string(sb1.data()) == to_string(sb2.data());
}
template<class ConstBufferSequence>
void
expect_size(std::size_t n, ConstBufferSequence const& buffers)
{
BEAST_EXPECT(test::size_pre(buffers) == n);
BEAST_EXPECT(test::size_post(buffers) == n);
BEAST_EXPECT(test::size_rev_pre(buffers) == n);
BEAST_EXPECT(test::size_rev_post(buffers) == n);
}
template<class U, class V>
static
void
self_assign(U& u, V&& v)
{
u = std::forward<V>(v);
}
void testSpecialMembers()
{
using boost::asio::buffer;
std::string const s = "Hello, world";
BEAST_EXPECT(s.size() == 12);
for(std::size_t i = 1; i < 12; ++i) {
for(std::size_t x = 1; x < 4; ++x) {
for(std::size_t y = 1; y < 4; ++y) {
std::size_t z = s.size() - (x + y);
{
multi_buffer b(i);
b.commit(buffer_copy(b.prepare(x), buffer(s.data(), x)));
b.commit(buffer_copy(b.prepare(y), buffer(s.data()+x, y)));
b.commit(buffer_copy(b.prepare(z), buffer(s.data()+x+y, z)));
BEAST_EXPECT(to_string(b.data()) == s);
{
multi_buffer sb2(b);
BEAST_EXPECT(eq(b, sb2));
}
{
multi_buffer sb2;
sb2 = b;
BEAST_EXPECT(eq(b, sb2));
}
{
multi_buffer sb2(std::move(b));
BEAST_EXPECT(to_string(sb2.data()) == s);
expect_size(0, b.data());
b = std::move(sb2);
BEAST_EXPECT(to_string(b.data()) == s);
expect_size(0, sb2.data());
}
self_assign(b, b);
BEAST_EXPECT(to_string(b.data()) == s);
self_assign(b, std::move(b));
BEAST_EXPECT(to_string(b.data()) == s);
}
}}}
try
{
multi_buffer sb0(0);
fail();
}
catch(std::exception const&)
{
pass();
}
}
void
testAllocator()
{
using test::test_allocator;
// VFALCO This needs work
{
using alloc_type =
test_allocator<char, false, false, false, false, false>;
using type = basic_multi_buffer<alloc_type>;
type b;
}
{
using alloc_type =
test_allocator<char, false, false, false, false, false>;
using type = basic_multi_buffer<alloc_type>;
type b;
type b2(b);
type b3(b, alloc_type{});
}
}
void
testPrepare()
{
using boost::asio::buffer_size;
{
multi_buffer b(2);
BEAST_EXPECT(buffer_size(b.prepare(5)) == 5);
BEAST_EXPECT(buffer_size(b.prepare(8)) == 8);
BEAST_EXPECT(buffer_size(b.prepare(7)) == 7);
}
{
multi_buffer b(2);
b.prepare(2);
BEAST_EXPECT(test::buffer_count(b.prepare(5)) == 2);
BEAST_EXPECT(test::buffer_count(b.prepare(8)) == 3);
BEAST_EXPECT(test::buffer_count(b.prepare(4)) == 2);
}
}
void testCommit()
{
multi_buffer b(2);
b.prepare(2);
b.prepare(5);
b.commit(1);
expect_size(1, b.data());
}
void testConsume()
{
multi_buffer b(1);
expect_size(5, b.prepare(5));
b.commit(3);
expect_size(3, b.data());
b.consume(1);
expect_size(2, b.data());
}
void testMatrix()
{
using boost::asio::buffer;
using boost::asio::buffer_size;
std::string const s = "Hello, world";
BEAST_EXPECT(s.size() == 12);
for(std::size_t i = 1; i < 12; ++i) {
for(std::size_t x = 1; x < 4; ++x) {
for(std::size_t y = 1; y < 4; ++y) {
for(std::size_t t = 1; t < 4; ++ t) {
for(std::size_t u = 1; u < 4; ++ u) {
std::size_t z = s.size() - (x + y);
std::size_t v = s.size() - (t + u);
{
multi_buffer b(i);
{
auto d = b.prepare(z);
BEAST_EXPECT(buffer_size(d) == z);
}
{
auto d = b.prepare(0);
BEAST_EXPECT(buffer_size(d) == 0);
}
{
auto d = b.prepare(y);
BEAST_EXPECT(buffer_size(d) == y);
}
{
auto d = b.prepare(x);
BEAST_EXPECT(buffer_size(d) == x);
b.commit(buffer_copy(d, buffer(s.data(), x)));
}
BEAST_EXPECT(b.size() == x);
BEAST_EXPECT(buffer_size(b.data()) == b.size());
{
auto d = b.prepare(x);
BEAST_EXPECT(buffer_size(d) == x);
}
{
auto d = b.prepare(0);
BEAST_EXPECT(buffer_size(d) == 0);
}
{
auto d = b.prepare(z);
BEAST_EXPECT(buffer_size(d) == z);
}
{
auto d = b.prepare(y);
BEAST_EXPECT(buffer_size(d) == y);
b.commit(buffer_copy(d, buffer(s.data()+x, y)));
}
b.commit(1);
BEAST_EXPECT(b.size() == x + y);
BEAST_EXPECT(buffer_size(b.data()) == b.size());
{
auto d = b.prepare(x);
BEAST_EXPECT(buffer_size(d) == x);
}
{
auto d = b.prepare(y);
BEAST_EXPECT(buffer_size(d) == y);
}
{
auto d = b.prepare(0);
BEAST_EXPECT(buffer_size(d) == 0);
}
{
auto d = b.prepare(z);
BEAST_EXPECT(buffer_size(d) == z);
b.commit(buffer_copy(d, buffer(s.data()+x+y, z)));
}
b.commit(2);
BEAST_EXPECT(b.size() == x + y + z);
BEAST_EXPECT(buffer_size(b.data()) == b.size());
BEAST_EXPECT(to_string(b.data()) == s);
b.consume(t);
{
auto d = b.prepare(0);
BEAST_EXPECT(buffer_size(d) == 0);
}
BEAST_EXPECT(to_string(b.data()) == s.substr(t, std::string::npos));
b.consume(u);
BEAST_EXPECT(to_string(b.data()) == s.substr(t + u, std::string::npos));
b.consume(v);
BEAST_EXPECT(to_string(b.data()) == "");
b.consume(1);
{
auto d = b.prepare(0);
BEAST_EXPECT(buffer_size(d) == 0);
}
}
}}}}}
}
void testIterators()
{
using boost::asio::buffer_size;
multi_buffer b(1);
b.prepare(1);
b.commit(1);
b.prepare(2);
b.commit(2);
expect_size(3, b.data());
b.prepare(1);
expect_size(3, b.prepare(3));
b.commit(2);
BEAST_EXPECT(test::buffer_count(b.data()) == 4);
}
void testCapacity()
{
using boost::asio::buffer_size;
{
multi_buffer b{10};
BEAST_EXPECT(b.alloc_size() == 10);
BEAST_EXPECT(read_size_helper(b, 1) == 1);
BEAST_EXPECT(read_size_helper(b, 10) == 10);
BEAST_EXPECT(read_size_helper(b, 20) == 20);
BEAST_EXPECT(read_size_helper(b, 1000) == 512);
b.prepare(3);
b.commit(3);
BEAST_EXPECT(read_size_helper(b, 10) == 7);
BEAST_EXPECT(read_size_helper(b, 1000) == 7);
}
{
multi_buffer b(1000);
BEAST_EXPECT(b.alloc_size() == 1000);
BEAST_EXPECT(read_size_helper(b, 1) == 1);
BEAST_EXPECT(read_size_helper(b, 1000) == 1000);
BEAST_EXPECT(read_size_helper(b, 2000) == 1000);
b.prepare(3);
BEAST_EXPECT(read_size_helper(b, 1) == 1);
BEAST_EXPECT(read_size_helper(b, 1000) == 1000);
BEAST_EXPECT(read_size_helper(b, 2000) == 1000);
b.commit(3);
BEAST_EXPECT(read_size_helper(b, 1) == 1);
BEAST_EXPECT(read_size_helper(b, 1000) == 997);
BEAST_EXPECT(read_size_helper(b, 2000) == 997);
b.consume(2);
BEAST_EXPECT(read_size_helper(b, 1) == 1);
BEAST_EXPECT(read_size_helper(b, 1000) == 997);
BEAST_EXPECT(read_size_helper(b, 2000) == 997);
}
{
multi_buffer b{2};
BEAST_EXPECT(b.alloc_size() == 2);
BEAST_EXPECT(test::buffer_count(b.prepare(2)) == 1);
BEAST_EXPECT(test::buffer_count(b.prepare(3)) == 2);
BEAST_EXPECT(buffer_size(b.prepare(5)) == 5);
BEAST_EXPECT(read_size_helper(b, 10) == 6);
}
{
auto avail =
[](multi_buffer const& b)
{
return b.capacity() - b.size();
};
multi_buffer b{100};
BEAST_EXPECT(b.alloc_size() == 100);
BEAST_EXPECT(avail(b) == 0);
b.prepare(100);
BEAST_EXPECT(avail(b) == 100);
b.commit(100);
BEAST_EXPECT(avail(b) == 0);
b.consume(100);
BEAST_EXPECT(avail(b) == 0);
b.alloc_size(200);
BEAST_EXPECT(b.alloc_size() == 200);
b.prepare(1);
BEAST_EXPECT(avail(b) == 200);
}
}
void run() override
{
testSpecialMembers();
testAllocator();
testPrepare();
testCommit();
testConsume();
testMatrix();
testIterators();
testCapacity();
}
};
BEAST_DEFINE_TESTSUITE(multi_buffer,core,beast);
} // beast

View File

@ -8,7 +8,7 @@
// Test that header file is self-contained. // Test that header file is self-contained.
#include <beast/core/ostream.hpp> #include <beast/core/ostream.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/unit_test/suite.hpp> #include <beast/unit_test/suite.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <ostream> #include <ostream>
@ -20,10 +20,10 @@ class ostream_test : public beast::unit_test::suite
public: public:
void run() override void run() override
{ {
streambuf sb; multi_buffer b;
ostream(sb) << "Hello, world!\n"; ostream(b) << "Hello, world!\n";
BEAST_EXPECT(boost::lexical_cast<std::string>( BEAST_EXPECT(boost::lexical_cast<std::string>(
buffers(sb.data())) == "Hello, world!\n"); buffers(b.data())) == "Hello, world!\n");
} }
}; };

View File

@ -1,364 +0,0 @@
//
// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Test that header file is self-contained.
#include <beast/core/streambuf.hpp>
#include "buffer_test.hpp"
#include <beast/core/buffer_concepts.hpp>
#include <beast/core/ostream.hpp>
#include <beast/test/test_allocator.hpp>
#include <beast/unit_test/suite.hpp>
#include <boost/asio/buffer.hpp>
#include <algorithm>
#include <atomic>
#include <memory>
#include <string>
namespace beast {
static_assert(is_DynamicBuffer<streambuf>::value, "");
class basic_streambuf_test : public beast::unit_test::suite
{
public:
template<class ConstBufferSequence>
static
std::string
to_string(ConstBufferSequence const& bs)
{
return boost::lexical_cast<
std::string>(buffers(bs));
}
template<class Alloc1, class Alloc2>
static
bool
eq(basic_streambuf<Alloc1> const& sb1,
basic_streambuf<Alloc2> const& sb2)
{
return to_string(sb1.data()) == to_string(sb2.data());
}
template<class ConstBufferSequence>
void
expect_size(std::size_t n, ConstBufferSequence const& buffers)
{
BEAST_EXPECT(test::size_pre(buffers) == n);
BEAST_EXPECT(test::size_post(buffers) == n);
BEAST_EXPECT(test::size_rev_pre(buffers) == n);
BEAST_EXPECT(test::size_rev_post(buffers) == n);
}
template<class U, class V>
static
void
self_assign(U& u, V&& v)
{
u = std::forward<V>(v);
}
void testSpecialMembers()
{
using boost::asio::buffer;
std::string const s = "Hello, world";
BEAST_EXPECT(s.size() == 12);
for(std::size_t i = 1; i < 12; ++i) {
for(std::size_t x = 1; x < 4; ++x) {
for(std::size_t y = 1; y < 4; ++y) {
std::size_t z = s.size() - (x + y);
{
streambuf sb(i);
sb.commit(buffer_copy(sb.prepare(x), buffer(s.data(), x)));
sb.commit(buffer_copy(sb.prepare(y), buffer(s.data()+x, y)));
sb.commit(buffer_copy(sb.prepare(z), buffer(s.data()+x+y, z)));
BEAST_EXPECT(to_string(sb.data()) == s);
{
streambuf sb2(sb);
BEAST_EXPECT(eq(sb, sb2));
}
{
streambuf sb2;
sb2 = sb;
BEAST_EXPECT(eq(sb, sb2));
}
{
streambuf sb2(std::move(sb));
BEAST_EXPECT(to_string(sb2.data()) == s);
expect_size(0, sb.data());
sb = std::move(sb2);
BEAST_EXPECT(to_string(sb.data()) == s);
expect_size(0, sb2.data());
}
self_assign(sb, sb);
BEAST_EXPECT(to_string(sb.data()) == s);
self_assign(sb, std::move(sb));
BEAST_EXPECT(to_string(sb.data()) == s);
}
}}}
try
{
streambuf sb0(0);
fail();
}
catch(std::exception const&)
{
pass();
}
}
void
testAllocator()
{
using test::test_allocator;
// VFALCO This needs work
{
using alloc_type =
test_allocator<char, false, false, false, false, false>;
using sb_type = basic_streambuf<alloc_type>;
sb_type sb;
BEAST_EXPECT(sb.get_allocator().id() == 1);
}
{
using alloc_type =
test_allocator<char, false, false, false, false, false>;
using sb_type = basic_streambuf<alloc_type>;
sb_type sb;
BEAST_EXPECT(sb.get_allocator().id() == 2);
sb_type sb2(sb);
BEAST_EXPECT(sb2.get_allocator().id() == 2);
sb_type sb3(sb, alloc_type{});
}
}
void
testPrepare()
{
using boost::asio::buffer_size;
{
streambuf sb(2);
BEAST_EXPECT(buffer_size(sb.prepare(5)) == 5);
BEAST_EXPECT(buffer_size(sb.prepare(8)) == 8);
BEAST_EXPECT(buffer_size(sb.prepare(7)) == 7);
}
{
streambuf sb(2);
sb.prepare(2);
BEAST_EXPECT(test::buffer_count(sb.prepare(5)) == 2);
BEAST_EXPECT(test::buffer_count(sb.prepare(8)) == 3);
BEAST_EXPECT(test::buffer_count(sb.prepare(4)) == 2);
}
}
void testCommit()
{
streambuf sb(2);
sb.prepare(2);
sb.prepare(5);
sb.commit(1);
expect_size(1, sb.data());
}
void testConsume()
{
streambuf sb(1);
expect_size(5, sb.prepare(5));
sb.commit(3);
expect_size(3, sb.data());
sb.consume(1);
expect_size(2, sb.data());
}
void testMatrix()
{
using boost::asio::buffer;
using boost::asio::buffer_size;
std::string const s = "Hello, world";
BEAST_EXPECT(s.size() == 12);
for(std::size_t i = 1; i < 12; ++i) {
for(std::size_t x = 1; x < 4; ++x) {
for(std::size_t y = 1; y < 4; ++y) {
for(std::size_t t = 1; t < 4; ++ t) {
for(std::size_t u = 1; u < 4; ++ u) {
std::size_t z = s.size() - (x + y);
std::size_t v = s.size() - (t + u);
{
streambuf sb(i);
{
auto d = sb.prepare(z);
BEAST_EXPECT(buffer_size(d) == z);
}
{
auto d = sb.prepare(0);
BEAST_EXPECT(buffer_size(d) == 0);
}
{
auto d = sb.prepare(y);
BEAST_EXPECT(buffer_size(d) == y);
}
{
auto d = sb.prepare(x);
BEAST_EXPECT(buffer_size(d) == x);
sb.commit(buffer_copy(d, buffer(s.data(), x)));
}
BEAST_EXPECT(sb.size() == x);
BEAST_EXPECT(buffer_size(sb.data()) == sb.size());
{
auto d = sb.prepare(x);
BEAST_EXPECT(buffer_size(d) == x);
}
{
auto d = sb.prepare(0);
BEAST_EXPECT(buffer_size(d) == 0);
}
{
auto d = sb.prepare(z);
BEAST_EXPECT(buffer_size(d) == z);
}
{
auto d = sb.prepare(y);
BEAST_EXPECT(buffer_size(d) == y);
sb.commit(buffer_copy(d, buffer(s.data()+x, y)));
}
sb.commit(1);
BEAST_EXPECT(sb.size() == x + y);
BEAST_EXPECT(buffer_size(sb.data()) == sb.size());
{
auto d = sb.prepare(x);
BEAST_EXPECT(buffer_size(d) == x);
}
{
auto d = sb.prepare(y);
BEAST_EXPECT(buffer_size(d) == y);
}
{
auto d = sb.prepare(0);
BEAST_EXPECT(buffer_size(d) == 0);
}
{
auto d = sb.prepare(z);
BEAST_EXPECT(buffer_size(d) == z);
sb.commit(buffer_copy(d, buffer(s.data()+x+y, z)));
}
sb.commit(2);
BEAST_EXPECT(sb.size() == x + y + z);
BEAST_EXPECT(buffer_size(sb.data()) == sb.size());
BEAST_EXPECT(to_string(sb.data()) == s);
sb.consume(t);
{
auto d = sb.prepare(0);
BEAST_EXPECT(buffer_size(d) == 0);
}
BEAST_EXPECT(to_string(sb.data()) == s.substr(t, std::string::npos));
sb.consume(u);
BEAST_EXPECT(to_string(sb.data()) == s.substr(t + u, std::string::npos));
sb.consume(v);
BEAST_EXPECT(to_string(sb.data()) == "");
sb.consume(1);
{
auto d = sb.prepare(0);
BEAST_EXPECT(buffer_size(d) == 0);
}
}
}}}}}
}
void testIterators()
{
using boost::asio::buffer_size;
streambuf sb(1);
sb.prepare(1);
sb.commit(1);
sb.prepare(2);
sb.commit(2);
expect_size(3, sb.data());
sb.prepare(1);
expect_size(3, sb.prepare(3));
sb.commit(2);
BEAST_EXPECT(test::buffer_count(sb.data()) == 4);
}
void testCapacity()
{
using boost::asio::buffer_size;
{
streambuf sb{10};
BEAST_EXPECT(sb.alloc_size() == 10);
BEAST_EXPECT(read_size_helper(sb, 1) == 1);
BEAST_EXPECT(read_size_helper(sb, 10) == 10);
BEAST_EXPECT(read_size_helper(sb, 20) == 20);
BEAST_EXPECT(read_size_helper(sb, 1000) == 512);
sb.prepare(3);
sb.commit(3);
BEAST_EXPECT(read_size_helper(sb, 10) == 7);
BEAST_EXPECT(read_size_helper(sb, 1000) == 7);
}
{
streambuf sb(1000);
BEAST_EXPECT(sb.alloc_size() == 1000);
BEAST_EXPECT(read_size_helper(sb, 1) == 1);
BEAST_EXPECT(read_size_helper(sb, 1000) == 1000);
BEAST_EXPECT(read_size_helper(sb, 2000) == 1000);
sb.prepare(3);
BEAST_EXPECT(read_size_helper(sb, 1) == 1);
BEAST_EXPECT(read_size_helper(sb, 1000) == 1000);
BEAST_EXPECT(read_size_helper(sb, 2000) == 1000);
sb.commit(3);
BEAST_EXPECT(read_size_helper(sb, 1) == 1);
BEAST_EXPECT(read_size_helper(sb, 1000) == 997);
BEAST_EXPECT(read_size_helper(sb, 2000) == 997);
sb.consume(2);
BEAST_EXPECT(read_size_helper(sb, 1) == 1);
BEAST_EXPECT(read_size_helper(sb, 1000) == 997);
BEAST_EXPECT(read_size_helper(sb, 2000) == 997);
}
{
streambuf sb{2};
BEAST_EXPECT(sb.alloc_size() == 2);
BEAST_EXPECT(test::buffer_count(sb.prepare(2)) == 1);
BEAST_EXPECT(test::buffer_count(sb.prepare(3)) == 2);
BEAST_EXPECT(buffer_size(sb.prepare(5)) == 5);
BEAST_EXPECT(read_size_helper(sb, 10) == 6);
}
{
auto avail =
[](streambuf const& sb)
{
return sb.capacity() - sb.size();
};
streambuf sb{100};
BEAST_EXPECT(sb.alloc_size() == 100);
BEAST_EXPECT(avail(sb) == 0);
sb.prepare(100);
BEAST_EXPECT(avail(sb) == 100);
sb.commit(100);
BEAST_EXPECT(avail(sb) == 0);
sb.consume(100);
BEAST_EXPECT(avail(sb) == 0);
sb.alloc_size(200);
BEAST_EXPECT(sb.alloc_size() == 200);
sb.prepare(1);
BEAST_EXPECT(avail(sb) == 200);
}
}
void run() override
{
testSpecialMembers();
testAllocator();
testPrepare();
testCommit();
testConsume();
testMatrix();
testIterators();
testCapacity();
}
};
BEAST_DEFINE_TESTSUITE(basic_streambuf,core,beast);
} // beast

View File

@ -12,7 +12,7 @@
#include <beast/core/buffer_cat.hpp> #include <beast/core/buffer_cat.hpp>
#include <beast/core/consuming_buffers.hpp> #include <beast/core/consuming_buffers.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/unit_test/suite.hpp> #include <beast/unit_test/suite.hpp>
namespace beast { namespace beast {
@ -902,8 +902,8 @@ public:
testSplit() testSplit()
{ {
#if 0 #if 0
streambuf sb; multi_buffer b;
sb << b <<
"POST / HTTP/1.1\r\n" "POST / HTTP/1.1\r\n"
"Content-Length: 5\r\n" "Content-Length: 5\r\n"
"\r\n" "\r\n"
@ -911,7 +911,7 @@ public:
error_code ec; error_code ec;
test_parser<true> p; test_parser<true> p;
p.pause(); p.pause();
auto n = feed(sb.data(), p, ec); auto n = feed(b.data(), p, ec);
BEAST_EXPECTS(! ec, ec.message()); BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.got_on_begin); BEAST_EXPECT(p.got_on_begin);
BEAST_EXPECT(p.got_on_field); BEAST_EXPECT(p.got_on_field);
@ -922,9 +922,9 @@ public:
BEAST_EXPECT(p.state() != parse_state::header); BEAST_EXPECT(p.state() != parse_state::header);
BEAST_EXPECT(! p.is_complete()); BEAST_EXPECT(! p.is_complete());
BEAST_EXPECT(p.body.empty()); BEAST_EXPECT(p.body.empty());
sb.consume(n); b.consume(n);
p.resume(); p.resume();
n = feed(sb.data(), p, ec); n = feed(b.data(), p, ec);
BEAST_EXPECTS(! ec, ec.message()); BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.got_on_begin); BEAST_EXPECT(p.got_on_begin);
BEAST_EXPECT(p.got_on_field); BEAST_EXPECT(p.got_on_field);

View File

@ -104,8 +104,8 @@ public:
"*" "*"
}; };
message<true, direct_body, fields> m; message<true, direct_body, fields> m;
flat_streambuf sb{1024}; flat_streambuf b{1024};
read(is, sb, m); read(is, b, m);
BEAST_EXPECT(m.body == "*"); BEAST_EXPECT(m.body == "*");
} }
@ -117,8 +117,8 @@ public:
"*" "*"
}; };
message<false, direct_body, fields> m; message<false, direct_body, fields> m;
flat_streambuf sb{20}; flat_streambuf b{20};
read(is, sb, m); read(is, b, m);
BEAST_EXPECT(m.body == "*"); BEAST_EXPECT(m.body == "*");
} }
@ -133,8 +133,8 @@ public:
"0\r\n\r\n" "0\r\n\r\n"
}; };
message<true, direct_body, fields> m; message<true, direct_body, fields> m;
flat_streambuf sb{100}; flat_streambuf b{100};
read(is, sb, m); read(is, b, m);
BEAST_EXPECT(m.body == "*"); BEAST_EXPECT(m.body == "*");
} }
} }
@ -201,8 +201,8 @@ public:
"*" "*"
}; };
message<true, indirect_body, fields> m; message<true, indirect_body, fields> m;
flat_streambuf sb{1024}; flat_streambuf b{1024};
read(is, sb, m); read(is, b, m);
BEAST_EXPECT(m.body == "*"); BEAST_EXPECT(m.body == "*");
} }
@ -214,8 +214,8 @@ public:
"*" "*"
}; };
message<false, indirect_body, fields> m; message<false, indirect_body, fields> m;
flat_streambuf sb{20}; flat_streambuf b{20};
read(is, sb, m); read(is, b, m);
BEAST_EXPECT(m.body == "*"); BEAST_EXPECT(m.body == "*");
} }
@ -231,8 +231,8 @@ public:
"0\r\n\r\n" "0\r\n\r\n"
}; };
message<true, indirect_body, fields> m; message<true, indirect_body, fields> m;
flat_streambuf sb{1024}; flat_streambuf b{1024};
read(is, sb, m); read(is, b, m);
BEAST_EXPECT(m.body == "*"); BEAST_EXPECT(m.body == "*");
} }
} }
@ -253,15 +253,15 @@ public:
"*****" "*****"
}; };
header_parser<true, fields> p; header_parser<true, fields> p;
flat_streambuf sb{38}; flat_streambuf b{38};
auto const bytes_used = auto const bytes_used =
read_some(is, sb, p); read_some(is, b, p);
sb.consume(bytes_used); b.consume(bytes_used);
BEAST_EXPECT(p.size() == 5); BEAST_EXPECT(p.size() == 5);
BEAST_EXPECT(sb.size() < 5); BEAST_EXPECT(b.size() < 5);
sb.commit(boost::asio::read( b.commit(boost::asio::read(
is, sb.prepare(5 - sb.size()))); is, b.prepare(5 - b.size())));
BEAST_EXPECT(sb.size() == 5); BEAST_EXPECT(b.size() == 5);
} }
// end of file // end of file
@ -272,16 +272,16 @@ public:
"*****" "*****"
}; };
header_parser<false, fields> p; header_parser<false, fields> p;
flat_streambuf sb{20}; flat_streambuf b{20};
auto const bytes_used = auto const bytes_used =
read_some(is, sb, p); read_some(is, b, p);
sb.consume(bytes_used); b.consume(bytes_used);
BEAST_EXPECT(p.state() == BEAST_EXPECT(p.state() ==
parse_state::body_to_eof); parse_state::body_to_eof);
BEAST_EXPECT(sb.size() < 5); BEAST_EXPECT(b.size() < 5);
sb.commit(boost::asio::read( b.commit(boost::asio::read(
is, sb.prepare(5 - sb.size()))); is, b.prepare(5 - b.size())));
BEAST_EXPECT(sb.size() == 5); BEAST_EXPECT(b.size() == 5);
} }
} }
@ -303,10 +303,10 @@ public:
}; };
header_parser<true, fields> p; header_parser<true, fields> p;
flat_streambuf sb{128}; flat_streambuf b{128};
auto const bytes_used = auto const bytes_used =
read_some(is, sb, p); read_some(is, b, p);
sb.consume(bytes_used); b.consume(bytes_used);
BEAST_EXPECT(p.got_header()); BEAST_EXPECT(p.got_header());
BEAST_EXPECT( BEAST_EXPECT(
p.get().fields["Expect"] == p.get().fields["Expect"] ==
@ -314,7 +314,7 @@ public:
message_parser< message_parser<
true, string_body, fields> p1{ true, string_body, fields> p1{
std::move(p)}; std::move(p)};
read(is, sb, p1); read(is, b, p1);
BEAST_EXPECT( BEAST_EXPECT(
p1.get().body == "*****"); p1.get().body == "*****");
} }
@ -332,7 +332,7 @@ public:
void void
relay( relay(
SyncWriteStream& out, SyncWriteStream& out,
DynamicBuffer& sb, DynamicBuffer& b,
SyncReadStream& in) SyncReadStream& in)
{ {
flat_streambuf buffer{4096}; // 4K limit flat_streambuf buffer{4096}; // 4K limit
@ -397,8 +397,8 @@ public:
3 // max_read 3 // max_read
}; };
test::string_ostream os{ios_}; test::string_ostream os{ios_};
flat_streambuf sb{16}; flat_streambuf b{16};
relay<true>(os, sb, is); relay<true>(os, b, is);
} }
// end of file // end of file
@ -410,8 +410,8 @@ public:
3 // max_read 3 // max_read
}; };
test::string_ostream os{ios_}; test::string_ostream os{ios_};
flat_streambuf sb{16}; flat_streambuf b{16};
relay<false>(os, sb, is); relay<false>(os, b, is);
} }
// chunked // chunked
@ -427,8 +427,8 @@ public:
2 // max_read 2 // max_read
}; };
test::string_ostream os{ios_}; test::string_ostream os{ios_};
flat_streambuf sb{16}; flat_streambuf b{16};
relay<true>(os, sb, is); relay<true>(os, b, is);
} }
} }

View File

@ -36,8 +36,8 @@ public:
"xyz"; "xyz";
test::string_istream ss(ios_, s); test::string_istream ss(ios_, s);
message_parser<false, dynamic_body, fields> p; message_parser<false, dynamic_body, fields> p;
streambuf sb; multi_buffer b;
read(ss, sb, p); read(ss, b, p);
auto const& m = p.get(); auto const& m = p.get();
BEAST_EXPECT(boost::lexical_cast<std::string>( BEAST_EXPECT(boost::lexical_cast<std::string>(
buffers(m.body.data())) == "xyz"); buffers(m.body.data())) == "xyz");

View File

@ -15,7 +15,7 @@
#include <beast/test/string_ostream.hpp> #include <beast/test/string_ostream.hpp>
#include <beast/test/yield_to.hpp> #include <beast/test/yield_to.hpp>
#include <beast/core/flat_streambuf.hpp> #include <beast/core/flat_streambuf.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/http/header_parser.hpp> #include <beast/http/header_parser.hpp>
#include <beast/http/read.hpp> #include <beast/http/read.hpp>
#include <beast/http/read.hpp> #include <beast/http/read.hpp>
@ -37,7 +37,7 @@ public:
beast::test::string_istream ss{get_io_service(), s}; beast::test::string_istream ss{get_io_service(), s};
error_code ec; error_code ec;
#if 0 #if 0
streambuf dynabuf; multi_buffer dynabuf;
#else #else
flat_streambuf dynabuf{1024}; flat_streambuf dynabuf{1024};
#endif #endif
@ -124,9 +124,9 @@ public:
"Content-Length: 1\r\n" "Content-Length: 1\r\n"
"\r\n" "\r\n"
"*"}; "*"};
flat_streambuf sb{1024}; flat_streambuf b{1024};
message_parser<true, string_body, fields> p; message_parser<true, string_body, fields> p;
read(is, sb, p, ec); read(is, b, p, ec);
auto const& m = p.get(); auto const& m = p.get();
BEAST_EXPECTS(! ec, ec.message()); BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.is_complete()); BEAST_EXPECT(p.is_complete());
@ -142,8 +142,8 @@ public:
// parse through the chunk body // parse through the chunk body
beast::test::string_istream is{ beast::test::string_istream is{
get_io_service(), ""}; get_io_service(), ""};
streambuf sb; multi_buffer b;
sb << b <<
"PUT / HTTP/1.1\r\n" "PUT / HTTP/1.1\r\n"
"Transfer-Encoding: chunked\r\n" "Transfer-Encoding: chunked\r\n"
"\r\n" "\r\n"
@ -151,20 +151,20 @@ public:
"*"; "*";
error_code ec; error_code ec;
message_parser<true, string_body, fields> p; message_parser<true, string_body, fields> p;
read(is, sb, p, ec); read(is, b, p, ec);
BEAST_EXPECT(sb.size() == 0); BEAST_EXPECT(b.size() == 0);
BEAST_EXPECTS(! ec, ec.message()); BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(!p.is_complete()); BEAST_EXPECT(!p.is_complete());
BEAST_EXPECT(p.get().body == "*"); BEAST_EXPECT(p.get().body == "*");
sb << "\r\n0;d;e=3;f=\"4\"\r\n" b << "\r\n0;d;e=3;f=\"4\"\r\n"
"Expires: never\r\n" "Expires: never\r\n"
"MD5-Fingerprint: -\r\n"; "MD5-Fingerprint: -\r\n";
// incomplete parse, missing the final crlf // incomplete parse, missing the final crlf
BEAST_EXPECT(p.write(sb.data(), ec) == 0); BEAST_EXPECT(p.write(b.data(), ec) == 0);
BEAST_EXPECTS(! ec, ec.message()); BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(!p.is_complete()); BEAST_EXPECT(!p.is_complete());
sb << "\r\n"; // final crlf to end message b << "\r\n"; // final crlf to end message
BEAST_EXPECT(p.write(sb.data(), ec) == sb.size()); BEAST_EXPECT(p.write(b.data(), ec) == b.size());
BEAST_EXPECTS(! ec, ec.message()); BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.is_complete()); BEAST_EXPECT(p.is_complete());
} }
@ -212,18 +212,18 @@ public:
"Content-Length: 5\r\n" "Content-Length: 5\r\n"
"\r\n" "\r\n"
"*****"}; "*****"};
streambuf sb; multi_buffer b;
error_code ec; error_code ec;
header_parser<true, fields> p0; header_parser<true, fields> p0;
auto const bytes_used = auto const bytes_used =
read_some(ss, sb, p0, ec); read_some(ss, b, p0, ec);
sb.consume(bytes_used); b.consume(bytes_used);
BEAST_EXPECTS(! ec, ec.message()); BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p0.state() != parse_state::header); BEAST_EXPECT(p0.state() != parse_state::header);
BEAST_EXPECT(! p0.is_complete()); BEAST_EXPECT(! p0.is_complete());
message_parser<true, message_parser<true,
string_body, fields> p1{std::move(p0)}; string_body, fields> p1{std::move(p0)};
read(ss, sb, p1, ec); read(ss, b, p1, ec);
BEAST_EXPECTS(! ec, ec.message()); BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p1.get().body == "*****"); BEAST_EXPECT(p1.get().body == "*****");
} }

View File

@ -11,7 +11,7 @@
#include <beast/http.hpp> #include <beast/http.hpp>
#include <beast/core/consuming_buffers.hpp> #include <beast/core/consuming_buffers.hpp>
#include <beast/core/ostream.hpp> #include <beast/core/ostream.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/unit_test/suite.hpp> #include <beast/unit_test/suite.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <chrono> #include <chrono>
@ -26,7 +26,7 @@ class parser_bench_test : public beast::unit_test::suite
public: public:
static std::size_t constexpr N = 2000; static std::size_t constexpr N = 2000;
using corpus = std::vector<streambuf>; using corpus = std::vector<multi_buffer>;
corpus creq_; corpus creq_;
corpus cres_; corpus cres_;
@ -110,13 +110,13 @@ public:
testParser1(std::size_t repeat, corpus const& v) testParser1(std::size_t repeat, corpus const& v)
{ {
while(repeat--) while(repeat--)
for(auto const& sb : v) for(auto const& b : v)
{ {
Parser p; Parser p;
error_code ec; error_code ec;
p.write(sb.data(), ec); p.write(b.data(), ec);
if(! BEAST_EXPECTS(! ec, ec.message())) if(! BEAST_EXPECTS(! ec, ec.message()))
log << to_string(sb.data()) << std::endl; log << to_string(b.data()) << std::endl;
} }
} }
@ -125,13 +125,13 @@ public:
testParser2(std::size_t repeat, corpus const& v) testParser2(std::size_t repeat, corpus const& v)
{ {
while(repeat--) while(repeat--)
for(auto const& sb : v) for(auto const& b : v)
{ {
Parser p; Parser p;
error_code ec; error_code ec;
feed(sb.data(), p, ec); feed(b.data(), p, ec);
if(! BEAST_EXPECTS(! ec, ec.message())) if(! BEAST_EXPECTS(! ec, ec.message()))
log << to_string(sb.data()) << std::endl; log << to_string(b.data()) << std::endl;
} }
} }

View File

@ -40,15 +40,15 @@ public:
auto const len = strlen(s); auto const len = strlen(s);
for(n = 0; n < limit; ++n) for(n = 0; n < limit; ++n)
{ {
streambuf sb; multi_buffer b;
sb.commit(buffer_copy( b.commit(buffer_copy(
sb.prepare(len), buffer(s, len))); b.prepare(len), buffer(s, len)));
test::fail_counter fc(n); test::fail_counter fc(n);
test::fail_stream< test::fail_stream<
test::string_istream> fs{fc, ios_, ""}; test::string_istream> fs{fc, ios_, ""};
test_parser<isRequest> p(fc); test_parser<isRequest> p(fc);
error_code ec; error_code ec;
read(fs, sb, p, ec); read(fs, b, p, ec);
if(! ec) if(! ec)
break; break;
} }
@ -56,30 +56,30 @@ public:
for(n = 0; n < limit; ++n) for(n = 0; n < limit; ++n)
{ {
static std::size_t constexpr pre = 10; static std::size_t constexpr pre = 10;
streambuf sb; multi_buffer b;
sb.commit(buffer_copy( b.commit(buffer_copy(
sb.prepare(pre), buffer(s, pre))); b.prepare(pre), buffer(s, pre)));
test::fail_counter fc(n); test::fail_counter fc(n);
test::fail_stream<test::string_istream> fs{ test::fail_stream<test::string_istream> fs{
fc, ios_, std::string{s + pre, len - pre}}; fc, ios_, std::string{s + pre, len - pre}};
test_parser<isRequest> p(fc); test_parser<isRequest> p(fc);
error_code ec; error_code ec;
read(fs, sb, p, ec); read(fs, b, p, ec);
if(! ec) if(! ec)
break; break;
} }
BEAST_EXPECT(n < limit); BEAST_EXPECT(n < limit);
for(n = 0; n < limit; ++n) for(n = 0; n < limit; ++n)
{ {
streambuf sb; multi_buffer b;
sb.commit(buffer_copy( b.commit(buffer_copy(
sb.prepare(len), buffer(s, len))); b.prepare(len), buffer(s, len)));
test::fail_counter fc(n); test::fail_counter fc(n);
test::fail_stream< test::fail_stream<
test::string_istream> fs{fc, ios_, ""}; test::string_istream> fs{fc, ios_, ""};
test_parser<isRequest> p(fc); test_parser<isRequest> p(fc);
error_code ec; error_code ec;
async_read(fs, sb, p, do_yield[ec]); async_read(fs, b, p, do_yield[ec]);
if(! ec) if(! ec)
break; break;
} }
@ -87,15 +87,15 @@ public:
for(n = 0; n < limit; ++n) for(n = 0; n < limit; ++n)
{ {
static std::size_t constexpr pre = 10; static std::size_t constexpr pre = 10;
streambuf sb; multi_buffer b;
sb.commit(buffer_copy( b.commit(buffer_copy(
sb.prepare(pre), buffer(s, pre))); b.prepare(pre), buffer(s, pre)));
test::fail_counter fc(n); test::fail_counter fc(n);
test::fail_stream<test::string_istream> fs{ test::fail_stream<test::string_istream> fs{
fc, ios_, std::string{s + pre, len - pre}}; fc, ios_, std::string{s + pre, len - pre}};
test_parser<isRequest> p(fc); test_parser<isRequest> p(fc);
error_code ec; error_code ec;
async_read(fs, sb, p, do_yield[ec]); async_read(fs, b, p, do_yield[ec]);
if(! ec) if(! ec)
break; break;
} }
@ -106,10 +106,10 @@ public:
{ {
try try
{ {
streambuf sb; multi_buffer b;
test::string_istream ss(ios_, "GET / X"); test::string_istream ss(ios_, "GET / X");
message_parser<true, dynamic_body, fields> p; message_parser<true, dynamic_body, fields> p;
read(ss, sb, p); read(ss, b, p);
fail(); fail();
} }
catch(std::exception const&) catch(std::exception const&)
@ -197,8 +197,8 @@ public:
request<dynamic_body> m; request<dynamic_body> m;
try try
{ {
streambuf sb; multi_buffer b;
read(fs, sb, m); read(fs, b, m);
break; break;
} }
catch(std::exception const&) catch(std::exception const&)
@ -218,8 +218,8 @@ public:
); );
request<dynamic_body> m; request<dynamic_body> m;
error_code ec; error_code ec;
streambuf sb; multi_buffer b;
read(fs, sb, m, ec); read(fs, b, m, ec);
if(! ec) if(! ec)
break; break;
} }
@ -236,8 +236,8 @@ public:
); );
request<dynamic_body> m; request<dynamic_body> m;
error_code ec; error_code ec;
streambuf sb; multi_buffer b;
async_read(fs, sb, m, do_yield[ec]); async_read(fs, b, m, do_yield[ec]);
if(! ec) if(! ec)
break; break;
} }
@ -248,19 +248,19 @@ public:
testEof(yield_context do_yield) testEof(yield_context do_yield)
{ {
{ {
streambuf sb; multi_buffer b;
test::string_istream ss(ios_, ""); test::string_istream ss(ios_, "");
message_parser<true, dynamic_body, fields> p; message_parser<true, dynamic_body, fields> p;
error_code ec; error_code ec;
read(ss, sb, p, ec); read(ss, b, p, ec);
BEAST_EXPECT(ec == boost::asio::error::eof); BEAST_EXPECT(ec == boost::asio::error::eof);
} }
{ {
streambuf sb; multi_buffer b;
test::string_istream ss(ios_, ""); test::string_istream ss(ios_, "");
message_parser<true, dynamic_body, fields> p; message_parser<true, dynamic_body, fields> p;
error_code ec; error_code ec;
async_read(ss, sb, p, do_yield[ec]); async_read(ss, b, p, do_yield[ec]);
BEAST_EXPECT(ec == boost::asio::error::eof); BEAST_EXPECT(ec == boost::asio::error::eof);
} }
} }
@ -286,9 +286,9 @@ public:
test::string_istream is{ios, test::string_istream is{ios,
"GET / HTTP/1.1\r\n\r\n"}; "GET / HTTP/1.1\r\n\r\n"};
BEAST_EXPECT(handler::count() == 0); BEAST_EXPECT(handler::count() == 0);
streambuf sb; multi_buffer b;
message<true, dynamic_body, fields> m; message<true, dynamic_body, fields> m;
async_read(is, sb, m, handler{}); async_read(is, b, m, handler{});
BEAST_EXPECT(handler::count() > 0); BEAST_EXPECT(handler::count() > 0);
ios.stop(); ios.stop();
BEAST_EXPECT(handler::count() > 0); BEAST_EXPECT(handler::count() > 0);
@ -305,9 +305,9 @@ public:
test::string_istream is{ios, test::string_istream is{ios,
"GET / HTTP/1.1\r\n\r\n"}; "GET / HTTP/1.1\r\n\r\n"};
BEAST_EXPECT(handler::count() == 0); BEAST_EXPECT(handler::count() == 0);
streambuf sb; multi_buffer b;
message<true, dynamic_body, fields> m; message<true, dynamic_body, fields> m;
async_read(is, sb, m, handler{}); async_read(is, b, m, handler{});
BEAST_EXPECT(handler::count() > 0); BEAST_EXPECT(handler::count() > 0);
} }
BEAST_EXPECT(handler::count() == 0); BEAST_EXPECT(handler::count() == 0);

View File

@ -13,7 +13,7 @@
#include <beast/http/string_body.hpp> #include <beast/http/string_body.hpp>
#include <beast/http/write.hpp> #include <beast/http/write.hpp>
#include <beast/core/error.hpp> #include <beast/core/error.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/test/fail_stream.hpp> #include <beast/test/fail_stream.hpp>
#include <beast/test/string_ostream.hpp> #include <beast/test/string_ostream.hpp>
#include <beast/test/yield_to.hpp> #include <beast/test/yield_to.hpp>

View File

@ -75,22 +75,22 @@ public:
auto check = auto check =
[&](frame_header const& fh) [&](frame_header const& fh)
{ {
fh_streambuf sb; fh_streambuf b;
write(sb, fh); write(b, fh);
close_code code; close_code code;
stream_base stream; stream_base stream;
stream.open(role); stream.open(role);
detail::frame_header fh1; detail::frame_header fh1;
auto const n = auto const n =
stream.read_fh1(fh1, sb, code); stream.read_fh1(fh1, b, code);
if(! BEAST_EXPECT(! code)) if(! BEAST_EXPECT(! code))
return; return;
if(! BEAST_EXPECT(sb.size() == n)) if(! BEAST_EXPECT(b.size() == n))
return; return;
stream.read_fh2(fh1, sb, code); stream.read_fh2(fh1, b, code);
if(! BEAST_EXPECT(! code)) if(! BEAST_EXPECT(! code))
return; return;
if(! BEAST_EXPECT(sb.size() == 0)) if(! BEAST_EXPECT(b.size() == 0))
return; return;
BEAST_EXPECT(fh1 == fh); BEAST_EXPECT(fh1 == fh);
}; };
@ -127,25 +127,25 @@ public:
auto check = auto check =
[&](frame_header const& fh) [&](frame_header const& fh)
{ {
fh_streambuf sb; fh_streambuf b;
write(sb, fh); write(b, fh);
close_code code; close_code code;
stream_base stream; stream_base stream;
stream.open(role); stream.open(role);
detail::frame_header fh1; detail::frame_header fh1;
auto const n = auto const n =
stream.read_fh1(fh1, sb, code); stream.read_fh1(fh1, b, code);
if(code) if(code)
{ {
pass(); pass();
return; return;
} }
if(! BEAST_EXPECT(sb.size() == n)) if(! BEAST_EXPECT(b.size() == n))
return; return;
stream.read_fh2(fh1, sb, code); stream.read_fh2(fh1, b, code);
if(! BEAST_EXPECT(code)) if(! BEAST_EXPECT(code))
return; return;
if(! BEAST_EXPECT(sb.size() == 0)) if(! BEAST_EXPECT(b.size() == 0))
return; return;
}; };
@ -193,25 +193,25 @@ public:
using boost::asio::buffer_copy; using boost::asio::buffer_copy;
static role_type constexpr role = role_type::client; static role_type constexpr role = role_type::client;
std::vector<std::uint8_t> v{bs}; std::vector<std::uint8_t> v{bs};
fh_streambuf sb; fh_streambuf b;
sb.commit(buffer_copy(sb.prepare(v.size()), buffer(v))); b.commit(buffer_copy(b.prepare(v.size()), buffer(v)));
stream_base stream; stream_base stream;
stream.open(role); stream.open(role);
close_code code; close_code code;
detail::frame_header fh; detail::frame_header fh;
auto const n = auto const n =
stream.read_fh1(fh, sb, code); stream.read_fh1(fh, b, code);
if(code) if(code)
{ {
pass(); pass();
return; return;
} }
if(! BEAST_EXPECT(sb.size() == n)) if(! BEAST_EXPECT(b.size() == n))
return; return;
stream.read_fh2(fh, sb, code); stream.read_fh2(fh, b, code);
if(! BEAST_EXPECT(code)) if(! BEAST_EXPECT(code))
return; return;
if(! BEAST_EXPECT(sb.size() == 0)) if(! BEAST_EXPECT(b.size() == 0))
return; return;
} }

View File

@ -129,16 +129,16 @@ public:
ws.write(boost::asio::buffer("Hello, world!", 13)); ws.write(boost::asio::buffer("Hello, world!", 13));
// Receive Secure WebSocket message, print and close using Beast // Receive Secure WebSocket message, print and close using Beast
beast::streambuf sb; beast::multi_buffer b;
beast::websocket::opcode op; beast::websocket::opcode op;
ws.read(op, sb); ws.read(op, b);
ws.close(beast::websocket::close_code::normal); ws.close(beast::websocket::close_code::normal);
try try
{ {
for(;;) for(;;)
{ {
ws.read(op, sb); ws.read(op, b);
sb.consume(sb.size()); b.consume(b.size());
} }
} }
catch(system_error const& se) catch(system_error const& se)
@ -147,7 +147,7 @@ public:
throw; throw;
} }
BEAST_EXPECT(boost::lexical_cast<std::string>( BEAST_EXPECT(boost::lexical_cast<std::string>(
buffers(sb.data())) == "Hello, world!"); buffers(b.data())) == "Hello, world!");
} }
}; };

View File

@ -9,7 +9,7 @@
#define WEBSOCKET_ASYNC_SSL_ECHO_SERVER_HPP #define WEBSOCKET_ASYNC_SSL_ECHO_SERVER_HPP
#include <beast/core/placeholders.hpp> #include <beast/core/placeholders.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/websocket/ssl.hpp> #include <beast/websocket/ssl.hpp>
#include <beast/websocket/stream.hpp> #include <beast/websocket/stream.hpp>
#include <boost/asio/ssl.hpp> #include <boost/asio/ssl.hpp>
@ -156,7 +156,7 @@ private:
boost::asio::ssl::stream<socket_type>> ws; boost::asio::ssl::stream<socket_type>> ws;
boost::asio::io_service::strand strand; boost::asio::io_service::strand strand;
beast::websocket::opcode op; beast::websocket::opcode op;
beast::streambuf db; beast::multi_buffer db;
std::size_t id; std::size_t id;
data(async_ssl_echo_server& server_, data(async_ssl_echo_server& server_,

View File

@ -12,7 +12,7 @@
#include "websocket_sync_echo_server.hpp" #include "websocket_sync_echo_server.hpp"
#include <beast/core/ostream.hpp> #include <beast/core/ostream.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/test/fail_stream.hpp> #include <beast/test/fail_stream.hpp>
#include <beast/test/string_istream.hpp> #include <beast/test/string_istream.hpp>
#include <beast/test/string_iostream.hpp> #include <beast/test/string_iostream.hpp>
@ -747,8 +747,8 @@ public:
try try
{ {
opcode op; opcode op;
streambuf sb; multi_buffer b;
c.read(ws, op, sb); c.read(ws, op, b);
fail("success", __FILE__, __LINE__); fail("success", __FILE__, __LINE__);
} }
catch(system_error const& e) catch(system_error const& e)
@ -777,8 +777,8 @@ public:
try try
{ {
opcode op; opcode op;
streambuf sb; multi_buffer b;
c.read(ws, op, sb); c.read(ws, op, b);
fail("success", __FILE__, __LINE__); fail("success", __FILE__, __LINE__);
} }
catch(system_error const& e) catch(system_error const& e)
@ -805,8 +805,8 @@ public:
try try
{ {
opcode op; opcode op;
streambuf sb; multi_buffer b;
c.read(ws, op, sb); c.read(ws, op, b);
fail("success", __FILE__, __LINE__); fail("success", __FILE__, __LINE__);
} }
catch(system_error const& e) catch(system_error const& e)
@ -834,8 +834,8 @@ public:
try try
{ {
opcode op; opcode op;
streambuf sb; multi_buffer b;
c.read(ws, op, sb); c.read(ws, op, b);
fail("success", __FILE__, __LINE__); fail("success", __FILE__, __LINE__);
} }
catch(system_error const& e) catch(system_error const& e)
@ -1199,7 +1199,7 @@ public:
if(! BEAST_EXPECTS(! ec, ec.message())) if(! BEAST_EXPECTS(! ec, ec.message()))
break; break;
opcode op; opcode op;
streambuf db; multi_buffer db;
ws.read(op, db, ec); ws.read(op, db, ec);
if(! BEAST_EXPECTS(! ec, ec.message())) if(! BEAST_EXPECTS(! ec, ec.message()))
break; break;
@ -1225,7 +1225,7 @@ public:
if(! BEAST_EXPECTS(! ec, ec.message())) if(! BEAST_EXPECTS(! ec, ec.message()))
break; break;
opcode op; opcode op;
streambuf db; multi_buffer db;
ws.async_read(op, db, do_yield[ec]); ws.async_read(op, db, do_yield[ec]);
if(! BEAST_EXPECTS(! ec, ec.message())) if(! BEAST_EXPECTS(! ec, ec.message()))
break; break;
@ -1290,7 +1290,7 @@ public:
// Read // Read
opcode op; opcode op;
streambuf db; multi_buffer db;
++count; ++count;
ws.async_read(op, db, ws.async_read(op, db,
[&](error_code ec) [&](error_code ec)
@ -1346,7 +1346,7 @@ public:
ws.write(buffer_cat(sbuf("TEXT"), ws.write(buffer_cat(sbuf("TEXT"),
cbuf(0x03, 0xea, 0xf0, 0x28, 0x8c, 0xbc))); cbuf(0x03, 0xea, 0xf0, 0x28, 0x8c, 0xbc)));
opcode op; opcode op;
streambuf db; multi_buffer db;
std::size_t count = 0; std::size_t count = 0;
// Read text message with bad utf8. // Read text message with bad utf8.
// Causes a close to be sent, blocking writes. // Causes a close to be sent, blocking writes.
@ -1414,7 +1414,7 @@ public:
ws.set_option(message_type(opcode::binary)); ws.set_option(message_type(opcode::binary));
ws.write(sbuf("CLOSE")); ws.write(sbuf("CLOSE"));
opcode op; opcode op;
streambuf db; multi_buffer db;
std::size_t count = 0; std::size_t count = 0;
// Read a close frame. // Read a close frame.
// Sends a close frame, blocking writes. // Sends a close frame, blocking writes.
@ -1480,7 +1480,7 @@ public:
ws.set_option(message_type(opcode::binary)); ws.set_option(message_type(opcode::binary));
ws.write(sbuf("CLOSE")); ws.write(sbuf("CLOSE"));
opcode op; opcode op;
streambuf db; multi_buffer db;
std::size_t count = 0; std::size_t count = 0;
ws.async_read(op, db, ws.async_read(op, db,
[&](error_code ec) [&](error_code ec)
@ -1531,7 +1531,7 @@ public:
}); });
}); });
opcode op; opcode op;
streambuf db; multi_buffer db;
ws.async_read(op, db, ws.async_read(op, db,
[&](error_code ec) [&](error_code ec)
{ {
@ -1562,9 +1562,9 @@ public:
return; return;
ws.write_frame(false, sbuf("u")); ws.write_frame(false, sbuf("u"));
ws.write_frame(true, sbuf("v")); ws.write_frame(true, sbuf("v"));
streambuf sb; multi_buffer b;
opcode op; opcode op;
ws.read(op, sb, ec); ws.read(op, b, ec);
if(! BEAST_EXPECTS(! ec, ec.message())) if(! BEAST_EXPECTS(! ec, ec.message()))
return; return;
} }
@ -1623,7 +1623,7 @@ public:
try try
{ {
opcode op; opcode op;
streambuf db; multi_buffer db;
c.read(ws, op, db); c.read(ws, op, db);
fail(); fail();
throw abort_test{}; throw abort_test{};
@ -1657,7 +1657,7 @@ public:
{ {
// receive echoed message // receive echoed message
opcode op; opcode op;
streambuf db; multi_buffer db;
c.read(ws, op, db); c.read(ws, op, db);
BEAST_EXPECT(op == opcode::text); BEAST_EXPECT(op == opcode::text);
BEAST_EXPECT(to_string(db.data()) == "Hello"); BEAST_EXPECT(to_string(db.data()) == "Hello");
@ -1691,7 +1691,7 @@ public:
{ {
// receive echoed message // receive echoed message
opcode op; opcode op;
streambuf db; multi_buffer db;
c.read(ws, op, db); c.read(ws, op, db);
BEAST_EXPECT(pong == 1); BEAST_EXPECT(pong == 1);
BEAST_EXPECT(op == opcode::binary); BEAST_EXPECT(op == opcode::binary);
@ -1713,7 +1713,7 @@ public:
{ {
// receive echoed message // receive echoed message
opcode op; opcode op;
streambuf db; multi_buffer db;
c.read(ws, op, db); c.read(ws, op, db);
BEAST_EXPECT(pong == 1); BEAST_EXPECT(pong == 1);
BEAST_EXPECT(to_string(db.data()) == "Hello, World!"); BEAST_EXPECT(to_string(db.data()) == "Hello, World!");
@ -1730,9 +1730,9 @@ public:
{ {
// receive echoed message // receive echoed message
opcode op; opcode op;
streambuf sb; multi_buffer b;
c.read(ws, op, sb); c.read(ws, op, b);
BEAST_EXPECT(to_string(sb.data()) == "Now is the time for all good men"); BEAST_EXPECT(to_string(b.data()) == "Now is the time for all good men");
} }
ws.set_option(auto_fragment{false}); ws.set_option(auto_fragment{false});
ws.set_option(write_buffer_size{4096}); ws.set_option(write_buffer_size{4096});
@ -1745,7 +1745,7 @@ public:
{ {
// receive echoed message // receive echoed message
opcode op; opcode op;
streambuf db; multi_buffer db;
c.read(ws, op, db); c.read(ws, op, db);
BEAST_EXPECT(to_string(db.data()) == s); BEAST_EXPECT(to_string(db.data()) == s);
} }
@ -1759,7 +1759,7 @@ public:
{ {
// receive echoed message // receive echoed message
opcode op; opcode op;
streambuf db; multi_buffer db;
c.read(ws, op, db); c.read(ws, op, db);
BEAST_EXPECT(op == opcode::text); BEAST_EXPECT(op == opcode::text);
BEAST_EXPECT(to_string(db.data()) == "Hello"); BEAST_EXPECT(to_string(db.data()) == "Hello");

View File

@ -9,7 +9,7 @@
#include <beast/websocket/detail/utf8_checker.hpp> #include <beast/websocket/detail/utf8_checker.hpp>
#include <beast/core/consuming_buffers.hpp> #include <beast/core/consuming_buffers.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/unit_test/suite.hpp> #include <beast/unit_test/suite.hpp>
#include <array> #include <array>
@ -379,15 +379,15 @@ public:
consuming_buffers< consuming_buffers<
boost::asio::const_buffers_1> cb{ boost::asio::const_buffers_1> cb{
boost::asio::const_buffers_1(s.data(), n)}; boost::asio::const_buffers_1(s.data(), n)};
streambuf sb{size}; multi_buffer b{size};
while(n) while(n)
{ {
auto const amount = (std::min)(n, size); auto const amount = (std::min)(n, size);
sb.commit(buffer_copy(sb.prepare(amount), cb)); b.commit(buffer_copy(b.prepare(amount), cb));
cb.consume(amount); cb.consume(amount);
n -= amount; n -= amount;
} }
BEAST_EXPECT(utf8.write(sb.data())); BEAST_EXPECT(utf8.write(b.data()));
BEAST_EXPECT(utf8.finish()); BEAST_EXPECT(utf8.finish());
} }
} }

View File

@ -9,7 +9,7 @@
#define BEAST_WEBSOCKET_ASYNC_ECHO_SERVER_HPP #define BEAST_WEBSOCKET_ASYNC_ECHO_SERVER_HPP
#include <beast/core/placeholders.hpp> #include <beast/core/placeholders.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/websocket/stream.hpp> #include <beast/websocket/stream.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/optional.hpp> #include <boost/optional.hpp>
@ -216,7 +216,7 @@ private:
beast::websocket::stream<socket_type> ws; beast::websocket::stream<socket_type> ws;
boost::asio::io_service::strand strand; boost::asio::io_service::strand strand;
beast::websocket::opcode op; beast::websocket::opcode op;
beast::streambuf db; beast::multi_buffer db;
std::size_t id; std::size_t id;
data(async_echo_server& server_, data(async_echo_server& server_,

View File

@ -9,7 +9,7 @@
#define BEAST_WEBSOCKET_SYNC_ECHO_SERVER_HPP #define BEAST_WEBSOCKET_SYNC_ECHO_SERVER_HPP
#include <beast/core/placeholders.hpp> #include <beast/core/placeholders.hpp>
#include <beast/core/streambuf.hpp> #include <beast/core/multi_buffer.hpp>
#include <beast/websocket.hpp> #include <beast/websocket.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/optional.hpp> #include <boost/optional.hpp>
@ -306,41 +306,41 @@ private:
for(;;) for(;;)
{ {
beast::websocket::opcode op; beast::websocket::opcode op;
beast::streambuf sb; beast::multi_buffer b;
ws.read(op, sb, ec); ws.read(op, b, ec);
if(ec) if(ec)
{ {
auto const s = ec.message(); auto const s = ec.message();
break; break;
} }
ws.set_option(beast::websocket::message_type{op}); ws.set_option(beast::websocket::message_type{op});
if(match(sb, "RAW")) if(match(b, "RAW"))
{ {
boost::asio::write( boost::asio::write(
ws.next_layer(), sb.data(), ec); ws.next_layer(), b.data(), ec);
} }
else if(match(sb, "TEXT")) else if(match(b, "TEXT"))
{ {
ws.set_option( ws.set_option(
beast::websocket::message_type{ beast::websocket::message_type{
beast::websocket::opcode::text}); beast::websocket::opcode::text});
ws.write(sb.data(), ec); ws.write(b.data(), ec);
} }
else if(match(sb, "PING")) else if(match(b, "PING"))
{ {
beast::websocket::ping_data payload; beast::websocket::ping_data payload;
sb.consume(buffer_copy( b.consume(buffer_copy(
buffer(payload.data(), payload.size()), buffer(payload.data(), payload.size()),
sb.data())); b.data()));
ws.ping(payload, ec); ws.ping(payload, ec);
} }
else if(match(sb, "CLOSE")) else if(match(b, "CLOSE"))
{ {
ws.close({}, ec); ws.close({}, ec);
} }
else else
{ {
ws.write(sb.data(), ec); ws.write(b.data(), ec);
} }
if(ec) if(ec)
break; break;