mirror of
https://github.com/boostorg/beast.git
synced 2025-07-30 04:47:29 +02:00
Rename concept to DynamicBuffer (API change):
Conform to the Networking TS by renaming the Streambuf concept to DynamicBuffer in all places. Values of types meeting the requirements of DynamicBuffer are renamed to dynabuf. See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4478.html#requirements.dynamic_buffers * Headers renamed * Formal parameter names renamed * Template argument types renamed * Documentation updated
This commit is contained in:
@ -11,4 +11,7 @@ API Changes:
|
||||
|
||||
* ci_equal is moved to beast::http namespace, in rfc7230.hpp
|
||||
|
||||
* "DynamicBuffer","dynabuf" renamed from "Streambuf", "streambuf". See:
|
||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4478.html#requirements.dynamic_buffers
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -15,6 +15,11 @@ Requirements:
|
||||
* C++11 or greater
|
||||
* OpenSSL (optional)
|
||||
|
||||
This software is currently in beta: interfaces are subject to change. For
|
||||
recent changes see [CHANGELOG](CHANGELOG).
|
||||
The library has been submitted to the
|
||||
[Boost Library Incubator](http://rrsd.com/blincubator.com/bi_library/beast-2/?gform_post_id=1579)
|
||||
|
||||
Example WebSocket program:
|
||||
```C++
|
||||
#include <beast/to_string.hpp>
|
||||
|
@ -192,11 +192,11 @@ supporting its development.
|
||||
[section:types Type Requirements]
|
||||
[include types/Body.qbk]
|
||||
[include types/BufferSequence.qbk]
|
||||
[include types/DynamicBuffer.qbk]
|
||||
[include types/Field.qbk]
|
||||
[include types/FieldSequence.qbk]
|
||||
[include types/Parser.qbk]
|
||||
[include types/Reader.qbk]
|
||||
[include types/Streambuf.qbk]
|
||||
[include types/Streams.qbk]
|
||||
[include types/Writer.qbk]
|
||||
[endsect]
|
||||
|
@ -25,13 +25,13 @@ libraries:
|
||||
* Let library users make the important decisions such as how to
|
||||
allocate memory or how to leverage flow control.
|
||||
|
||||
Beast formalizes the [link beast.types.Streambuf [*`Streambuf`]] concept,
|
||||
and relies heavily on the Boost.Asio [*`ConstBufferSequence`] and
|
||||
[*`MutableBufferSequence`] concepts for passing buffers to functions.
|
||||
The authors have found the `Streambuf` and buffer sequence interfaces
|
||||
to be optimal for interacting with Asio, and for other tasks such as
|
||||
incremental parsing of data in buffers (for example, parsing websocket
|
||||
frames stored in a [link beast.ref.static_streambuf `static_streambuf`]).
|
||||
Beast uses the [link beast.types.DynamicBuffer [*`DynamicBuffer`]] concept
|
||||
presented in the Netwoking TS, and relies heavily on the Boost.Asio
|
||||
[*`ConstBufferSequence`] and [*`MutableBufferSequence`] concepts for passing
|
||||
buffers to functions. The authors have found the dynamic buffer and buffer
|
||||
sequence interfaces to be optimal for interacting with Asio, and for other
|
||||
tasks such as incremental parsing of data in buffers (for example, parsing
|
||||
websocket frames stored in a [link beast.ref.static_streambuf `static_streambuf`]).
|
||||
|
||||
During the development of Beast the authors have studied other software
|
||||
packages and in particular the comments left during the Boost Review process
|
||||
|
24
doc/http.qbk
24
doc/http.qbk
@ -182,21 +182,9 @@ used in the examples:
|
||||
resp.body = "Here is the data you requested";
|
||||
```
|
||||
|
||||
* [link beast.ref.http__basic_streambuf_body [*`basic_streambuf_body`:]] A body with a
|
||||
`value_type` of `streambuf`. A streambuf is an efficient storage object which
|
||||
uses multiple octet arrays of varying lengths to represent data. Here is
|
||||
a body that uses a `boost::asio::streambuf` as its container:
|
||||
```
|
||||
template<class ConstBufferSequence>
|
||||
http::response<http::basic_streambuf_body<boost::asio::streambuf>>
|
||||
make_response(ConstBufferSequence const& buffers)
|
||||
{
|
||||
http::response<http::streambuf_body<boost::asio::streambuf>> resp;
|
||||
resp.body.commit(boost::asio::buffer_copy(resp.body.prepare(
|
||||
boost::asio::buffer_size(buffers)), buffers));
|
||||
return resp;
|
||||
}
|
||||
```
|
||||
* [link beast.ref.http__streambuf_body [*`streambuf_body`:]] A body with a
|
||||
`value_type` of [link beast.ref.streambuf `streambuf`]: an efficient storage
|
||||
object which uses multiple octet arrays of varying lengths to represent data.
|
||||
|
||||
[heading Sockets]
|
||||
|
||||
@ -234,7 +222,7 @@ When the implementation reads messages from a socket, it can read bytes lying
|
||||
after the end of the message if they are present (the alternative is to read
|
||||
a single byte at a time which is unsuitable for performance reasons). To
|
||||
store and re-use these extra bytes on subsequent messages, the read interface
|
||||
requires an additional paramter: a [link beast.types.Streambuf [*`Streambuf`]]
|
||||
requires an additional paramter: a [link beast.types.DynamicBuffer [*`DynamicBuffer`]]
|
||||
object. This example reads a message from the socket, with the extra bytes
|
||||
stored in the streambuf parameter for use in a subsequent call to read:
|
||||
```
|
||||
@ -264,7 +252,7 @@ called:
|
||||
|
||||
An alternative to using a `boost::asio::streambuf` is to use a
|
||||
[link beast.ref.streambuf `beast::streambuf`], which meets the requirements of
|
||||
[*`Streambuf`] and is optimized for performance:
|
||||
[*`DynamicBuffer`] and is optimized for performance:
|
||||
```
|
||||
void handle_read(boost::system::error_code);
|
||||
...
|
||||
@ -274,7 +262,7 @@ An alternative to using a `boost::asio::streambuf` is to use a
|
||||
```
|
||||
|
||||
The `read` implementation can use any object meeting the requirements of
|
||||
[link beast.types.Streambuf [*`Streambuf`]], allowing callers to define custom
|
||||
[link beast.types.DynamicBuffer [*`DynamicBuffer`]], allowing callers to define custom
|
||||
memory management strategies used by the implementation.
|
||||
|
||||
[endsect]
|
||||
|
@ -29,9 +29,9 @@
|
||||
<entry valign="top">
|
||||
<bridgehead renderas="sect3">Classes</bridgehead>
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.ref.http__basic_dynabuf_body">basic_dynabuf_body</link></member>
|
||||
<member><link linkend="beast.ref.http__basic_headers">basic_headers</link></member>
|
||||
<member><link linkend="beast.ref.http__basic_parser_v1">basic_parser_v1</link></member>
|
||||
<member><link linkend="beast.ref.http__basic_streambuf_body">basic_streambuf_body</link></member>
|
||||
<member><link linkend="beast.ref.http__empty_body">empty_body</link></member>
|
||||
<member><link linkend="beast.ref.http__headers">headers</link></member>
|
||||
<member><link linkend="beast.ref.http__message">message</link></member>
|
||||
@ -130,6 +130,7 @@
|
||||
<member><link linkend="beast.ref.basic_streambuf">basic_streambuf</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.dynabuf_readstream">dynabuf_readstream</link></member>
|
||||
<member><link linkend="beast.ref.error_code">error_code</link></member>
|
||||
<member><link linkend="beast.ref.handler_alloc">handler_alloc</link></member>
|
||||
<member><link linkend="beast.ref.prepared_buffers">prepared_buffers</link></member>
|
||||
@ -137,7 +138,6 @@
|
||||
<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.streambuf">streambuf</link></member>
|
||||
<member><link linkend="beast.ref.streambuf_readstream">streambuf_readstream</link></member>
|
||||
<member><link linkend="beast.ref.system_error">system_error</link></member>
|
||||
</simplelist>
|
||||
</entry>
|
||||
@ -164,8 +164,8 @@
|
||||
<member><link linkend="beast.ref.is_BufferSequence">is_BufferSequence</link></member>
|
||||
<member><link linkend="beast.ref.is_CompletionHandler">is_CompletionHandler</link></member>
|
||||
<member><link linkend="beast.ref.is_ConstBufferSequence">is_ConstBufferSequence</link></member>
|
||||
<member><link linkend="beast.ref.is_DynamicBuffer">is_DynamicBuffer</link></member>
|
||||
<member><link linkend="beast.ref.is_MutableBufferSequence">is_MutableBufferSequence</link></member>
|
||||
<member><link linkend="beast.ref.is_Streambuf">is_Streambuf</link></member>
|
||||
<member><link linkend="beast.ref.is_SyncReadStream">is_SyncReadStream</link></member>
|
||||
<member><link linkend="beast.ref.is_SyncStream">is_SyncStream</link></member>
|
||||
<member><link linkend="beast.ref.is_SyncWriteStream">is_SyncWriteStream</link></member>
|
||||
@ -174,10 +174,10 @@
|
||||
<entry valign="top">
|
||||
<bridgehead renderas="sect3">Concepts</bridgehead>
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.types.BufferSequence">BufferSequence</link></member>
|
||||
<member><link linkend="beast.types.streams.AsyncStream">AsyncStream</link></member>
|
||||
<member><link linkend="beast.types.BufferSequence">BufferSequence</link></member>
|
||||
<member><link linkend="beast.types.DynamicBuffer">DynamicBuffer</link></member>
|
||||
<member><link linkend="beast.types.streams.Stream">Stream</link></member>
|
||||
<member><link linkend="beast.types.Streambuf">Streambuf</link></member>
|
||||
<member><link linkend="beast.types.streams.SyncStream">SyncStream</link></member>
|
||||
</simplelist>
|
||||
</entry>
|
||||
|
@ -1552,15 +1552,15 @@
|
||||
<xsl:when test="declname = 'ConstBufferSequence' or type = 'class ConstBufferSequence'">
|
||||
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*ConstBufferSequence]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="declname = 'DynamicBuffer' or type = 'class DynamicBuffer'">
|
||||
<xsl:text>class ``[link beast.types.DynamicBuffer [*DynamicBuffer]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="declname = 'MutableBufferSequence' or type = 'class MutableBufferSequence'">
|
||||
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*MutableBufferSequence]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="declname = 'Stream' or type = 'class Stream'">
|
||||
<xsl:when test="declname = 'Stream' or type = 'class Stream'">
|
||||
<xsl:text>class ``[link beast.types.streams.Stream [*Stream]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="declname = 'Streambuf' or type = 'class Streambuf'">
|
||||
<xsl:text>class ``[link beast.types.Streambuf [*Streambuf]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="type = 'class SyncStream'">
|
||||
<xsl:text>class ``[link beast.types.streams.SyncStream [*SyncStream]]``</xsl:text>
|
||||
</xsl:when>
|
||||
|
125
doc/types/DynamicBuffer.qbk
Normal file
125
doc/types/DynamicBuffer.qbk
Normal file
@ -0,0 +1,125 @@
|
||||
[/
|
||||
Copyright (c) 2013-2016 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)
|
||||
]
|
||||
|
||||
[section:DynamicBuffer DynamicBuffer]
|
||||
|
||||
A dynamic buffer encapsulates memory storage that may be automatically resized
|
||||
as required, where the memory is divided into an input sequence followed by an
|
||||
output sequence. These memory regions are internal to the dynamic buffer, but
|
||||
direct access to the elements is provided to permit them to be efficiently used
|
||||
with I/O operations, such as the send or receive operations of a socket. Data
|
||||
written to the output sequence of a dynamic buffer object is appended to the
|
||||
input sequence of the same object.
|
||||
|
||||
The interface to this concept is intended to permit the following
|
||||
implementation strategies:
|
||||
|
||||
* A single contiguous octet array, which is reallocated as necessary to
|
||||
accommodate changes in the size of the octet sequence.
|
||||
|
||||
* A sequence of one or more octet arrays, where each array is of the same
|
||||
size. Additional octet array objects are appended to the sequence to
|
||||
accommodate changes in the size of the octet sequence.
|
||||
|
||||
* A sequence of one or more octet arrays of varying sizes. Additional octet
|
||||
array objects are appended to the sequence to accommodate changes in the
|
||||
size of the character sequence. This is the implementation approached
|
||||
currently offered by [link beast.ref.basic_streambuf `basic_streambuf`].
|
||||
|
||||
In the table below:
|
||||
|
||||
* `X` denotes a dynamic buffer class.
|
||||
* `a` denotes a value of type `X`.
|
||||
* `c` denotes a (possibly const) value of type `X`.
|
||||
* `n` denotes a value of type `std::size_t`.
|
||||
* `T` denotes a type meeting the requirements for [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/ConstBufferSequence.html `ConstBufferSequence`].
|
||||
* `U` denotes a type meeting the requirements for [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/MutableBufferSequence.html `MutableBufferSequence`].
|
||||
|
||||
[table DynamicBuffer requirements
|
||||
[[operation] [type] [semantics, pre/post-conditions]]
|
||||
[
|
||||
[`X::const_buffers_type`]
|
||||
[`T`]
|
||||
[
|
||||
This type represents the memory associated with the input sequence.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`X::mutable_buffers_type`]
|
||||
[`U`]
|
||||
[
|
||||
This type represents the memory associated with the output sequence.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`c.size()`]
|
||||
[`std::size_t`]
|
||||
[
|
||||
Returns the size, in bytes, of the input sequence.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`c.max_size()`]
|
||||
[`std::size_t`]
|
||||
[
|
||||
Returns the permitted maximum of the sum of the sizes of the input
|
||||
sequence and output sequence.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`c.capacity()`]
|
||||
[`std::size_t`]
|
||||
[
|
||||
Returns the maximum sum of the sizes of the input sequence and output
|
||||
sequence that the dynamic buffer can hold without requiring reallocation.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`c.data()`]
|
||||
[`X::const_buffers_type`]
|
||||
[
|
||||
Returns a constant buffer sequence u that represents the memory
|
||||
associated with the input sequence, and where `buffer_size(u) == size()`.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`a.prepare(n)`]
|
||||
[`X:mutable_buffers_type`]
|
||||
[
|
||||
Returns a mutable buffer sequence u representing the output sequence,
|
||||
and where `buffer_size(u) == n`. The dynamic buffer reallocates memory
|
||||
as required. All constant or mutable buffer sequences previously
|
||||
obtained using `data()` or `prepare()` are invalidated.
|
||||
|
||||
Throws: `length_error` if `size() + n` exceeds `max_size()`.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`a.commit(n)`]
|
||||
[ ]
|
||||
[
|
||||
Appends `n` bytes from the start of the output sequence to the end of
|
||||
the input sequence. The remainder of the output sequence is discarded.
|
||||
If `n` is greater than the size of the output sequence, the entire
|
||||
output sequence is appended to the input sequence. All constant or
|
||||
mutable buffer sequences previously obtained using `data()` or
|
||||
`prepare()` are invalidated.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`a.consume(n)`]
|
||||
[ ]
|
||||
[
|
||||
Removes `n` bytes from beginning of the input sequence. If `n` is
|
||||
greater than the size of the input sequence, the entire input sequence
|
||||
is removed. All constant or mutable buffer sequences previously
|
||||
obtained using `data()` or `prepare()` are invalidated.
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
[endsect]
|
@ -1,96 +0,0 @@
|
||||
[/
|
||||
Copyright (c) 2013-2016 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)
|
||||
]
|
||||
|
||||
[section:Streambuf Streambuf]
|
||||
|
||||
A [*`Streambuf`] represents a logical octet sequence divided in two sections,
|
||||
the input sequence and the output sequence. Octets are written to the output
|
||||
sequence, then moved to the input sequence where they are available for
|
||||
reading. When some or all of the input sequence is no longer needed, it may
|
||||
be consumed.
|
||||
|
||||
The interface to this concept is intended to permit the following
|
||||
implementation strategies:
|
||||
|
||||
* A single contiguous octet array, which is reallocated as necessary to
|
||||
accommodate changes in the size of the octet sequence.
|
||||
|
||||
* A sequence of one or more octet arrays, where each array is of the same
|
||||
size. Additional octet array objects are appended to the sequence to
|
||||
accommodate changes in the size of the octet sequence.
|
||||
|
||||
* A sequence of one or more octet arrays of varying sizes. Additional octet
|
||||
array objects are appended to the sequence to accommodate changes in the
|
||||
size of the character sequence. This is the implementation approached
|
||||
currently offered by [link beast.ref.basic_streambuf `basic_streambuf`].
|
||||
|
||||
In the table below:
|
||||
|
||||
* `X` denotes a class meeting the requirements of [*`Streambuf`]
|
||||
* `a` denotes a value of type `X`
|
||||
* `n` denotes a value convertible to `std::size_t`
|
||||
* `U`, `T` denote unspecified types.
|
||||
|
||||
[table Streambuf requirements
|
||||
[[operation] [type] [semantics, pre/post-conditions]]
|
||||
[
|
||||
[`X::const_buffers_type`]
|
||||
[`T`]
|
||||
[`T` meets the requirements for [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/ConstBufferSequence.html `ConstBufferSequence`].]
|
||||
]
|
||||
[
|
||||
[`X::mutable_buffers_type`]
|
||||
[`U`]
|
||||
[`U` meets the requirements for [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/MutableBufferSequence.html `MutableBufferSequence`].]
|
||||
]
|
||||
[
|
||||
[`a.commit(n)`]
|
||||
[`void`]
|
||||
[Moves bytes from the output sequence to the input sequence.]
|
||||
]
|
||||
[
|
||||
[`a.consume(n)`]
|
||||
[`void`]
|
||||
[Removes bytes from the input sequence.]
|
||||
]
|
||||
[
|
||||
[`a.data()`]
|
||||
[`T`]
|
||||
[Returns a list of buffers that represents the input sequence.]
|
||||
]
|
||||
[
|
||||
[`a.prepare(n)`]
|
||||
[`U`]
|
||||
[Returns a list of buffers that represents the output sequence, with
|
||||
the given size.]
|
||||
]
|
||||
[
|
||||
[`a.size()`]
|
||||
[`std::size_t`]
|
||||
[Returns the size of the input sequence.]
|
||||
]
|
||||
[
|
||||
[`a.max_size()`]
|
||||
[`std::size_t`]
|
||||
[Returns the maximum size of the stream buffer.]
|
||||
]
|
||||
[
|
||||
[`read_size_helper(a, n)`]
|
||||
[`std::size_t`]
|
||||
[
|
||||
Returns the suggested number of bytes to read into the output
|
||||
sequence where `n` is an upper limit on this value. One possible
|
||||
implementation is to return the number of bytes that may be prepared
|
||||
without causing a dynamic allocation or `n`, whichever is smaller.
|
||||
Calls to `read_size_helper` will be made without namespace
|
||||
qualification, to allow the rules for argument dependent lookup to
|
||||
take effect.
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
[endsect]
|
@ -358,7 +358,7 @@ handler of the corresponding read function.]
|
||||
|
||||
Because calls to read data may return a variable amount of bytes, the
|
||||
interface to calls that read data require an object that meets the requirements
|
||||
of [link beast.types.Streambuf [*`Streambuf`]]. This concept is modeled on
|
||||
of [link beast.types.DynamicBuffer [*`DynamicBuffer`]]. This concept is modeled on
|
||||
[@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/basic_streambuf.html `boost::asio::basic_streambuf`].
|
||||
|
||||
The implementation does not perform queueing or buffering of messages. If
|
||||
|
@ -24,8 +24,8 @@
|
||||
#include <beast/core/static_string.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <beast/core/streambuf_readstream.hpp>
|
||||
#include <beast/core/dynabuf_readstream.hpp>
|
||||
#include <beast/core/to_string.hpp>
|
||||
#include <beast/core/write_streambuf.hpp>
|
||||
#include <beast/core/write_dynabuf.hpp>
|
||||
|
||||
#endif
|
||||
|
@ -18,14 +18,14 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A @b `Streambuf` that uses multiple buffers internally.
|
||||
/** A @b `DynamicBuffer` that uses multiple buffers internally.
|
||||
|
||||
The implementation uses a sequence of one or more character arrays
|
||||
of varying sizes. Additional character array objects are appended to
|
||||
the sequence to accommodate changes in the size of the character
|
||||
sequence.
|
||||
|
||||
@note Meets the requirements of @b Streambuf.
|
||||
@note Meets the requirements of @b `DynamicBuffer`.
|
||||
|
||||
@tparam Allocator The allocator to use for managing memory.
|
||||
*/
|
||||
@ -202,26 +202,37 @@ public:
|
||||
basic_streambuf(std::size_t alloc_size = 1024,
|
||||
Allocator const& alloc = allocator_type{});
|
||||
|
||||
/// Get the associated allocator
|
||||
/// Returns a copy of the associated allocator.
|
||||
allocator_type
|
||||
get_allocator() const
|
||||
{
|
||||
return this->member();
|
||||
}
|
||||
|
||||
/// Get the maximum size of the basic_streambuf.
|
||||
/// Returns the size of the input sequence.
|
||||
size_type
|
||||
size() const
|
||||
{
|
||||
return in_size_;
|
||||
}
|
||||
|
||||
/// Returns the permitted maximum sum of the sizes of the input and output sequence.
|
||||
size_type
|
||||
max_size() const
|
||||
{
|
||||
return std::numeric_limits<std::size_t>::max();
|
||||
}
|
||||
|
||||
/// Get the size of the input sequence.
|
||||
size_type
|
||||
size() const
|
||||
{
|
||||
return in_size_;
|
||||
}
|
||||
/// Returns the maximum sum of the sizes of the input sequence and output sequence the buffer can hold without requiring reallocation.
|
||||
std::size_t
|
||||
capacity() const;
|
||||
|
||||
/** Get a list of buffers that represents the input sequence.
|
||||
|
||||
@note These buffers remain valid across subsequent calls to `prepare`.
|
||||
*/
|
||||
const_buffers_type
|
||||
data() const;
|
||||
|
||||
/** Get a list of buffers that represents the output sequence, with the given size.
|
||||
|
||||
@ -239,22 +250,11 @@ public:
|
||||
void
|
||||
commit(size_type n);
|
||||
|
||||
/** Get a list of buffers that represents the input sequence.
|
||||
|
||||
@note These buffers remain valid across subsequent calls to `prepare`.
|
||||
*/
|
||||
const_buffers_type
|
||||
data() const;
|
||||
|
||||
/// Remove bytes from the input sequence.
|
||||
void
|
||||
consume(size_type n);
|
||||
|
||||
/// Clear everything.
|
||||
void
|
||||
clear();
|
||||
|
||||
// Helper for read_until
|
||||
// Helper for boost::asio::read_until
|
||||
template<class OtherAllocator>
|
||||
friend
|
||||
std::size_t
|
||||
@ -262,6 +262,9 @@ public:
|
||||
OtherAllocator> const& streambuf, std::size_t max_size);
|
||||
|
||||
private:
|
||||
void
|
||||
clear();
|
||||
|
||||
void
|
||||
move_assign(basic_streambuf& other, std::false_type);
|
||||
|
||||
@ -277,20 +280,17 @@ private:
|
||||
void
|
||||
delete_list();
|
||||
|
||||
std::size_t
|
||||
prepare_size() const;
|
||||
|
||||
void
|
||||
debug_check() const;
|
||||
};
|
||||
|
||||
/** Format output to a stream buffer.
|
||||
/** Format output to a @ref basic_streambuf.
|
||||
|
||||
@param streambuf The streambuf to write to.
|
||||
@param streambuf The @ref basic_streambuf to write to.
|
||||
|
||||
@param t The object to write.
|
||||
|
||||
@return The stream buffer.
|
||||
@return A reference to the @ref basic_streambuf.
|
||||
*/
|
||||
template<class Allocator, class T>
|
||||
basic_streambuf<Allocator>&
|
||||
|
@ -35,6 +35,16 @@ struct is_ConstBufferSequence :
|
||||
{
|
||||
};
|
||||
|
||||
/// Determine if `T` meets the requirements of @b `DynamicBuffer`.
|
||||
template<class T>
|
||||
#if GENERATING_DOCS
|
||||
struct is_DynamicBuffer : std::integral_constant<bool, ...>
|
||||
#else
|
||||
struct is_DynamicBuffer : detail::is_DynamicBuffer<T>::type
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
/// Determine if `T` meets the requirements of @b `MutableBufferSequence`.
|
||||
template<class T>
|
||||
#if GENERATING_DOCS
|
||||
@ -46,16 +56,6 @@ struct is_MutableBufferSequence :
|
||||
{
|
||||
};
|
||||
|
||||
/// Determine if `T` meets the requirements of @b `Streambuf`.
|
||||
template<class T>
|
||||
#if GENERATING_DOCS
|
||||
struct is_Streambuf : std::integral_constant<bool, ...>
|
||||
#else
|
||||
struct is_Streambuf : detail::is_Streambuf<T>::type
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
@ -86,7 +86,7 @@ public:
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class is_Streambuf
|
||||
class is_DynamicBuffer
|
||||
{
|
||||
template<class U, class R = std::integral_constant<
|
||||
bool, is_BufferSequence<decltype(
|
||||
|
@ -5,8 +5,8 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_WRITE_STREAMBUF_HPP
|
||||
#define BEAST_DETAIL_WRITE_STREAMBUF_HPP
|
||||
#ifndef BEAST_DETAIL_WRITE_DYNABUF_HPP
|
||||
#define BEAST_DETAIL_WRITE_DYNABUF_HPP
|
||||
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
@ -42,73 +42,73 @@ public:
|
||||
! is_string_literal<T>::value;
|
||||
};
|
||||
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
write_streambuf(Streambuf& streambuf,
|
||||
write_dynabuf(DynamicBuffer& dynabuf,
|
||||
boost::asio::const_buffer const& buffer)
|
||||
{
|
||||
using boost::asio::buffer_copy;
|
||||
using boost::asio::buffer_size;
|
||||
streambuf.commit(buffer_copy(
|
||||
streambuf.prepare(buffer_size(buffer)),
|
||||
dynabuf.commit(buffer_copy(
|
||||
dynabuf.prepare(buffer_size(buffer)),
|
||||
buffer));
|
||||
}
|
||||
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
write_streambuf(Streambuf& streambuf,
|
||||
write_dynabuf(DynamicBuffer& dynabuf,
|
||||
boost::asio::mutable_buffer const& buffer)
|
||||
{
|
||||
using boost::asio::buffer_copy;
|
||||
using boost::asio::buffer_size;
|
||||
streambuf.commit(buffer_copy(
|
||||
streambuf.prepare(buffer_size(buffer)),
|
||||
dynabuf.commit(buffer_copy(
|
||||
dynabuf.prepare(buffer_size(buffer)),
|
||||
buffer));
|
||||
}
|
||||
|
||||
template<class Streambuf, class T>
|
||||
template<class DynamicBuffer, class T>
|
||||
typename std::enable_if<
|
||||
is_BufferConvertible<T>::value &&
|
||||
! std::is_convertible<T, boost::asio::const_buffer>::value &&
|
||||
! std::is_convertible<T, boost::asio::mutable_buffer>::value
|
||||
>::type
|
||||
write_streambuf(Streambuf& streambuf, T const& t)
|
||||
write_dynabuf(DynamicBuffer& dynabuf, T const& t)
|
||||
{
|
||||
using boost::asio::buffer_copy;
|
||||
using boost::asio::buffer_size;
|
||||
auto const buffers = boost::asio::buffer(t);
|
||||
streambuf.commit(buffer_copy(
|
||||
streambuf.prepare(buffer_size(buffers)),
|
||||
dynabuf.commit(buffer_copy(
|
||||
dynabuf.prepare(buffer_size(buffers)),
|
||||
buffers));
|
||||
}
|
||||
|
||||
template<class Streambuf, class Buffers>
|
||||
template<class DynamicBuffer, class Buffers>
|
||||
typename std::enable_if<
|
||||
is_ConstBufferSequence<Buffers>::value &&
|
||||
! is_BufferConvertible<Buffers>::value &&
|
||||
! std::is_convertible<Buffers, boost::asio::const_buffer>::value &&
|
||||
! std::is_convertible<Buffers, boost::asio::mutable_buffer>::value
|
||||
>::type
|
||||
write_streambuf(Streambuf& streambuf, Buffers const& buffers)
|
||||
write_dynabuf(DynamicBuffer& dynabuf, Buffers const& buffers)
|
||||
{
|
||||
using boost::asio::buffer_copy;
|
||||
using boost::asio::buffer_size;
|
||||
streambuf.commit(buffer_copy(
|
||||
streambuf.prepare(buffer_size(buffers)),
|
||||
dynabuf.commit(buffer_copy(
|
||||
dynabuf.prepare(buffer_size(buffers)),
|
||||
buffers));
|
||||
}
|
||||
|
||||
template<class Streambuf, std::size_t N>
|
||||
template<class DynamicBuffer, std::size_t N>
|
||||
void
|
||||
write_streambuf(Streambuf& streambuf, const char (&s)[N])
|
||||
write_dynabuf(DynamicBuffer& dynabuf, const char (&s)[N])
|
||||
{
|
||||
using boost::asio::buffer_copy;
|
||||
streambuf.commit(buffer_copy(
|
||||
streambuf.prepare(N - 1),
|
||||
dynabuf.commit(buffer_copy(
|
||||
dynabuf.prepare(N - 1),
|
||||
boost::asio::buffer(s, N - 1)));
|
||||
}
|
||||
|
||||
template<class Streambuf, class T>
|
||||
template<class DynamicBuffer, class T>
|
||||
typename std::enable_if<
|
||||
! is_string_literal<T>::value &&
|
||||
! is_ConstBufferSequence<T>::value &&
|
||||
@ -116,22 +116,22 @@ typename std::enable_if<
|
||||
! std::is_convertible<T, boost::asio::const_buffer>::value &&
|
||||
! std::is_convertible<T, boost::asio::mutable_buffer>::value
|
||||
>::type
|
||||
write_streambuf(Streambuf& streambuf, T const& t)
|
||||
write_dynabuf(DynamicBuffer& dynabuf, T const& t)
|
||||
{
|
||||
using boost::asio::buffer;
|
||||
using boost::asio::buffer_copy;
|
||||
auto const s = boost::lexical_cast<std::string>(t);
|
||||
streambuf.commit(buffer_copy(
|
||||
streambuf.prepare(s.size()), buffer(s)));
|
||||
dynabuf.commit(buffer_copy(
|
||||
dynabuf.prepare(s.size()), buffer(s)));
|
||||
}
|
||||
|
||||
template<class Streambuf, class T0, class T1, class... TN>
|
||||
template<class DynamicBuffer, class T0, class T1, class... TN>
|
||||
void
|
||||
write_streambuf(Streambuf& streambuf,
|
||||
write_dynabuf(DynamicBuffer& dynabuf,
|
||||
T0 const& t0, T1 const& t1, TN const&... tn)
|
||||
{
|
||||
write_streambuf(streambuf, t0);
|
||||
write_streambuf(streambuf, t1, tn...);
|
||||
write_dynabuf(dynabuf, t0);
|
||||
write_dynabuf(dynabuf, t1, tn...);
|
||||
}
|
||||
|
||||
} // detail
|
@ -5,8 +5,8 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_STREAMBUF_READSTREAM_HPP
|
||||
#define BEAST_STREAMBUF_READSTREAM_HPP
|
||||
#ifndef BEAST_DYNABUF_READSTREAM_HPP
|
||||
#define BEAST_DYNABUF_READSTREAM_HPP
|
||||
|
||||
#include <beast/core/async_completion.hpp>
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
@ -22,11 +22,11 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A @b `Stream` with attached @b `Streambuf` to buffer reads.
|
||||
/** A @b `Stream` with attached @b `DynamicBuffer` to buffer reads.
|
||||
|
||||
This wraps a @b `Stream` implementation so that calls to write are
|
||||
passed through to the underlying stream, while calls to read will
|
||||
first consume the input sequence stored in a @b `Streambuf` which
|
||||
first consume the input sequence stored in a @b `DynamicBuffer` which
|
||||
is part of the object.
|
||||
|
||||
The use-case for this class is different than that of the
|
||||
@ -50,9 +50,9 @@ namespace beast {
|
||||
// Process the next HTTP headers on the stream,
|
||||
// leaving excess bytes behind for the next call.
|
||||
//
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void process_http_message(
|
||||
streambuf_readstream<Streambuf>& stream)
|
||||
dynabuf_readstream<DynamicBuffer>& stream)
|
||||
{
|
||||
// Read up to and including the end of the HTTP
|
||||
// headers, leaving the sequence in the stream's
|
||||
@ -85,24 +85,24 @@ namespace beast {
|
||||
|
||||
@tparam Stream The type of stream to wrap.
|
||||
|
||||
@tparam Streambuf The type of stream buffer to use.
|
||||
@tparam DynamicBuffer The type of stream buffer to use.
|
||||
*/
|
||||
template<class Stream, class Streambuf>
|
||||
class streambuf_readstream
|
||||
template<class Stream, class DynamicBuffer>
|
||||
class dynabuf_readstream
|
||||
{
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
|
||||
template<class Buffers, class Handler>
|
||||
class read_some_op;
|
||||
|
||||
Streambuf sb_;
|
||||
DynamicBuffer sb_;
|
||||
std::size_t capacity_ = 0;
|
||||
Stream next_layer_;
|
||||
|
||||
public:
|
||||
/// The type of the internal buffer
|
||||
using streambuf_type = Streambuf;
|
||||
using dynabuf_type = DynamicBuffer;
|
||||
|
||||
/// The type of the next layer.
|
||||
using next_layer_type =
|
||||
@ -122,14 +122,14 @@ public:
|
||||
@note The behavior of move assignment on or from streams
|
||||
with active or pending operations is undefined.
|
||||
*/
|
||||
streambuf_readstream(streambuf_readstream&&) = default;
|
||||
dynabuf_readstream(dynabuf_readstream&&) = default;
|
||||
|
||||
/** Move assignment.
|
||||
|
||||
@note The behavior of move assignment on or from streams
|
||||
with active or pending operations is undefined.
|
||||
*/
|
||||
streambuf_readstream& operator=(streambuf_readstream&&) = default;
|
||||
dynabuf_readstream& operator=(dynabuf_readstream&&) = default;
|
||||
|
||||
/** Construct the wrapping stream.
|
||||
|
||||
@ -137,7 +137,7 @@ public:
|
||||
*/
|
||||
template<class... Args>
|
||||
explicit
|
||||
streambuf_readstream(Args&&... args);
|
||||
dynabuf_readstream(Args&&... args);
|
||||
|
||||
/// Get a reference to the next layer.
|
||||
next_layer_type&
|
||||
@ -174,7 +174,7 @@ public:
|
||||
by causing the internal buffer size to increase beyond
|
||||
the caller defined maximum.
|
||||
*/
|
||||
Streambuf&
|
||||
DynamicBuffer&
|
||||
buffer()
|
||||
{
|
||||
return sb_;
|
||||
@ -187,7 +187,7 @@ public:
|
||||
by causing the internal buffer size to increase beyond
|
||||
the caller defined maximum.
|
||||
*/
|
||||
Streambuf const&
|
||||
DynamicBuffer const&
|
||||
buffer() const
|
||||
{
|
||||
return sb_;
|
||||
@ -275,6 +275,6 @@ public:
|
||||
|
||||
} // beast
|
||||
|
||||
#include <beast/core/impl/streambuf_readstream.ipp>
|
||||
#include <beast/core/impl/dynabuf_readstream.ipp>
|
||||
|
||||
#endif
|
@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_IMPL_BASIC_STREAMBUF_IPP
|
||||
#define BEAST_IMPL_BASIC_STREAMBUF_IPP
|
||||
|
||||
#include <beast/core/detail/write_streambuf.hpp>
|
||||
#include <beast/core/detail/write_dynabuf.hpp>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
@ -527,6 +527,28 @@ basic_streambuf<Allocator>::basic_streambuf(
|
||||
"basic_streambuf: invalid alloc_size");
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
std::size_t
|
||||
basic_streambuf<Allocator>::capacity() const
|
||||
{
|
||||
auto pos = out_;
|
||||
if(pos == list_.end())
|
||||
return 0;
|
||||
auto n = pos->size() - out_pos_;
|
||||
while(++pos != list_.end())
|
||||
n += pos->size();
|
||||
return in_size_ + n;
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
auto
|
||||
basic_streambuf<Allocator>::
|
||||
data() const ->
|
||||
const_buffers_type
|
||||
{
|
||||
return const_buffers_type(*this);
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
auto
|
||||
basic_streambuf<Allocator>::prepare(size_type n) ->
|
||||
@ -646,14 +668,6 @@ basic_streambuf<Allocator>::commit(size_type n)
|
||||
debug_check();
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
auto
|
||||
basic_streambuf<Allocator>::data() const ->
|
||||
const_buffers_type
|
||||
{
|
||||
return const_buffers_type(*this);
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
void
|
||||
basic_streambuf<Allocator>::consume(size_type n)
|
||||
@ -717,7 +731,8 @@ basic_streambuf<Allocator>::consume(size_type n)
|
||||
|
||||
template<class Allocator>
|
||||
void
|
||||
basic_streambuf<Allocator>::clear()
|
||||
basic_streambuf<Allocator>::
|
||||
clear()
|
||||
{
|
||||
delete_list();
|
||||
list_.clear();
|
||||
@ -795,21 +810,6 @@ basic_streambuf<Allocator>::delete_list()
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the number of bytes which can be
|
||||
// prepared without causing a memory allocation.
|
||||
template<class Allocator>
|
||||
std::size_t
|
||||
basic_streambuf<Allocator>::prepare_size() const
|
||||
{
|
||||
auto pos = out_;
|
||||
if(pos == list_.end())
|
||||
return 0;
|
||||
auto n = pos->size() - out_pos_;
|
||||
while(++pos != list_.end())
|
||||
n += pos->size();
|
||||
return n;
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
void
|
||||
basic_streambuf<Allocator>::debug_check() const
|
||||
@ -855,7 +855,7 @@ std::size_t
|
||||
read_size_helper(basic_streambuf<
|
||||
Allocator> const& streambuf, std::size_t max_size)
|
||||
{
|
||||
auto const avail = streambuf.prepare_size();
|
||||
auto const avail = streambuf.capacity() - streambuf.size();
|
||||
if(avail == 0)
|
||||
return std::min(max_size,
|
||||
std::max<std::size_t>(512, streambuf.alloc_size_));
|
||||
@ -866,7 +866,7 @@ template<class Alloc, class T>
|
||||
basic_streambuf<Alloc>&
|
||||
operator<<(basic_streambuf<Alloc>& streambuf, T const& t)
|
||||
{
|
||||
detail::write_streambuf(streambuf, t);
|
||||
detail::write_dynabuf(streambuf, t);
|
||||
return streambuf;
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,8 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_IMPL_STREAMBUF_READSTREAM_IPP
|
||||
#define BEAST_IMPL_STREAMBUF_READSTREAM_IPP
|
||||
#ifndef BEAST_IMPL_DYNABUF_READSTREAM_HPP
|
||||
#define BEAST_IMPL_DYNABUF_READSTREAM_HPP
|
||||
|
||||
#include <beast/core/bind_handler.hpp>
|
||||
#include <beast/core/handler_concepts.hpp>
|
||||
@ -16,24 +16,24 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
template<class Stream, class Streambuf>
|
||||
template<class Stream, class DynamicBuffer>
|
||||
template<class MutableBufferSequence, class Handler>
|
||||
class streambuf_readstream<
|
||||
Stream, Streambuf>::read_some_op
|
||||
class dynabuf_readstream<
|
||||
Stream, DynamicBuffer>::read_some_op
|
||||
{
|
||||
using alloc_type =
|
||||
handler_alloc<char, Handler>;
|
||||
|
||||
struct data
|
||||
{
|
||||
streambuf_readstream& srs;
|
||||
dynabuf_readstream& srs;
|
||||
MutableBufferSequence bs;
|
||||
Handler h;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_,
|
||||
streambuf_readstream& srs_,
|
||||
dynabuf_readstream& srs_,
|
||||
MutableBufferSequence const& bs_)
|
||||
: srs(srs_)
|
||||
, bs(bs_)
|
||||
@ -50,7 +50,7 @@ public:
|
||||
|
||||
template<class DeducedHandler, class... Args>
|
||||
read_some_op(DeducedHandler&& h,
|
||||
streambuf_readstream& srs, Args&&... args)
|
||||
dynabuf_readstream& srs, Args&&... args)
|
||||
: d_(std::allocate_shared<data>(alloc_type{h},
|
||||
std::forward<DeducedHandler>(h), srs,
|
||||
std::forward<Args>(args)...))
|
||||
@ -94,10 +94,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<class Stream, class Streambuf>
|
||||
template<class Stream, class DynamicBuffer>
|
||||
template<class MutableBufferSequence, class Handler>
|
||||
void
|
||||
streambuf_readstream<Stream, Streambuf>::
|
||||
dynabuf_readstream<Stream, DynamicBuffer>::
|
||||
read_some_op<MutableBufferSequence, Handler>::operator()(
|
||||
error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
@ -155,18 +155,18 @@ read_some_op<MutableBufferSequence, Handler>::operator()(
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class Stream, class Streambuf>
|
||||
template<class Stream, class DynamicBuffer>
|
||||
template<class... Args>
|
||||
streambuf_readstream<Stream, Streambuf>::
|
||||
streambuf_readstream(Args&&... args)
|
||||
dynabuf_readstream<Stream, DynamicBuffer>::
|
||||
dynabuf_readstream(Args&&... args)
|
||||
: next_layer_(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Stream, class Streambuf>
|
||||
template<class Stream, class DynamicBuffer>
|
||||
template<class ConstBufferSequence, class WriteHandler>
|
||||
auto
|
||||
streambuf_readstream<Stream, Streambuf>::
|
||||
dynabuf_readstream<Stream, DynamicBuffer>::
|
||||
async_write_some(ConstBufferSequence const& buffers,
|
||||
WriteHandler&& handler) ->
|
||||
typename async_completion<
|
||||
@ -184,10 +184,10 @@ async_write_some(ConstBufferSequence const& buffers,
|
||||
std::forward<WriteHandler>(handler));
|
||||
}
|
||||
|
||||
template<class Stream, class Streambuf>
|
||||
template<class Stream, class DynamicBuffer>
|
||||
template<class MutableBufferSequence>
|
||||
std::size_t
|
||||
streambuf_readstream<Stream, Streambuf>::
|
||||
dynabuf_readstream<Stream, DynamicBuffer>::
|
||||
read_some(
|
||||
MutableBufferSequence const& buffers)
|
||||
{
|
||||
@ -203,10 +203,10 @@ read_some(
|
||||
return n;
|
||||
}
|
||||
|
||||
template<class Stream, class Streambuf>
|
||||
template<class Stream, class DynamicBuffer>
|
||||
template<class MutableBufferSequence>
|
||||
std::size_t
|
||||
streambuf_readstream<Stream, Streambuf>::
|
||||
dynabuf_readstream<Stream, DynamicBuffer>::
|
||||
read_some(MutableBufferSequence const& buffers,
|
||||
error_code& ec)
|
||||
{
|
||||
@ -232,10 +232,10 @@ read_some(MutableBufferSequence const& buffers,
|
||||
return bytes_transferred;
|
||||
}
|
||||
|
||||
template<class Stream, class Streambuf>
|
||||
template<class Stream, class DynamicBuffer>
|
||||
template<class MutableBufferSequence, class ReadHandler>
|
||||
auto
|
||||
streambuf_readstream<Stream, Streambuf>::
|
||||
dynabuf_readstream<Stream, DynamicBuffer>::
|
||||
async_read_some(
|
||||
MutableBufferSequence const& buffers,
|
||||
ReadHandler&& handler) ->
|
@ -15,7 +15,7 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A @b `Streambuf` with a fixed size internal buffer.
|
||||
/** A @b `DynamicBuffer` with a fixed size internal buffer.
|
||||
|
||||
Ownership of the underlying storage belongs to the derived class.
|
||||
|
||||
|
@ -5,20 +5,20 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_WRITE_STREAMBUF_HPP
|
||||
#define BEAST_WRITE_STREAMBUF_HPP
|
||||
#ifndef BEAST_WRITE_DYNABUF_HPP
|
||||
#define BEAST_WRITE_DYNABUF_HPP
|
||||
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <beast/core/detail/write_streambuf.hpp>
|
||||
#include <beast/core/detail/write_dynabuf.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Write to a Streambuf.
|
||||
/** Write to a @b `DynamicBuffer`.
|
||||
|
||||
This function appends the serialized representation of each provided
|
||||
argument into the stream buffer. It is capable of converting the
|
||||
argument into the dynamic buffer. It is capable of converting the
|
||||
following types of arguments:
|
||||
|
||||
@li `boost::asio::const_buffer`
|
||||
@ -33,29 +33,29 @@ namespace beast {
|
||||
|
||||
For all types not listed above, the function will invoke
|
||||
`boost::lexical_cast` on the argument in an attempt to convert to
|
||||
a string, which is then appended to the stream buffer.
|
||||
a string, which is then appended to the dynamic buffer.
|
||||
|
||||
When this function serializes numbers, it converts them to
|
||||
their text representation as if by a call to `std::to_string`.
|
||||
|
||||
@param streambuf The stream buffer to write to.
|
||||
@param dynabuf The dynamic buffer to write to.
|
||||
|
||||
@param args A list of one or more arguments to write.
|
||||
|
||||
@throws unspecified Any exceptions thrown by `boost::lexical_cast`.
|
||||
|
||||
@note This function participates in overload resolution only if
|
||||
the `streambuf` parameter meets the requirements of @b `Streambuf`.
|
||||
the `dynabuf` parameter meets the requirements of @b `DynamicBuffer`.
|
||||
*/
|
||||
template<class Streambuf, class... Args>
|
||||
template<class DynamicBuffer, class... Args>
|
||||
#if GENERATING_DOCS
|
||||
void
|
||||
#else
|
||||
typename std::enable_if<is_Streambuf<Streambuf>::value>::type
|
||||
typename std::enable_if<is_DynamicBuffer<DynamicBuffer>::value>::type
|
||||
#endif
|
||||
write(Streambuf& streambuf, Args const&... args)
|
||||
write(DynamicBuffer& dynabuf, Args const&... args)
|
||||
{
|
||||
detail::write_streambuf(streambuf, args...);
|
||||
detail::write_dynabuf(dynabuf, args...);
|
||||
}
|
||||
|
||||
} // beast
|
95
include/beast/http/basic_dynabuf_body.hpp
Normal file
95
include/beast/http/basic_dynabuf_body.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 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)
|
||||
//
|
||||
|
||||
#ifndef BEAST_HTTP_BASIC_DYNABUF_BODY_HPP
|
||||
#define BEAST_HTTP_BASIC_DYNABUF_BODY_HPP
|
||||
|
||||
#include <beast/http/body_type.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** A message body represented by a @b `DynamicBuffer`
|
||||
|
||||
Meets the requirements of @b `Body`.
|
||||
*/
|
||||
template<class DynamicBuffer>
|
||||
struct basic_dynabuf_body
|
||||
{
|
||||
/// The type of the `message::body` member
|
||||
using value_type = DynamicBuffer;
|
||||
|
||||
#if GENERATING_DOCS
|
||||
private:
|
||||
#endif
|
||||
|
||||
class reader
|
||||
{
|
||||
value_type& sb_;
|
||||
|
||||
public:
|
||||
template<bool isRequest, class Headers>
|
||||
explicit
|
||||
reader(message<isRequest,
|
||||
basic_dynabuf_body, Headers>& m) noexcept
|
||||
: sb_(m.body)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
write(void const* data,
|
||||
std::size_t size, error_code&) noexcept
|
||||
{
|
||||
using boost::asio::buffer;
|
||||
using boost::asio::buffer_copy;
|
||||
sb_.commit(buffer_copy(
|
||||
sb_.prepare(size), buffer(data, size)));
|
||||
}
|
||||
};
|
||||
|
||||
class writer
|
||||
{
|
||||
DynamicBuffer const& body_;
|
||||
|
||||
public:
|
||||
writer(writer const&) = delete;
|
||||
writer& operator=(writer const&) = delete;
|
||||
|
||||
template<bool isRequest, class Headers>
|
||||
explicit
|
||||
writer(message<
|
||||
isRequest, basic_dynabuf_body, Headers> const& m)
|
||||
: body_(m.body)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
init(error_code& ec)
|
||||
{
|
||||
}
|
||||
|
||||
std::uint64_t
|
||||
content_length() const
|
||||
{
|
||||
return body_.size();
|
||||
}
|
||||
|
||||
template<class Write>
|
||||
boost::tribool
|
||||
operator()(resume_context&&, error_code&, Write&& write)
|
||||
{
|
||||
write(body_.data());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
#endif
|
@ -9,7 +9,6 @@
|
||||
#define BEAST_HTTP_EMPTY_BODY_HPP
|
||||
|
||||
#include <beast/http/body_type.hpp>
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
@ -21,7 +21,7 @@ namespace http {
|
||||
namespace detail {
|
||||
|
||||
template<class Stream,
|
||||
class Streambuf, class Parser, class Handler>
|
||||
class DynamicBuffer, class Parser, class Handler>
|
||||
class parse_op
|
||||
{
|
||||
using alloc_type =
|
||||
@ -30,7 +30,7 @@ class parse_op
|
||||
struct data
|
||||
{
|
||||
Stream& s;
|
||||
Streambuf& sb;
|
||||
DynamicBuffer& db;
|
||||
Parser& p;
|
||||
Handler h;
|
||||
bool started = false;
|
||||
@ -39,9 +39,9 @@ class parse_op
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, Stream& s_,
|
||||
Streambuf& sb_, Parser& p_)
|
||||
DynamicBuffer& sb_, Parser& p_)
|
||||
: s(s_)
|
||||
, sb(sb_)
|
||||
, db(sb_)
|
||||
, p(p_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
@ -101,9 +101,9 @@ public:
|
||||
};
|
||||
|
||||
template<class Stream,
|
||||
class Streambuf, class Parser, class Handler>
|
||||
class DynamicBuffer, class Parser, class Handler>
|
||||
void
|
||||
parse_op<Stream, Streambuf, Parser, Handler>::
|
||||
parse_op<Stream, DynamicBuffer, Parser, Handler>::
|
||||
operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
||||
{
|
||||
auto& d = *d_;
|
||||
@ -115,7 +115,7 @@ operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
||||
case 0:
|
||||
{
|
||||
auto const used =
|
||||
d.p.write(d.sb.data(), ec);
|
||||
d.p.write(d.db.data(), ec);
|
||||
if(ec)
|
||||
{
|
||||
// call handler
|
||||
@ -126,7 +126,7 @@ operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
||||
}
|
||||
if(used > 0)
|
||||
d.started = true;
|
||||
d.sb.consume(used);
|
||||
d.db.consume(used);
|
||||
if(d.p.complete())
|
||||
{
|
||||
// call handler
|
||||
@ -142,8 +142,8 @@ operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
||||
case 1:
|
||||
// read
|
||||
d.state = 2;
|
||||
d.s.async_read_some(d.sb.prepare(
|
||||
read_size_helper(d.sb, 65536)),
|
||||
d.s.async_read_some(d.db.prepare(
|
||||
read_size_helper(d.db, 65536)),
|
||||
std::move(*this));
|
||||
return;
|
||||
|
||||
@ -172,8 +172,8 @@ operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
||||
d.state = 99;
|
||||
break;
|
||||
}
|
||||
d.sb.commit(bytes_transferred);
|
||||
auto const used = d.p.write(d.sb.data(), ec);
|
||||
d.db.commit(bytes_transferred);
|
||||
auto const used = d.p.write(d.db.data(), ec);
|
||||
if(ec)
|
||||
{
|
||||
// call handler
|
||||
@ -182,7 +182,7 @@ operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
||||
}
|
||||
if(used > 0)
|
||||
d.started = true;
|
||||
d.sb.consume(used);
|
||||
d.db.consume(used);
|
||||
if(d.p.complete())
|
||||
{
|
||||
// call handler
|
||||
@ -199,7 +199,7 @@ operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class Stream, class Streambuf,
|
||||
template<class Stream, class DynamicBuffer,
|
||||
bool isRequest, class Body, class Headers,
|
||||
class Handler>
|
||||
class read_op
|
||||
@ -216,7 +216,7 @@ class read_op
|
||||
struct data
|
||||
{
|
||||
Stream& s;
|
||||
Streambuf& sb;
|
||||
DynamicBuffer& db;
|
||||
message_type& m;
|
||||
parser_type p;
|
||||
Handler h;
|
||||
@ -226,9 +226,9 @@ class read_op
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, Stream& s_,
|
||||
Streambuf& sb_, message_type& m_)
|
||||
DynamicBuffer& sb_, message_type& m_)
|
||||
: s(s_)
|
||||
, sb(sb_)
|
||||
, db(sb_)
|
||||
, m(m_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
@ -286,11 +286,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<class Stream, class Streambuf,
|
||||
template<class Stream, class DynamicBuffer,
|
||||
bool isRequest, class Body, class Headers,
|
||||
class Handler>
|
||||
void
|
||||
read_op<Stream, Streambuf, isRequest, Body, Headers, Handler>::
|
||||
read_op<Stream, DynamicBuffer, isRequest, Body, Headers, Handler>::
|
||||
operator()(error_code ec, bool again)
|
||||
{
|
||||
auto& d = *d_;
|
||||
@ -301,7 +301,7 @@ operator()(error_code ec, bool again)
|
||||
{
|
||||
case 0:
|
||||
d.state = 1;
|
||||
async_parse(d.s, d.sb, d.p, std::move(*this));
|
||||
async_parse(d.s, d.db, d.p, std::move(*this));
|
||||
return;
|
||||
|
||||
case 1:
|
||||
@ -318,49 +318,49 @@ operator()(error_code ec, bool again)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class SyncReadStream, class Streambuf, class Parser>
|
||||
template<class SyncReadStream, class DynamicBuffer, class Parser>
|
||||
void
|
||||
parse(SyncReadStream& stream,
|
||||
Streambuf& streambuf, Parser& parser)
|
||||
DynamicBuffer& dynabuf, Parser& parser)
|
||||
{
|
||||
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
||||
"SyncReadStream requirements not met");
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
static_assert(is_Parser<Parser>::value,
|
||||
"Parser requirements not met");
|
||||
error_code ec;
|
||||
parse(stream, streambuf, parser, ec);
|
||||
parse(stream, dynabuf, parser, ec);
|
||||
if(ec)
|
||||
throw boost::system::system_error{ec};
|
||||
}
|
||||
|
||||
template<class SyncReadStream, class Streambuf, class Parser>
|
||||
template<class SyncReadStream, class DynamicBuffer, class Parser>
|
||||
void
|
||||
parse(SyncReadStream& stream, Streambuf& streambuf,
|
||||
parse(SyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||
Parser& parser, error_code& ec)
|
||||
{
|
||||
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
||||
"SyncReadStream requirements not met");
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
static_assert(is_Parser<Parser>::value,
|
||||
"Parser requirements not met");
|
||||
bool started = false;
|
||||
for(;;)
|
||||
{
|
||||
auto used =
|
||||
parser.write(streambuf.data(), ec);
|
||||
parser.write(dynabuf.data(), ec);
|
||||
if(ec)
|
||||
return;
|
||||
streambuf.consume(used);
|
||||
dynabuf.consume(used);
|
||||
if(used > 0)
|
||||
started = true;
|
||||
if(parser.complete())
|
||||
break;
|
||||
streambuf.commit(stream.read_some(
|
||||
streambuf.prepare(read_size_helper(
|
||||
streambuf, 65536)), ec));
|
||||
dynabuf.commit(stream.read_some(
|
||||
dynabuf.prepare(read_size_helper(
|
||||
dynabuf, 65536)), ec));
|
||||
if(ec && ec != boost::asio::error::eof)
|
||||
return;
|
||||
if(ec == boost::asio::error::eof)
|
||||
@ -379,86 +379,86 @@ parse(SyncReadStream& stream, Streambuf& streambuf,
|
||||
}
|
||||
|
||||
template<class AsyncReadStream,
|
||||
class Streambuf, class Parser, class ReadHandler>
|
||||
class DynamicBuffer, class Parser, class ReadHandler>
|
||||
typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
async_parse(AsyncReadStream& stream,
|
||||
Streambuf& streambuf, Parser& parser, ReadHandler&& handler)
|
||||
DynamicBuffer& dynabuf, Parser& parser, ReadHandler&& handler)
|
||||
{
|
||||
static_assert(is_AsyncReadStream<AsyncReadStream>::value,
|
||||
"AsyncReadStream requirements not met");
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
static_assert(is_Parser<Parser>::value,
|
||||
"Parser requirements not met");
|
||||
beast::async_completion<ReadHandler,
|
||||
void(error_code)> completion(handler);
|
||||
detail::parse_op<AsyncReadStream, Streambuf,
|
||||
detail::parse_op<AsyncReadStream, DynamicBuffer,
|
||||
Parser, decltype(completion.handler)>{
|
||||
completion.handler, stream, streambuf, parser};
|
||||
completion.handler, stream, dynabuf, parser};
|
||||
return completion.result.get();
|
||||
}
|
||||
|
||||
template<class SyncReadStream, class Streambuf,
|
||||
template<class SyncReadStream, class DynamicBuffer,
|
||||
bool isRequest, class Body, class Headers>
|
||||
void
|
||||
read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
read(SyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||
message_v1<isRequest, Body, Headers>& msg)
|
||||
{
|
||||
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
||||
"SyncReadStream requirements not met");
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
static_assert(is_ReadableBody<Body>::value,
|
||||
"ReadableBody requirements not met");
|
||||
error_code ec;
|
||||
read(stream, streambuf, msg, ec);
|
||||
read(stream, dynabuf, msg, ec);
|
||||
if(ec)
|
||||
throw system_error{ec};
|
||||
}
|
||||
|
||||
template<class SyncReadStream, class Streambuf,
|
||||
template<class SyncReadStream, class DynamicBuffer,
|
||||
bool isRequest, class Body, class Headers>
|
||||
void
|
||||
read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
read(SyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||
message_v1<isRequest, Body, Headers>& m,
|
||||
error_code& ec)
|
||||
{
|
||||
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
||||
"SyncReadStream requirements not met");
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
static_assert(is_ReadableBody<Body>::value,
|
||||
"ReadableBody requirements not met");
|
||||
parser_v1<isRequest, Body, Headers> p;
|
||||
parse(stream, streambuf, p, ec);
|
||||
parse(stream, dynabuf, p, ec);
|
||||
if(ec)
|
||||
return;
|
||||
assert(p.complete());
|
||||
m = p.release();
|
||||
}
|
||||
|
||||
template<class AsyncReadStream, class Streambuf,
|
||||
template<class AsyncReadStream, class DynamicBuffer,
|
||||
bool isRequest, class Body, class Headers,
|
||||
class ReadHandler>
|
||||
typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
async_read(AsyncReadStream& stream, Streambuf& streambuf,
|
||||
async_read(AsyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||
message_v1<isRequest, Body, Headers>& m,
|
||||
ReadHandler&& handler)
|
||||
{
|
||||
static_assert(is_AsyncReadStream<AsyncReadStream>::value,
|
||||
"AsyncReadStream requirements not met");
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
static_assert(is_ReadableBody<Body>::value,
|
||||
"ReadableBody requirements not met");
|
||||
beast::async_completion<ReadHandler,
|
||||
void(error_code)> completion(handler);
|
||||
detail::read_op<AsyncReadStream, Streambuf,
|
||||
detail::read_op<AsyncReadStream, DynamicBuffer,
|
||||
isRequest, Body, Headers, decltype(
|
||||
completion.handler)>{completion.handler,
|
||||
stream, streambuf, m};
|
||||
stream, dynabuf, m};
|
||||
return completion.result.get();
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <beast/core/write_streambuf.hpp>
|
||||
#include <beast/core/write_dynabuf.hpp>
|
||||
#include <boost/asio/write.hpp>
|
||||
#include <boost/logic/tribool.hpp>
|
||||
#include <condition_variable>
|
||||
@ -32,51 +32,51 @@ namespace http {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class Streambuf, class Body, class Headers>
|
||||
template<class DynamicBuffer, class Body, class Headers>
|
||||
void
|
||||
write_firstline(Streambuf& streambuf,
|
||||
write_firstline(DynamicBuffer& dynabuf,
|
||||
message_v1<true, Body, Headers> const& msg)
|
||||
{
|
||||
write(streambuf, msg.method);
|
||||
write(streambuf, " ");
|
||||
write(streambuf, msg.url);
|
||||
write(streambuf, " HTTP/");
|
||||
write(streambuf, msg.version / 10);
|
||||
write(streambuf, ".");
|
||||
write(streambuf, msg.version % 10);
|
||||
write(streambuf, "\r\n");
|
||||
write(dynabuf, msg.method);
|
||||
write(dynabuf, " ");
|
||||
write(dynabuf, msg.url);
|
||||
write(dynabuf, " HTTP/");
|
||||
write(dynabuf, msg.version / 10);
|
||||
write(dynabuf, ".");
|
||||
write(dynabuf, msg.version % 10);
|
||||
write(dynabuf, "\r\n");
|
||||
}
|
||||
|
||||
template<class Streambuf, class Body, class Headers>
|
||||
template<class DynamicBuffer, class Body, class Headers>
|
||||
void
|
||||
write_firstline(Streambuf& streambuf,
|
||||
write_firstline(DynamicBuffer& dynabuf,
|
||||
message_v1<false, Body, Headers> const& msg)
|
||||
{
|
||||
write(streambuf, "HTTP/");
|
||||
write(streambuf, msg.version / 10);
|
||||
write(streambuf, ".");
|
||||
write(streambuf, msg.version % 10);
|
||||
write(streambuf, " ");
|
||||
write(streambuf, msg.status);
|
||||
write(streambuf, " ");
|
||||
write(streambuf, msg.reason);
|
||||
write(streambuf, "\r\n");
|
||||
write(dynabuf, "HTTP/");
|
||||
write(dynabuf, msg.version / 10);
|
||||
write(dynabuf, ".");
|
||||
write(dynabuf, msg.version % 10);
|
||||
write(dynabuf, " ");
|
||||
write(dynabuf, msg.status);
|
||||
write(dynabuf, " ");
|
||||
write(dynabuf, msg.reason);
|
||||
write(dynabuf, "\r\n");
|
||||
}
|
||||
|
||||
template<class Streambuf, class FieldSequence>
|
||||
template<class DynamicBuffer, class FieldSequence>
|
||||
void
|
||||
write_fields(Streambuf& streambuf, FieldSequence const& fields)
|
||||
write_fields(DynamicBuffer& dynabuf, FieldSequence const& fields)
|
||||
{
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
//static_assert(is_FieldSequence<FieldSequence>::value,
|
||||
// "FieldSequence requirements not met");
|
||||
for(auto const& field : fields)
|
||||
{
|
||||
write(streambuf, field.name());
|
||||
write(streambuf, ": ");
|
||||
write(streambuf, field.value());
|
||||
write(streambuf, "\r\n");
|
||||
write(dynabuf, field.name());
|
||||
write(dynabuf, ": ");
|
||||
write(dynabuf, field.value());
|
||||
write(dynabuf, "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -378,17 +378,17 @@ operator()(error_code ec, std::size_t, bool again)
|
||||
d.copy = {};
|
||||
}
|
||||
|
||||
template<class SyncWriteStream, class Streambuf>
|
||||
template<class SyncWriteStream, class DynamicBuffer>
|
||||
class writef0_lambda
|
||||
{
|
||||
Streambuf const& sb_;
|
||||
DynamicBuffer const& sb_;
|
||||
SyncWriteStream& stream_;
|
||||
bool chunked_;
|
||||
error_code& ec_;
|
||||
|
||||
public:
|
||||
writef0_lambda(SyncWriteStream& stream,
|
||||
Streambuf const& sb, bool chunked, error_code& ec)
|
||||
DynamicBuffer const& sb, bool chunked, error_code& ec)
|
||||
: sb_(sb)
|
||||
, stream_(stream)
|
||||
, chunked_(chunked)
|
||||
@ -548,9 +548,8 @@ async_write(AsyncWriteStream& stream,
|
||||
message_v1<isRequest, Body, Headers> const& msg,
|
||||
WriteHandler&& handler)
|
||||
{
|
||||
static_assert(
|
||||
is_AsyncWriteStream<AsyncWriteStream>::value,
|
||||
"AsyncWriteStream requirements not met");
|
||||
static_assert(is_AsyncWriteStream<AsyncWriteStream>::value,
|
||||
"AsyncWriteStream requirements not met");
|
||||
static_assert(is_WritableBody<Body>::value,
|
||||
"WritableBody requirements not met");
|
||||
beast::async_completion<WriteHandler,
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <beast/core/error.hpp>
|
||||
#include <beast/core/async_completion.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
@ -36,7 +35,7 @@ namespace http {
|
||||
@param stream The stream from which the data is to be read.
|
||||
The type must support the @b `SyncReadStream` concept.
|
||||
|
||||
@param streambuf A `Streambuf` holding additional bytes
|
||||
@param dynabuf A @b `DynamicBuffer` holding additional bytes
|
||||
read by the implementation from the stream. This is both
|
||||
an input and an output parameter; on entry, any data in the
|
||||
stream buffer's input sequence will be given to the parser
|
||||
@ -47,10 +46,10 @@ namespace http {
|
||||
|
||||
@throws boost::system::system_error on failure.
|
||||
*/
|
||||
template<class SyncReadStream, class Streambuf, class Parser>
|
||||
template<class SyncReadStream, class DynamicBuffer, class Parser>
|
||||
void
|
||||
parse(SyncReadStream& stream,
|
||||
Streambuf& streambuf, Parser& parser);
|
||||
DynamicBuffer& dynabuf, Parser& parser);
|
||||
|
||||
/** Parse a HTTP/1 message from a stream.
|
||||
|
||||
@ -71,7 +70,7 @@ parse(SyncReadStream& stream,
|
||||
@param stream The stream from which the data is to be read.
|
||||
The type must support the @b `SyncReadStream` concept.
|
||||
|
||||
@param streambuf A `Streambuf` holding additional bytes
|
||||
@param dynabuf A @b `DynamicBuffer` holding additional bytes
|
||||
read by the implementation from the stream. This is both
|
||||
an input and an output parameter; on entry, any data in the
|
||||
stream buffer's input sequence will be given to the parser
|
||||
@ -82,10 +81,10 @@ parse(SyncReadStream& stream,
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
template<class SyncReadStream, class Streambuf, class Parser>
|
||||
template<class SyncReadStream, class DynamicBuffer, class Parser>
|
||||
void
|
||||
parse(SyncReadStream& stream,
|
||||
Streambuf& streambuf, Parser& parser, error_code& ec);
|
||||
DynamicBuffer& dynabuf, Parser& parser, error_code& ec);
|
||||
|
||||
/** Start an asynchronous operation to parse a HTTP/1 message from a stream.
|
||||
|
||||
@ -106,7 +105,7 @@ parse(SyncReadStream& stream,
|
||||
@param stream The stream from which the data is to be read.
|
||||
The type must support the @b `AsyncReadStream` concept.
|
||||
|
||||
@param streambuf A `Streambuf` holding additional bytes
|
||||
@param dynabuf A @b `DynamicBuffer` holding additional bytes
|
||||
read by the implementation from the stream. This is both
|
||||
an input and an output parameter; on entry, any data in the
|
||||
stream buffer's input sequence will be given to the parser
|
||||
@ -128,14 +127,14 @@ parse(SyncReadStream& stream,
|
||||
manner equivalent to using `boost::asio::io_service::post`.
|
||||
*/
|
||||
template<class AsyncReadStream,
|
||||
class Streambuf, class Parser, class ReadHandler>
|
||||
class DynamicBuffer, class Parser, class ReadHandler>
|
||||
#if GENERATING_DOCS
|
||||
void_or_deduced
|
||||
#else
|
||||
typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
#endif
|
||||
async_parse(AsyncReadStream& stream, Streambuf& streambuf,
|
||||
async_parse(AsyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||
Parser& parser, ReadHandler&& handler);
|
||||
|
||||
/** Read a HTTP/1 message from a stream.
|
||||
@ -157,7 +156,7 @@ async_parse(AsyncReadStream& stream, Streambuf& streambuf,
|
||||
@param stream The stream from which the data is to be read.
|
||||
The type must support the @b `SyncReadStream` concept.
|
||||
|
||||
@param streambuf A `Streambuf` holding additional bytes
|
||||
@param dynabuf A @b `DynamicBuffer` holding additional bytes
|
||||
read by the implementation from the stream. This is both
|
||||
an input and an output parameter; on entry, any data in the
|
||||
stream buffer's input sequence will be given to the parser
|
||||
@ -168,10 +167,10 @@ async_parse(AsyncReadStream& stream, Streambuf& streambuf,
|
||||
|
||||
@throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template<class SyncReadStream, class Streambuf,
|
||||
template<class SyncReadStream, class DynamicBuffer,
|
||||
bool isRequest, class Body, class Headers>
|
||||
void
|
||||
read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
read(SyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||
message_v1<isRequest, Body, Headers>& msg);
|
||||
|
||||
/** Read a HTTP/1 message from a stream.
|
||||
@ -193,7 +192,7 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
@param stream The stream from which the data is to be read.
|
||||
The type must support the @b `SyncReadStream` concept.
|
||||
|
||||
@param streambuf A `Streambuf` holding additional bytes
|
||||
@param dynabuf A @b `DynamicBuffer` holding additional bytes
|
||||
read by the implementation from the stream. This is both
|
||||
an input and an output parameter; on entry, any data in the
|
||||
stream buffer's input sequence will be given to the parser
|
||||
@ -204,10 +203,10 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
template<class SyncReadStream, class Streambuf,
|
||||
template<class SyncReadStream, class DynamicBuffer,
|
||||
bool isRequest, class Body, class Headers>
|
||||
void
|
||||
read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
read(SyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||
message_v1<isRequest, Body, Headers>& msg,
|
||||
error_code& ec);
|
||||
|
||||
@ -229,7 +228,7 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
@param stream The stream to read the message from.
|
||||
The type must support the @b `AsyncReadStream` concept.
|
||||
|
||||
@param streambuf A `Streambuf` holding additional bytes
|
||||
@param dynabuf A @b `DynamicBuffer` holding additional bytes
|
||||
read by the implementation from the stream. This is both
|
||||
an input and an output parameter; on entry, any data in the
|
||||
stream buffer's input sequence will be given to the parser
|
||||
@ -249,7 +248,7 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
this function. Invocation of the handler will be performed in a
|
||||
manner equivalent to using `boost::asio::io_service::post`.
|
||||
*/
|
||||
template<class AsyncReadStream, class Streambuf,
|
||||
template<class AsyncReadStream, class DynamicBuffer,
|
||||
bool isRequest, class Body, class Headers,
|
||||
class ReadHandler>
|
||||
#if GENERATING_DOCS
|
||||
@ -258,7 +257,7 @@ void_or_deduced
|
||||
typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
#endif
|
||||
async_read(AsyncReadStream& stream, Streambuf& streambuf,
|
||||
async_read(AsyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||
message_v1<isRequest, Body, Headers>& msg,
|
||||
ReadHandler&& handler);
|
||||
|
||||
|
@ -8,91 +8,17 @@
|
||||
#ifndef BEAST_HTTP_STREAMBUF_BODY_HPP
|
||||
#define BEAST_HTTP_STREAMBUF_BODY_HPP
|
||||
|
||||
#include <beast/http/body_type.hpp>
|
||||
#include <beast/core/buffer_cat.hpp>
|
||||
#include <beast/http/basic_dynabuf_body.hpp>
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** A message body represented by a Streambuf
|
||||
/** A message body represented by a @ref streambuf
|
||||
|
||||
Meets the requirements of @b `Body`.
|
||||
*/
|
||||
template<class Streambuf>
|
||||
struct basic_streambuf_body
|
||||
{
|
||||
/// The type of the `message::body` member
|
||||
using value_type = Streambuf;
|
||||
|
||||
#if GENERATING_DOCS
|
||||
private:
|
||||
#endif
|
||||
|
||||
class reader
|
||||
{
|
||||
value_type& sb_;
|
||||
|
||||
public:
|
||||
template<bool isRequest, class Headers>
|
||||
explicit
|
||||
reader(message<isRequest,
|
||||
basic_streambuf_body, Headers>& m) noexcept
|
||||
: sb_(m.body)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
write(void const* data,
|
||||
std::size_t size, error_code&) noexcept
|
||||
{
|
||||
using boost::asio::buffer;
|
||||
using boost::asio::buffer_copy;
|
||||
sb_.commit(buffer_copy(
|
||||
sb_.prepare(size), buffer(data, size)));
|
||||
}
|
||||
};
|
||||
|
||||
class writer
|
||||
{
|
||||
Streambuf const& body_;
|
||||
|
||||
public:
|
||||
writer(writer const&) = delete;
|
||||
writer& operator=(writer const&) = delete;
|
||||
|
||||
template<bool isRequest, class Headers>
|
||||
explicit
|
||||
writer(message<
|
||||
isRequest, basic_streambuf_body, Headers> const& m)
|
||||
: body_(m.body)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
init(error_code& ec)
|
||||
{
|
||||
}
|
||||
|
||||
std::uint64_t
|
||||
content_length() const
|
||||
{
|
||||
return body_.size();
|
||||
}
|
||||
|
||||
template<class Write>
|
||||
boost::tribool
|
||||
operator()(resume_context&&, error_code&, Write&& write)
|
||||
{
|
||||
write(body_.data());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
using streambuf_body = basic_streambuf_body<streambuf>;
|
||||
using streambuf_body = basic_dynabuf_body<streambuf>;
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
@ -9,8 +9,7 @@
|
||||
#define BEAST_HTTP_STRING_BODY_HPP
|
||||
|
||||
#include <beast/http/body_type.hpp>
|
||||
#include <beast/core/buffer_cat.hpp>
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
@ -117,11 +117,11 @@ is_valid(close_code::value code)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Write frame header to streambuf
|
||||
// Write frame header to dynamic buffer
|
||||
//
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
write(Streambuf& sb, frame_header const& fh)
|
||||
write(DynamicBuffer& db, frame_header const& fh)
|
||||
{
|
||||
using boost::asio::buffer;
|
||||
using boost::asio::buffer_copy;
|
||||
@ -159,24 +159,24 @@ write(Streambuf& sb, frame_header const& fh)
|
||||
native_to_little_uint32(fh.key, &b[n]);
|
||||
n += 4;
|
||||
}
|
||||
sb.commit(buffer_copy(
|
||||
sb.prepare(n), buffer(b)));
|
||||
db.commit(buffer_copy(
|
||||
db.prepare(n), buffer(b)));
|
||||
}
|
||||
|
||||
// Read fixed frame header
|
||||
// Requires at least 2 bytes
|
||||
//
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
std::size_t
|
||||
read_fh1(frame_header& fh, Streambuf& sb,
|
||||
read_fh1(frame_header& fh, DynamicBuffer& db,
|
||||
role_type role, close_code::value& code)
|
||||
{
|
||||
using boost::asio::buffer;
|
||||
using boost::asio::buffer_copy;
|
||||
using boost::asio::buffer_size;
|
||||
std::uint8_t b[2];
|
||||
assert(buffer_size(sb.data()) >= sizeof(b));
|
||||
sb.consume(buffer_copy(buffer(b), sb.data()));
|
||||
assert(buffer_size(db.data()) >= sizeof(b));
|
||||
db.consume(buffer_copy(buffer(b), db.data()));
|
||||
std::size_t need;
|
||||
fh.len = b[1] & 0x7f;
|
||||
switch(fh.len)
|
||||
@ -236,9 +236,9 @@ read_fh1(frame_header& fh, Streambuf& sb,
|
||||
|
||||
// Decode variable frame header from stream
|
||||
//
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
read_fh2(frame_header& fh, Streambuf& sb,
|
||||
read_fh2(frame_header& fh, DynamicBuffer& db,
|
||||
role_type role, close_code::value& code)
|
||||
{
|
||||
using boost::asio::buffer;
|
||||
@ -250,8 +250,8 @@ read_fh2(frame_header& fh, Streambuf& sb,
|
||||
case 126:
|
||||
{
|
||||
std::uint8_t b[2];
|
||||
assert(buffer_size(sb.data()) >= sizeof(b));
|
||||
sb.consume(buffer_copy(buffer(b), sb.data()));
|
||||
assert(buffer_size(db.data()) >= sizeof(b));
|
||||
db.consume(buffer_copy(buffer(b), db.data()));
|
||||
fh.len = big_uint16_to_native(&b[0]);
|
||||
// length not canonical
|
||||
if(fh.len < 126)
|
||||
@ -264,8 +264,8 @@ read_fh2(frame_header& fh, Streambuf& sb,
|
||||
case 127:
|
||||
{
|
||||
std::uint8_t b[8];
|
||||
assert(buffer_size(sb.data()) >= sizeof(b));
|
||||
sb.consume(buffer_copy(buffer(b), sb.data()));
|
||||
assert(buffer_size(db.data()) >= sizeof(b));
|
||||
db.consume(buffer_copy(buffer(b), db.data()));
|
||||
fh.len = big_uint64_to_native(&b[0]);
|
||||
// length not canonical
|
||||
if(fh.len < 65536)
|
||||
@ -279,8 +279,8 @@ read_fh2(frame_header& fh, Streambuf& sb,
|
||||
if(fh.mask)
|
||||
{
|
||||
std::uint8_t b[4];
|
||||
assert(buffer_size(sb.data()) >= sizeof(b));
|
||||
sb.consume(buffer_copy(buffer(b), sb.data()));
|
||||
assert(buffer_size(db.data()) >= sizeof(b));
|
||||
db.consume(buffer_copy(buffer(b), db.data()));
|
||||
fh.key = little_uint32_to_native(&b[0]);
|
||||
}
|
||||
else
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <beast/http/empty_body.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/string_body.hpp>
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
@ -107,15 +106,13 @@ protected:
|
||||
void
|
||||
prepare_fh(close_code::value& code);
|
||||
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
write_close(Streambuf& sb,
|
||||
close_reason const& rc);
|
||||
write_close(DynamicBuffer& db, close_reason const& rc);
|
||||
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
write_ping(Streambuf& sb, opcode op,
|
||||
ping_data const& data);
|
||||
write_ping(DynamicBuffer& db, opcode op, ping_data const& data);
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
@ -23,7 +23,7 @@ namespace websocket {
|
||||
// processes any received control frames.
|
||||
//
|
||||
template<class NextLayer>
|
||||
template<class Streambuf, class Handler>
|
||||
template<class DynamicBuffer, class Handler>
|
||||
class stream<NextLayer>::read_frame_op
|
||||
{
|
||||
using alloc_type =
|
||||
@ -35,27 +35,27 @@ class stream<NextLayer>::read_frame_op
|
||||
using fmb_type =
|
||||
typename fb_type::mutable_buffers_type;
|
||||
|
||||
using smb_type =
|
||||
typename Streambuf::mutable_buffers_type;
|
||||
using dmb_type =
|
||||
typename DynamicBuffer::mutable_buffers_type;
|
||||
|
||||
struct data : op
|
||||
{
|
||||
stream<NextLayer>& ws;
|
||||
frame_info& fi;
|
||||
Streambuf& sb;
|
||||
DynamicBuffer& db;
|
||||
Handler h;
|
||||
fb_type fb;
|
||||
boost::optional<smb_type> smb;
|
||||
boost::optional<dmb_type> dmb;
|
||||
boost::optional<fmb_type> fmb;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, stream<NextLayer>& ws_,
|
||||
frame_info& fi_, Streambuf& sb_)
|
||||
frame_info& fi_, DynamicBuffer& sb_)
|
||||
: ws(ws_)
|
||||
, fi(fi_)
|
||||
, sb(sb_)
|
||||
, db(sb_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(h))
|
||||
@ -127,9 +127,9 @@ public:
|
||||
};
|
||||
|
||||
template<class NextLayer>
|
||||
template<class Buffers, class Handler>
|
||||
template<class DynamicBuffer, class Handler>
|
||||
void
|
||||
stream<NextLayer>::read_frame_op<Buffers, Handler>::
|
||||
stream<NextLayer>::read_frame_op<DynamicBuffer, Handler>::
|
||||
operator()(error_code ec, std::size_t bytes_transferred)
|
||||
{
|
||||
auto& d = *d_;
|
||||
@ -139,9 +139,9 @@ operator()(error_code ec, std::size_t bytes_transferred)
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
template<class Buffers, class Handler>
|
||||
template<class DynamicBuffer, class Handler>
|
||||
void
|
||||
stream<NextLayer>::read_frame_op<Buffers, Handler>::
|
||||
stream<NextLayer>::read_frame_op<DynamicBuffer, Handler>::
|
||||
operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
||||
{
|
||||
enum
|
||||
@ -187,18 +187,18 @@ operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
||||
|
||||
case do_read_payload:
|
||||
d.state = do_read_payload + 1;
|
||||
d.smb = d.sb.prepare(
|
||||
d.dmb = d.db.prepare(
|
||||
detail::clamp(d.ws.rd_need_));
|
||||
// receive payload data
|
||||
d.ws.stream_.async_read_some(
|
||||
*d.smb, std::move(*this));
|
||||
*d.dmb, std::move(*this));
|
||||
return;
|
||||
|
||||
case do_read_payload + 1:
|
||||
{
|
||||
d.ws.rd_need_ -= bytes_transferred;
|
||||
auto const pb = prepare_buffers(
|
||||
bytes_transferred, *d.smb);
|
||||
bytes_transferred, *d.dmb);
|
||||
if(d.ws.rd_fh_.mask)
|
||||
detail::mask_inplace(pb, d.ws.rd_key_);
|
||||
if(d.ws.rd_opcode_ == opcode::text)
|
||||
@ -213,7 +213,7 @@ operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
||||
break;
|
||||
}
|
||||
}
|
||||
d.sb.commit(bytes_transferred);
|
||||
d.db.commit(bytes_transferred);
|
||||
if(d.ws.rd_need_ > 0)
|
||||
{
|
||||
d.state = do_read_payload;
|
||||
|
@ -17,7 +17,7 @@ namespace websocket {
|
||||
// read an entire message
|
||||
//
|
||||
template<class NextLayer>
|
||||
template<class Streambuf, class Handler>
|
||||
template<class DynamicBuffer, class Handler>
|
||||
class stream<NextLayer>::read_op
|
||||
{
|
||||
using alloc_type =
|
||||
@ -27,7 +27,7 @@ class stream<NextLayer>::read_op
|
||||
{
|
||||
stream<NextLayer>& ws;
|
||||
opcode& op;
|
||||
Streambuf& sb;
|
||||
DynamicBuffer& db;
|
||||
Handler h;
|
||||
frame_info fi;
|
||||
bool cont;
|
||||
@ -36,10 +36,10 @@ class stream<NextLayer>::read_op
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_,
|
||||
stream<NextLayer>& ws_, opcode& op_,
|
||||
Streambuf& sb_)
|
||||
DynamicBuffer& sb_)
|
||||
: ws(ws_)
|
||||
, op(op_)
|
||||
, sb(sb_)
|
||||
, db(sb_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(h))
|
||||
@ -98,9 +98,9 @@ public:
|
||||
};
|
||||
|
||||
template<class NextLayer>
|
||||
template<class Streambuf, class Handler>
|
||||
template<class DynamicBuffer, class Handler>
|
||||
void
|
||||
stream<NextLayer>::read_op<Streambuf, Handler>::
|
||||
stream<NextLayer>::read_op<DynamicBuffer, Handler>::
|
||||
operator()(error_code const& ec, bool again)
|
||||
{
|
||||
auto& d = *d_;
|
||||
@ -117,9 +117,9 @@ operator()(error_code const& ec, bool again)
|
||||
// the handler is moved from the data block
|
||||
// before asio_handler_deallocate is called.
|
||||
d.ws.async_read_frame(
|
||||
d.fi, d.sb, std::move(*this));
|
||||
d.fi, d.db, std::move(*this));
|
||||
#else
|
||||
d.ws.async_read_frame(d.fi, d.sb, *this);
|
||||
d.ws.async_read_frame(d.fi, d.db, *this);
|
||||
#endif
|
||||
return;
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include <beast/core/prepare_buffers.hpp>
|
||||
#include <beast/core/static_streambuf.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
@ -94,10 +93,10 @@ stream_base::prepare_fh(close_code::value& code)
|
||||
}
|
||||
}
|
||||
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
stream_base::write_close(
|
||||
Streambuf& sb, close_reason const& cr)
|
||||
DynamicBuffer& db, close_reason const& cr)
|
||||
{
|
||||
using namespace boost::endian;
|
||||
frame_header fh;
|
||||
@ -111,7 +110,7 @@ stream_base::write_close(
|
||||
fh.mask = role_ == detail::role_type::client;
|
||||
if(fh.mask)
|
||||
fh.key = maskgen_();
|
||||
detail::write(sb, fh);
|
||||
detail::write(db, fh);
|
||||
if(cr.code != close_code::none)
|
||||
{
|
||||
detail::prepared_key_type key;
|
||||
@ -121,29 +120,29 @@ stream_base::write_close(
|
||||
std::uint8_t b[2];
|
||||
::new(&b[0]) big_uint16_buf_t{
|
||||
(std::uint16_t)cr.code};
|
||||
auto d = sb.prepare(2);
|
||||
auto d = db.prepare(2);
|
||||
boost::asio::buffer_copy(d,
|
||||
boost::asio::buffer(b));
|
||||
if(fh.mask)
|
||||
detail::mask_inplace(d, key);
|
||||
sb.commit(2);
|
||||
db.commit(2);
|
||||
}
|
||||
if(! cr.reason.empty())
|
||||
{
|
||||
auto d = sb.prepare(cr.reason.size());
|
||||
auto d = db.prepare(cr.reason.size());
|
||||
boost::asio::buffer_copy(d,
|
||||
boost::asio::const_buffer(
|
||||
cr.reason.data(), cr.reason.size()));
|
||||
if(fh.mask)
|
||||
detail::mask_inplace(d, key);
|
||||
sb.commit(cr.reason.size());
|
||||
db.commit(cr.reason.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
stream_base::write_ping(Streambuf& sb,
|
||||
stream_base::write_ping(DynamicBuffer& db,
|
||||
opcode op, ping_data const& data)
|
||||
{
|
||||
frame_header fh;
|
||||
@ -156,19 +155,19 @@ stream_base::write_ping(Streambuf& sb,
|
||||
fh.mask = role_ == role_type::client;
|
||||
if(fh.mask)
|
||||
fh.key = maskgen_();
|
||||
detail::write(sb, fh);
|
||||
detail::write(db, fh);
|
||||
if(data.empty())
|
||||
return;
|
||||
detail::prepared_key_type key;
|
||||
if(fh.mask)
|
||||
detail::prepare_key(key, fh.key);
|
||||
auto d = sb.prepare(data.size());
|
||||
auto d = db.prepare(data.size());
|
||||
boost::asio::buffer_copy(d,
|
||||
boost::asio::const_buffers_1(
|
||||
data.data(), data.size()));
|
||||
if(fh.mask)
|
||||
detail::mask_inplace(d, key);
|
||||
sb.commit(data.size());
|
||||
db.commit(data.size());
|
||||
}
|
||||
|
||||
} // detail
|
||||
@ -453,10 +452,10 @@ void
|
||||
stream<NextLayer>::
|
||||
ping(ping_data const& payload, error_code& ec)
|
||||
{
|
||||
detail::frame_streambuf sb;
|
||||
detail::frame_streambuf db;
|
||||
write_ping<static_streambuf>(
|
||||
sb, opcode::ping, payload);
|
||||
boost::asio::write(stream_, sb.data(), ec);
|
||||
db, opcode::ping, payload);
|
||||
boost::asio::write(stream_, db.data(), ec);
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
@ -477,31 +476,35 @@ async_ping(ping_data const& payload, PingHandler&& handler)
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
stream<NextLayer>::
|
||||
read(opcode& op, Streambuf& streambuf)
|
||||
read(opcode& op, DynamicBuffer& dynabuf)
|
||||
{
|
||||
static_assert(is_SyncStream<next_layer_type>::value,
|
||||
"SyncStream requirements not met");
|
||||
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
error_code ec;
|
||||
read(op, streambuf, ec);
|
||||
read(op, dynabuf, ec);
|
||||
if(ec)
|
||||
throw system_error{ec};
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
stream<NextLayer>::
|
||||
read(opcode& op, Streambuf& streambuf, error_code& ec)
|
||||
read(opcode& op, DynamicBuffer& dynabuf, error_code& ec)
|
||||
{
|
||||
static_assert(is_SyncStream<next_layer_type>::value,
|
||||
"SyncStream requirements not met");
|
||||
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
frame_info fi;
|
||||
for(;;)
|
||||
{
|
||||
read_frame(fi, streambuf, ec);
|
||||
read_frame(fi, dynabuf, ec);
|
||||
if(ec)
|
||||
break;
|
||||
op = fi.op;
|
||||
@ -511,47 +514,51 @@ read(opcode& op, Streambuf& streambuf, error_code& ec)
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
template<class Streambuf, class ReadHandler>
|
||||
template<class DynamicBuffer, class ReadHandler>
|
||||
typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
stream<NextLayer>::
|
||||
async_read(opcode& op,
|
||||
Streambuf& streambuf, ReadHandler&& handler)
|
||||
DynamicBuffer& dynabuf, ReadHandler&& handler)
|
||||
{
|
||||
static_assert(is_AsyncStream<next_layer_type>::value,
|
||||
"AsyncStream requirements requirements not met");
|
||||
static_assert(beast::is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
beast::async_completion<
|
||||
ReadHandler, void(error_code)
|
||||
> completion(handler);
|
||||
read_op<Streambuf, decltype(completion.handler)>{
|
||||
completion.handler, *this, op, streambuf};
|
||||
read_op<DynamicBuffer, decltype(completion.handler)>{
|
||||
completion.handler, *this, op, dynabuf};
|
||||
return completion.result.get();
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
stream<NextLayer>::
|
||||
read_frame(frame_info& fi, Streambuf& streambuf)
|
||||
read_frame(frame_info& fi, DynamicBuffer& dynabuf)
|
||||
{
|
||||
static_assert(is_SyncStream<next_layer_type>::value,
|
||||
"SyncStream requirements not met");
|
||||
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
error_code ec;
|
||||
read_frame(fi, streambuf, ec);
|
||||
read_frame(fi, dynabuf, ec);
|
||||
if(ec)
|
||||
throw system_error{ec};
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
stream<NextLayer>::
|
||||
read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
||||
read_frame(frame_info& fi, DynamicBuffer& dynabuf, error_code& ec)
|
||||
{
|
||||
static_assert(is_SyncStream<next_layer_type>::value,
|
||||
"SyncStream requirements not met");
|
||||
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
close_code::value code{};
|
||||
for(;;)
|
||||
{
|
||||
@ -630,7 +637,7 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
||||
}
|
||||
}
|
||||
// read payload
|
||||
auto smb = streambuf.prepare(
|
||||
auto smb = dynabuf.prepare(
|
||||
detail::clamp(rd_need_));
|
||||
auto const bytes_transferred =
|
||||
stream_.read_some(smb, ec);
|
||||
@ -652,7 +659,7 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
||||
break;
|
||||
}
|
||||
}
|
||||
streambuf.commit(bytes_transferred);
|
||||
dynabuf.commit(bytes_transferred);
|
||||
fi.op = rd_opcode_;
|
||||
fi.fin = rd_fh_.fin && rd_need_ == 0;
|
||||
return;
|
||||
@ -686,21 +693,21 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
template<class Streambuf, class ReadHandler>
|
||||
template<class DynamicBuffer, class ReadHandler>
|
||||
typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
stream<NextLayer>::
|
||||
async_read_frame(frame_info& fi,
|
||||
Streambuf& streambuf, ReadHandler&& handler)
|
||||
DynamicBuffer& dynabuf, ReadHandler&& handler)
|
||||
{
|
||||
static_assert(is_AsyncStream<next_layer_type>::value,
|
||||
"AsyncStream requirements requirements not met");
|
||||
static_assert(beast::is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
beast::async_completion<
|
||||
ReadHandler, void(error_code)> completion(handler);
|
||||
read_frame_op<Streambuf, decltype(completion.handler)>{
|
||||
completion.handler, *this, fi, streambuf};
|
||||
read_frame_op<DynamicBuffer, decltype(completion.handler)>{
|
||||
completion.handler, *this, fi, dynabuf};
|
||||
return completion.result.get();
|
||||
}
|
||||
|
||||
@ -712,6 +719,9 @@ write(ConstBufferSequence const& buffers)
|
||||
{
|
||||
static_assert(is_SyncStream<next_layer_type>::value,
|
||||
"SyncStream requirements not met");
|
||||
static_assert(beast::is_ConstBufferSequence<
|
||||
ConstBufferSequence>::value,
|
||||
"ConstBufferSequence requirements not met");
|
||||
error_code ec;
|
||||
write(buffers, ec);
|
||||
if(ec)
|
||||
@ -774,6 +784,9 @@ write_frame(bool fin, ConstBufferSequence const& buffers)
|
||||
{
|
||||
static_assert(is_SyncStream<next_layer_type>::value,
|
||||
"SyncStream requirements not met");
|
||||
static_assert(beast::is_ConstBufferSequence<
|
||||
ConstBufferSequence>::value,
|
||||
"ConstBufferSequence requirements not met");
|
||||
error_code ec;
|
||||
write_frame(fin, buffers, ec);
|
||||
if(ec)
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <beast/websocket/detail/stream_base.hpp>
|
||||
#include <beast/http/message_v1.hpp>
|
||||
#include <beast/http/string_body.hpp>
|
||||
#include <beast/core/streambuf_readstream.hpp>
|
||||
#include <beast/core/dynabuf_readstream.hpp>
|
||||
#include <beast/core/async_completion.hpp>
|
||||
#include <beast/core/detail/get_lowest_layer.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
@ -78,7 +78,7 @@ struct frame_info
|
||||
@par Concepts
|
||||
@b `AsyncStream`,
|
||||
@b `Decorator`,
|
||||
@b `Streambuf`,
|
||||
@b `DynamicBuffer`,
|
||||
@b `SyncStream`
|
||||
*/
|
||||
template<class NextLayer>
|
||||
@ -86,7 +86,7 @@ class stream : public detail::stream_base
|
||||
{
|
||||
friend class stream_test;
|
||||
|
||||
streambuf_readstream<NextLayer, streambuf> stream_;
|
||||
dynabuf_readstream<NextLayer, streambuf> stream_;
|
||||
|
||||
public:
|
||||
/// The type of the next layer.
|
||||
@ -567,7 +567,7 @@ public:
|
||||
|
||||
@throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
// VFALCO TODO This should also take a streambuf with any leftover bytes.
|
||||
// VFALCO TODO This should also take a DynamicBuffer with any leftover bytes.
|
||||
template<class Body, class Headers>
|
||||
void
|
||||
accept(http::request_v1<Body, Headers> const& request);
|
||||
@ -1007,14 +1007,14 @@ public:
|
||||
@param op A value to receive the message type.
|
||||
This object must remain valid until the handler is called.
|
||||
|
||||
@param streambuf A stream buffer to hold the message data.
|
||||
This object must remain valid until the handler is called.
|
||||
@param dynabuf A dynamic buffer to hold the message data after
|
||||
any masking or decompression has been applied.
|
||||
|
||||
@throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
read(opcode& op, Streambuf& streambuf);
|
||||
read(opcode& op, DynamicBuffer& dynabuf);
|
||||
|
||||
/** Read a message from the stream.
|
||||
|
||||
@ -1042,15 +1042,14 @@ public:
|
||||
@param op A value to receive the message type.
|
||||
This object must remain valid until the handler is called.
|
||||
|
||||
@param streambuf A stream buffer to hold the message data.
|
||||
This object must remain valid until the handler is called.
|
||||
@param dynabuf A dynamic buffer to hold the message data after
|
||||
any masking or decompression has been applied.
|
||||
|
||||
@param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
read(opcode& op,
|
||||
Streambuf& streambuf, error_code& ec);
|
||||
read(opcode& op, DynamicBuffer& dynabuf, error_code& ec);
|
||||
|
||||
/** Start an asynchronous operation to read a message from the stream.
|
||||
|
||||
@ -1086,8 +1085,9 @@ public:
|
||||
@param op A value to receive the message type.
|
||||
This object must remain valid until the handler is called.
|
||||
|
||||
@param streambuf A stream buffer to hold the message data.
|
||||
This object must remain valid until the handler is called.
|
||||
@param dynabuf A dynamic buffer to hold the message data after
|
||||
any masking or decompression has been applied. This object must
|
||||
remain valid until the handler is called.
|
||||
|
||||
@param handler The handler to be called when the read operation
|
||||
completes. Copies will be made of the handler as required. The
|
||||
@ -1102,15 +1102,14 @@ public:
|
||||
this function. Invocation of the handler will be performed in a
|
||||
manner equivalent to using `boost::asio::io_service::post`.
|
||||
*/
|
||||
template<class Streambuf, class ReadHandler>
|
||||
template<class DynamicBuffer, class ReadHandler>
|
||||
#if GENERATING_DOCS
|
||||
void_or_deduced
|
||||
#else
|
||||
typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
#endif
|
||||
async_read(opcode& op,
|
||||
Streambuf& streambuf, ReadHandler&& handler);
|
||||
async_read(opcode& op, DynamicBuffer& dynabuf, ReadHandler&& handler);
|
||||
|
||||
/** Read a message frame from the stream.
|
||||
|
||||
@ -1141,13 +1140,14 @@ public:
|
||||
|
||||
@param fi An object to store metadata about the message.
|
||||
|
||||
@param streambuf A stream buffer to hold the message data.
|
||||
@param dynabuf A dynamic buffer to hold the message data after
|
||||
any masking or decompression has been applied.
|
||||
|
||||
@throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
read_frame(frame_info& fi, Streambuf& streambuf);
|
||||
read_frame(frame_info& fi, DynamicBuffer& dynabuf);
|
||||
|
||||
/** Read a message frame from the stream.
|
||||
|
||||
@ -1178,13 +1178,14 @@ public:
|
||||
|
||||
@param fi An object to store metadata about the message.
|
||||
|
||||
@param streambuf A stream buffer to hold the message data.
|
||||
@param dynabuf A dynamic buffer to hold the message data after
|
||||
any masking or decompression has been applied.
|
||||
|
||||
@param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
template<class Streambuf>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec);
|
||||
read_frame(frame_info& fi, DynamicBuffer& dynabuf, error_code& ec);
|
||||
|
||||
/** Start an asynchronous operation to read a message frame from the stream.
|
||||
|
||||
@ -1225,7 +1226,7 @@ public:
|
||||
@param fi An object to store metadata about the message.
|
||||
This object must remain valid until the handler is called.
|
||||
|
||||
@param streambuf A stream buffer to hold the message data after
|
||||
@param dynabuf A dynamic buffer to hold the message data after
|
||||
any masking or decompression has been applied. This object must
|
||||
remain valid until the handler is called.
|
||||
|
||||
@ -1242,7 +1243,7 @@ public:
|
||||
this function. Invocation of the handler will be performed in a
|
||||
manner equivalent to using boost::asio::io_service::post().
|
||||
*/
|
||||
template<class Streambuf, class ReadHandler>
|
||||
template<class DynamicBuffer, class ReadHandler>
|
||||
#if GENERATING_DOCS
|
||||
void_or_deduced
|
||||
#else
|
||||
@ -1250,7 +1251,7 @@ public:
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
#endif
|
||||
async_read_frame(frame_info& fi,
|
||||
Streambuf& streambuf, ReadHandler&& handler);
|
||||
DynamicBuffer& dynabuf, ReadHandler&& handler);
|
||||
|
||||
/** Write a message to the stream.
|
||||
|
||||
@ -1495,8 +1496,8 @@ private:
|
||||
template<class Handler> class response_op;
|
||||
template<class Buffers, class Handler> class write_op;
|
||||
template<class Buffers, class Handler> class write_frame_op;
|
||||
template<class Streambuf, class Handler> class read_op;
|
||||
template<class Streambuf, class Handler> class read_frame_op;
|
||||
template<class DynamicBuffer, class Handler> class read_op;
|
||||
template<class DynamicBuffer, class Handler> class read_frame_op;
|
||||
|
||||
void
|
||||
reset();
|
||||
|
@ -21,6 +21,7 @@ unit-test core-tests :
|
||||
core/buffer_concepts.cpp
|
||||
core/buffers_adapter.cpp
|
||||
core/consuming_buffers.cpp
|
||||
core/dynabuf_readstream.cpp
|
||||
core/error.cpp
|
||||
core/handler_alloc.cpp
|
||||
core/handler_concepts.cpp
|
||||
@ -30,9 +31,8 @@ unit-test core-tests :
|
||||
core/static_string.cpp
|
||||
core/stream_concepts.cpp
|
||||
core/streambuf.cpp
|
||||
core/streambuf_readstream.cpp
|
||||
core/to_string.cpp
|
||||
core/write_streambuf.cpp
|
||||
core/write_dynabuf.cpp
|
||||
core/detail/base64.cpp
|
||||
core/detail/empty_base_optimization.cpp
|
||||
core/detail/get_lowest_layer.cpp
|
||||
@ -41,6 +41,7 @@ unit-test core-tests :
|
||||
|
||||
unit-test http-tests :
|
||||
../extras/beast/unit_test/main.cpp
|
||||
http/basic_dynabuf_body.cpp
|
||||
http/basic_headers.cpp
|
||||
http/basic_parser_v1.cpp
|
||||
http/body_type.cpp
|
||||
|
@ -15,6 +15,7 @@ add_executable (core-tests
|
||||
buffer_concepts.cpp
|
||||
buffers_adapter.cpp
|
||||
consuming_buffers.cpp
|
||||
dynabuf_readstream.cpp
|
||||
error.cpp
|
||||
handler_alloc.cpp
|
||||
handler_concepts.cpp
|
||||
@ -24,9 +25,8 @@ add_executable (core-tests
|
||||
static_string.cpp
|
||||
stream_concepts.cpp
|
||||
streambuf.cpp
|
||||
streambuf_readstream.cpp
|
||||
to_string.cpp
|
||||
write_streambuf.cpp
|
||||
write_dynabuf.cpp
|
||||
detail/base64.cpp
|
||||
detail/empty_base_optimization.cpp
|
||||
detail/get_lowest_layer.cpp
|
||||
|
@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <beast/core/streambuf_readstream.hpp>
|
||||
#include <beast/core/dynabuf_readstream.hpp>
|
||||
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <beast/test/fail_stream.hpp>
|
||||
@ -17,11 +17,11 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
class streambuf_readstream_test
|
||||
class dynabuf_readstream_test
|
||||
: public unit_test::suite
|
||||
, public test::enable_yield_to
|
||||
{
|
||||
using self = streambuf_readstream_test;
|
||||
using self = dynabuf_readstream_test;
|
||||
|
||||
public:
|
||||
void testSpecialMembers()
|
||||
@ -29,16 +29,16 @@ public:
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
boost::asio::io_service ios;
|
||||
{
|
||||
streambuf_readstream<socket_type, streambuf> srs(ios);
|
||||
streambuf_readstream<socket_type, streambuf> srs2(std::move(srs));
|
||||
dynabuf_readstream<socket_type, streambuf> srs(ios);
|
||||
dynabuf_readstream<socket_type, streambuf> srs2(std::move(srs));
|
||||
srs = std::move(srs2);
|
||||
expect(&srs.get_io_service() == &ios);
|
||||
expect(&srs.get_io_service() == &srs2.get_io_service());
|
||||
}
|
||||
{
|
||||
socket_type sock(ios);
|
||||
streambuf_readstream<socket_type&, streambuf> srs(sock);
|
||||
streambuf_readstream<socket_type&, streambuf> srs2(std::move(srs));
|
||||
dynabuf_readstream<socket_type&, streambuf> srs(sock);
|
||||
dynabuf_readstream<socket_type&, streambuf> srs2(std::move(srs));
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ public:
|
||||
{
|
||||
test::fail_stream<
|
||||
test::string_stream> fs(n, ios_, ", world!");
|
||||
streambuf_readstream<
|
||||
dynabuf_readstream<
|
||||
decltype(fs)&, streambuf> srs(fs);
|
||||
srs.buffer().commit(buffer_copy(
|
||||
srs.buffer().prepare(5), buffer("Hello", 5)));
|
||||
@ -73,7 +73,7 @@ public:
|
||||
{
|
||||
test::fail_stream<
|
||||
test::string_stream> fs(n, ios_, ", world!");
|
||||
streambuf_readstream<
|
||||
dynabuf_readstream<
|
||||
decltype(fs)&, streambuf> srs(fs);
|
||||
srs.capacity(3);
|
||||
srs.buffer().commit(buffer_copy(
|
||||
@ -92,7 +92,7 @@ public:
|
||||
{
|
||||
test::fail_stream<
|
||||
test::string_stream> fs(n, ios_, ", world!");
|
||||
streambuf_readstream<
|
||||
dynabuf_readstream<
|
||||
decltype(fs)&, streambuf> srs(fs);
|
||||
srs.buffer().commit(buffer_copy(
|
||||
srs.buffer().prepare(5), buffer("Hello", 5)));
|
||||
@ -111,7 +111,7 @@ public:
|
||||
{
|
||||
test::fail_stream<
|
||||
test::string_stream> fs(n, ios_, ", world!");
|
||||
streambuf_readstream<
|
||||
dynabuf_readstream<
|
||||
decltype(fs)&, streambuf> srs(fs);
|
||||
srs.capacity(3);
|
||||
srs.buffer().commit(buffer_copy(
|
||||
@ -137,7 +137,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(streambuf_readstream,core,beast);
|
||||
BEAST_DEFINE_TESTSUITE(dynabuf_readstream,core,beast);
|
||||
|
||||
} // beast
|
||||
|
@ -6,14 +6,14 @@
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <beast/core/write_streambuf.hpp>
|
||||
#include <beast/core/write_dynabuf.hpp>
|
||||
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <beast/unit_test/suite.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class write_streambuf_test : public beast::unit_test::suite
|
||||
class write_dynabuf_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void run() override
|
||||
@ -31,6 +31,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(write_streambuf,core,beast);
|
||||
BEAST_DEFINE_TESTSUITE(write_dynabuf,core,beast);
|
||||
|
||||
} // beast
|
@ -7,6 +7,7 @@ GroupSources(test/http "/")
|
||||
add_executable (http-tests
|
||||
${BEAST_INCLUDES}
|
||||
../../extras/beast/unit_test/main.cpp
|
||||
basic_dynabuf_body.cpp
|
||||
basic_headers.cpp
|
||||
basic_parser_v1.cpp
|
||||
body_type.cpp
|
||||
|
9
test/http/basic_dynabuf_body.cpp
Normal file
9
test/http/basic_dynabuf_body.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 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/http/basic_dynabuf_body.hpp>
|
@ -11,7 +11,7 @@
|
||||
#include "message_fuzz.hpp"
|
||||
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <beast/core/write_streambuf.hpp>
|
||||
#include <beast/core/write_dynabuf.hpp>
|
||||
#include <beast/core/detail/ci_char_traits.hpp>
|
||||
#include <beast/http/rfc7230.hpp>
|
||||
#include <beast/unit_test/suite.hpp>
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_HTTP_TEST_MESSAGE_FUZZ_HPP
|
||||
#define BEAST_HTTP_TEST_MESSAGE_FUZZ_HPP
|
||||
|
||||
#include <beast/core/write_streambuf.hpp>
|
||||
#include <beast/core/write_dynabuf.hpp>
|
||||
#include <beast/http/detail/basic_parser_v1.hpp>
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
|
Reference in New Issue
Block a user