forked from boostorg/beast
Tidy up tests, build scripts, and documentation:
* Concepts split up into individual files * Function definitions moved to .ipp files * Add more tests to fill gaps in coverage * Fix documentation Xsl
This commit is contained in:
10
TODO.txt
10
TODO.txt
@@ -1,3 +1,5 @@
|
||||
* Add writer::prepare(msg&) interface to set Content-Type
|
||||
|
||||
General:
|
||||
* Use SFINAE on return values (search for "class =")
|
||||
|
||||
@@ -13,18 +15,21 @@ Docs:
|
||||
* melpon sandbox?
|
||||
* Check DOXYGEN, GENERATIC_DOCS directives in source
|
||||
- See if we can include them now that xsl is fixed
|
||||
* Implement cleanup-param to remove spaces around template arguments
|
||||
e.g. in basic_streambuf move constructor members
|
||||
|
||||
Core:
|
||||
* Replace Jamroot with Jamfile
|
||||
* Fix bidirectional buffers iterators operator->()
|
||||
* Tidy up type_checks
|
||||
- Derive from std::integral_constant
|
||||
* Complete allocator testing in basic_streambuf, basic_headers
|
||||
|
||||
WebSocket:
|
||||
* optimized versions of key/masking, choose prepared_key size
|
||||
* invokable unit test
|
||||
* Finish up all of static_string including tests
|
||||
* Don't rely on default constructible mutable buffers
|
||||
type in read_frame_op (smb_type). To see the error, use
|
||||
boost::asio::streambuf in websocket_async_echo_peer
|
||||
|
||||
HTTP:
|
||||
* Define Parser concept in HTTP
|
||||
@@ -37,3 +42,4 @@ HTTP:
|
||||
* HTTP parser trailers with test
|
||||
* URL parser, strong URL checking in HTTP parser
|
||||
* Update for rfc7230
|
||||
* Consider rename to MessageBody concept
|
||||
|
@@ -103,6 +103,11 @@ WARN_LOGFILE =
|
||||
# Configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = \
|
||||
../include/beast/ \
|
||||
../include/beast/http \
|
||||
../include/beast/websocket \
|
||||
../include/beast/doc_debug.hpp \
|
||||
|
||||
../include/beast/async_completion.hpp \
|
||||
../include/beast/basic_streambuf.hpp \
|
||||
../include/beast/bind_handler.hpp \
|
||||
@@ -121,7 +126,7 @@ INPUT = \
|
||||
../include/beast/websocket.hpp \
|
||||
../include/beast/write_streambuf.hpp \
|
||||
../include/beast/http/basic_headers.hpp \
|
||||
../include/beast/http/basic_parser.hpp \
|
||||
../include/beast/http/basic_parser_v1.hpp \
|
||||
../include/beast/http/body_writer.hpp \
|
||||
../include/beast/http/chunk_encode.hpp \
|
||||
../include/beast/http/empty_body.hpp \
|
||||
|
@@ -186,7 +186,12 @@ documentation is based.
|
||||
|
||||
[include http.qbk]
|
||||
[include websocket.qbk]
|
||||
[include types.qbk]
|
||||
|
||||
[section:types Type Requirements]
|
||||
[include core_types.qbk]
|
||||
[include http_types.qbk]
|
||||
[endsect]
|
||||
|
||||
[include design.qbk]
|
||||
[section:quickref Quick Reference]
|
||||
[xinclude quickref.xml]
|
||||
|
118
doc/core_types.qbk
Normal file
118
doc/core_types.qbk
Normal file
@@ -0,0 +1,118 @@
|
||||
[/
|
||||
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:BufferSequence BufferSequence]
|
||||
|
||||
A `BufferSequence` is a type meeting either of the following requirements:
|
||||
|
||||
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*`ConstBufferSequence`]]
|
||||
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*`MutableBufferSequence`]]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section:stream Streams]
|
||||
|
||||
Stream types represent objects capable of performing synchronous or
|
||||
asynchronous I/O. They are based on concepts from `boost::asio`.
|
||||
|
||||
[heading:Stream Stream]
|
||||
|
||||
A type modeling [*`Stream`] meets either or both of the following requirements:
|
||||
|
||||
* [link beast.types.stream.AsyncStream [*`AsyncStream`]]
|
||||
* [link beast.types.stream.SyncStream [*`SyncStream`]]
|
||||
|
||||
[heading:AsyncStream AsyncStream]
|
||||
|
||||
A type modeling [*`AsyncStream`] meets the following requirements:
|
||||
|
||||
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncReadStream.html [*`AsyncReadStream`]]
|
||||
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncWriteStream.html [*`AsyncWriteStream`]]
|
||||
|
||||
[heading:SyncStream SyncStream]
|
||||
|
||||
A type modeling [*`SyncStream`] meets the following requirements:
|
||||
|
||||
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncReadStream.html [*`SyncReadStream`]]
|
||||
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncWriteStream.html [*`SyncWriteStream`]]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section:Streambuf Streambuf]
|
||||
|
||||
In the table below:
|
||||
|
||||
* `X` denotes a class
|
||||
* `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 `ConstBufferSequence`.]
|
||||
]
|
||||
[
|
||||
[`X::mutable_buffers_type`]
|
||||
[`U`]
|
||||
[`U` meets the requirements for `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 `Streambuf`.]
|
||||
]
|
||||
[
|
||||
[`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]
|
@@ -8,7 +8,7 @@
|
||||
[section:design Design choices]
|
||||
|
||||
The implementations are driven by business needs of cryptocurrency server
|
||||
applications ([link https://ripple.com Ripple] written in C++. These
|
||||
applications ([@https://ripple.com Ripple] written in C++. These
|
||||
needs were not met by existing solutions so new code was written. The new
|
||||
code tries to avoid design flaws encountered in the already-existing software
|
||||
libraries:
|
||||
@@ -194,8 +194,8 @@ start. Other design goals:
|
||||
|
||||
The WebSocket implementation [*does] provides support for shutting down
|
||||
the TLS connection through the use of the ADL compile-time virtual functions
|
||||
[link beast.ref.wsproto__teardown `teardown`] and
|
||||
[link beast.ref.wsproto__async_teardown `async_teardown`]. These will
|
||||
[link beast.ref.websocket__teardown `teardown`] and
|
||||
[link beast.ref.websocket__async_teardown `async_teardown`]. These will
|
||||
properly close the connection as per rfc6455 and overloads are available
|
||||
for TLS streams. Callers may provide their own overloads of these functions
|
||||
for user-defined next layer types.
|
||||
|
77
doc/http.qbk
77
doc/http.qbk
@@ -9,7 +9,7 @@
|
||||
|
||||
Beast.HTTP offers programmers simple and performant models of HTTP messages and
|
||||
their associated operations including synchronous and asynchronous reading and
|
||||
writing using Boost.Asio.
|
||||
writing of messages in the HTTP/1 wire format using Boost.Asio.
|
||||
|
||||
The HTTP protocol is described fully in
|
||||
[@https://tools.ietf.org/html/rfc2616 rfc2616]
|
||||
@@ -25,20 +25,43 @@ compliant with the Hypertext Transfer Protocol and the supplements that
|
||||
follow. Unfortunately reliable implementations or industry standards do not
|
||||
exist in C++.
|
||||
|
||||
Beast.HTTP is built on Boost.Asio and uses HTTP parser from NodeJS, which is
|
||||
extensively field tested and exceptionally robust. A proposal to add networking
|
||||
functionality to the C++ standard library, based on Boost.Asio, is under
|
||||
consideration by the standards committee. Since the final approved networking
|
||||
interface for the C++ standard library will likely closely resemble the current
|
||||
interface of Boost.Asio, it is logical for Beast.HTTP to use Boost.Asio as its
|
||||
network transport.
|
||||
Beast.HTTP is built on Boost.Asio and uses its own robust header-only HTTP/1
|
||||
message parser modeled after the nodejs http-parser (written in C). A proposal
|
||||
to add networking functionality to the C++ standard library, based on
|
||||
Boost.Asio, is under consideration by the standards committee. Since the final
|
||||
approved networking interface for the C++ standard library will likely closely
|
||||
resemble the current interface of Boost.Asio, it is logical for Beast.HTTP to
|
||||
use Boost.Asio as its network transport.
|
||||
|
||||
[heading Scope]
|
||||
[endsect]
|
||||
|
||||
The scope of this library is meant to include only the functionality of
|
||||
modeling the HTTP message, serializing and deserializing the message, and
|
||||
sending and receiving messages on sockets or streams. It is designed to
|
||||
be a building block for creating higher level abstractions.
|
||||
|
||||
|
||||
[section:scope Scope]
|
||||
|
||||
This library is designed to be a building block for creating higher level
|
||||
libraries. It is not designed to be end-user facing. There is no convenient
|
||||
class that implements the core of a web server, nor is there a convenient
|
||||
class to quickly perform common operations such as fetching a file or
|
||||
connecting and retrieving a document from a secure connection. These
|
||||
use-cases are important. But this library does not try to do that. Instead,
|
||||
it offers primitives that can be used to build those user-facing algorithms.
|
||||
|
||||
A HTTP message (referred to hereafter as "message") contains request or
|
||||
response specific attributes, a series of zero or more name/value pairs
|
||||
(collectively termed "headers"), and a series of octets called the message
|
||||
body which may be zero in length. The HTTP protocol defines the client and
|
||||
server roles: clients send messages called requests and servers send back
|
||||
messages called responses. `http::message` models both requests and responses.
|
||||
Beast aims to offer this functionality:
|
||||
|
||||
* [*Model]: Provide a universal HTTP message class model.
|
||||
|
||||
* [*Build]: Construct a new message and manipulate its contents.
|
||||
|
||||
* [*Parse]: Deserialize a message from a network or memory stream in HTTP/1 wire format.
|
||||
|
||||
* [*Serialize]: Serialize a message into a network or memory stream in HTTP/1 wire format.
|
||||
|
||||
[note The documentation which follows assumes familiarity with
|
||||
both Boost.Asio and the HTTP protocol specification described in
|
||||
@@ -59,35 +82,17 @@ both Boost.Asio and the HTTP protocol specification described in
|
||||
```
|
||||
]
|
||||
|
||||
A HTTP message (referred to hereafter as "message") contains a request or
|
||||
response line, a series of zero or more name/value pairs (collectively
|
||||
termed "headers"), and a series of octets called the message body which may
|
||||
be zero in length. The HTTP protocol defines the client and server roles:
|
||||
clients send messages called requests and servers send back messages called
|
||||
responses. `http::message` models both requests and responses. The library
|
||||
provides interfaces to perform these operations on messages:
|
||||
|
||||
* [*Parse] a new message from a series of octets.
|
||||
|
||||
* [*Assemble] a new message from scratch or from an existing message.
|
||||
|
||||
* [*Serialize] a message into a series of octets.
|
||||
|
||||
* [*Read] a message from a stream. This can be thought of as a compound
|
||||
operation; a network read, followed by a [*parse].
|
||||
|
||||
* [*Write] a message to a stream. This can be thought of as a compound
|
||||
operation: a [*serialize] followed by a network write.
|
||||
|
||||
In the paragraphs that follow we describe simple interfaces that will serve
|
||||
the majority of users looking merely to interact with a HTTP server, or
|
||||
handle simple HTTP requests from clients. Subsequent sections cover the
|
||||
message model in more depth, for advanced applications.
|
||||
In the paragraphs that follow we describe the available interfaces for
|
||||
performing typical operations such as interacting with a HTTP server
|
||||
or handling simple requests. Subsequent sections cover the message model
|
||||
and its customization points in more depth, for advanced applications.
|
||||
|
||||
[heading Declarations]
|
||||
|
||||
To do anything, a message must be declared. The message class template
|
||||
requires at mininum, a bool indicating whether the message is a request
|
||||
requires at mininum, a value indicating whether the message is a request
|
||||
(versus a response), and a `Body` type. The choice of `Body` determines the
|
||||
kind of container used to represent the message body. Here we will
|
||||
declare a request that has a `std::string` for the body container:
|
||||
|
@@ -5,8 +5,6 @@
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
[section:types Type Requirements]
|
||||
|
||||
|
||||
|
||||
[section:Body Body]
|
||||
@@ -57,10 +55,10 @@ In this table:
|
||||
|
||||
[section:BufferSequence BufferSequence]
|
||||
|
||||
A `BufferSequence` meets [*one of] the following requirements:
|
||||
A `BufferSequence` is a type meeting either of the following requirements:
|
||||
|
||||
* `ConstBufferSequence`
|
||||
* `MutableBufferSequence`
|
||||
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*`ConstBufferSequence`]]
|
||||
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*`MutableBufferSequence`]]
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -223,7 +221,7 @@ In this table:
|
||||
* `m` denotes a value of type `message const&` where
|
||||
`std::is_same<decltype(m.body), Body::value_type>:value == true`.
|
||||
|
||||
* `rc` is an object of type [link beast.reference.http__resume_context resume_context].
|
||||
* `rc` is an object of type [link beast.ref.http__resume_context resume_context].
|
||||
|
||||
* `ec` is a value of type `error_code&`.
|
||||
|
||||
@@ -373,74 +371,3 @@ public:
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section:Stream Stream]
|
||||
|
||||
A `Stream` meets the following requirements:
|
||||
|
||||
* `SyncReadStream`
|
||||
* `SyncWriteStream`
|
||||
* `AsyncReadStream`
|
||||
* `AsyncWriteStream`
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section:Streambuf Streambuf]
|
||||
|
||||
In the table below, `X` denotes a class, `a` denotes a value
|
||||
of type `X`, `n` denotes a value convertible to `std::size_t`,
|
||||
and `U` and `T` denote unspecified types.
|
||||
|
||||
[table Streambuf requirements
|
||||
[[operation] [type] [semantics, pre/post-conditions]]
|
||||
[
|
||||
[`X::const_buffers_type`]
|
||||
[`T`]
|
||||
[`T` meets the requirements for `ConstBufferSequence`.]
|
||||
]
|
||||
[
|
||||
[`X::mutable_buffers_type`]
|
||||
[`U`]
|
||||
[`U` meets the requirements for `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 `Streambuf`.]
|
||||
]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[endsect]
|
@@ -30,7 +30,7 @@
|
||||
<bridgehead renderas="sect3">Classes</bridgehead>
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.ref.http__basic_headers">basic_headers</link></member>
|
||||
<member><link linkend="beast.ref.http__basic_parser">basic_parser</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__error_code">error_code</link></member>
|
||||
@@ -42,7 +42,7 @@
|
||||
</simplelist>
|
||||
<bridgehead renderas="sect3">Type Traits</bridgehead>
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.ref.http__is_Body">is_Body</link></member>
|
||||
<member><link linkend="beast.ref.http__is_Parser">is_Parser</link></member>
|
||||
</simplelist>
|
||||
</entry>
|
||||
<entry valign="top">
|
||||
@@ -50,9 +50,14 @@
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.ref.http__async_read">async_read</link></member>
|
||||
<member><link linkend="beast.ref.http__async_write">async_write</link></member>
|
||||
<member><link linkend="beast.ref.http__prepare">prepare</link></member>
|
||||
<member><link linkend="beast.ref.http__read">read</link></member>
|
||||
<member><link linkend="beast.ref.http__write">write</link></member>
|
||||
</simplelist>
|
||||
<bridgehead renderas="sect3">Constants</bridgehead>
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.ref.http__connection">connection</link></member>
|
||||
</simplelist>
|
||||
<bridgehead renderas="sect3">Concepts</bridgehead>
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.types.Body">Body</link></member>
|
||||
@@ -66,7 +71,6 @@
|
||||
<bridgehead renderas="sect3">Classes</bridgehead>
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.ref.websocket__close_reason">close_reason</link></member>
|
||||
<member><link linkend="beast.ref.websocket__static_string">static_string</link></member>
|
||||
<member><link linkend="beast.ref.websocket__stream">stream</link></member>
|
||||
</simplelist>
|
||||
<bridgehead renderas="sect3">Options</bridgehead>
|
||||
@@ -119,6 +123,7 @@
|
||||
<member><link linkend="beast.ref.prepared_buffers">prepared_buffers</link></member>
|
||||
<member><link linkend="beast.ref.static_streambuf">static_streambuf</link></member>
|
||||
<member><link linkend="beast.ref.static_streambuf_n">static_streambuf_n</link></member>
|
||||
<member><link linkend="beast.ref.static_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>
|
||||
</simplelist>
|
||||
@@ -128,20 +133,24 @@
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.ref.bind_handler">bind_handler</link></member>
|
||||
<member><link linkend="beast.ref.buffer_cat">buffer_cat</link></member>
|
||||
<member><link linkend="beast.ref.consumed_buffers">consumed_buffers</link></member>
|
||||
<member><link linkend="beast.ref.prepare_buffer">prepare_buffer</link></member>
|
||||
<member><link linkend="beast.ref.prepare_buffers">prepare_buffers</link></member>
|
||||
<member><link linkend="beast.ref.to_string">to_string</link></member>
|
||||
|
||||
<member><link linkend="beast.ref.write">write</link></member>
|
||||
</simplelist>
|
||||
</entry>
|
||||
<entry valign="top">
|
||||
<bridgehead renderas="sect3">Type Traits</bridgehead>
|
||||
<simplelist type="vert" columns="1">
|
||||
|
||||
<member><link linkend="beast.ref.is_AsyncReadStream">is_AsyncReadStream</link></member>
|
||||
<member><link linkend="beast.ref.is_AsyncWriteStream">is_AsyncWriteStream</link></member>
|
||||
<member><link linkend="beast.ref.is_AsyncStream">is_AsyncStream</link></member>
|
||||
<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_Handler">is_Handler</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>
|
||||
@@ -153,8 +162,30 @@
|
||||
<bridgehead renderas="sect3">Concepts</bridgehead>
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.types.BufferSequence">BufferSequence</link></member>
|
||||
<member><link linkend="beast.types.Stream">Stream</link></member>
|
||||
<member><link linkend="beast.types.stream.AsyncStream">AsyncStream</link></member>
|
||||
<member><link linkend="beast.types.stream.Stream">Stream</link></member>
|
||||
<member><link linkend="beast.types.Streambuf">Streambuf</link></member>
|
||||
<member><link linkend="beast.types.stream.SyncStream">SyncStream</link></member>
|
||||
</simplelist>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
<tgroup cols="1">
|
||||
<colspec colname="a"/>
|
||||
<thead>
|
||||
<row>
|
||||
<entry valign="center" namest="a" nameend="a">
|
||||
<bridgehead renderas="sect2">Diagnostic</bridgehead>
|
||||
</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry valign="top">
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.ref.doc_debug">doc_debug</link></member>
|
||||
<member><link linkend="beast.ref.nested__nested_doc_debug">nested_doc_debug</link></member>
|
||||
</simplelist>
|
||||
</entry>
|
||||
</row>
|
||||
|
@@ -43,6 +43,7 @@
|
||||
<xsl:when test="@kind='class' or @kind='struct'">
|
||||
<xsl:if test="
|
||||
contains(compoundname, 'beast::') and
|
||||
not(contains(compoundname, 'boost::')) and
|
||||
not(contains(compoundname, '::detail')) and
|
||||
not(contains(compoundname, 'rfc2616')) and
|
||||
not(contains(@prot, 'private'))">
|
||||
@@ -61,7 +62,6 @@
|
||||
<xsl:text>
[endsect]</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!--========== Utilities ==========-->
|
||||
|
||||
<xsl:template name="strip-beast-ns">
|
||||
@@ -73,6 +73,9 @@
|
||||
<xsl:when test="contains($name, 'beast::')">
|
||||
<xsl:value-of select="substring-after($name, 'beast::')"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="$name = 'beast'">
|
||||
<xsl:text></xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$name"/>
|
||||
</xsl:otherwise>
|
||||
@@ -108,6 +111,38 @@
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="cleanup-param">
|
||||
<xsl:param name="name"/>
|
||||
<xsl:variable name="clean">
|
||||
<xsl:value-of select="$name"/>
|
||||
</xsl:variable>
|
||||
<xsl:choose>
|
||||
<xsl:when test="' *' = substring($clean, string-length($clean) - 1)">
|
||||
<xsl:value-of select="substring($clean, 1, string-length($clean) - 2)"/>
|
||||
<xsl:text>*</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="' &' = substring($clean, string-length($clean) - 1)">
|
||||
<xsl:value-of select="substring($clean, 1, string-length($clean) - 2)"/>
|
||||
<xsl:text>&</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="' &...' = substring($clean, string-length($clean) - 4)">
|
||||
<xsl:value-of select="substring($clean, 1, string-length($clean) - 5)"/>
|
||||
<xsl:text>&...</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="' &&' = substring($clean, string-length($clean) - 2)">
|
||||
<xsl:value-of select="substring($clean, 1, string-length($clean) - 3)"/>
|
||||
<xsl:text>&&</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="' &&...' = substring($clean, string-length($clean) - 5)">
|
||||
<xsl:value-of select="substring($clean, 1, string-length($clean) - 6)"/>
|
||||
<xsl:text>&&...</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$clean"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="cleanup-type">
|
||||
<xsl:param name="name"/>
|
||||
<xsl:variable name="type">
|
||||
@@ -124,20 +159,22 @@
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
<xsl:choose>
|
||||
<xsl:when test="$type='ConstBufferSequence'">
|
||||
<xsl:text>``[link beast.ref.ConstBufferSequence ['ConstBufferSequence]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="$type='implementation_defined'">
|
||||
<xsl:text>``['implementation-defined]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="$type='void_or_deduced'">
|
||||
<xsl:text>``[link beast.ref.asynchronous_operations.return_type_of_an_initiating_function ['void-or-deduced]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$type"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:variable name="cleaned">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$type='implementation_defined'">
|
||||
<xsl:text>``['implementation-defined]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="$type='void_or_deduced'">
|
||||
<xsl:text>``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.return_type_of_an_initiating_function ['void-or-deduced]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$type"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
<xsl:call-template name="cleanup-param">
|
||||
<xsl:with-param name="name" select="$cleaned"/>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make-id">
|
||||
@@ -260,8 +297,9 @@
|
||||
<!--========== Markup ==========-->
|
||||
|
||||
<xsl:template match="para" mode="markup">
|
||||
<xsl:apply-templates mode="markup"/>
|
||||
<xsl:text>
</xsl:text>
|
||||
<xsl:value-of select="$newline"/>
|
||||
<xsl:apply-templates mode="markup"/>
|
||||
<xsl:value-of select="$newline"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="para" mode="markup-nested">
|
||||
@@ -391,6 +429,8 @@
|
||||
<xsl:apply-templates mode="markup"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="@kind='see'">
|
||||
<xsl:text>[heading See Also]
</xsl:text>
|
||||
<xsl:apply-templates mode="markup"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="@kind='note'">
|
||||
<xsl:text>[heading Remarks]
</xsl:text>
|
||||
@@ -536,12 +576,13 @@
|
||||
</xsl:template>
|
||||
|
||||
|
||||
|
||||
<xsl:template match="ref[@kindref='compound']" mode="markup">
|
||||
<xsl:variable name="name">
|
||||
<xsl:value-of select="."/>
|
||||
</xsl:variable>
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains(@refid, 'asio') or contains($name, 'asio::')">
|
||||
<xsl:when test="contains(@refid, 'beast')">
|
||||
<xsl:variable name="dox-ref-id" select="@refid"/>
|
||||
<xsl:variable name="ref-name">
|
||||
<xsl:call-template name="strip-beast-ns">
|
||||
@@ -554,6 +595,14 @@
|
||||
<xsl:with-param name="name" select="$ref-name"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<!--<xsl:text>|1|</xsl:text>-->
|
||||
<!--
|
||||
<xsl:text>[role red ref-name='</xsl:text>
|
||||
<xsl:value-of select="$ref-name"/>
|
||||
<xsl:text>'|ref-id='</xsl:text>
|
||||
<xsl:value-of select="$ref-id"/>
|
||||
<xsl:text>']|</xsl:text>
|
||||
-->
|
||||
<xsl:text>[link beast.ref.</xsl:text>
|
||||
<xsl:value-of select="$ref-id"/>
|
||||
<xsl:text> `</xsl:text>
|
||||
@@ -561,89 +610,106 @@
|
||||
<xsl:text>`]</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>`</xsl:text>
|
||||
<xsl:text>[role red |1|</xsl:text>
|
||||
<xsl:value-of select="."/>
|
||||
<xsl:text>`</xsl:text>
|
||||
<xsl:text>]</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="ref[@kindref='member']" mode="markup">
|
||||
<xsl:variable name="name">
|
||||
<xsl:value-of select="."/>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="dox-ref-id" select="@refid"/>
|
||||
<xsl:variable name="memberdefs" select="/doxygen//compounddef/sectiondef/memberdef[@id=$dox-ref-id]"/>
|
||||
<xsl:variable name="def-kind" select="($memberdefs)/../../@kind"/>
|
||||
<xsl:variable name="sec-kind" select="($memberdefs)/../@kind"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains(@refid, 'beast') and count($memberdefs) > 0">
|
||||
<xsl:variable name="dox-compound-name" select="($memberdefs)[1]/../../compoundname"/>
|
||||
<xsl:variable name="dox-name" select="($memberdefs)[1]/name"/>
|
||||
<xsl:variable name="ref-name">
|
||||
<xsl:call-template name="strip-beast-ns">
|
||||
<xsl:with-param name="name" select="$dox-compound-name"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="ref-id">
|
||||
<xsl:call-template name="make-id">
|
||||
<xsl:with-param name="name" select="$ref-name"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<!--<xsl:text>|2|</xsl:text>-->
|
||||
<!--
|
||||
<xsl:text>[role red def-kind='</xsl:text>
|
||||
<xsl:value-of select="$def-kind"/>
|
||||
<xsl:text>', sec-kind='</xsl:text>
|
||||
<xsl:value-of select="$sec-kind"/>
|
||||
<xsl:text>', ref-id='</xsl:text>
|
||||
<xsl:value-of select="$ref-id"/>
|
||||
<xsl:text>'] </xsl:text>
|
||||
-->
|
||||
<xsl:choose>
|
||||
<xsl:when test="$def-kind = 'namespace'">
|
||||
<xsl:text>[link beast.ref.</xsl:text>
|
||||
<xsl:choose>
|
||||
<xsl:when test="string-length($ref-id) > 0">
|
||||
<xsl:value-of select="concat($ref-id,'__',$dox-name)"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$dox-name"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:text> `</xsl:text>
|
||||
<xsl:value-of name="text" select="$dox-name"/>
|
||||
<xsl:text>`]</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="$def-kind = 'class' or $def-kind = 'struct'">
|
||||
<xsl:text>[link beast.ref.</xsl:text>
|
||||
<xsl:value-of select="concat($ref-id,'.',$dox-name)"/>
|
||||
<xsl:text> `</xsl:text>
|
||||
<xsl:value-of name="text" select="$name"/>
|
||||
<xsl:text>`]</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>[role red </xsl:text>
|
||||
<xsl:value-of select="$name"/>
|
||||
<xsl:text>]</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>[role red </xsl:text>
|
||||
<xsl:value-of select="$name"/>
|
||||
<xsl:text>]</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="ref[@kindref='compound']" mode="markup-nested">
|
||||
<xsl:variable name="name">
|
||||
<xsl:value-of select="."/>
|
||||
</xsl:variable>
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains(@refid, 'asio') or contains($name, 'asio::')">
|
||||
<xsl:variable name="dox-ref-id" select="@refid"/>
|
||||
<xsl:variable name="ref-name">
|
||||
<xsl:call-template name="strip-beast-ns">
|
||||
<xsl:with-param name="name"
|
||||
select="(/doxygen//compounddef[@id=$dox-ref-id])[1]/compoundname"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="ref-id">
|
||||
<xsl:call-template name="make-id">
|
||||
<xsl:with-param name="name" select="$ref-name"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<xsl:text>[link beast.ref.</xsl:text>
|
||||
<xsl:value-of select="$ref-id"/>
|
||||
<xsl:text> `</xsl:text>
|
||||
<xsl:value-of name="text" select="$ref-name"/>
|
||||
<xsl:text>`]</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>`</xsl:text>
|
||||
<xsl:value-of select="."/>
|
||||
<xsl:text>`</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:text>[role red |3|</xsl:text>
|
||||
<xsl:value-of select="."/>
|
||||
<xsl:text>]</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="ref[@kindref='member']" mode="markup">
|
||||
<xsl:variable name="dox-ref-id" select="@refid"/>
|
||||
<xsl:variable name="memberdefs" select="/doxygen//compounddef/sectiondef/memberdef[@id=$dox-ref-id]"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains(@refid, 'namespaceboost_1_1asio') and count($memberdefs) > 0">
|
||||
<xsl:variable name="dox-compound-name" select="($memberdefs)[1]/../../compoundname"/>
|
||||
<xsl:variable name="dox-name" select="($memberdefs)[1]/name"/>
|
||||
<xsl:variable name="ref-name">
|
||||
<xsl:call-template name="strip-beast-ns">
|
||||
<xsl:with-param name="name" select="concat($dox-compound-name,'::',$dox-name)"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="ref-id">
|
||||
<xsl:call-template name="make-id">
|
||||
<xsl:with-param name="name" select="$ref-name"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<xsl:text>[link beast.ref.</xsl:text>
|
||||
<xsl:value-of select="$ref-id"/>
|
||||
<xsl:text> `</xsl:text>
|
||||
<xsl:value-of name="text" select="$ref-name"/>
|
||||
<xsl:text>`]</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>`</xsl:text>
|
||||
<xsl:value-of select="."/>
|
||||
<xsl:text>`</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="ref[@kindref='member']" mode="markup-nested">
|
||||
<xsl:variable name="name">
|
||||
<xsl:value-of select="."/>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="dox-ref-id" select="@refid"/>
|
||||
<xsl:variable name="memberdefs" select="/doxygen//compounddef/sectiondef/memberdef[@id=$dox-ref-id]"/>
|
||||
<xsl:variable name="def-kind" select="($memberdefs)/../../@kind"/>
|
||||
<xsl:variable name="sec-kind" select="($memberdefs)/../@kind"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains(@refid, 'namespaceboost_1_1asio') and count($memberdefs) > 0">
|
||||
<xsl:when test="contains(@refid, 'beast') and count($memberdefs) > 0">
|
||||
<xsl:variable name="dox-compound-name" select="($memberdefs)[1]/../../compoundname"/>
|
||||
<xsl:variable name="dox-name" select="($memberdefs)[1]/name"/>
|
||||
<xsl:variable name="ref-name">
|
||||
<xsl:call-template name="strip-beast-ns">
|
||||
<xsl:with-param name="name" select="concat($dox-compound-name,'::',$dox-name)"/>
|
||||
<xsl:with-param name="name" select="$dox-compound-name"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="ref-id">
|
||||
@@ -651,16 +717,49 @@
|
||||
<xsl:with-param name="name" select="$ref-name"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<xsl:text>[link beast.ref.</xsl:text>
|
||||
<!--<xsl:text>|2|</xsl:text>-->
|
||||
<!--
|
||||
<xsl:text>[role red def-kind='</xsl:text>
|
||||
<xsl:value-of select="$def-kind"/>
|
||||
<xsl:text>', sec-kind='</xsl:text>
|
||||
<xsl:value-of select="$sec-kind"/>
|
||||
<xsl:text>', ref-id='</xsl:text>
|
||||
<xsl:value-of select="$ref-id"/>
|
||||
<xsl:text> `</xsl:text>
|
||||
<xsl:value-of name="text" select="$ref-name"/>
|
||||
<xsl:text>`]</xsl:text>
|
||||
<xsl:text>'] </xsl:text>
|
||||
-->
|
||||
<xsl:choose>
|
||||
<xsl:when test="$def-kind = 'namespace'">
|
||||
<xsl:text>[link beast.ref.</xsl:text>
|
||||
<xsl:choose>
|
||||
<xsl:when test="string-length($ref-id) > 0">
|
||||
<xsl:value-of select="concat($ref-id,'__',$dox-name)"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$dox-name"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:text> `</xsl:text>
|
||||
<xsl:value-of name="text" select="$dox-name"/>
|
||||
<xsl:text>`]</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="$def-kind = 'class' or $def-kind = 'struct'">
|
||||
<xsl:text>[link beast.ref.</xsl:text>
|
||||
<xsl:value-of select="concat($ref-id,'.',$dox-name)"/>
|
||||
<xsl:text> `</xsl:text>
|
||||
<xsl:value-of name="text" select="$name"/>
|
||||
<xsl:text>`]</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>[role red </xsl:text>
|
||||
<xsl:value-of select="$name"/>
|
||||
<xsl:text>]</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>`</xsl:text>
|
||||
<xsl:value-of select="."/>
|
||||
<xsl:text>`</xsl:text>
|
||||
<xsl:text>[role red </xsl:text>
|
||||
<xsl:value-of select="$name"/>
|
||||
<xsl:text>]</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
@@ -1185,7 +1284,8 @@
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<xsl:if test="string-length($stripped-type) > 0">
|
||||
<xsl:value-of select="$stripped-type"/><xsl:text> </xsl:text>
|
||||
<xsl:value-of select="$stripped-type"/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>``[link beast.ref.</xsl:text>
|
||||
<xsl:value-of select="$class-id"/>
|
||||
@@ -1412,21 +1512,62 @@
|
||||
</xsl:template>
|
||||
|
||||
|
||||
|
||||
<xsl:template match="templateparamlist" mode="class-detail">
|
||||
<xsl:text>template<
</xsl:text>
|
||||
<xsl:apply-templates select="param" mode="class-detail-template"/>
|
||||
<xsl:text>>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
|
||||
<xsl:template match="param" mode="class-detail-template">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:choose>
|
||||
<xsl:when test="type = 'class AsyncStream'">
|
||||
<xsl:text>class ``[link beast.types.stream.AsyncStream [*AsyncStream]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="type = 'class AsyncReadStream'">
|
||||
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncReadStream.html [*AsyncReadStream]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="type = 'class AsyncWriteStream'">
|
||||
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncWriteStream.html [*AsyncWriteStream]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="type = 'class Body'">
|
||||
<xsl:text>class ``[link beast.types.Body [*Body]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="type = 'class Streambuf'">
|
||||
<xsl:when test="type = 'class BufferSequence'">
|
||||
<xsl:text>class ``[link beast.types.BufferSequence [*BufferSequence]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="(type = 'class' or type = 'class...') and declname = 'BufferSequence'">
|
||||
<xsl:value-of select="type"/>
|
||||
<xsl:text> ``[link beast.types.BufferSequence [*BufferSequence]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="declname = 'CompletionHandler' or type = 'class CompletionHandler'">
|
||||
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/CompletionHandler.html [*CompletionHandler]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<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 = '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:text>class ``[link beast.types.stream.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.stream.SyncStream [*SyncStream]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="declname = 'SyncReadStream' or type = 'class SyncReadStream'">
|
||||
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncReadStream.html [*SyncReadStream]]``</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="declname = 'SyncWriteStream' or type = 'class SyncWriteStream'">
|
||||
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncWriteStream.html [*SyncWriteStream]]``</xsl:text>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="declname = 'T'">
|
||||
<xsl:value-of select="declname"/>
|
||||
</xsl:when>
|
||||
@@ -1466,28 +1607,19 @@
|
||||
<xsl:value-of select="array"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:choose>
|
||||
<xsl:when test="' &&' = substring(type, string-length(type) - 2)">
|
||||
<xsl:value-of select="substring(type, 1, string-length(type) - 3)"/>
|
||||
<xsl:text>&&</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="' &' = substring(type, string-length(type) - 1)">
|
||||
<xsl:value-of select="substring(type, 1, string-length(type) - 2)"/>
|
||||
<xsl:text>&</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="' *' = substring(type, string-length(type) - 1)">
|
||||
<xsl:value-of select="substring(type, 1, string-length(type) - 2)"/>
|
||||
<xsl:text>*</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="type"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="declname"/>
|
||||
<xsl:call-template name="cleanup-param">
|
||||
<xsl:with-param name="name" select="type"/>
|
||||
</xsl:call-template>
|
||||
<xsl:if test="count(declname) > 0">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="declname"/>
|
||||
</xsl:if>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:if test="count(defval) > 0"> = <xsl:value-of select="defval"/></xsl:if>
|
||||
<xsl:if test="count(defval) > 0">
|
||||
<xsl:text> = </xsl:text>
|
||||
<xsl:value-of select="defval"/>
|
||||
</xsl:if>
|
||||
<xsl:if test="not(position() = last())">
|
||||
<xsl:text>,</xsl:text>
|
||||
</xsl:if>
|
||||
|
@@ -20,7 +20,7 @@
|
||||
#ifndef BEAST_EXAMPLE_FILE_BODY_H_INCLUDED
|
||||
#define BEAST_EXAMPLE_FILE_BODY_H_INCLUDED
|
||||
|
||||
#include <beast/http/body_writer.hpp>
|
||||
#include <beast/http/body_type.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <cstdio>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_ASYNC_COMPLETION_HPP
|
||||
#define BEAST_ASYNC_COMPLETION_HPP
|
||||
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/handler_concepts.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/handler_type.hpp>
|
||||
#include <type_traits>
|
||||
@@ -19,11 +19,11 @@ namespace beast {
|
||||
/** Helper for customizing the return type of asynchronous initiation functions.
|
||||
|
||||
This class template is used to transform caller-provided completion
|
||||
tokens in calls to asynchronous initiation functions. The transformation
|
||||
handlers in calls to asynchronous initiation functions. The transformation
|
||||
allows customization of the return type of the initiating function, and the
|
||||
function signature of the final handler.
|
||||
|
||||
@tparam CompletionToken A CompletionHandler, or a user defined type
|
||||
@tparam CompletionHandler A completion handler, or a user defined type
|
||||
with specializations for customizing the return type (for example,
|
||||
`boost::asio::use_future` or `boost::asio::yield_context`).
|
||||
|
||||
@@ -32,22 +32,22 @@ namespace beast {
|
||||
Example:
|
||||
@code
|
||||
...
|
||||
template<class CompletionToken>
|
||||
typename async_completion<CompletionToken,
|
||||
template<class CompletionHandler>
|
||||
typename async_completion<CompletionHandler,
|
||||
void(boost::system::error_code)>::result_type
|
||||
async_initfn(..., CompletionToken&& token)
|
||||
async_initfn(..., CompletionHandler&& handler)
|
||||
{
|
||||
async_completion<CompletionToken,
|
||||
void(boost::system::error_code)> completion(token);
|
||||
async_completion<CompletionHandler,
|
||||
void(boost::system::error_code)> completion(handler);
|
||||
...
|
||||
return completion.result.get();
|
||||
}
|
||||
@endcode
|
||||
|
||||
See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3896.pdf">
|
||||
@note See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3896.pdf">
|
||||
Library Foundations For Asynchronous Operations</a>
|
||||
*/
|
||||
template <class CompletionToken, class Signature>
|
||||
template <class CompletionHandler, class Signature>
|
||||
struct async_completion
|
||||
{
|
||||
/** The type of the final handler called by the asynchronous initiation function.
|
||||
@@ -56,7 +56,7 @@ struct async_completion
|
||||
*/
|
||||
using handler_type =
|
||||
typename boost::asio::handler_type<
|
||||
CompletionToken, Signature>::type;
|
||||
CompletionHandler, Signature>::type;
|
||||
|
||||
/// The type of the value returned by the asynchronous initiation function.
|
||||
using result_type = typename
|
||||
@@ -64,14 +64,14 @@ struct async_completion
|
||||
|
||||
/** Construct the helper.
|
||||
|
||||
@param token The completion token. Copies will be made as
|
||||
required. If `CompletionToken` is movable, it may also be moved.
|
||||
@param token The completion handler. Copies will be made as
|
||||
required. If `CompletionHandler` is movable, it may also be moved.
|
||||
*/
|
||||
async_completion(typename std::remove_reference<CompletionToken>::type& token)
|
||||
: handler(std::forward<CompletionToken>(token))
|
||||
async_completion(typename std::remove_reference<CompletionHandler>::type& token)
|
||||
: handler(std::forward<CompletionHandler>(token))
|
||||
, result(handler)
|
||||
{
|
||||
static_assert(is_Handler<handler_type, Signature>::value,
|
||||
static_assert(is_CompletionHandler<handler_type, Signature>::value,
|
||||
"Handler requirements not met");
|
||||
}
|
||||
|
||||
|
@@ -18,13 +18,15 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A `Streambuf` that uses multiple buffers internally.
|
||||
/** A @b `Streambuf` 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.
|
||||
|
||||
@tparam Allocator The allocator to use for managing memory.
|
||||
*/
|
||||
template<class Allocator>
|
||||
@@ -36,10 +38,14 @@ class basic_streambuf
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
#if GENERATING_DOCS
|
||||
/// The type of allocator used.
|
||||
using allocator_type = Allocator;
|
||||
#else
|
||||
using allocator_type = typename
|
||||
std::allocator_traits<Allocator>::
|
||||
template rebind_alloc<std::uint8_t>;
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Storage for the list of buffers representing the input
|
||||
@@ -93,106 +99,104 @@ public:
|
||||
|
||||
/** Move constructor.
|
||||
|
||||
The output sequence of this object will be empty.
|
||||
The new object will have the input sequence of
|
||||
the other stream buffer, and an empty output sequence.
|
||||
|
||||
After the move, the moved-from object will have an
|
||||
empty input and output sequence, with no internal
|
||||
@note After the move, the moved-from object will have
|
||||
an empty input and output sequence, with no internal
|
||||
buffers allocated.
|
||||
|
||||
@param other The stream buffer to move from.
|
||||
*/
|
||||
basic_streambuf(basic_streambuf&& other);
|
||||
basic_streambuf(basic_streambuf&&);
|
||||
|
||||
/** Move constructor.
|
||||
|
||||
The output sequence of this object will be empty.
|
||||
The new object will have the input sequence of
|
||||
the other stream buffer, and an empty output sequence.
|
||||
|
||||
After the move, the moved-from object will have an
|
||||
empty input and output sequence, with no internal
|
||||
@note After the move, the moved-from object will have
|
||||
an empty input and output sequence, with no internal
|
||||
buffers allocated.
|
||||
|
||||
@param other The stream buffer to move from.
|
||||
|
||||
@param alloc The allocator to associate with the
|
||||
stream buffer.
|
||||
*/
|
||||
basic_streambuf(basic_streambuf&& other,
|
||||
basic_streambuf(basic_streambuf&&,
|
||||
allocator_type const& alloc);
|
||||
|
||||
/** Move assignment.
|
||||
|
||||
The output sequence of this object will be empty.
|
||||
This object will have the input sequence of
|
||||
the other stream buffer, and an empty output sequence.
|
||||
|
||||
After the move, the moved-from object will have an
|
||||
empty input and output sequence, with no internal
|
||||
@note After the move, the moved-from object will have
|
||||
an empty input and output sequence, with no internal
|
||||
buffers allocated.
|
||||
|
||||
@param other The stream buffer to move from.
|
||||
*/
|
||||
basic_streambuf&
|
||||
operator=(basic_streambuf&& other);
|
||||
|
||||
/// Copy constructor.
|
||||
basic_streambuf(basic_streambuf const& other);
|
||||
operator=(basic_streambuf&&);
|
||||
|
||||
/** Copy constructor.
|
||||
|
||||
The output sequence of this object will be empty.
|
||||
This object will have a copy of the other stream
|
||||
buffer's input sequence, and an empty output sequence.
|
||||
*/
|
||||
basic_streambuf(basic_streambuf const&);
|
||||
|
||||
@param other The stream buffer to copy.
|
||||
/** Copy constructor.
|
||||
|
||||
This object will have a copy of the other stream
|
||||
buffer's input sequence, and an empty output sequence.
|
||||
|
||||
@param alloc The allocator to associate with the
|
||||
stream buffer.
|
||||
*/
|
||||
basic_streambuf(basic_streambuf const& other,
|
||||
basic_streambuf(basic_streambuf const&,
|
||||
allocator_type const& alloc);
|
||||
|
||||
/** Copy assignment.
|
||||
|
||||
The output sequence of this object will be empty.
|
||||
|
||||
@param other The stream buffer to copy.
|
||||
This object will have a copy of the other stream
|
||||
buffer's input sequence, and an empty output sequence.
|
||||
*/
|
||||
basic_streambuf& operator=(basic_streambuf const& other);
|
||||
basic_streambuf& operator=(basic_streambuf const&);
|
||||
|
||||
/** Copy constructor.
|
||||
|
||||
The output sequence of this object will be empty.
|
||||
|
||||
@param other The stream buffer to copy.
|
||||
This object will have a copy of the other stream
|
||||
buffer's input sequence, and an empty output sequence.
|
||||
*/
|
||||
template<class OtherAlloc>
|
||||
basic_streambuf(basic_streambuf<OtherAlloc> const& other);
|
||||
basic_streambuf(basic_streambuf<OtherAlloc> const&);
|
||||
|
||||
/** Copy constructor.
|
||||
|
||||
The output sequence of this object will be empty.
|
||||
|
||||
@param other The stream buffer to copy.
|
||||
This object will have a copy of the other stream
|
||||
buffer's input sequence, and an empty output sequence.
|
||||
|
||||
@param alloc The allocator to associate with the
|
||||
stream buffer.
|
||||
*/
|
||||
template<class OtherAlloc>
|
||||
basic_streambuf(basic_streambuf<OtherAlloc> const& other,
|
||||
basic_streambuf(basic_streambuf<OtherAlloc> const&,
|
||||
allocator_type const& alloc);
|
||||
|
||||
/** Copy assignment.
|
||||
|
||||
The output sequence of this object will be empty.
|
||||
|
||||
@param other The stream buffer to copy.
|
||||
This object will have a copy of the other stream
|
||||
buffer's input sequence, and an empty output sequence.
|
||||
*/
|
||||
template<class OtherAlloc>
|
||||
basic_streambuf& operator=(basic_streambuf<OtherAlloc> const& other);
|
||||
basic_streambuf& operator=(basic_streambuf<OtherAlloc> const&);
|
||||
|
||||
/** Default constructor.
|
||||
/** Construct a stream buffer.
|
||||
|
||||
@param alloc_size The size of buffer to allocate. This is a soft
|
||||
limit, calls to prepare for buffers exceeding this size will allocate
|
||||
the larger size.
|
||||
@param alloc_size The size of buffer to allocate. This is a
|
||||
soft limit, calls to prepare for buffers exceeding this size
|
||||
will allocate the larger size. The default allocation size
|
||||
is 1KB (1024 bytes).
|
||||
|
||||
@param alloc The allocator to use.
|
||||
@param alloc The allocator to use. If this parameter is
|
||||
unspecified, a default constructed allocator will be used.
|
||||
*/
|
||||
explicit
|
||||
basic_streambuf(std::size_t alloc_size = 1024,
|
||||
@@ -219,15 +223,26 @@ public:
|
||||
return in_size_;
|
||||
}
|
||||
|
||||
/// Get a list of buffers that represents the output sequence, with the given size.
|
||||
/** Get a list of buffers that represents the output sequence, with the given size.
|
||||
|
||||
@note Buffers representing the input sequence acquired prior to
|
||||
this call remain valid.
|
||||
*/
|
||||
mutable_buffers_type
|
||||
prepare(size_type n);
|
||||
|
||||
/// Move bytes from the output sequence to the input sequence.
|
||||
/** Move bytes from the output sequence to the input sequence.
|
||||
|
||||
@note Buffers representing the input sequence acquired prior to
|
||||
this call remain valid.
|
||||
*/
|
||||
void
|
||||
commit(size_type n);
|
||||
|
||||
/// Get a list of buffers that represents the input sequence.
|
||||
/** 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;
|
||||
|
||||
@@ -277,19 +292,9 @@ private:
|
||||
|
||||
@return The stream buffer.
|
||||
*/
|
||||
template<class Alloc, class T>
|
||||
basic_streambuf<Alloc>&
|
||||
operator<<(basic_streambuf<Alloc>& streambuf, T const& t);
|
||||
|
||||
/** Convert the entire basic_streambuf to a string.
|
||||
|
||||
@param streambuf The streambuf to convert.
|
||||
|
||||
@return A string representing the contents of the input sequence.
|
||||
*/
|
||||
template<class Allocator>
|
||||
std::string
|
||||
to_string(basic_streambuf<Allocator> const& streambuf);
|
||||
template<class Allocator, class T>
|
||||
basic_streambuf<Allocator>&
|
||||
operator<<(basic_streambuf<Allocator>& streambuf, T const& t);
|
||||
|
||||
} // beast
|
||||
|
||||
|
@@ -8,110 +8,19 @@
|
||||
#ifndef BEAST_BIND_HANDLER_HPP
|
||||
#define BEAST_BIND_HANDLER_HPP
|
||||
|
||||
#include <beast/detail/integer_sequence.hpp>
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
#include <functional>
|
||||
#include <beast/handler_concepts.hpp>
|
||||
#include <beast/detail/bind_handler.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/* Nullary handler that calls Handler with bound arguments.
|
||||
|
||||
The bound handler provides the same io_service execution
|
||||
guarantees as the original handler.
|
||||
*/
|
||||
template<class Handler, class... Args>
|
||||
class bound_handler
|
||||
{
|
||||
private:
|
||||
using args_type = std::tuple<typename std::decay<Args>::type...>;
|
||||
|
||||
Handler h_;
|
||||
args_type args_;
|
||||
|
||||
template<class Tuple, std::size_t... S>
|
||||
static void invoke(Handler& h, Tuple& args,
|
||||
index_sequence<S...>)
|
||||
{
|
||||
h(std::get<S>(args)...);
|
||||
}
|
||||
|
||||
public:
|
||||
using result_type = void;
|
||||
|
||||
template<class DeducedHandler>
|
||||
explicit
|
||||
bound_handler(DeducedHandler&& handler, Args&&... args)
|
||||
: h_(std::forward<DeducedHandler>(handler))
|
||||
, args_(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
operator()()
|
||||
{
|
||||
invoke(h_, args_,
|
||||
index_sequence_for<Args...> ());
|
||||
}
|
||||
|
||||
void
|
||||
operator()() const
|
||||
{
|
||||
invoke(h_, args_,
|
||||
index_sequence_for<Args...> ());
|
||||
}
|
||||
|
||||
friend
|
||||
void*
|
||||
asio_handler_allocate(
|
||||
std::size_t size, bound_handler* h)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, h->h_);
|
||||
}
|
||||
|
||||
friend
|
||||
void
|
||||
asio_handler_deallocate(
|
||||
void* p, std::size_t size, bound_handler* h)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, h->h_);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
asio_handler_is_continuation(bound_handler* h)
|
||||
{
|
||||
return boost_asio_handler_cont_helpers::
|
||||
is_continuation (h->h_);
|
||||
}
|
||||
|
||||
template<class F>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke(F&& f, bound_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke(f, h->h_);
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Bind parameters to a completion handler, creating a wrapped handler.
|
||||
|
||||
This function creates a new handler which invoked with no parameters
|
||||
calls the original handler with the list of bound arguments. The passed
|
||||
handler and arguments are forwarded into the returned handler, which
|
||||
provides the same `io_service` execution guarantees as the original
|
||||
This function creates a new handler which, when invoked with no
|
||||
parameters, calls the original handler with the list of bound arguments.
|
||||
The passed handler and arguments are forwarded into the returned handler,
|
||||
which provides the same `io_service` execution guarantees as the original
|
||||
handler.
|
||||
|
||||
Unlike `io_service::wrap`, the returned handler can be used in a
|
||||
@@ -145,6 +54,9 @@ detail::bound_handler<
|
||||
#endif
|
||||
bind_handler(CompletionHandler&& handler, Args&&... args)
|
||||
{
|
||||
static_assert(is_CompletionHandler<
|
||||
CompletionHandler, void(Args...)>::value,
|
||||
"CompletionHandler requirements not met");
|
||||
return detail::bound_handler<typename std::decay<
|
||||
CompletionHandler>::type, Args...>(std::forward<
|
||||
CompletionHandler>(handler),
|
||||
@@ -153,10 +65,4 @@ bind_handler(CompletionHandler&& handler, Args&&... args)
|
||||
|
||||
} // beast
|
||||
|
||||
namespace std {
|
||||
template<class Handler, class... Args>
|
||||
void bind(beast::detail::bound_handler<
|
||||
Handler, Args...>, ...) = delete;
|
||||
} // std
|
||||
|
||||
#endif
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#ifndef BEAST_BUFFER_CAT_HPP
|
||||
#define BEAST_BUFFER_CAT_HPP
|
||||
|
||||
#include <beast/detail/buffer_cat.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
@@ -18,463 +19,9 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
class buffer_cat_helper
|
||||
{
|
||||
std::tuple<Bs...> bs_;
|
||||
|
||||
public:
|
||||
using value_type = ValueType;
|
||||
|
||||
class const_iterator;
|
||||
|
||||
buffer_cat_helper(buffer_cat_helper&&) = default;
|
||||
buffer_cat_helper(buffer_cat_helper const&) = default;
|
||||
buffer_cat_helper& operator=(buffer_cat_helper&&) = default;
|
||||
buffer_cat_helper& operator=(buffer_cat_helper const&) = default;
|
||||
|
||||
explicit
|
||||
buffer_cat_helper(Bs const&... bs)
|
||||
: bs_(bs...)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin() const;
|
||||
|
||||
const_iterator
|
||||
end() const;
|
||||
};
|
||||
|
||||
template<class U>
|
||||
std::size_t constexpr
|
||||
max_sizeof()
|
||||
{
|
||||
return sizeof(U);
|
||||
}
|
||||
|
||||
template<class U0, class U1, class... Us>
|
||||
std::size_t constexpr
|
||||
max_sizeof()
|
||||
{
|
||||
return
|
||||
max_sizeof<U0>() > max_sizeof<U1, Us...>() ?
|
||||
max_sizeof<U0>() : max_sizeof<U1, Us...>();
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
class buffer_cat_helper<
|
||||
ValueType, Bs...>::const_iterator
|
||||
{
|
||||
std::size_t n_;
|
||||
std::tuple<Bs...> const* bs_;
|
||||
std::array<std::uint8_t,
|
||||
max_sizeof<typename Bs::const_iterator...>()> buf_;
|
||||
|
||||
friend class buffer_cat_helper<ValueType, Bs...>;
|
||||
|
||||
template<std::size_t I>
|
||||
using C = std::integral_constant<std::size_t, I>;
|
||||
|
||||
template<std::size_t I>
|
||||
using iter_t = typename std::tuple_element<
|
||||
I, std::tuple<Bs...>>::type::const_iterator;
|
||||
|
||||
template<std::size_t I>
|
||||
iter_t<I>&
|
||||
iter()
|
||||
{
|
||||
return *reinterpret_cast<
|
||||
iter_t<I>*>(buf_.data());
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
iter_t<I> const&
|
||||
iter() const
|
||||
{
|
||||
return *reinterpret_cast<
|
||||
iter_t<I> const*>(buf_.data());
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = ValueType;
|
||||
using pointer = value_type const*;
|
||||
using reference = value_type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using iterator_category =
|
||||
std::bidirectional_iterator_tag;
|
||||
|
||||
~const_iterator();
|
||||
const_iterator();
|
||||
const_iterator(const_iterator&& other);
|
||||
const_iterator(const_iterator const& other);
|
||||
const_iterator& operator=(const_iterator&& other);
|
||||
const_iterator& operator=(const_iterator const& other);
|
||||
|
||||
bool
|
||||
operator==(const_iterator const& other) const;
|
||||
|
||||
bool
|
||||
operator!=(const_iterator const& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
reference
|
||||
operator*() const;
|
||||
|
||||
pointer
|
||||
operator->() const = delete;
|
||||
|
||||
const_iterator&
|
||||
operator++();
|
||||
|
||||
const_iterator
|
||||
operator++(int)
|
||||
{
|
||||
auto temp = *this;
|
||||
++(*this);
|
||||
return temp;
|
||||
}
|
||||
|
||||
const_iterator&
|
||||
operator--();
|
||||
|
||||
const_iterator
|
||||
operator--(int)
|
||||
{
|
||||
auto temp = *this;
|
||||
--(*this);
|
||||
return temp;
|
||||
}
|
||||
|
||||
private:
|
||||
const_iterator(
|
||||
std::tuple<Bs...> const& bs, bool at_end);
|
||||
|
||||
void
|
||||
construct(C<sizeof...(Bs)>)
|
||||
{
|
||||
auto constexpr I = sizeof...(Bs);
|
||||
n_ = I;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
void
|
||||
construct(C<I>)
|
||||
{
|
||||
if(std::get<I>(*bs_).begin() !=
|
||||
std::get<I>(*bs_).end())
|
||||
{
|
||||
n_ = I;
|
||||
new(buf_.data()) iter_t<I>{
|
||||
std::get<I>(*bs_).begin()};
|
||||
return;
|
||||
}
|
||||
construct(C<I+1>{});
|
||||
}
|
||||
|
||||
void
|
||||
destroy(C<sizeof...(Bs)>)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
void
|
||||
destroy(C<I>)
|
||||
{
|
||||
if(n_ == I)
|
||||
{
|
||||
using Iter = iter_t<I>;
|
||||
iter<I>().~Iter();
|
||||
return;
|
||||
}
|
||||
destroy(C<I+1>{});
|
||||
}
|
||||
|
||||
void
|
||||
move(C<sizeof...(Bs)>, const_iterator&&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
void
|
||||
move(C<I>, const_iterator&& other)
|
||||
{
|
||||
if(n_ == I)
|
||||
{
|
||||
new(buf_.data()) iter_t<I>{
|
||||
std::move(other.iter<I>())};
|
||||
return;
|
||||
}
|
||||
move(C<I+1>{}, std::move(other));
|
||||
}
|
||||
|
||||
void
|
||||
copy(C<sizeof...(Bs)>, const_iterator const&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
void
|
||||
copy(C<I>, const_iterator const& other)
|
||||
{
|
||||
if(n_ == I)
|
||||
{
|
||||
new(buf_.data()) iter_t<I>{
|
||||
other.iter<I>()};
|
||||
return;
|
||||
}
|
||||
copy(C<I+1>{}, other);
|
||||
}
|
||||
|
||||
bool
|
||||
equal(C<sizeof...(Bs)>,
|
||||
const_iterator const&) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
bool
|
||||
equal(C<I>, const_iterator const& other) const
|
||||
{
|
||||
if(n_ == I)
|
||||
return iter<I>() == other.iter<I>();
|
||||
return equal(C<I+1>{}, other);
|
||||
}
|
||||
|
||||
[[noreturn]]
|
||||
reference
|
||||
dereference(C<sizeof...(Bs)>) const
|
||||
{
|
||||
throw std::logic_error("invalid iterator");
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
reference
|
||||
dereference(C<I>) const
|
||||
{
|
||||
if(n_ == I)
|
||||
return *iter<I>();
|
||||
return dereference(C<I+1>{});
|
||||
}
|
||||
|
||||
[[noreturn]]
|
||||
void
|
||||
increment(C<sizeof...(Bs)>)
|
||||
{
|
||||
throw std::logic_error("invalid iterator");
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
void
|
||||
increment(C<I>)
|
||||
{
|
||||
if(n_ == I)
|
||||
{
|
||||
if(++iter<I>() !=
|
||||
std::get<I>(*bs_).end())
|
||||
return;
|
||||
using Iter = iter_t<I>;
|
||||
iter<I>().~Iter();
|
||||
return construct(C<I+1>{});
|
||||
}
|
||||
increment(C<I+1>{});
|
||||
}
|
||||
|
||||
void
|
||||
decrement(C<sizeof...(Bs)>)
|
||||
{
|
||||
auto constexpr I = sizeof...(Bs);
|
||||
if(n_ == I)
|
||||
{
|
||||
--n_;
|
||||
new(buf_.data()) iter_t<I-1>{
|
||||
std::get<I-1>(*bs_).end()};
|
||||
}
|
||||
decrement(C<I-1>{});
|
||||
}
|
||||
|
||||
void
|
||||
decrement(C<0>)
|
||||
{
|
||||
auto constexpr I = 0;
|
||||
if(iter<I>() != std::get<I>(*bs_).begin())
|
||||
{
|
||||
--iter<I>();
|
||||
return;
|
||||
}
|
||||
throw std::logic_error("invalid iterator");
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
void
|
||||
decrement(C<I>)
|
||||
{
|
||||
if(n_ == I)
|
||||
{
|
||||
if(iter<I>() != std::get<I>(*bs_).begin())
|
||||
{
|
||||
--iter<I>();
|
||||
return;
|
||||
}
|
||||
--n_;
|
||||
using Iter = iter_t<I>;
|
||||
iter<I>().~Iter();
|
||||
new(buf_.data()) iter_t<I-1>{
|
||||
std::get<I-1>(*bs_).end()};
|
||||
}
|
||||
decrement(C<I-1>{});
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::~const_iterator()
|
||||
{
|
||||
destroy(C<0>{});
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::const_iterator()
|
||||
: n_(sizeof...(Bs))
|
||||
, bs_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::const_iterator(
|
||||
std::tuple<Bs...> const& bs, bool at_end)
|
||||
: bs_(&bs)
|
||||
{
|
||||
if(at_end)
|
||||
n_ = sizeof...(Bs);
|
||||
else
|
||||
construct(C<0>{});
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::const_iterator(const_iterator&& other)
|
||||
: n_(other.n_)
|
||||
, bs_(other.bs_)
|
||||
{
|
||||
move(C<0>{}, std::move(other));
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::const_iterator(const_iterator const& other)
|
||||
: n_(other.n_)
|
||||
, bs_(other.bs_)
|
||||
{
|
||||
copy(C<0>{}, other);
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::operator=(const_iterator&& other) ->
|
||||
const_iterator&
|
||||
{
|
||||
if(&other == this)
|
||||
return *this;
|
||||
destroy(C<0>{});
|
||||
n_ = other.n_;
|
||||
bs_ = other.bs_;
|
||||
move(C<0>{}, std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::operator=(const_iterator const& other) ->
|
||||
const_iterator&
|
||||
{
|
||||
if(&other == this)
|
||||
return *this;
|
||||
destroy(C<0>{});
|
||||
n_ = other.n_;
|
||||
bs_ = other.bs_;
|
||||
copy(C<0>{}, other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
bool
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::operator==(const_iterator const& other) const
|
||||
{
|
||||
if(bs_ != other.bs_)
|
||||
return false;
|
||||
if(n_ != other.n_)
|
||||
return false;
|
||||
return equal(C<0>{}, other);
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::operator*() const ->
|
||||
reference
|
||||
{
|
||||
return dereference(C<0>{});
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::operator++() ->
|
||||
const_iterator&
|
||||
{
|
||||
increment(C<0>{});
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::operator--() ->
|
||||
const_iterator&
|
||||
{
|
||||
decrement(C<sizeof...(Bs)>{});
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::begin() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator(bs_, false);
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::end() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator(bs_, true);
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Concatenate 2 or more buffer sequences to form a `ConstBufferSequence`.
|
||||
|
||||
This function returns a `ConstBufferSequence` that when iterated,
|
||||
This function returns a @b `ConstBufferSequence` that when iterated,
|
||||
efficiently concatenates the input buffer sequences. Copies of the
|
||||
arguments passed will be made; however, the returned object does
|
||||
not take ownership of the underlying memory. The application is still
|
||||
@@ -482,8 +29,8 @@ buffer_cat_helper<ValueType, Bs...>::end() const ->
|
||||
|
||||
@param buffers The list of buffer sequences to concatenate.
|
||||
|
||||
@return A new `ConstBufferSequence` that represents the concatenation
|
||||
of the input buffer sequences.
|
||||
@return A new @b `ConstBufferSequence` that represents the
|
||||
concatenation of the input buffer sequences.
|
||||
*/
|
||||
#if GENERATING_DOCS
|
||||
template<class... BufferSequence>
|
||||
|
61
include/beast/buffer_concepts.hpp
Normal file
61
include/beast/buffer_concepts.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// 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_BUFFER_CONCEPTS_HPP
|
||||
#define BEAST_BUFFER_CONCEPTS_HPP
|
||||
|
||||
#include <beast/detail/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/// Determine if `T` meets the requirements of @b `BufferSequence`.
|
||||
template<class T, class BufferType>
|
||||
#if GENERATING_DOCS
|
||||
struct is_BufferSequence : std::integral_constant<bool, ...>
|
||||
#else
|
||||
struct is_BufferSequence : detail::is_BufferSequence<T, BufferType>::type
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
/// Determine if `T` meets the requirements of @b `ConstBufferSequence`.
|
||||
template<class T>
|
||||
#if GENERATING_DOCS
|
||||
struct is_ConstBufferSequence : std::integral_constant<bool, ...>
|
||||
#else
|
||||
struct is_ConstBufferSequence :
|
||||
is_BufferSequence<T, boost::asio::const_buffer>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
/// Determine if `T` meets the requirements of @b `MutableBufferSequence`.
|
||||
template<class T>
|
||||
#if GENERATING_DOCS
|
||||
struct is_MutableBufferSequence : std::integral_constant<bool, ...>
|
||||
#else
|
||||
struct is_MutableBufferSequence :
|
||||
is_BufferSequence<T, boost::asio::mutable_buffer>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
/// 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
|
@@ -8,15 +8,16 @@
|
||||
#ifndef BEAST_BUFFERS_ADAPTER_HPP
|
||||
#define BEAST_BUFFERS_ADAPTER_HPP
|
||||
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Adapts a `MutableBufferSequence` into a `Streambuf`.
|
||||
/** Adapts a @b `MutableBufferSequence` into a @b `Streambuf`.
|
||||
|
||||
This class wraps a `MutableBufferSequence` to meet the requirements
|
||||
of `Streambuf`. Upon construction the input and output sequences are
|
||||
This class wraps a @b `MutableBufferSequence` to meet the requirements
|
||||
of @b `Streambuf`. Upon construction the input and output sequences are
|
||||
empty. A copy of the mutable buffer sequence object is stored; however,
|
||||
ownership of the underlying memory is not transferred. The caller is
|
||||
responsible for making sure that referenced memory remains valid
|
||||
@@ -25,20 +26,18 @@ namespace beast {
|
||||
The size of the mutable buffer sequence determines the maximum
|
||||
number of bytes which may be prepared and committed.
|
||||
|
||||
@tparam Buffers The type of mutable buffer sequence to wrap.
|
||||
@tparam MutableBufferSequence The type of mutable buffer sequence to wrap.
|
||||
*/
|
||||
template<class Buffers>
|
||||
template<class MutableBufferSequence>
|
||||
class buffers_adapter
|
||||
{
|
||||
private:
|
||||
using buffers_type = typename std::decay<Buffers>::type;
|
||||
using iter_type = typename buffers_type::const_iterator;
|
||||
static_assert(is_MutableBufferSequence<MutableBufferSequence>::value,
|
||||
"MutableBufferSequence requirements not met");
|
||||
|
||||
static auto constexpr is_mutable =
|
||||
std::is_constructible<boost::asio::mutable_buffer,
|
||||
typename std::iterator_traits<iter_type>::value_type>::value;
|
||||
using iter_type = typename MutableBufferSequence::const_iterator;
|
||||
|
||||
Buffers bs_;
|
||||
MutableBufferSequence bs_;
|
||||
iter_type begin_;
|
||||
iter_type out_;
|
||||
iter_type end_;
|
||||
@@ -98,7 +97,7 @@ public:
|
||||
transferred.
|
||||
*/
|
||||
explicit
|
||||
buffers_adapter(Buffers const& buffers);
|
||||
buffers_adapter(MutableBufferSequence const& buffers);
|
||||
|
||||
/// Returns the largest size output sequence possible.
|
||||
std::size_t
|
||||
@@ -118,15 +117,25 @@ public:
|
||||
|
||||
@throws std::length_error if the size would exceed the limit
|
||||
imposed by the underlying mutable buffer sequence.
|
||||
|
||||
@note Buffers representing the input sequence acquired prior to
|
||||
this call remain valid.
|
||||
*/
|
||||
mutable_buffers_type
|
||||
prepare(std::size_t n);
|
||||
|
||||
/// Move bytes from the output sequence to the input sequence.
|
||||
/** Move bytes from the output sequence to the input sequence.
|
||||
|
||||
@note Buffers representing the input sequence acquired prior to
|
||||
this call remain valid.
|
||||
*/
|
||||
void
|
||||
commit(std::size_t n);
|
||||
|
||||
/// Get a list of buffers that represents the input sequence.
|
||||
/** 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;
|
||||
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#ifndef BEAST_CONSUMING_BUFFERS_HPP
|
||||
#define BEAST_CONSUMING_BUFFERS_HPP
|
||||
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
@@ -28,26 +29,29 @@ namespace beast {
|
||||
Ownership of the underlying memory is not transferred, the application
|
||||
is still responsible for managing its lifetime.
|
||||
|
||||
@tparam Buffers The buffer sequence to wrap.
|
||||
@tparam BufferSequence The buffer sequence to wrap.
|
||||
|
||||
@ptaram ValueType The type of buffer of the final buffer sequence. This
|
||||
@tparam ValueType The type of buffer of the final buffer sequence. This
|
||||
can be different from the buffer type of the wrapped sequence. For
|
||||
example, a `MutableBufferSequence` can be transformed into a
|
||||
consumable `ConstBufferSequence`. Violations of buffer const safety
|
||||
are not permitted, and will result in a compile error.
|
||||
*/
|
||||
template<class Buffers,
|
||||
class ValueType = typename Buffers::value_type>
|
||||
template<class BufferSequence,
|
||||
class ValueType = typename BufferSequence::value_type>
|
||||
class consuming_buffers
|
||||
{
|
||||
using iter_type =
|
||||
typename Buffers::const_iterator;
|
||||
typename BufferSequence::const_iterator;
|
||||
|
||||
static_assert(is_BufferSequence<BufferSequence, ValueType>::value,
|
||||
"BufferSequence requirements not met");
|
||||
|
||||
static_assert(std::is_constructible<ValueType,
|
||||
typename std::iterator_traits<iter_type>::value_type>::value,
|
||||
"ValueType requirements not met");
|
||||
|
||||
Buffers bs_;
|
||||
BufferSequence bs_;
|
||||
iter_type begin_;
|
||||
std::size_t skip_ = 0;
|
||||
|
||||
@@ -90,7 +94,7 @@ public:
|
||||
underlying memory is not transferred or copied.
|
||||
*/
|
||||
explicit
|
||||
consuming_buffers(Buffers const& buffers);
|
||||
consuming_buffers(BufferSequence const& buffers);
|
||||
|
||||
/// Get a bidirectional iterator to the first element.
|
||||
const_iterator
|
||||
|
113
include/beast/detail/bind_handler.hpp
Normal file
113
include/beast/detail/bind_handler.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
//
|
||||
// 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_BIND_DETAIL_HANDLER_HPP
|
||||
#define BEAST_BIND_DETAIL_HANDLER_HPP
|
||||
|
||||
#include <beast/detail/integer_sequence.hpp>
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
/* Nullary handler that calls Handler with bound arguments.
|
||||
|
||||
The bound handler provides the same io_service execution
|
||||
guarantees as the original handler.
|
||||
*/
|
||||
template<class Handler, class... Args>
|
||||
class bound_handler
|
||||
{
|
||||
private:
|
||||
using args_type = std::tuple<
|
||||
typename std::decay<Args>::type...>;
|
||||
|
||||
Handler h_;
|
||||
args_type args_;
|
||||
|
||||
template<class Tuple, std::size_t... S>
|
||||
static void invoke(Handler& h, Tuple& args,
|
||||
index_sequence<S...>)
|
||||
{
|
||||
h(std::get<S>(args)...);
|
||||
}
|
||||
|
||||
public:
|
||||
using result_type = void;
|
||||
|
||||
template<class DeducedHandler>
|
||||
explicit
|
||||
bound_handler(DeducedHandler&& handler, Args&&... args)
|
||||
: h_(std::forward<DeducedHandler>(handler))
|
||||
, args_(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
operator()()
|
||||
{
|
||||
invoke(h_, args_,
|
||||
index_sequence_for<Args...> ());
|
||||
}
|
||||
|
||||
void
|
||||
operator()() const
|
||||
{
|
||||
invoke(h_, args_,
|
||||
index_sequence_for<Args...> ());
|
||||
}
|
||||
|
||||
friend
|
||||
void*
|
||||
asio_handler_allocate(
|
||||
std::size_t size, bound_handler* h)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, h->h_);
|
||||
}
|
||||
|
||||
friend
|
||||
void
|
||||
asio_handler_deallocate(
|
||||
void* p, std::size_t size, bound_handler* h)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, h->h_);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
asio_handler_is_continuation(bound_handler* h)
|
||||
{
|
||||
return boost_asio_handler_cont_helpers::
|
||||
is_continuation (h->h_);
|
||||
}
|
||||
|
||||
template<class F>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke(F&& f, bound_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke(f, h->h_);
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#include <functional>
|
||||
namespace std {
|
||||
template<class Handler, class... Args>
|
||||
void bind(beast::detail::bound_handler<
|
||||
Handler, Args...>, ...) = delete;
|
||||
} // std
|
||||
|
||||
#endif
|
473
include/beast/detail/buffer_cat.hpp
Normal file
473
include/beast/detail/buffer_cat.hpp
Normal file
@@ -0,0 +1,473 @@
|
||||
//
|
||||
// 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_DETAIL_BUFFER_CAT_HPP
|
||||
#define BEAST_DETAIL_BUFFER_CAT_HPP
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <new>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
class buffer_cat_helper
|
||||
{
|
||||
std::tuple<Bs...> bs_;
|
||||
|
||||
public:
|
||||
using value_type = ValueType;
|
||||
|
||||
class const_iterator;
|
||||
|
||||
buffer_cat_helper(buffer_cat_helper&&) = default;
|
||||
buffer_cat_helper(buffer_cat_helper const&) = default;
|
||||
buffer_cat_helper& operator=(buffer_cat_helper&&) = default;
|
||||
buffer_cat_helper& operator=(buffer_cat_helper const&) = default;
|
||||
|
||||
explicit
|
||||
buffer_cat_helper(Bs const&... bs)
|
||||
: bs_(bs...)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin() const;
|
||||
|
||||
const_iterator
|
||||
end() const;
|
||||
};
|
||||
|
||||
template<class U>
|
||||
std::size_t constexpr
|
||||
max_sizeof()
|
||||
{
|
||||
return sizeof(U);
|
||||
}
|
||||
|
||||
template<class U0, class U1, class... Us>
|
||||
std::size_t constexpr
|
||||
max_sizeof()
|
||||
{
|
||||
return
|
||||
max_sizeof<U0>() > max_sizeof<U1, Us...>() ?
|
||||
max_sizeof<U0>() : max_sizeof<U1, Us...>();
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
class buffer_cat_helper<
|
||||
ValueType, Bs...>::const_iterator
|
||||
{
|
||||
std::size_t n_;
|
||||
std::tuple<Bs...> const* bs_;
|
||||
std::array<std::uint8_t,
|
||||
max_sizeof<typename Bs::const_iterator...>()> buf_;
|
||||
|
||||
friend class buffer_cat_helper<ValueType, Bs...>;
|
||||
|
||||
template<std::size_t I>
|
||||
using C = std::integral_constant<std::size_t, I>;
|
||||
|
||||
template<std::size_t I>
|
||||
using iter_t = typename std::tuple_element<
|
||||
I, std::tuple<Bs...>>::type::const_iterator;
|
||||
|
||||
template<std::size_t I>
|
||||
iter_t<I>&
|
||||
iter()
|
||||
{
|
||||
return *reinterpret_cast<
|
||||
iter_t<I>*>(buf_.data());
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
iter_t<I> const&
|
||||
iter() const
|
||||
{
|
||||
return *reinterpret_cast<
|
||||
iter_t<I> const*>(buf_.data());
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = ValueType;
|
||||
using pointer = value_type const*;
|
||||
using reference = value_type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using iterator_category =
|
||||
std::bidirectional_iterator_tag;
|
||||
|
||||
~const_iterator();
|
||||
const_iterator();
|
||||
const_iterator(const_iterator&& other);
|
||||
const_iterator(const_iterator const& other);
|
||||
const_iterator& operator=(const_iterator&& other);
|
||||
const_iterator& operator=(const_iterator const& other);
|
||||
|
||||
bool
|
||||
operator==(const_iterator const& other) const;
|
||||
|
||||
bool
|
||||
operator!=(const_iterator const& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
reference
|
||||
operator*() const;
|
||||
|
||||
pointer
|
||||
operator->() const = delete;
|
||||
|
||||
const_iterator&
|
||||
operator++();
|
||||
|
||||
const_iterator
|
||||
operator++(int)
|
||||
{
|
||||
auto temp = *this;
|
||||
++(*this);
|
||||
return temp;
|
||||
}
|
||||
|
||||
const_iterator&
|
||||
operator--();
|
||||
|
||||
const_iterator
|
||||
operator--(int)
|
||||
{
|
||||
auto temp = *this;
|
||||
--(*this);
|
||||
return temp;
|
||||
}
|
||||
|
||||
private:
|
||||
const_iterator(
|
||||
std::tuple<Bs...> const& bs, bool at_end);
|
||||
|
||||
void
|
||||
construct(C<sizeof...(Bs)>)
|
||||
{
|
||||
auto constexpr I = sizeof...(Bs);
|
||||
n_ = I;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
void
|
||||
construct(C<I>)
|
||||
{
|
||||
if(std::get<I>(*bs_).begin() !=
|
||||
std::get<I>(*bs_).end())
|
||||
{
|
||||
n_ = I;
|
||||
new(buf_.data()) iter_t<I>{
|
||||
std::get<I>(*bs_).begin()};
|
||||
return;
|
||||
}
|
||||
construct(C<I+1>{});
|
||||
}
|
||||
|
||||
void
|
||||
destroy(C<sizeof...(Bs)>)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
void
|
||||
destroy(C<I>)
|
||||
{
|
||||
if(n_ == I)
|
||||
{
|
||||
using Iter = iter_t<I>;
|
||||
iter<I>().~Iter();
|
||||
return;
|
||||
}
|
||||
destroy(C<I+1>{});
|
||||
}
|
||||
|
||||
void
|
||||
move(C<sizeof...(Bs)>, const_iterator&&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
void
|
||||
move(C<I>, const_iterator&& other)
|
||||
{
|
||||
if(n_ == I)
|
||||
{
|
||||
new(buf_.data()) iter_t<I>{
|
||||
std::move(other.iter<I>())};
|
||||
return;
|
||||
}
|
||||
move(C<I+1>{}, std::move(other));
|
||||
}
|
||||
|
||||
void
|
||||
copy(C<sizeof...(Bs)>, const_iterator const&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
void
|
||||
copy(C<I>, const_iterator const& other)
|
||||
{
|
||||
if(n_ == I)
|
||||
{
|
||||
new(buf_.data()) iter_t<I>{
|
||||
other.iter<I>()};
|
||||
return;
|
||||
}
|
||||
copy(C<I+1>{}, other);
|
||||
}
|
||||
|
||||
bool
|
||||
equal(C<sizeof...(Bs)>,
|
||||
const_iterator const&) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
bool
|
||||
equal(C<I>, const_iterator const& other) const
|
||||
{
|
||||
if(n_ == I)
|
||||
return iter<I>() == other.iter<I>();
|
||||
return equal(C<I+1>{}, other);
|
||||
}
|
||||
|
||||
[[noreturn]]
|
||||
reference
|
||||
dereference(C<sizeof...(Bs)>) const
|
||||
{
|
||||
throw std::logic_error("invalid iterator");
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
reference
|
||||
dereference(C<I>) const
|
||||
{
|
||||
if(n_ == I)
|
||||
return *iter<I>();
|
||||
return dereference(C<I+1>{});
|
||||
}
|
||||
|
||||
[[noreturn]]
|
||||
void
|
||||
increment(C<sizeof...(Bs)>)
|
||||
{
|
||||
throw std::logic_error("invalid iterator");
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
void
|
||||
increment(C<I>)
|
||||
{
|
||||
if(n_ == I)
|
||||
{
|
||||
if(++iter<I>() !=
|
||||
std::get<I>(*bs_).end())
|
||||
return;
|
||||
using Iter = iter_t<I>;
|
||||
iter<I>().~Iter();
|
||||
return construct(C<I+1>{});
|
||||
}
|
||||
increment(C<I+1>{});
|
||||
}
|
||||
|
||||
void
|
||||
decrement(C<sizeof...(Bs)>)
|
||||
{
|
||||
auto constexpr I = sizeof...(Bs);
|
||||
if(n_ == I)
|
||||
{
|
||||
--n_;
|
||||
new(buf_.data()) iter_t<I-1>{
|
||||
std::get<I-1>(*bs_).end()};
|
||||
}
|
||||
decrement(C<I-1>{});
|
||||
}
|
||||
|
||||
void
|
||||
decrement(C<0>)
|
||||
{
|
||||
auto constexpr I = 0;
|
||||
if(iter<I>() != std::get<I>(*bs_).begin())
|
||||
{
|
||||
--iter<I>();
|
||||
return;
|
||||
}
|
||||
throw std::logic_error("invalid iterator");
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
void
|
||||
decrement(C<I>)
|
||||
{
|
||||
if(n_ == I)
|
||||
{
|
||||
if(iter<I>() != std::get<I>(*bs_).begin())
|
||||
{
|
||||
--iter<I>();
|
||||
return;
|
||||
}
|
||||
--n_;
|
||||
using Iter = iter_t<I>;
|
||||
iter<I>().~Iter();
|
||||
new(buf_.data()) iter_t<I-1>{
|
||||
std::get<I-1>(*bs_).end()};
|
||||
}
|
||||
decrement(C<I-1>{});
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::~const_iterator()
|
||||
{
|
||||
destroy(C<0>{});
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::const_iterator()
|
||||
: n_(sizeof...(Bs))
|
||||
, bs_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::const_iterator(
|
||||
std::tuple<Bs...> const& bs, bool at_end)
|
||||
: bs_(&bs)
|
||||
{
|
||||
if(at_end)
|
||||
n_ = sizeof...(Bs);
|
||||
else
|
||||
construct(C<0>{});
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::const_iterator(const_iterator&& other)
|
||||
: n_(other.n_)
|
||||
, bs_(other.bs_)
|
||||
{
|
||||
move(C<0>{}, std::move(other));
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::const_iterator(const_iterator const& other)
|
||||
: n_(other.n_)
|
||||
, bs_(other.bs_)
|
||||
{
|
||||
copy(C<0>{}, other);
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::operator=(const_iterator&& other) ->
|
||||
const_iterator&
|
||||
{
|
||||
if(&other == this)
|
||||
return *this;
|
||||
destroy(C<0>{});
|
||||
n_ = other.n_;
|
||||
bs_ = other.bs_;
|
||||
move(C<0>{}, std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::operator=(const_iterator const& other) ->
|
||||
const_iterator&
|
||||
{
|
||||
if(&other == this)
|
||||
return *this;
|
||||
destroy(C<0>{});
|
||||
n_ = other.n_;
|
||||
bs_ = other.bs_;
|
||||
copy(C<0>{}, other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
bool
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::operator==(const_iterator const& other) const
|
||||
{
|
||||
if(bs_ != other.bs_)
|
||||
return false;
|
||||
if(n_ != other.n_)
|
||||
return false;
|
||||
return equal(C<0>{}, other);
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::operator*() const ->
|
||||
reference
|
||||
{
|
||||
return dereference(C<0>{});
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::operator++() ->
|
||||
const_iterator&
|
||||
{
|
||||
increment(C<0>{});
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::
|
||||
const_iterator::operator--() ->
|
||||
const_iterator&
|
||||
{
|
||||
decrement(C<sizeof...(Bs)>{});
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::begin() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator(bs_, false);
|
||||
}
|
||||
|
||||
template<class ValueType, class... Bs>
|
||||
auto
|
||||
buffer_cat_helper<ValueType, Bs...>::end() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator(bs_, true);
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
140
include/beast/detail/buffer_concepts.hpp
Normal file
140
include/beast/detail/buffer_concepts.hpp
Normal file
@@ -0,0 +1,140 @@
|
||||
//
|
||||
// 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_DETAIL_BUFFER_CONCEPTS_HPP
|
||||
#define BEAST_DETAIL_BUFFER_CONCEPTS_HPP
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
// Types that meet the requirements,
|
||||
// for use with std::declval only.
|
||||
template<class BufferType>
|
||||
struct BufferSequence
|
||||
{
|
||||
using value_type = BufferType;
|
||||
using const_iterator = BufferType const*;
|
||||
~BufferSequence();
|
||||
BufferSequence(BufferSequence const&) = default;
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
};
|
||||
using ConstBufferSequence =
|
||||
BufferSequence<boost::asio::const_buffer>;
|
||||
using MutableBufferSequence =
|
||||
BufferSequence<boost::asio::mutable_buffer>;
|
||||
|
||||
template<class T, class BufferType>
|
||||
class is_BufferSequence
|
||||
{
|
||||
template<class U, class R = std::is_convertible<
|
||||
typename U::value_type, BufferType> >
|
||||
static R check1(int);
|
||||
template<class>
|
||||
static std::false_type check1(...);
|
||||
using type1 = decltype(check1<T>(0));
|
||||
|
||||
template<class U, class R = std::is_base_of<
|
||||
#if 0
|
||||
std::bidirectional_iterator_tag,
|
||||
typename std::iterator_traits<
|
||||
typename U::const_iterator>::iterator_category>>
|
||||
#else
|
||||
// workaround:
|
||||
// boost::asio::detail::consuming_buffers::const_iterator
|
||||
// is not bidirectional
|
||||
std::forward_iterator_tag,
|
||||
typename std::iterator_traits<
|
||||
typename U::const_iterator>::iterator_category>>
|
||||
#endif
|
||||
static R check2(int);
|
||||
template<class>
|
||||
static std::false_type check2(...);
|
||||
using type2 = decltype(check2<T>(0));
|
||||
|
||||
template<class U, class R = typename
|
||||
std::is_convertible<decltype(
|
||||
std::declval<U>().begin()),
|
||||
typename U::const_iterator>::type>
|
||||
static R check3(int);
|
||||
template<class>
|
||||
static std::false_type check3(...);
|
||||
using type3 = decltype(check3<T>(0));
|
||||
|
||||
template<class U, class R = typename std::is_convertible<decltype(
|
||||
std::declval<U>().end()),
|
||||
typename U::const_iterator>::type>
|
||||
static R check4(int);
|
||||
template<class>
|
||||
static std::false_type check4(...);
|
||||
using type4 = decltype(check4<T>(0));
|
||||
|
||||
public:
|
||||
using type = std::integral_constant<bool,
|
||||
std::is_copy_constructible<T>::value &&
|
||||
std::is_destructible<T>::value &&
|
||||
type1::value && type2::value &&
|
||||
type3::value && type4::value>;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class is_Streambuf
|
||||
{
|
||||
template<class U, class R = std::integral_constant<
|
||||
bool, is_BufferSequence<decltype(
|
||||
std::declval<U>().prepare(1)),
|
||||
boost::asio::mutable_buffer>::type::value>>
|
||||
static R check1(int);
|
||||
template<class>
|
||||
static std::false_type check1(...);
|
||||
using type1 = decltype(check1<T>(0));
|
||||
|
||||
template<class U, class R = std::integral_constant<
|
||||
bool, is_BufferSequence<decltype(
|
||||
std::declval<U>().data()),
|
||||
boost::asio::const_buffer>::type::value>>
|
||||
static R check2(int);
|
||||
template<class>
|
||||
static std::false_type check2(...);
|
||||
using type2 = decltype(check2<T>(0));
|
||||
|
||||
template<class U, class R = decltype(
|
||||
std::declval<U>().commit(1), std::true_type{})>
|
||||
static R check3(int);
|
||||
template<class>
|
||||
static std::false_type check3(...);
|
||||
using type3 = decltype(check3<T>(0));
|
||||
|
||||
template<class U, class R = decltype(
|
||||
std::declval<U>().consume(1), std::true_type{})>
|
||||
static R check4(int);
|
||||
template<class>
|
||||
static std::false_type check4(...);
|
||||
using type4 = decltype(check4<T>(0));
|
||||
|
||||
template<class U, class R = std::is_same<decltype(
|
||||
std::declval<U>().size()), std::size_t>>
|
||||
static R check5(int);
|
||||
template<class>
|
||||
static std::false_type check5(...);
|
||||
using type5 = decltype(check5<T>(0));
|
||||
|
||||
public:
|
||||
using type = std::integral_constant<bool,
|
||||
type1::value && type2::value &&
|
||||
type3::value && type4::value &&
|
||||
type5::value>;
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
140
include/beast/detail/stream_concepts.hpp
Normal file
140
include/beast/detail/stream_concepts.hpp
Normal file
@@ -0,0 +1,140 @@
|
||||
//
|
||||
// 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_DETAIL_STREAM_CONCEPTS_HPP
|
||||
#define BEAST_DETAIL_STREAM_CONCEPTS_HPP
|
||||
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
// Types that meet the requirements,
|
||||
// for use with std::declval only.
|
||||
struct StreamHandler
|
||||
{
|
||||
StreamHandler(StreamHandler const&) = default;
|
||||
void operator()(boost::system::error_code ec, std::size_t);
|
||||
};
|
||||
using ReadHandler = StreamHandler;
|
||||
using WriteHandler = StreamHandler;
|
||||
|
||||
template<class T>
|
||||
class has_get_io_service
|
||||
{
|
||||
template<class U, class R = typename std::is_same<
|
||||
decltype(std::declval<U>().get_io_service()),
|
||||
boost::asio::io_service&>>
|
||||
static R check(int);
|
||||
template <class>
|
||||
static std::false_type check(...);
|
||||
public:
|
||||
using type = decltype(check<T>(0));
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class is_AsyncReadStream
|
||||
{
|
||||
template<class U, class R = decltype(
|
||||
std::declval<U>().async_read_some(
|
||||
std::declval<MutableBufferSequence>(),
|
||||
std::declval<ReadHandler>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type1 = decltype(check<T>(0));
|
||||
public:
|
||||
using type = std::integral_constant<bool,
|
||||
type1::value &&
|
||||
has_get_io_service<T>::type::value>;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class is_AsyncWriteStream
|
||||
{
|
||||
template<class U, class R = decltype(
|
||||
std::declval<U>().async_write_some(
|
||||
std::declval<ConstBufferSequence>(),
|
||||
std::declval<WriteHandler>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type1 = decltype(check<T>(0));
|
||||
public:
|
||||
using type = std::integral_constant<bool,
|
||||
type1::value &&
|
||||
has_get_io_service<T>::type::value>;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class is_SyncReadStream
|
||||
{
|
||||
using error_code =
|
||||
boost::system::error_code;
|
||||
|
||||
template<class U, class R = std::is_same<decltype(
|
||||
std::declval<U>().read_some(
|
||||
std::declval<MutableBufferSequence>())),
|
||||
std::size_t>>
|
||||
static R check1(int);
|
||||
template<class>
|
||||
static std::false_type check1(...);
|
||||
using type1 = decltype(check1<T>(0));
|
||||
|
||||
template<class U, class R = std::is_same<decltype(
|
||||
std::declval<U>().read_some(
|
||||
std::declval<MutableBufferSequence>(),
|
||||
std::declval<error_code&>())), std::size_t>>
|
||||
static R check2(int);
|
||||
template<class>
|
||||
static std::false_type check2(...);
|
||||
using type2 = decltype(check2<T>(0));
|
||||
|
||||
public:
|
||||
using type = std::integral_constant<bool,
|
||||
type1::value && type2::value>;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class is_SyncWriteStream
|
||||
{
|
||||
using error_code =
|
||||
boost::system::error_code;
|
||||
|
||||
template<class U, class R = std::is_same<decltype(
|
||||
std::declval<U>().write_some(
|
||||
std::declval<ConstBufferSequence>())),
|
||||
std::size_t>>
|
||||
static R check1(int);
|
||||
template<class>
|
||||
static std::false_type check1(...);
|
||||
using type1 = decltype(check1<T>(0));
|
||||
|
||||
template<class U, class R = std::is_same<decltype(
|
||||
std::declval<U>().write_some(
|
||||
std::declval<ConstBufferSequence>(),
|
||||
std::declval<error_code&>())), std::size_t>>
|
||||
static R check2(int);
|
||||
template<class>
|
||||
static std::false_type check2(...);
|
||||
using type2 = decltype(check2<T>(0));
|
||||
|
||||
public:
|
||||
using type = std::integral_constant<bool,
|
||||
type1::value && type2::value>;
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
@@ -8,6 +8,7 @@
|
||||
#ifndef BEAST_DETAIL_WRITE_STREAMBUF_HPP
|
||||
#define BEAST_DETAIL_WRITE_STREAMBUF_HPP
|
||||
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <utility>
|
||||
|
170
include/beast/doc_debug.hpp
Normal file
170
include/beast/doc_debug.hpp
Normal file
@@ -0,0 +1,170 @@
|
||||
//
|
||||
// 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_DOC_DEBUG_HPP
|
||||
#define BEAST_DOC_DEBUG_HPP
|
||||
|
||||
namespace beast {
|
||||
|
||||
#if GENERATING_DOCS
|
||||
|
||||
/// doc type (documentation debug helper)
|
||||
using doc_type = int;
|
||||
|
||||
/// doc enum (documentation debug helper)
|
||||
enum doc_enum
|
||||
{
|
||||
/// One (documentation debug helper)
|
||||
one,
|
||||
|
||||
/// Two (documentation debug helper)
|
||||
two
|
||||
};
|
||||
|
||||
/// doc enum class (documentation debug helper)
|
||||
enum class doc_enum_class : unsigned
|
||||
{
|
||||
/// one (documentation debug helper)
|
||||
one,
|
||||
|
||||
/// two (documentation debug helper)
|
||||
two
|
||||
};
|
||||
|
||||
/// doc func (documentation debug helper)
|
||||
void doc_func();
|
||||
|
||||
/// doc class (documentation debug helper)
|
||||
struct doc_class
|
||||
{
|
||||
/// doc class member func (documentation debug helper)
|
||||
void func();
|
||||
};
|
||||
|
||||
/// (documentation debug helper)
|
||||
namespace nested {
|
||||
|
||||
/// doc type (documentation debug helper)
|
||||
using nested_doc_type = int;
|
||||
|
||||
/// doc enum (documentation debug helper)
|
||||
enum nested_doc_enum
|
||||
{
|
||||
/// One (documentation debug helper)
|
||||
one,
|
||||
|
||||
/// Two (documentation debug helper)
|
||||
two
|
||||
};
|
||||
|
||||
/// doc enum class (documentation debug helper)
|
||||
enum class nested_doc_enum_class : unsigned
|
||||
{
|
||||
/// one (documentation debug helper)
|
||||
one,
|
||||
|
||||
/// two (documentation debug helper)
|
||||
two
|
||||
};
|
||||
|
||||
/// doc func (documentation debug helper)
|
||||
void nested_doc_func();
|
||||
|
||||
/// doc class (documentation debug helper)
|
||||
struct nested_doc_class
|
||||
{
|
||||
/// doc class member func (documentation debug helper)
|
||||
void func();
|
||||
};
|
||||
|
||||
} // nested
|
||||
|
||||
/** This is here to help troubleshoot doc/reference.xsl problems
|
||||
|
||||
Embedded references:
|
||||
|
||||
@li type @ref doc_type
|
||||
|
||||
@li enum @ref doc_enum
|
||||
|
||||
@li enum item @ref doc_enum::one
|
||||
|
||||
@li enum_class @ref doc_enum_class
|
||||
|
||||
@li enum_class item @ref doc_enum_class::one
|
||||
|
||||
@li func @ref doc_func
|
||||
|
||||
@li class @ref doc_class
|
||||
|
||||
@li class func @ref doc_class::func
|
||||
|
||||
@li nested type @ref nested::nested_doc_type
|
||||
|
||||
@li nested enum @ref nested::nested_doc_enum
|
||||
|
||||
@li nested enum item @ref nested::nested_doc_enum::one
|
||||
|
||||
@li nested enum_class @ref nested::nested_doc_enum_class
|
||||
|
||||
@li nested enum_class item @ref nested::nested_doc_enum_class::one
|
||||
|
||||
@li nested func @ref nested::nested_doc_func
|
||||
|
||||
@li nested class @ref nested::nested_doc_class
|
||||
|
||||
@li nested class func @ref nested::nested_doc_class::func
|
||||
*/
|
||||
void doc_debug();
|
||||
|
||||
namespace nested {
|
||||
|
||||
/** This is here to help troubleshoot doc/reference.xsl problems
|
||||
|
||||
Embedded references:
|
||||
|
||||
@li type @ref doc_type
|
||||
|
||||
@li enum @ref doc_enum
|
||||
|
||||
@li enum item @ref doc_enum::one
|
||||
|
||||
@li enum_class @ref doc_enum_class
|
||||
|
||||
@li enum_class item @ref doc_enum_class::one
|
||||
|
||||
@li func @ref doc_func
|
||||
|
||||
@li class @ref doc_class
|
||||
|
||||
@li class func @ref doc_class::func
|
||||
|
||||
@li nested type @ref nested_doc_type
|
||||
|
||||
@li nested enum @ref nested_doc_enum
|
||||
|
||||
@li nested enum item @ref nested_doc_enum::one
|
||||
|
||||
@li nested enum_class @ref nested_doc_enum_class
|
||||
|
||||
@li nested enum_class item @ref nested_doc_enum_class::one
|
||||
|
||||
@li nested func @ref nested_doc_func
|
||||
|
||||
@li nested class @ref nested_doc_class
|
||||
|
||||
@li nested class func @ref nested_doc_class::func
|
||||
*/
|
||||
void nested_doc_debug();
|
||||
|
||||
} // nested
|
||||
|
||||
#endif
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
@@ -28,28 +28,28 @@ namespace beast {
|
||||
|
||||
@tparam T The type of objects allocated by the allocator.
|
||||
|
||||
@tparam Handler The type of handler.
|
||||
@tparam CompletionHandler The type of handler.
|
||||
|
||||
@note Allocated memory is only valid until the handler is called. The
|
||||
caller is still responsible for freeing memory.
|
||||
*/
|
||||
#if GENERATING_DOCS
|
||||
template <class T, class Handler>
|
||||
template <class T, class CompletionHandler>
|
||||
class handler_alloc;
|
||||
#else
|
||||
template <class T, class Handler>
|
||||
template <class T, class CompletionHandler>
|
||||
class handler_alloc
|
||||
{
|
||||
private:
|
||||
// We want a partial template specialization as a friend
|
||||
// but that isn't allowed so we friend all versions. This
|
||||
// should produce a compile error if Handler is not
|
||||
// should produce a compile error if CompletionHandler is not
|
||||
// constructible from H.
|
||||
//
|
||||
template <class U, class H>
|
||||
friend class handler_alloc;
|
||||
|
||||
Handler h_;
|
||||
CompletionHandler h_;
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
The handler is moved or copied into the allocator.
|
||||
*/
|
||||
explicit
|
||||
handler_alloc(Handler&& h)
|
||||
handler_alloc(CompletionHandler&& h)
|
||||
: h_(std::move(h))
|
||||
{
|
||||
}
|
||||
@@ -76,21 +76,21 @@ public:
|
||||
A copy of the handler is made.
|
||||
*/
|
||||
explicit
|
||||
handler_alloc(Handler const& h)
|
||||
handler_alloc(CompletionHandler const& h)
|
||||
: h_(h)
|
||||
{
|
||||
}
|
||||
|
||||
template<class U>
|
||||
handler_alloc(
|
||||
handler_alloc<U, Handler>&& other)
|
||||
handler_alloc<U, CompletionHandler>&& other)
|
||||
: h_(std::move(other.h_))
|
||||
{
|
||||
}
|
||||
|
||||
template<class U>
|
||||
handler_alloc(
|
||||
handler_alloc<U, Handler> const& other)
|
||||
handler_alloc<U, CompletionHandler> const& other)
|
||||
: h_(other.h_)
|
||||
{
|
||||
}
|
||||
@@ -127,7 +127,7 @@ public:
|
||||
friend
|
||||
bool
|
||||
operator==(handler_alloc const& lhs,
|
||||
handler_alloc<U, Handler> const& rhs)
|
||||
handler_alloc<U, CompletionHandler> const& rhs)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -136,7 +136,7 @@ public:
|
||||
friend
|
||||
bool
|
||||
operator!=(handler_alloc const& lhs,
|
||||
handler_alloc<U, Handler> const& rhs)
|
||||
handler_alloc<U, CompletionHandler> const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
27
include/beast/handler_concepts.hpp
Normal file
27
include/beast/handler_concepts.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// 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_HANDLER_CONCEPTS_HPP
|
||||
#define BEAST_HANDLER_CONCEPTS_HPP
|
||||
|
||||
#include <beast/detail/is_call_possible.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/// Determine if `T` meets the requirements of @b `CompletionHandler`.
|
||||
template<class T, class Signature>
|
||||
#if GENERATING_DOCS
|
||||
using is_CompletionHandler = std::integral_constant<bool, ...>;
|
||||
#else
|
||||
using is_CompletionHandler = std::integral_constant<bool,
|
||||
std::is_copy_constructible<typename std::decay<T>::type>::value &&
|
||||
detail::is_call_possible<T, Signature>::value>;
|
||||
#endif
|
||||
} // beast
|
||||
|
||||
#endif
|
@@ -5,12 +5,12 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_HTTP_HPP_INCLUDED
|
||||
#define BEAST_HTTP_HPP_INCLUDED
|
||||
#ifndef BEAST_HTTP_HPP
|
||||
#define BEAST_HTTP_HPP
|
||||
|
||||
#include <beast/http/basic_headers.hpp>
|
||||
#include <beast/http/basic_parser_v1.hpp>
|
||||
#include <beast/http/body_writer.hpp>
|
||||
#include <beast/http/body_type.hpp>
|
||||
#include <beast/http/empty_body.hpp>
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/headers.hpp>
|
||||
|
@@ -8,7 +8,6 @@
|
||||
#ifndef BEAST_HTTP_BASIC_HEADERS_HPP
|
||||
#define BEAST_HTTP_BASIC_HEADERS_HPP
|
||||
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/detail/ci_char_traits.hpp>
|
||||
#include <beast/detail/empty_base_optimization.hpp>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
@@ -237,9 +236,20 @@ public:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Container to store HTTP headers.
|
||||
/** A container for storing HTTP headers.
|
||||
|
||||
Meets the requirements of `FieldSequence`.
|
||||
This container is designed to store the field value pairs that make
|
||||
up the headers and trailers in a HTTP message. Objects of this type
|
||||
are iterable, which each element holding the field name and field
|
||||
value.
|
||||
|
||||
Field names are stored as-is, but comparison are case-insensitive.
|
||||
The container preserves the order of insertion of fields with
|
||||
different names. For fields with the same name, the implementation
|
||||
concatenates values inserted with duplicate names as per the
|
||||
rules in rfc2616 section 4.2.
|
||||
|
||||
@note Meets the requirements of @b `FieldSequence`.
|
||||
*/
|
||||
template<class Allocator>
|
||||
class basic_headers
|
||||
|
@@ -12,7 +12,6 @@
|
||||
#include <beast/http/parse_error.hpp>
|
||||
#include <beast/http/rfc7230.hpp>
|
||||
#include <beast/http/detail/basic_parser_v1.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
@@ -43,49 +42,49 @@ enum values
|
||||
if those members are present (detected through SFINAE). The
|
||||
signatures which can be present in the derived class are:<br>
|
||||
|
||||
@li `void on_method(boost::string_ref const&, error_code& ec)`
|
||||
@li `void on_method(boost::string_ref const&, error_code&)`
|
||||
|
||||
Called for each piece of the Request-Method
|
||||
|
||||
@li `void on_uri(boost::string_ref const&, error_code& ec)`
|
||||
@li `void on_uri(boost::string_ref const&, error_code&)`
|
||||
|
||||
Called for each piece of the Request-URI
|
||||
|
||||
@li `void on_reason(boost::string_ref const&, error_code& ec)`
|
||||
@li `void on_reason(boost::string_ref const&, error_code&)`
|
||||
|
||||
Called for each piece of the reason-phrase
|
||||
|
||||
@li `void on_request(error_code& ec)`
|
||||
@li `void on_request(error_code&)`
|
||||
|
||||
Called after the entire Request-Line has been parsed successfully.
|
||||
|
||||
@li `void on_response(error_code& ec)`
|
||||
@li `void on_response(error_code&)`
|
||||
|
||||
Called after the entire Response-Line has been parsed successfully.
|
||||
|
||||
@li `void on_field(boost::string_ref const&, error_code& ec)`
|
||||
@li `void on_field(boost::string_ref const&, error_code&)`
|
||||
|
||||
Called for each piece of the current header field.
|
||||
|
||||
@li `void on_value(boost::string_ref const&, error_code& ec)`
|
||||
@li `void on_value(boost::string_ref const&, error_code&)`
|
||||
|
||||
Called for each piece of the current header value.
|
||||
|
||||
@li `int on_headers(error_code& ec)`
|
||||
@li `int on_headers(error_code&)`
|
||||
|
||||
Called when all the headers have been parsed successfully.
|
||||
|
||||
@li `void on_body(boost::string_ref const&, error_code& ec)`
|
||||
@li `void on_body(boost::string_ref const&, error_code&)`
|
||||
|
||||
Called for each piece of the body. If the headers indicated
|
||||
chunked encoding, the chunk encoding is removed from the
|
||||
buffer before being passed to the callback.
|
||||
|
||||
@li `void on_complete(error_code& ec)`
|
||||
@li `void on_complete(error_code&)`
|
||||
|
||||
Called when the entire message has been parsed successfully.
|
||||
At this point, basic_parser_v1::complete() returns `true`, and
|
||||
the parser is ready to parse another message if keep_alive()
|
||||
At this point, @ref basic_parser_v1::complete returns `true`, and
|
||||
the parser is ready to parse another message if keep_alive
|
||||
would return `true`.
|
||||
|
||||
The return value of `on_headers` is special, it controls whether
|
||||
@@ -101,7 +100,7 @@ enum values
|
||||
|
||||
The parser uses traits to determine if the callback is possible.
|
||||
If the Derived type omits one or more callbacks, they are simply
|
||||
skipped with no compilation error. The default behavior of on_body
|
||||
skipped with no compilation error. The default behavior of `on_body`
|
||||
when the derived class does not provide the member, is to specify that
|
||||
the body should not be skipped.
|
||||
|
||||
@@ -354,12 +353,15 @@ public:
|
||||
|
||||
@return The number of bytes consumed in the input sequence.
|
||||
*/
|
||||
template<class ConstBufferSequence,
|
||||
class = typename std::enable_if<
|
||||
! std::is_convertible<ConstBufferSequence,
|
||||
boost::asio::const_buffer>::value>::type
|
||||
>
|
||||
template<class ConstBufferSequence>
|
||||
#if GENERATING_DOCS
|
||||
std::size_t
|
||||
#else
|
||||
typename std::enable_if<
|
||||
! std::is_convertible<ConstBufferSequence,
|
||||
boost::asio::const_buffer>::value,
|
||||
std::size_t>::type
|
||||
#endif
|
||||
write(ConstBufferSequence const& buffers, error_code& ec);
|
||||
|
||||
/** Write a single buffer of data to the parser.
|
||||
@@ -380,8 +382,6 @@ public:
|
||||
Callbacks and errors will still be processed as usual.
|
||||
|
||||
@note This is typically called when a socket read returns eof.
|
||||
|
||||
@throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
void
|
||||
write_eof(error_code& ec);
|
||||
|
@@ -5,11 +5,11 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_HTTP_BODY_WRITER_HPP
|
||||
#define BEAST_HTTP_BODY_WRITER_HPP
|
||||
#ifndef BEAST_HTTP_BODY_TYPE_HPP
|
||||
#define BEAST_HTTP_BODY_TYPE_HPP
|
||||
|
||||
// Convenience header to include everything necessary for
|
||||
// declaring an object meeting the BodyWriter requirements.
|
||||
// Convenience header to include everything
|
||||
// needed when declarating a user defined Body type.
|
||||
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/message.hpp>
|
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_HTTP_EMPTY_BODY_HPP
|
||||
#define BEAST_HTTP_EMPTY_BODY_HPP
|
||||
|
||||
#include <beast/http/body_writer.hpp>
|
||||
#include <beast/http/body_type.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <memory>
|
||||
@@ -18,6 +18,8 @@ namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** An empty content-body.
|
||||
|
||||
Meets the requirements of @b `Body`.
|
||||
*/
|
||||
struct empty_body
|
||||
{
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#define BEAST_HTTP_ERROR_HPP
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
@@ -8,8 +8,6 @@
|
||||
#ifndef BEAST_HTTP_IMPL_BASIC_HEADERS_IPP
|
||||
#define BEAST_HTTP_IMPL_BASIC_HEADERS_IPP
|
||||
|
||||
#include <beast/type_check.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
|
@@ -8,6 +8,8 @@
|
||||
#ifndef BEAST_HTTP_IMPL_BASIC_PARSER_V1_IPP
|
||||
#define BEAST_HTTP_IMPL_BASIC_PARSER_V1_IPP
|
||||
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
@@ -32,8 +34,11 @@ keep_alive() const
|
||||
// Implementation inspired by nodejs/http-parser
|
||||
|
||||
template<bool isRequest, class Derived>
|
||||
template<class ConstBufferSequence, class>
|
||||
std::size_t
|
||||
template<class ConstBufferSequence>
|
||||
typename std::enable_if<
|
||||
! std::is_convertible<ConstBufferSequence,
|
||||
boost::asio::const_buffer>::value,
|
||||
std::size_t>::type
|
||||
basic_parser_v1<isRequest, Derived>::
|
||||
write(ConstBufferSequence const& buffers, error_code& ec)
|
||||
{
|
||||
|
@@ -10,7 +10,6 @@
|
||||
|
||||
#include <beast/http/rfc2616.hpp>
|
||||
#include <beast/http/detail/has_content_length.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#include <beast/http/parser_v1.hpp>
|
||||
#include <beast/bind_handler.hpp>
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <beast/stream_concepts.hpp>
|
||||
#include <cassert>
|
||||
|
||||
namespace beast {
|
||||
|
@@ -13,9 +13,10 @@
|
||||
#include <beast/http/detail/has_content_length.hpp>
|
||||
#include <beast/buffer_cat.hpp>
|
||||
#include <beast/bind_handler.hpp>
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <beast/stream_concepts.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/write_streambuf.hpp>
|
||||
#include <boost/asio/write.hpp>
|
||||
#include <boost/logic/tribool.hpp>
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#define BEAST_HTTP_MESSAGE_HPP
|
||||
|
||||
#include <beast/http/basic_headers.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#define BEAST_HTTP_MESSAGE_V1_HPP
|
||||
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
@@ -92,7 +91,7 @@ is_upgrade(message_v1<isRequest, Body, Headers> const& msg);
|
||||
|
||||
/** HTTP/1 connection prepare options.
|
||||
|
||||
@note These values are used with `prepare`.
|
||||
@note These values are used with @ref prepare.
|
||||
*/
|
||||
enum class connection
|
||||
{
|
||||
|
@@ -19,17 +19,29 @@ namespace http {
|
||||
|
||||
/** Read a HTTP/1 message from a stream.
|
||||
|
||||
@param stream The stream to read the message from.
|
||||
This function is used to synchronously read a message from
|
||||
the stream. The call blocks until one of the following conditions
|
||||
is true:
|
||||
|
||||
@param streambuf A Streambuf used to hold unread bytes. The
|
||||
implementation may read past the end of the message. The extra
|
||||
bytes are stored here, to be presented in a subsequent call to
|
||||
read.
|
||||
@li A complete message is read in.
|
||||
|
||||
@param msg An object used to store the read message. Any
|
||||
@li An error occurs on the stream.
|
||||
|
||||
This function is implemented in terms of one or more calls to the
|
||||
stream's `read_some` function.
|
||||
|
||||
@param stream The stream to which the data is to be written.
|
||||
The type must support the @b `SyncReadStream` concept.
|
||||
|
||||
@param streambuf An object meeting the @b `Streambuf` type requirements
|
||||
used to hold unread bytes. The implementation may read past the end of
|
||||
the message. The extra bytes are stored here, to be presented in a
|
||||
subsequent call to @ref read.
|
||||
|
||||
@param msg An object used to store the message. Any
|
||||
contents will be overwritten.
|
||||
|
||||
@throws boost::system::system_error on failure.
|
||||
@throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template<class SyncReadStream, class Streambuf,
|
||||
bool isRequest, class Body, class Headers>
|
||||
@@ -43,17 +55,29 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
throw boost::system::system_error{ec};
|
||||
}
|
||||
|
||||
/** Read a HTTP message from a stream.
|
||||
/** Read a HTTP/1 message from a stream.
|
||||
|
||||
@param stream The stream to read the message from.
|
||||
This function is used to synchronously read a message from
|
||||
the stream. The call blocks until one of the following conditions
|
||||
is true:
|
||||
|
||||
@param streambuf A Streambuf used to hold unread bytes. The
|
||||
implementation may read past the end of the message. The extra
|
||||
bytes are stored here, to be presented in a subsequent call to
|
||||
read.
|
||||
@li A complete message is read in.
|
||||
|
||||
@param msg An object used to store the read message. Any
|
||||
contents will be overwritten.
|
||||
@li An error occurs on the stream.
|
||||
|
||||
This function is implemented in terms of one or more calls to the
|
||||
stream's `read_some` function.
|
||||
|
||||
@param stream The stream to which the data is to be written.
|
||||
The type must support the @b `SyncReadStream` concept.
|
||||
|
||||
@param streambuf An object meeting the @b `Streambuf` type requirements
|
||||
used to hold unread bytes. The implementation may read past the end of
|
||||
the message. The extra bytes are stored here, to be presented in a
|
||||
subsequent call to @ref read.
|
||||
|
||||
@param msg An object used to store the message. Any contents
|
||||
will be overwritten.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
@@ -64,17 +88,31 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
message_v1<isRequest, Body, Headers>& msg,
|
||||
error_code& ec);
|
||||
|
||||
/** Start reading a HTTP message from a stream asynchronously.
|
||||
/** Start an asynchronous operation to read a HTTP/1 message from a stream.
|
||||
|
||||
This function is used to asynchronously read a message from the
|
||||
stream. The function call always returns immediately. The asynchronous
|
||||
operation will continue until one of the following conditions is true:
|
||||
|
||||
@li A complete message is read in.
|
||||
|
||||
@li An error occurs on the stream.
|
||||
|
||||
This operation is implemented in terms of one or more calls to the
|
||||
next layer's `async_read_some` function, and is known as a
|
||||
<em>composed operation</em>. The program must ensure that the stream
|
||||
performs no other operations until this operation completes.
|
||||
|
||||
@param stream The stream to read the message from.
|
||||
The type must support the @b `AsyncReadStream` concept.
|
||||
|
||||
@param streambuf A Streambuf used to hold unread bytes. The
|
||||
implementation may read past the end of the message. The extra
|
||||
bytes are stored here, to be presented in a subsequent call to
|
||||
async_read.
|
||||
@ref async_read.
|
||||
|
||||
@param msg An object used to store the read message. Any
|
||||
contents will be overwritten.
|
||||
@param msg An object used to store the message. Any contents
|
||||
will be overwritten.
|
||||
|
||||
@param handler The handler to be called when the request completes.
|
||||
Copies will be made of the handler as required. The equivalent
|
||||
@@ -85,7 +123,7 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
Regardless of whether the asynchronous operation completes
|
||||
immediately or not, the handler will not be invoked from within
|
||||
this function. Invocation of the handler will be performed in a
|
||||
manner equivalent to using boost::asio::io_service::post().
|
||||
manner equivalent to using `boost::asio::io_service::post`.
|
||||
*/
|
||||
template<class AsyncReadStream, class Streambuf,
|
||||
bool isRequest, class Body, class Headers,
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_HTTP_STREAMBUF_BODY_HPP
|
||||
#define BEAST_HTTP_STREAMBUF_BODY_HPP
|
||||
|
||||
#include <beast/http/body_writer.hpp>
|
||||
#include <beast/http/body_type.hpp>
|
||||
#include <beast/buffer_cat.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <memory>
|
||||
@@ -17,7 +17,9 @@
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** A Body represented by a Streambuf
|
||||
/** A message body represented by a Streambuf
|
||||
|
||||
Meets the requirements of @b `Body`.
|
||||
*/
|
||||
template<class Streambuf>
|
||||
struct basic_streambuf_body
|
||||
@@ -34,10 +36,10 @@ private:
|
||||
value_type& sb_;
|
||||
|
||||
public:
|
||||
template<bool isRequest, class Allocator>
|
||||
template<bool isRequest, class Headers>
|
||||
explicit
|
||||
reader(message<isRequest,
|
||||
basic_streambuf_body, Allocator>& m) noexcept
|
||||
basic_streambuf_body, Headers>& m) noexcept
|
||||
: sb_(m.body)
|
||||
{
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_HTTP_STRING_BODY_HPP
|
||||
#define BEAST_HTTP_STRING_BODY_HPP
|
||||
|
||||
#include <beast/http/body_writer.hpp>
|
||||
#include <beast/http/body_type.hpp>
|
||||
#include <beast/buffer_cat.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <memory>
|
||||
@@ -18,6 +18,8 @@ namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** A Body represented by a std::string.
|
||||
|
||||
Meets the requirements of @b `Body`.
|
||||
*/
|
||||
struct string_body
|
||||
{
|
||||
@@ -33,10 +35,10 @@ private:
|
||||
value_type& s_;
|
||||
|
||||
public:
|
||||
template<bool isRequest, class Allocator>
|
||||
template<bool isRequest, class Headers>
|
||||
explicit
|
||||
reader(message<isRequest,
|
||||
string_body, Allocator>& m) noexcept
|
||||
string_body, Headers>& m) noexcept
|
||||
: s_(m.body)
|
||||
{
|
||||
}
|
||||
|
@@ -18,13 +18,30 @@
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** Write a HTTP/1 message to a stream.
|
||||
/** Write a HTTP/1 message on a stream.
|
||||
|
||||
@param stream The stream to send the message on.
|
||||
This function is used to write a message to a stream. The call
|
||||
will block until one of the following conditions is true:
|
||||
|
||||
@param msg The message to send.
|
||||
@li The entire message is sent.
|
||||
|
||||
@throws boost::system::error code on failure.
|
||||
@li An error occurs.
|
||||
|
||||
This operation is implemented in terms of one or more calls
|
||||
to the stream's `write_some` function.
|
||||
|
||||
The implementation will automatically perform chunk encoding if
|
||||
the contents of the message indicate that chunk encoding is required.
|
||||
If the semantics of the message indicate that the connection should
|
||||
be closed after the message is sent, the error returns from this
|
||||
function will be `boost::asio::error::eof`.
|
||||
|
||||
@param stream The stream to which the data is to be written.
|
||||
The type must support the @b `SyncWriteStream` concept.
|
||||
|
||||
@param msg The message to write.
|
||||
|
||||
@throws boost::system::error Thrown on failure.
|
||||
*/
|
||||
template<class SyncWriteStream,
|
||||
bool isRequest, class Body, class Headers>
|
||||
@@ -32,11 +49,28 @@ void
|
||||
write(SyncWriteStream& stream,
|
||||
message_v1<isRequest, Body, Headers> const& msg);
|
||||
|
||||
/** Write a HTTP/1 message to a stream.
|
||||
/** Write a HTTP/1 message on a stream.
|
||||
|
||||
@param stream The stream to send the message on.
|
||||
This function is used to write a message to a stream. The call
|
||||
will block until one of the following conditions is true:
|
||||
|
||||
@param msg The message to send.
|
||||
@li The entire message is sent.
|
||||
|
||||
@li An error occurs.
|
||||
|
||||
This operation is implemented in terms of one or more calls
|
||||
to the stream's `write_some` function.
|
||||
|
||||
The implementation will automatically perform chunk encoding if
|
||||
the contents of the message indicate that chunk encoding is required.
|
||||
If the semantics of the message indicate that the connection should
|
||||
be closed after the message is sent, the error returns from this
|
||||
function will be `boost::asio::error::eof`.
|
||||
|
||||
@param stream The stream to which the data is to be written.
|
||||
The type must support the @b `SyncWriteStream` concept.
|
||||
|
||||
@param msg The message to write.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
@@ -47,13 +81,35 @@ write(SyncWriteStream& stream,
|
||||
message_v1<isRequest, Body, Headers> const& msg,
|
||||
error_code& ec);
|
||||
|
||||
/** Start writing a HTTP/1 message to a stream asynchronously.
|
||||
/** Start an asynchronous operation to write a HTTP/1 message to a stream.
|
||||
|
||||
@param stream The stream to send the message on.
|
||||
This function is used to asynchronously write a message to a stream.
|
||||
The function call always returns immediately. The asynchronous
|
||||
operation will continue until one of the following conditions is true:
|
||||
|
||||
@li The entire message is sent.
|
||||
|
||||
@li An error occurs.
|
||||
|
||||
This operation is implemented in terms of one or more calls to the
|
||||
stream's `async_write_some` functions, and is known as a <em>composed
|
||||
operation</em>. The program must ensure that the stream performs no
|
||||
other write operations (such as @ref async_write, the stream's
|
||||
`async_write_some` function, or any other composed operations that
|
||||
perform writes) until this operation completes.
|
||||
|
||||
The implementation will automatically perform chunk encoding if
|
||||
the contents of the message indicate that chunk encoding is required.
|
||||
If the semantics of the message indicate that the connection should
|
||||
be closed after the message is sent, the operation will complete with
|
||||
the error set to `boost::asio::error::eof`.
|
||||
|
||||
@param stream The stream to which the data is to be written.
|
||||
The type must support the @b `AsyncWriteStream` concept.
|
||||
|
||||
@param msg The message to send.
|
||||
|
||||
@param token The handler to be called when the request completes.
|
||||
@param handler The handler to be called when the request completes.
|
||||
Copies will be made of the handler as required. The equivalent
|
||||
function signature of the handler must be:
|
||||
@code void handler(
|
||||
@@ -62,9 +118,9 @@ write(SyncWriteStream& stream,
|
||||
Regardless of whether the asynchronous operation completes
|
||||
immediately or not, the handler will not be invoked from within
|
||||
this function. Invocation of the handler will be performed in a
|
||||
manner equivalent to using boost::asio::io_service::post().
|
||||
manner equivalent to using `boost::asio::io_service::post`.
|
||||
|
||||
@note The message must remain valid at least until the
|
||||
@note The message object must remain valid at least until the
|
||||
completion handler is called, no copies are made.
|
||||
*/
|
||||
template<class AsyncWriteStream,
|
||||
@@ -85,6 +141,9 @@ async_write(AsyncWriteStream& stream,
|
||||
The function converts the message to its HTTP/1 serialized
|
||||
representation and stores the result in the output stream.
|
||||
|
||||
The implementation will automatically perform chunk encoding if
|
||||
the contents of the message indicate that chunk encoding is required.
|
||||
|
||||
@param os The ostream to write to.
|
||||
|
||||
@param msg The message to write.
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#ifndef BEAST_IMPL_BASIC_STREAMBUF_IPP
|
||||
#define BEAST_IMPL_BASIC_STREAMBUF_IPP
|
||||
|
||||
#include <beast/detail/write_streambuf.hpp>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
@@ -849,22 +850,6 @@ basic_streambuf<Allocator>::debug_check() const
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class Alloc, class T>
|
||||
basic_streambuf<Alloc>&
|
||||
operator<<(basic_streambuf<Alloc>& streambuf, T const& t)
|
||||
{
|
||||
using boost::asio::buffer;
|
||||
using boost::asio::buffer_copy;
|
||||
std::stringstream ss;
|
||||
ss << t;
|
||||
auto const& s = ss.str();
|
||||
streambuf.commit(buffer_copy(
|
||||
streambuf.prepare(s.size()), buffer(s)));
|
||||
return streambuf;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class Allocator>
|
||||
std::size_t
|
||||
read_size_helper(basic_streambuf<
|
||||
@@ -874,17 +859,12 @@ read_size_helper(basic_streambuf<
|
||||
std::max<std::size_t>(512, streambuf.prepare_size()));
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
std::string
|
||||
to_string(basic_streambuf<Allocator> const& streambuf)
|
||||
template<class Alloc, class T>
|
||||
basic_streambuf<Alloc>&
|
||||
operator<<(basic_streambuf<Alloc>& streambuf, T const& t)
|
||||
{
|
||||
using boost::asio::buffer;
|
||||
using boost::asio::buffer_copy;
|
||||
std::string s;
|
||||
s.resize(streambuf.size());
|
||||
buffer_copy(
|
||||
buffer(&s[0], s.size()), streambuf.data());
|
||||
return s;
|
||||
detail::write_streambuf(streambuf, t);
|
||||
return streambuf;
|
||||
}
|
||||
|
||||
} // beast
|
||||
|
@@ -17,8 +17,9 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
template<class Buffers>
|
||||
class buffers_adapter<Buffers>::const_buffers_type
|
||||
template<class MutableBufferSequence>
|
||||
class buffers_adapter<MutableBufferSequence>::
|
||||
const_buffers_type
|
||||
{
|
||||
buffers_adapter const* ba_;
|
||||
|
||||
@@ -48,8 +49,9 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template<class Buffers>
|
||||
class buffers_adapter<Buffers>::const_buffers_type::const_iterator
|
||||
template<class MutableBufferSequence>
|
||||
class buffers_adapter<MutableBufferSequence>::
|
||||
const_buffers_type::const_iterator
|
||||
{
|
||||
iter_type it_;
|
||||
buffers_adapter const* ba_ = nullptr;
|
||||
@@ -136,19 +138,19 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template<class Buffers>
|
||||
template<class MutableBufferSequence>
|
||||
inline
|
||||
auto
|
||||
buffers_adapter<Buffers>::const_buffers_type::begin() const ->
|
||||
buffers_adapter<MutableBufferSequence>::const_buffers_type::begin() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator{*ba_, ba_->begin_};
|
||||
}
|
||||
|
||||
template<class Buffers>
|
||||
template<class MutableBufferSequence>
|
||||
inline
|
||||
auto
|
||||
buffers_adapter<Buffers>::const_buffers_type::end() const ->
|
||||
buffers_adapter<MutableBufferSequence>::const_buffers_type::end() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator{*ba_, ba_->out_ ==
|
||||
@@ -157,8 +159,9 @@ buffers_adapter<Buffers>::const_buffers_type::end() const ->
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class Buffers>
|
||||
class buffers_adapter<Buffers>::mutable_buffers_type
|
||||
template<class MutableBufferSequence>
|
||||
class buffers_adapter<MutableBufferSequence>::
|
||||
mutable_buffers_type
|
||||
{
|
||||
buffers_adapter const* ba_;
|
||||
|
||||
@@ -189,8 +192,9 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template<class Buffers>
|
||||
class buffers_adapter<Buffers>::mutable_buffers_type::const_iterator
|
||||
template<class MutableBufferSequence>
|
||||
class buffers_adapter<MutableBufferSequence>::
|
||||
mutable_buffers_type::const_iterator
|
||||
{
|
||||
iter_type it_;
|
||||
buffers_adapter const* ba_ = nullptr;
|
||||
@@ -277,19 +281,19 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template<class Buffers>
|
||||
template<class MutableBufferSequence>
|
||||
inline
|
||||
auto
|
||||
buffers_adapter<Buffers>::mutable_buffers_type::begin() const ->
|
||||
buffers_adapter<MutableBufferSequence>::mutable_buffers_type::begin() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator{*ba_, ba_->out_};
|
||||
}
|
||||
|
||||
template<class Buffers>
|
||||
template<class MutableBufferSequence>
|
||||
inline
|
||||
auto
|
||||
buffers_adapter<Buffers>::mutable_buffers_type::end() const ->
|
||||
buffers_adapter<MutableBufferSequence>::mutable_buffers_type::end() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator{*ba_, ba_->end_};
|
||||
@@ -297,8 +301,8 @@ buffers_adapter<Buffers>::mutable_buffers_type::end() const ->
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class Buffers>
|
||||
buffers_adapter<Buffers>::buffers_adapter(
|
||||
template<class MutableBufferSequence>
|
||||
buffers_adapter<MutableBufferSequence>::buffers_adapter(
|
||||
buffers_adapter&& other)
|
||||
: buffers_adapter(std::move(other),
|
||||
std::distance<iter_type>(other.bs_.begin(), other.begin_),
|
||||
@@ -307,8 +311,8 @@ buffers_adapter<Buffers>::buffers_adapter(
|
||||
{
|
||||
}
|
||||
|
||||
template<class Buffers>
|
||||
buffers_adapter<Buffers>::buffers_adapter(
|
||||
template<class MutableBufferSequence>
|
||||
buffers_adapter<MutableBufferSequence>::buffers_adapter(
|
||||
buffers_adapter const& other)
|
||||
: buffers_adapter(other,
|
||||
std::distance<iter_type>(other.bs_.begin(), other.begin_),
|
||||
@@ -317,9 +321,9 @@ buffers_adapter<Buffers>::buffers_adapter(
|
||||
{
|
||||
}
|
||||
|
||||
template<class Buffers>
|
||||
template<class MutableBufferSequence>
|
||||
auto
|
||||
buffers_adapter<Buffers>::operator=(
|
||||
buffers_adapter<MutableBufferSequence>::operator=(
|
||||
buffers_adapter&& other) -> buffers_adapter&
|
||||
{
|
||||
auto const nbegin = std::distance<iter_type>(
|
||||
@@ -340,9 +344,9 @@ buffers_adapter<Buffers>::operator=(
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Buffers>
|
||||
template<class MutableBufferSequence>
|
||||
auto
|
||||
buffers_adapter<Buffers>::operator=(
|
||||
buffers_adapter<MutableBufferSequence>::operator=(
|
||||
buffers_adapter const& other) -> buffers_adapter&
|
||||
{
|
||||
auto const nbegin = std::distance<iter_type>(
|
||||
@@ -363,9 +367,9 @@ buffers_adapter<Buffers>::operator=(
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Buffers>
|
||||
buffers_adapter<Buffers>::buffers_adapter(
|
||||
Buffers const& bs)
|
||||
template<class MutableBufferSequence>
|
||||
buffers_adapter<MutableBufferSequence>::buffers_adapter(
|
||||
MutableBufferSequence const& bs)
|
||||
: bs_(bs)
|
||||
, begin_(bs_.begin())
|
||||
, out_(bs_.begin())
|
||||
@@ -374,14 +378,12 @@ buffers_adapter<Buffers>::buffers_adapter(
|
||||
{
|
||||
}
|
||||
|
||||
template<class Buffers>
|
||||
template<class MutableBufferSequence>
|
||||
auto
|
||||
buffers_adapter<Buffers>::prepare(std::size_t n) ->
|
||||
buffers_adapter<MutableBufferSequence>::prepare(std::size_t n) ->
|
||||
mutable_buffers_type
|
||||
{
|
||||
using boost::asio::buffer_size;
|
||||
static_assert(is_mutable,
|
||||
"Operation not valid for ConstBufferSequence");
|
||||
end_ = out_;
|
||||
if(end_ != bs_.end())
|
||||
{
|
||||
@@ -416,13 +418,11 @@ buffers_adapter<Buffers>::prepare(std::size_t n) ->
|
||||
return mutable_buffers_type{*this};
|
||||
}
|
||||
|
||||
template<class Buffers>
|
||||
template<class MutableBufferSequence>
|
||||
void
|
||||
buffers_adapter<Buffers>::commit(std::size_t n)
|
||||
buffers_adapter<MutableBufferSequence>::commit(std::size_t n)
|
||||
{
|
||||
using boost::asio::buffer_size;
|
||||
static_assert(is_mutable,
|
||||
"Operation not valid for ConstBufferSequence");
|
||||
if(out_ == end_)
|
||||
return;
|
||||
auto const last = std::prev(end_);
|
||||
@@ -456,18 +456,18 @@ buffers_adapter<Buffers>::commit(std::size_t n)
|
||||
}
|
||||
}
|
||||
|
||||
template<class Buffers>
|
||||
template<class MutableBufferSequence>
|
||||
inline
|
||||
auto
|
||||
buffers_adapter<Buffers>::data() const ->
|
||||
buffers_adapter<MutableBufferSequence>::data() const ->
|
||||
const_buffers_type
|
||||
{
|
||||
return const_buffers_type{*this};
|
||||
}
|
||||
|
||||
template<class Buffers>
|
||||
template<class MutableBufferSequence>
|
||||
void
|
||||
buffers_adapter<Buffers>::consume(std::size_t n)
|
||||
buffers_adapter<MutableBufferSequence>::consume(std::size_t n)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_IMPL_CONSUMING_BUFFERS_IPP
|
||||
#define BEAST_IMPL_CONSUMING_BUFFERS_IPP
|
||||
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
@@ -18,13 +18,13 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
template<class Buffers, class ValueType>
|
||||
class consuming_buffers<Buffers, ValueType>::const_iterator
|
||||
template<class BufferSequence, class ValueType>
|
||||
class consuming_buffers<BufferSequence, ValueType>::const_iterator
|
||||
{
|
||||
friend class consuming_buffers<Buffers, ValueType>;
|
||||
friend class consuming_buffers<BufferSequence, ValueType>;
|
||||
|
||||
using iter_type =
|
||||
typename Buffers::const_iterator;
|
||||
typename BufferSequence::const_iterator;
|
||||
|
||||
iter_type it_;
|
||||
consuming_buffers const* b_ = nullptr;
|
||||
@@ -105,8 +105,8 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template<class Buffers, class ValueType>
|
||||
consuming_buffers<Buffers, ValueType>::
|
||||
template<class BufferSequence, class ValueType>
|
||||
consuming_buffers<BufferSequence, ValueType>::
|
||||
consuming_buffers(consuming_buffers&& other)
|
||||
: consuming_buffers(std::move(other),
|
||||
std::distance<iter_type>(
|
||||
@@ -114,8 +114,8 @@ consuming_buffers(consuming_buffers&& other)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Buffers, class ValueType>
|
||||
consuming_buffers<Buffers, ValueType>::
|
||||
template<class BufferSequence, class ValueType>
|
||||
consuming_buffers<BufferSequence, ValueType>::
|
||||
consuming_buffers(consuming_buffers const& other)
|
||||
: consuming_buffers(other,
|
||||
std::distance<iter_type>(
|
||||
@@ -123,9 +123,9 @@ consuming_buffers(consuming_buffers const& other)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Buffers, class ValueType>
|
||||
template<class BufferSequence, class ValueType>
|
||||
auto
|
||||
consuming_buffers<Buffers, ValueType>::
|
||||
consuming_buffers<BufferSequence, ValueType>::
|
||||
operator=(consuming_buffers&& other) ->
|
||||
consuming_buffers&
|
||||
{
|
||||
@@ -137,9 +137,9 @@ operator=(consuming_buffers&& other) ->
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Buffers, class ValueType>
|
||||
template<class BufferSequence, class ValueType>
|
||||
auto
|
||||
consuming_buffers<Buffers, ValueType>::
|
||||
consuming_buffers<BufferSequence, ValueType>::
|
||||
operator=(consuming_buffers const& other) ->
|
||||
consuming_buffers&
|
||||
{
|
||||
@@ -151,35 +151,35 @@ operator=(consuming_buffers const& other) ->
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Buffers, class ValueType>
|
||||
consuming_buffers<Buffers, ValueType>::
|
||||
consuming_buffers(Buffers const& bs)
|
||||
template<class BufferSequence, class ValueType>
|
||||
consuming_buffers<BufferSequence, ValueType>::
|
||||
consuming_buffers(BufferSequence const& bs)
|
||||
: bs_(bs)
|
||||
, begin_(bs_.begin())
|
||||
{
|
||||
static_assert(is_BufferSequence<Buffers, ValueType>::value,
|
||||
static_assert(is_BufferSequence<BufferSequence, ValueType>::value,
|
||||
"BufferSequence requirements not met");
|
||||
}
|
||||
|
||||
template<class Buffers, class ValueType>
|
||||
template<class BufferSequence, class ValueType>
|
||||
auto
|
||||
consuming_buffers<Buffers, ValueType>::begin() const ->
|
||||
consuming_buffers<BufferSequence, ValueType>::begin() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator{*this, begin_};
|
||||
}
|
||||
|
||||
template<class Buffers, class ValueType>
|
||||
template<class BufferSequence, class ValueType>
|
||||
auto
|
||||
consuming_buffers<Buffers, ValueType>::end() const ->
|
||||
consuming_buffers<BufferSequence, ValueType>::end() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator{*this, bs_.end()};
|
||||
}
|
||||
|
||||
template<class Buffers, class ValueType>
|
||||
template<class BufferSequence, class ValueType>
|
||||
void
|
||||
consuming_buffers<Buffers, ValueType>::consume(std::size_t n)
|
||||
consuming_buffers<BufferSequence, ValueType>::consume(std::size_t n)
|
||||
{
|
||||
using boost::asio::buffer_size;
|
||||
for(;n > 0 && begin_ != bs_.end(); ++begin_)
|
||||
@@ -196,11 +196,11 @@ consuming_buffers<Buffers, ValueType>::consume(std::size_t n)
|
||||
}
|
||||
}
|
||||
|
||||
template<class Buffers>
|
||||
consuming_buffers<Buffers, typename Buffers::value_type>
|
||||
consumed_buffers(Buffers const& bs, std::size_t n)
|
||||
template<class BufferSequence>
|
||||
consuming_buffers<BufferSequence, typename BufferSequence::value_type>
|
||||
consumed_buffers(BufferSequence const& bs, std::size_t n)
|
||||
{
|
||||
consuming_buffers<Buffers> cb(bs);
|
||||
consuming_buffers<BufferSequence> cb(bs);
|
||||
cb.consume(n);
|
||||
return cb;
|
||||
}
|
||||
|
@@ -9,7 +9,10 @@
|
||||
#define BEAST_IMPL_STREAMBUF_READSTREAM_IPP
|
||||
|
||||
#include <beast/bind_handler.hpp>
|
||||
#include <beast/handler_concepts.hpp>
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -157,8 +160,6 @@ streambuf_readstream<Stream, Streambuf>::
|
||||
streambuf_readstream(Args&&... args)
|
||||
: next_layer_(std::forward<Args>(args)...)
|
||||
{
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
}
|
||||
|
||||
template<class Stream, class Streambuf>
|
||||
@@ -175,7 +176,7 @@ async_write_some(ConstBufferSequence const& buffers,
|
||||
static_assert(is_ConstBufferSequence<
|
||||
ConstBufferSequence>::value,
|
||||
"ConstBufferSequence requirements not met");
|
||||
static_assert(is_Handler<WriteHandler,
|
||||
static_assert(is_CompletionHandler<WriteHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"WriteHandler requirements not met");
|
||||
return next_layer_.async_write_some(buffers,
|
||||
|
@@ -15,15 +15,15 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A `Streambuf` with a fixed size internal buffer.
|
||||
/** A @b `Streambuf` with a fixed size internal buffer.
|
||||
|
||||
Ownership of the underlying storage belongs to the derived class.
|
||||
|
||||
@note Variables are usually declared using the template class
|
||||
`static_streambuf_n`; however, to reduce the number of instantiations
|
||||
@ref static_streambuf_n; however, to reduce the number of instantiations
|
||||
of template functions receiving static stream buffer arguments in a
|
||||
deduced context, the signature of the receiving function should use
|
||||
`static_streambuf`.
|
||||
@ref static_streambuf.
|
||||
*/
|
||||
class static_streambuf
|
||||
{
|
||||
@@ -75,18 +75,28 @@ public:
|
||||
|
||||
@throws std::length_error if the size would exceed the limit
|
||||
imposed by the underlying mutable buffer sequence.
|
||||
|
||||
@note Buffers representing the input sequence acquired prior to
|
||||
this call remain valid.
|
||||
*/
|
||||
mutable_buffers_type
|
||||
prepare(std::size_t n);
|
||||
|
||||
/// Move bytes from the output sequence to the input sequence.
|
||||
/** Move bytes from the output sequence to the input sequence.
|
||||
|
||||
@note Buffers representing the input sequence acquired prior to
|
||||
this call remain valid.
|
||||
*/
|
||||
void
|
||||
commit(std::size_t n)
|
||||
{
|
||||
out_ += std::min<std::size_t>(n, last_ - out_);
|
||||
}
|
||||
|
||||
/// Get a list of buffers that represents the input sequence.
|
||||
/** 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;
|
||||
|
||||
@@ -129,9 +139,11 @@ protected:
|
||||
*/
|
||||
template<std::size_t N>
|
||||
class static_streambuf_n
|
||||
: private boost::base_from_member<
|
||||
: public static_streambuf
|
||||
#if ! GENERATING_DOCS
|
||||
, private boost::base_from_member<
|
||||
std::array<std::uint8_t, N>>
|
||||
, public static_streambuf
|
||||
#endif
|
||||
{
|
||||
using member_type = boost::base_from_member<
|
||||
std::array<std::uint8_t, N>>;
|
||||
|
@@ -20,7 +20,6 @@
|
||||
#ifndef BEAST_WEBSOCKET_STATIC_STRING_HPP
|
||||
#define BEAST_WEBSOCKET_STATIC_STRING_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
@@ -28,13 +27,11 @@
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace websocket {
|
||||
|
||||
/** A string with a fixed-size storage area.
|
||||
|
||||
`static_string` objects behave like `std::string` except that
|
||||
the storage is not dynamically allocated but rather fixed in
|
||||
size.
|
||||
These objects behave like `std::string` except that the storage
|
||||
is not dynamically allocated but rather fixed in size.
|
||||
|
||||
These strings offer performance advantages when a protocol
|
||||
imposes a natural small upper limit on the size of a value.
|
||||
@@ -281,7 +278,7 @@ public:
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
|
||||
/// Reduces memory usage by freeing unused memory.
|
||||
void
|
||||
shrink_to_fit()
|
||||
@@ -401,7 +398,7 @@ operator=(const CharT (&s)[M]) ->
|
||||
static_assert(M-1 <= N,
|
||||
"static_string overflow");
|
||||
n_ = M-1;
|
||||
std::copy(&s[0], &s[M], &s_[0]);
|
||||
Traits::copy(&s_[0], &s[0], M);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -690,7 +687,6 @@ bool operator>=(
|
||||
|
||||
#endif
|
||||
|
||||
} // websocket
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
76
include/beast/stream_concepts.hpp
Normal file
76
include/beast/stream_concepts.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// 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_STREAM_CONCEPTS_HPP
|
||||
#define BEAST_STREAM_CONCEPTS_HPP
|
||||
|
||||
#include <beast/detail/stream_concepts.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/// Determine if `T` has the `get_io_service` member.
|
||||
template<class T>
|
||||
#if GENERATING_DOCS
|
||||
struct has_get_io_service : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
using has_get_io_service = typename detail::has_get_io_service<T>::type;
|
||||
#endif
|
||||
|
||||
/// Determine if `T` meets the requirements of @b `AsyncReadStream`.
|
||||
template<class T>
|
||||
#if GENERATING_DOCS
|
||||
struct is_AsyncReadStream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
using is_AsyncReadStream = typename detail::is_AsyncReadStream<T>::type;
|
||||
#endif
|
||||
|
||||
/// Determine if `T` meets the requirements of @b `AsyncWriteStream`.
|
||||
template<class T>
|
||||
#if GENERATING_DOCS
|
||||
struct is_AsyncWriteStream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
using is_AsyncWriteStream = typename detail::is_AsyncWriteStream<T>::type;
|
||||
#endif
|
||||
|
||||
/// Determine if `T` meets the requirements of @b `SyncReadStream`.
|
||||
template<class T>
|
||||
#if GENERATING_DOCS
|
||||
struct is_SyncReadStream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
using is_SyncReadStream = typename detail::is_SyncReadStream<T>::type;
|
||||
#endif
|
||||
|
||||
/// Determine if `T` meets the requirements of @b `SyncWriterStream`.
|
||||
template<class T>
|
||||
#if GENERATING_DOCS
|
||||
struct is_SyncWriteStream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
using is_SyncWriteStream = typename detail::is_SyncWriteStream<T>::type;
|
||||
#endif
|
||||
|
||||
/// Determine if `T` meets the requirements of @b `AsyncStream`.
|
||||
template<class T>
|
||||
#if GENERATING_DOCS
|
||||
struct is_AsyncStream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
using is_AsyncStream = std::integral_constant<bool,
|
||||
is_AsyncReadStream<T>::value && is_AsyncWriteStream<T>::value>;
|
||||
#endif
|
||||
|
||||
/// Determine if `T` meets the requirements of @b `SyncStream`.
|
||||
template<class T>
|
||||
#if GENERATING_DOCS
|
||||
struct is_SyncStream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
using is_SyncStream = std::integral_constant<bool,
|
||||
is_SyncReadStream<T>::value && is_SyncWriteStream<T>::value>;
|
||||
#endif
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
@@ -12,6 +12,15 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A @b `Streambuf` 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`.
|
||||
*/
|
||||
using streambuf = basic_streambuf<std::allocator<char>>;
|
||||
|
||||
} // beast
|
||||
|
@@ -9,8 +9,9 @@
|
||||
#define BEAST_STREAMBUF_READSTREAM_HPP
|
||||
|
||||
#include <beast/async_completion.hpp>
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/stream_concepts.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/detail/get_lowest_layer.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
@@ -20,11 +21,11 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A `Stream` with attached `Streambuf` to buffer reads.
|
||||
/** A @b `Stream` with attached @b `Streambuf` to buffer reads.
|
||||
|
||||
This wraps a `Stream` implementation so that calls to write are
|
||||
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 `Streambuf` which
|
||||
first consume the input sequence stored in a @b `Streambuf` which
|
||||
is part of the object.
|
||||
|
||||
The use-case for this class is different than that of the
|
||||
@@ -37,10 +38,10 @@ namespace beast {
|
||||
|
||||
Uses:
|
||||
|
||||
* Transparently leave untouched input acquired in calls
|
||||
@li Transparently leave untouched input acquired in calls
|
||||
to `boost::asio::read_until` behind for subsequent callers.
|
||||
|
||||
* "Preload" a stream with handshake input data acquired
|
||||
@li "Preload" a stream with handshake input data acquired
|
||||
from other sources.
|
||||
|
||||
Example:
|
||||
@@ -88,6 +89,9 @@ namespace beast {
|
||||
template<class Stream, class Streambuf>
|
||||
class streambuf_readstream
|
||||
{
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
|
||||
using error_code = boost::system::error_code;
|
||||
|
||||
template<class Buffers, class Handler>
|
||||
@@ -107,8 +111,12 @@ public:
|
||||
|
||||
/// The type of the lowest layer.
|
||||
using lowest_layer_type =
|
||||
#if GENERATING_DOCS
|
||||
implementation_defined;
|
||||
#else
|
||||
typename detail::get_lowest_layer<
|
||||
next_layer_type>::type;
|
||||
#endif
|
||||
|
||||
/** Move constructor.
|
||||
|
||||
@@ -233,8 +241,11 @@ public:
|
||||
/// Start an asynchronous write. The data being written must be valid for the
|
||||
/// lifetime of the asynchronous operation.
|
||||
template<class ConstBufferSequence, class WriteHandler>
|
||||
typename async_completion<
|
||||
WriteHandler, void(error_code)>::result_type
|
||||
#if GENERATING_DOCS
|
||||
void_or_deduced
|
||||
#else
|
||||
typename async_completion<WriteHandler, void(error_code)>::result_type
|
||||
#endif
|
||||
async_write_some(ConstBufferSequence const& buffers,
|
||||
WriteHandler&& handler);
|
||||
|
||||
@@ -254,8 +265,11 @@ public:
|
||||
/// Start an asynchronous read. The buffer into which the data will be read
|
||||
/// must be valid for the lifetime of the asynchronous operation.
|
||||
template<class MutableBufferSequence, class ReadHandler>
|
||||
typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
#if GENERATING_DOCS
|
||||
void_or_deduced
|
||||
#else
|
||||
typename async_completion<ReadHandler, void(error_code)>::result_type
|
||||
#endif
|
||||
async_read_some(MutableBufferSequence const& buffers,
|
||||
ReadHandler&& handler);
|
||||
};
|
||||
|
@@ -8,24 +8,24 @@
|
||||
#ifndef BEAST_TO_STRING_HPP
|
||||
#define BEAST_TO_STRING_HPP
|
||||
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Convert a `ConstBufferSequence` to a `std::string`.
|
||||
/** Convert a @b `ConstBufferSequence` to a `std::string`.
|
||||
|
||||
This function will convert the octets in a buffer sequence to a string.
|
||||
All octets will be inserted into the resulting string, including null
|
||||
or unprintable characters.
|
||||
|
||||
@param buffers The buffer sequence to convert.
|
||||
|
||||
@returns A string representing the contents of the input area.
|
||||
|
||||
@return A string representing the contents of the input area.
|
||||
|
||||
@note This function participates in overload resolution only if
|
||||
the streambuf parameter meets the requirements of Streambuf.
|
||||
the streambuf parameter meets the requirements of @b `Streambuf`.
|
||||
*/
|
||||
template<class ConstBufferSequence
|
||||
#if ! GENERATING_DOCS
|
||||
|
@@ -1,356 +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)
|
||||
//
|
||||
|
||||
#ifndef BEAST_TYPE_CHECK_HPP
|
||||
#define BEAST_TYPE_CHECK_HPP
|
||||
|
||||
#include <beast/detail/is_call_possible.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Types that meet the requirements,
|
||||
// for use with std::declval only.
|
||||
//
|
||||
|
||||
#if GENERATING_DOCS
|
||||
namespace detail {
|
||||
#else
|
||||
namespace concept {
|
||||
#endif
|
||||
|
||||
template<class BufferType>
|
||||
struct BufferSequence
|
||||
{
|
||||
using value_type = BufferType;
|
||||
using const_iterator = BufferType const*;
|
||||
~BufferSequence();
|
||||
BufferSequence(BufferSequence const&) = default;
|
||||
const_iterator
|
||||
begin() const noexcept;
|
||||
const_iterator
|
||||
end() const noexcept;
|
||||
};
|
||||
|
||||
using ConstBufferSequence =
|
||||
BufferSequence<boost::asio::const_buffer>;
|
||||
|
||||
using MutableBufferSequence =
|
||||
BufferSequence<boost::asio::mutable_buffer>;
|
||||
|
||||
struct StreamHandler
|
||||
{
|
||||
StreamHandler(StreamHandler const&) = default;
|
||||
void
|
||||
operator()(boost::system::error_code ec,
|
||||
std::size_t);
|
||||
};
|
||||
|
||||
using ReadHandler = StreamHandler;
|
||||
using WriteHandler = StreamHandler;
|
||||
|
||||
} // concept
|
||||
|
||||
// http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/ConstBufferSequence.html
|
||||
// http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/MutableBufferSequence.html
|
||||
//
|
||||
/// Determine if `T` meets the requirements of `BufferSequence`.
|
||||
template<class T, class BufferType>
|
||||
class is_BufferSequence
|
||||
{
|
||||
template<class U, class R = std::is_convertible<
|
||||
typename U::value_type, BufferType> >
|
||||
static R check1(int);
|
||||
template<class>
|
||||
static std::false_type check1(...);
|
||||
using type1 = decltype(check1<T>(0));
|
||||
|
||||
template<class U, class R = std::is_base_of<
|
||||
#if 0
|
||||
std::bidirectional_iterator_tag,
|
||||
typename std::iterator_traits<
|
||||
typename U::const_iterator>::iterator_category>>
|
||||
#else
|
||||
// workaround:
|
||||
// boost::asio::detail::consuming_buffers::const_iterator
|
||||
// is not bidirectional
|
||||
std::forward_iterator_tag,
|
||||
typename std::iterator_traits<
|
||||
typename U::const_iterator>::iterator_category>>
|
||||
#endif
|
||||
static R check2(int);
|
||||
template<class>
|
||||
static std::false_type check2(...);
|
||||
using type2 = decltype(check2<T>(0));
|
||||
|
||||
template<class U, class R = typename
|
||||
std::is_convertible<decltype(
|
||||
std::declval<U>().begin()),
|
||||
typename U::const_iterator>::type>
|
||||
static R check3(int);
|
||||
template<class>
|
||||
static std::false_type check3(...);
|
||||
using type3 = decltype(check3<T>(0));
|
||||
|
||||
template<class U, class R = typename std::is_convertible<decltype(
|
||||
std::declval<U>().end()),
|
||||
typename U::const_iterator>::type>
|
||||
static R check4(int);
|
||||
template<class>
|
||||
static std::false_type check4(...);
|
||||
using type4 = decltype(check4<T>(0));
|
||||
|
||||
public:
|
||||
/// `true` if `T` meets the requirements.
|
||||
static bool const value =
|
||||
std::is_copy_constructible<T>::value &&
|
||||
std::is_destructible<T>::value &&
|
||||
type1::value && type2::value &&
|
||||
type3::value && type4::value;
|
||||
};
|
||||
|
||||
#if ! GENERATING_DOCS
|
||||
|
||||
/// Determine if `T` meets the requirements of `ConstBufferSequence`.
|
||||
template<class T>
|
||||
using is_ConstBufferSequence =
|
||||
is_BufferSequence<T, boost::asio::const_buffer>;
|
||||
static_assert(is_ConstBufferSequence<concept::ConstBufferSequence>::value, "");
|
||||
static_assert(! is_ConstBufferSequence<int>::value, "");
|
||||
|
||||
/// Determine if `T` meets the requirements of `MutableBufferSequence`.
|
||||
template<class C>
|
||||
using is_MutableBufferSequence =
|
||||
is_BufferSequence<C, boost::asio::mutable_buffer>;
|
||||
static_assert(is_MutableBufferSequence<concept::MutableBufferSequence>::value, "");
|
||||
static_assert(! is_MutableBufferSequence<int>::value, "");
|
||||
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/// Determine if `T` has the `get_io_service` member.
|
||||
template<class T>
|
||||
class has_get_io_service
|
||||
{
|
||||
template<class U, class R = typename std::is_same<
|
||||
decltype(std::declval<U>().get_io_service()),
|
||||
boost::asio::io_service&>>
|
||||
static R check(int);
|
||||
template <class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<T>(0));
|
||||
|
||||
public:
|
||||
/// `true` if `T` meets the requirements.
|
||||
static bool const value = type::value;
|
||||
};
|
||||
static_assert(! has_get_io_service<int>::value, "");
|
||||
|
||||
// http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncReadStream.html
|
||||
//
|
||||
/// Determine if `T` meets the requirements of `AsyncReadStream`.
|
||||
template<class T>
|
||||
class is_AsyncReadStream
|
||||
{
|
||||
template<class U, class R = decltype(
|
||||
std::declval<U>().async_read_some(
|
||||
std::declval<concept::MutableBufferSequence>(),
|
||||
std::declval<concept::ReadHandler>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<T>(0));
|
||||
|
||||
public:
|
||||
/// `true` if `T` meets the requirements.
|
||||
static bool const value =
|
||||
has_get_io_service<T>::value && type::value;
|
||||
};
|
||||
static_assert(! is_AsyncReadStream<int>::value, "");
|
||||
|
||||
// http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncWriteStream.html
|
||||
//
|
||||
/// Determine if `T` meets the requirements of `AsyncWriteStream`.
|
||||
template<class T>
|
||||
class is_AsyncWriteStream
|
||||
{
|
||||
template<class U, class R = decltype(
|
||||
std::declval<U>().async_write_some(
|
||||
std::declval<concept::ConstBufferSequence>(),
|
||||
std::declval<concept::WriteHandler>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<T>(0));
|
||||
|
||||
public:
|
||||
/// `true` if `T` meets the requirements.
|
||||
static bool const value =
|
||||
has_get_io_service<T>::value && type::value;
|
||||
};
|
||||
static_assert(! is_AsyncWriteStream<int>::value, "");
|
||||
|
||||
// http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncReadStream.html
|
||||
//
|
||||
/// Determine if `T` meets the requirements of `SyncReadStream`.
|
||||
template<class T>
|
||||
class is_SyncReadStream
|
||||
{
|
||||
using error_code =
|
||||
boost::system::error_code;
|
||||
|
||||
template<class U, class R = std::is_same<decltype(
|
||||
std::declval<U>().read_some(
|
||||
std::declval<concept::MutableBufferSequence>())),
|
||||
std::size_t>>
|
||||
static R check1(int);
|
||||
template<class>
|
||||
static std::false_type check1(...);
|
||||
using type1 = decltype(check1<T>(0));
|
||||
|
||||
template<class U, class R = std::is_same<decltype(
|
||||
std::declval<U>().read_some(
|
||||
std::declval<concept::MutableBufferSequence>(),
|
||||
std::declval<error_code&>())), std::size_t>>
|
||||
static R check2(int);
|
||||
template<class>
|
||||
static std::false_type check2(...);
|
||||
using type2 = decltype(check2<T>(0));
|
||||
|
||||
public:
|
||||
/// `true` if `T` meets the requirements.
|
||||
static bool const value =
|
||||
type1::value && type2::value;
|
||||
};
|
||||
static_assert(! is_SyncReadStream<int>::value, "");
|
||||
|
||||
// http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncWriteStream.html
|
||||
//
|
||||
/// Determine if `T` meets the requirements of `SyncWriterStream`.
|
||||
template<class T>
|
||||
class is_SyncWriteStream
|
||||
{
|
||||
using error_code =
|
||||
boost::system::error_code;
|
||||
|
||||
template<class U, class R = std::is_same<decltype(
|
||||
std::declval<U>().write_some(
|
||||
std::declval<concept::ConstBufferSequence>())),
|
||||
std::size_t>>
|
||||
static R check1(int);
|
||||
template<class>
|
||||
static std::false_type check1(...);
|
||||
using type1 = decltype(check1<T>(0));
|
||||
|
||||
template<class U, class R = std::is_same<decltype(
|
||||
std::declval<U>().write_some(
|
||||
std::declval<concept::ConstBufferSequence>(),
|
||||
std::declval<error_code&>())), std::size_t>>
|
||||
static R check2(int);
|
||||
template<class>
|
||||
static std::false_type check2(...);
|
||||
using type2 = decltype(check2<T>(0));
|
||||
|
||||
public:
|
||||
/// `true` if `T` meets the requirements.
|
||||
static bool const value =
|
||||
type1::value && type2::value;
|
||||
};
|
||||
static_assert(! is_SyncWriteStream<int>::value, "");
|
||||
|
||||
/// Determine if `T` meets the requirements of `SyncStream`.
|
||||
template<class T>
|
||||
struct is_SyncStream
|
||||
{
|
||||
/// `true` if `T` meets the requirements.
|
||||
static bool const value =
|
||||
is_SyncReadStream<T>::value &&
|
||||
is_SyncWriteStream<T>::value;
|
||||
};
|
||||
|
||||
/// Determine if `T` meets the requirements of `SyncStream`.
|
||||
template<class T>
|
||||
struct is_AsyncStream
|
||||
{
|
||||
/// `true` if `T` meets the requirements.
|
||||
static bool const value =
|
||||
is_AsyncReadStream<T>::value &&
|
||||
is_AsyncWriteStream<T>::value;
|
||||
};
|
||||
|
||||
/// Determine if `T` meets the requirements of `Streambuf`.
|
||||
template<class T>
|
||||
class is_Streambuf
|
||||
{
|
||||
template<class U, class R = std::integral_constant<
|
||||
bool, is_MutableBufferSequence<decltype(
|
||||
std::declval<U>().prepare(1))>::value>>
|
||||
static R check1(int);
|
||||
template<class>
|
||||
static std::false_type check1(...);
|
||||
using type1 = decltype(check1<T>(0));
|
||||
|
||||
template<class U, class R = std::integral_constant<
|
||||
bool, is_ConstBufferSequence<decltype(
|
||||
std::declval<U>().data())>::value>>
|
||||
static R check2(int);
|
||||
template<class>
|
||||
static std::false_type check2(...);
|
||||
using type2 = decltype(check2<T>(0));
|
||||
|
||||
template<class U, class R = decltype(
|
||||
std::declval<U>().commit(1), std::true_type{})>
|
||||
static R check3(int);
|
||||
template<class>
|
||||
static std::false_type check3(...);
|
||||
using type3 = decltype(check3<T>(0));
|
||||
|
||||
template<class U, class R = decltype(
|
||||
std::declval<U>().consume(1), std::true_type{})>
|
||||
static R check4(int);
|
||||
template<class>
|
||||
static std::false_type check4(...);
|
||||
using type4 = decltype(check4<T>(0));
|
||||
|
||||
template<class U, class R = std::is_same<decltype(
|
||||
std::declval<U>().size()), std::size_t>>
|
||||
static R check5(int);
|
||||
template<class>
|
||||
static std::false_type check5(...);
|
||||
using type5 = decltype(check5<T>(0));
|
||||
|
||||
public:
|
||||
/// `true` if `T` meets the requirements.
|
||||
static bool const value =
|
||||
type1::value && type2::value &&
|
||||
type3::value && type4::value &&
|
||||
type5::value;
|
||||
};
|
||||
|
||||
#if ! GENERATING_DOCS
|
||||
|
||||
/// Determine if `T` meets the requirements of `CompletionHandler`.
|
||||
template<class T, class Signature>
|
||||
using is_Handler = std::integral_constant<bool,
|
||||
std::is_copy_constructible<typename std::decay<T>::type>::value &&
|
||||
detail::is_call_possible<T, Signature>::value>;
|
||||
|
||||
#endif
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
@@ -17,10 +17,9 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_WSPROTO_DEBUG_H_INCLUDED
|
||||
#define BEAST_WSPROTO_DEBUG_H_INCLUDED
|
||||
#ifndef BEAST_WEBSOCKET_DETAIL_DEBUG_HPP
|
||||
#define BEAST_WEBSOCKET_DETAIL_DEBUG_HPP
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
@@ -82,7 +81,7 @@ format(std::string s)
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // wsproto
|
||||
} // websocket
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
@@ -30,7 +30,7 @@ public:
|
||||
const char*
|
||||
name() const noexcept override
|
||||
{
|
||||
return "wsproto";
|
||||
return "websocket";
|
||||
}
|
||||
|
||||
std::string
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
case error::request_invalid: return "upgrade request invalid";
|
||||
case error::request_denied: return "upgrade request denied";
|
||||
default:
|
||||
return "wsproto.error";
|
||||
return "websocket error";
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#define BEAST_WEBSOCKET_ERROR_HPP
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace websocket {
|
||||
@@ -16,7 +17,7 @@ namespace websocket {
|
||||
/// The type of error used by functions and completion handlers.
|
||||
using error_code = boost::system::error_code;
|
||||
|
||||
/// Error values
|
||||
/// Error codes returned from @ref stream operations.
|
||||
enum class error
|
||||
{
|
||||
/// Both sides performed a WebSocket close
|
||||
@@ -50,8 +51,10 @@ enum class error
|
||||
request_denied
|
||||
};
|
||||
|
||||
#if ! GENERATING_DOCS
|
||||
error_code
|
||||
make_error_code(error e);
|
||||
#endif
|
||||
|
||||
} // websocket
|
||||
} // beast
|
||||
|
@@ -396,7 +396,7 @@ operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
||||
// teardown
|
||||
case 11:
|
||||
d.state = 12;
|
||||
wsproto_helpers::call_async_teardown(
|
||||
websocket_helpers::call_async_teardown(
|
||||
d.ws.next_layer(), std::move(*this));
|
||||
return;
|
||||
|
||||
@@ -482,7 +482,7 @@ operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
||||
// teardown
|
||||
case 19:
|
||||
d.state = 20;
|
||||
wsproto_helpers::call_async_teardown(
|
||||
websocket_helpers::call_async_teardown(
|
||||
d.ws.next_layer(), std::move(*this));
|
||||
return;
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
#define BEAST_WEBSOCKET_IMPL_SSL_IPP_INCLUDED
|
||||
|
||||
#include <beast/async_completion.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/handler_concepts.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace websocket {
|
||||
@@ -144,7 +144,7 @@ async_teardown(
|
||||
boost::asio::ssl::stream<AsyncStream>& stream,
|
||||
TeardownHandler&& handler)
|
||||
{
|
||||
static_assert(beast::is_Handler<
|
||||
static_assert(beast::is_CompletionHandler<
|
||||
TeardownHandler, void(error_code)>::value,
|
||||
"TeardownHandler requirements not met");
|
||||
detail::teardown_ssl_op<AsyncStream, typename std::decay<
|
||||
|
@@ -18,16 +18,17 @@
|
||||
#include <beast/websocket/impl/response_op.ipp>
|
||||
#include <beast/websocket/impl/write_op.ipp>
|
||||
#include <beast/websocket/impl/write_frame_op.ipp>
|
||||
#include <beast/buffer_cat.hpp>
|
||||
#include <beast/consuming_buffers.hpp>
|
||||
#include <beast/prepare_buffers.hpp>
|
||||
#include <beast/static_streambuf.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/http/read.hpp>
|
||||
#include <beast/http/write.hpp>
|
||||
#include <beast/http/reason.hpp>
|
||||
#include <beast/http/rfc2616.hpp>
|
||||
#include <beast/buffer_cat.hpp>
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/consuming_buffers.hpp>
|
||||
#include <beast/prepare_buffers.hpp>
|
||||
#include <beast/static_streambuf.hpp>
|
||||
#include <beast/stream_concepts.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
@@ -613,7 +614,7 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
||||
if(error_)
|
||||
return;
|
||||
}
|
||||
wsproto_helpers::call_teardown(next_layer(), ec);
|
||||
websocket_helpers::call_teardown(next_layer(), ec);
|
||||
error_ = ec != 0;
|
||||
if(error_)
|
||||
return;
|
||||
@@ -622,7 +623,7 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
||||
return;
|
||||
}
|
||||
if(! ec)
|
||||
wsproto_helpers::call_teardown(next_layer(), ec);
|
||||
websocket_helpers::call_teardown(next_layer(), ec);
|
||||
if(! ec)
|
||||
ec = error::closed;
|
||||
error_ = ec != 0;
|
||||
|
@@ -9,7 +9,7 @@
|
||||
#define BEAST_WEBSOCKET_IMPL_TEARDOWN_IPP
|
||||
|
||||
#include <beast/async_completion.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/handler_concepts.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace beast {
|
||||
@@ -157,7 +157,7 @@ async_teardown(
|
||||
boost::asio::ip::tcp::socket& socket,
|
||||
TeardownHandler&& handler)
|
||||
{
|
||||
static_assert(beast::is_Handler<
|
||||
static_assert(beast::is_CompletionHandler<
|
||||
TeardownHandler, void(error_code)>::value,
|
||||
"TeardownHandler requirements not met");
|
||||
detail::teardown_tcp_op<typename std::decay<
|
||||
|
@@ -19,17 +19,17 @@ namespace websocket {
|
||||
|
||||
/** Automatic fragmentation size option.
|
||||
|
||||
Sets the maximum size of fragments generated when sending
|
||||
messages on a WebSocket socket.
|
||||
Sets the maximum size of fragments generated when sending messages
|
||||
on a WebSocket stream.
|
||||
|
||||
When the automatic fragmentation size is non-zero, messages
|
||||
exceeding the size will be split into multiple frames no
|
||||
larger than the size. This setting does not affect frames
|
||||
send explicitly using `write_frame` or `async_write_frame`.
|
||||
When the automatic fragmentation size is non-zero, messages exceeding
|
||||
the size will be split into multiple frames no larger than the size.
|
||||
This setting does not affect frames sent explicitly using
|
||||
@ref stream::write_frame or @ref stream::async_write_frame.
|
||||
|
||||
The default setting is to fragment messages into 16KB frames.
|
||||
|
||||
@note Objects of this type are passed to socket::set_option.
|
||||
@note Objects of this type are passed to @ref stream::set_option.
|
||||
|
||||
@par Example
|
||||
Setting the automatic fragmentation size option:
|
||||
@@ -61,18 +61,20 @@ struct auto_fragment_size
|
||||
Server or User-Agent fields. The default setting applies no
|
||||
transformation to the HTTP message.
|
||||
|
||||
For synchronous operations, the implementation will call the
|
||||
decorator before the function call to perform the operation
|
||||
returns.
|
||||
The context in which the decorator is called depends on the
|
||||
type of operation performed:
|
||||
|
||||
For asynchronous operations, the implementation guarantees that
|
||||
calls to the decorator will be made from the same implicit or
|
||||
explicit strand used to call the asynchronous initiation
|
||||
@li For synchronous operations, the implementation will call the
|
||||
decorator before the operation unblocks.
|
||||
|
||||
@li For asynchronous operations, the implementation guarantees
|
||||
that calls to the decorator will be made from the same implicit
|
||||
or explicit strand used to call the asynchronous initiation
|
||||
function.
|
||||
|
||||
The default setting is no decorator.
|
||||
|
||||
@note Objects of this type are passed to socket::set_option.
|
||||
@note Objects of this type are passed to @ref stream::set_option.
|
||||
|
||||
@par Example
|
||||
Setting the decorator.
|
||||
@@ -121,7 +123,7 @@ decorate(Decorator&& d)
|
||||
The default setting is to close connections after a failed
|
||||
upgrade request.
|
||||
|
||||
@note Objects of this type are passed to socket::set_option.
|
||||
@note Objects of this type are passed to @ref stream::set_option.
|
||||
|
||||
@par Example
|
||||
Setting the keep alive option.
|
||||
@@ -155,7 +157,7 @@ struct keep_alive
|
||||
|
||||
The default setting is opcode::text.
|
||||
|
||||
@note Objects of this type are passed to socket::set_option.
|
||||
@note Objects of this type are passed to @ref stream::set_option.
|
||||
|
||||
@par Example
|
||||
Setting the message type to binary.
|
||||
@@ -191,7 +193,7 @@ struct message_type
|
||||
|
||||
The default is no buffering.
|
||||
|
||||
@note Objects of this type are passed to socket::set_option.
|
||||
@note Objects of this type are passed to @ref stream::set_option.
|
||||
|
||||
@par Example
|
||||
Setting the read buffer size.
|
||||
@@ -224,7 +226,7 @@ struct read_buffer_size
|
||||
|
||||
The default setting is 16 megabytes.
|
||||
|
||||
@note Objects of this type are passed to socket::set_option.
|
||||
@note Objects of this type are passed to @ref stream::set_option.
|
||||
|
||||
@par Example
|
||||
Setting the maximum read message size.
|
||||
@@ -262,7 +264,7 @@ struct read_message_max
|
||||
|
||||
The default setting is 4096. The minimum value is 1024.
|
||||
|
||||
@note Objects of this type are passed to socket::set_option.
|
||||
@note Objects of this type are passed to @ref stream::set_option.
|
||||
|
||||
@par Example
|
||||
Setting the write buffer size.
|
||||
|
@@ -41,19 +41,24 @@ enum class opcode : std::uint8_t
|
||||
|
||||
These codes accompany close frames.
|
||||
|
||||
@see RFC 6455 7.4.1 Defined Status Codes
|
||||
https://tools.ietf.org/html/rfc6455#section-7.4.1
|
||||
@see <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455 7.4.1 Defined Status Codes</a>
|
||||
|
||||
*/
|
||||
#if GENERATING_DOCS
|
||||
enum close_code
|
||||
#else
|
||||
namespace close_code {
|
||||
using value = std::uint16_t;
|
||||
enum
|
||||
#endif
|
||||
{
|
||||
// used internally to mean "no error"
|
||||
/// used internally to mean "no error"
|
||||
none = 0,
|
||||
|
||||
normal = 1000,
|
||||
going_away = 1001,
|
||||
protocol_error = 1002,
|
||||
|
||||
unknown_data = 1003,
|
||||
bad_payload = 1007,
|
||||
policy_error = 1008,
|
||||
@@ -71,17 +76,15 @@ enum
|
||||
|
||||
last = 5000 // satisfy warnings
|
||||
};
|
||||
#if ! GENERATING_DOCS
|
||||
} // close_code
|
||||
#endif
|
||||
|
||||
#if ! GENERATING_DOCS
|
||||
|
||||
using reason_string_type =
|
||||
static_string<123, char>;
|
||||
|
||||
/// Payload type for pings and pongs
|
||||
using ping_payload_type =
|
||||
static_string<125, char>;
|
||||
|
||||
#endif
|
||||
|
||||
/** Description of the close reason.
|
||||
|
@@ -25,14 +25,14 @@ namespace websocket {
|
||||
`boost::asio::ssl::stream`, callers are responsible for
|
||||
providing a suitable overload of this function.
|
||||
|
||||
@param socket The stream to tear down.
|
||||
@param stream The stream to tear down.
|
||||
|
||||
@param ec Set to the error if any occurred.
|
||||
*/
|
||||
template<class AsyncStream>
|
||||
template<class SyncStream>
|
||||
void
|
||||
teardown(
|
||||
boost::asio::ssl::stream<AsyncStream>& stream,
|
||||
boost::asio::ssl::stream<SyncStream>& stream,
|
||||
error_code& ec);
|
||||
|
||||
/** Start tearing down a `boost::asio::ssl::stream`.
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -30,8 +30,8 @@ namespace websocket {
|
||||
/** Tear down a connection.
|
||||
|
||||
This tears down a connection. The implementation will call
|
||||
the overload of this function based on the `Stream` parameter
|
||||
used to consruct the socket. When `Stream` is a user defined
|
||||
the overload of this function based on the `Socket` parameter
|
||||
used to consruct the socket. When `Socket` is a user defined
|
||||
type, and not a `boost::asio::ip::tcp::socket` or any
|
||||
`boost::asio::ssl::stream`, callers are responsible for
|
||||
providing a suitable overload of this function.
|
||||
@@ -48,7 +48,7 @@ teardown(Socket& socket, error_code& ec) = delete;
|
||||
|
||||
This begins tearing down a connection asynchronously.
|
||||
The implementation will call the overload of this function
|
||||
based on the `Stream` parameter used to consruct the socket.
|
||||
based on the `Socket` parameter used to consruct the socket.
|
||||
When `Stream` is a user defined type, and not a
|
||||
`boost::asio::ip::tcp::socket` or any `boost::asio::ssl::stream`,
|
||||
callers are responsible for providing a suitable overload
|
||||
@@ -68,9 +68,9 @@ teardown(Socket& socket, error_code& ec) = delete;
|
||||
manner equivalent to using boost::asio::io_service::post().
|
||||
|
||||
*/
|
||||
template<class AsyncSocket, class TeardownHandler>
|
||||
template<class Socket, class TeardownHandler>
|
||||
void
|
||||
async_teardown(AsyncSocket& socket, TeardownHandler&& handler) = delete;
|
||||
async_teardown(Socket& socket, TeardownHandler&& handler) = delete;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -126,11 +126,11 @@ async_teardown(
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace wsproto_helpers {
|
||||
namespace websocket_helpers {
|
||||
|
||||
// Calls to teardown and async_teardown must be made from
|
||||
// a namespace that does not contain any overloads of these
|
||||
// functions. The wsproto_helpers namespace is defined here
|
||||
// functions. The websocket_helpers namespace is defined here
|
||||
// for that purpose.
|
||||
|
||||
template<class Socket>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_WRITE_STREAMBUF_HPP
|
||||
#define BEAST_WRITE_STREAMBUF_HPP
|
||||
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/detail/write_streambuf.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@@ -21,15 +21,15 @@ namespace beast {
|
||||
argument into the stream buffer. It is capable of converting the
|
||||
following types of arguments:
|
||||
|
||||
@li `boost::asio::const_buffer`
|
||||
@li `boost::asio::const_buffer`
|
||||
|
||||
@li `boost::asio::mutable_buffer`
|
||||
|
||||
@li A type for which the call to `boost::asio::buffer()` is defined
|
||||
@li A type meeting the requirements of @b `ConvertibleToConstBuffer`
|
||||
|
||||
@li A type meeting the requirements of `ConstBufferSequence`
|
||||
@li A type meeting the requirements of @b `ConstBufferSequence`
|
||||
|
||||
@li A type meeting the requirements of `MutableBufferSequence`
|
||||
@li A type meeting the requirements of @b `MutableBufferSequence`
|
||||
|
||||
For all types not listed above, the function will invoke
|
||||
`boost::lexical_cast` on the argument in an attempt to convert to
|
||||
@@ -45,7 +45,7 @@ namespace beast {
|
||||
@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 Streambuf.
|
||||
the `streambuf` parameter meets the requirements of @b `Streambuf`.
|
||||
*/
|
||||
template<class Streambuf, class... Args>
|
||||
#if GENERATING_DOCS
|
||||
|
@@ -10,17 +10,23 @@ add_executable (core-tests
|
||||
basic_streambuf.cpp
|
||||
bind_handler.cpp
|
||||
buffer_cat.cpp
|
||||
buffer_concepts.cpp
|
||||
buffers_adapter.cpp
|
||||
consuming_buffers.cpp
|
||||
handler_alloc.cpp
|
||||
handler_concepts.cpp
|
||||
http.cpp
|
||||
placeholders.cpp
|
||||
prepare_buffers.cpp
|
||||
static_streambuf.cpp
|
||||
static_string.cpp
|
||||
stream_concepts.cpp
|
||||
streambuf.cpp
|
||||
streambuf_readstream.cpp
|
||||
to_string.cpp
|
||||
type_check.cpp
|
||||
version.cpp
|
||||
websocket.cpp
|
||||
write_streambuf.cpp
|
||||
detail/base64.cpp
|
||||
detail/empty_base_optimization.cpp
|
||||
)
|
||||
@@ -34,13 +40,14 @@ add_executable (http-tests
|
||||
main.cpp
|
||||
http/basic_headers.cpp
|
||||
http/basic_parser_v1.cpp
|
||||
http/body_type.cpp
|
||||
http/empty_body.cpp
|
||||
http/error.cpp
|
||||
http/headers.cpp
|
||||
http/message.cpp
|
||||
http/message_v1.cpp
|
||||
http/parse_error.cpp
|
||||
http/parser.cpp
|
||||
http/parser_v1.cpp
|
||||
http/read.cpp
|
||||
http/reason.cpp
|
||||
http/resume_context.cpp
|
||||
@@ -49,6 +56,7 @@ add_executable (http-tests
|
||||
http/status.cpp
|
||||
http/streambuf_body.cpp
|
||||
http/string_body.cpp
|
||||
http/type_check.cpp
|
||||
http/write.cpp
|
||||
)
|
||||
|
||||
|
12
test/Jamfile
12
test/Jamfile
@@ -13,17 +13,23 @@ unit-test core-tests :
|
||||
basic_streambuf.cpp
|
||||
bind_handler.cpp
|
||||
buffer_cat.cpp
|
||||
buffer_concepts.cpp
|
||||
buffers_adapter.cpp
|
||||
consuming_buffers.cpp
|
||||
handler_alloc.cpp
|
||||
handler_concepts.cpp
|
||||
http.cpp
|
||||
placeholders.cpp
|
||||
prepare_buffers.cpp
|
||||
static_streambuf.cpp
|
||||
static_string.cpp
|
||||
stream_concepts.cpp
|
||||
streambuf.cpp
|
||||
streambuf_readstream.cpp
|
||||
to_string.cpp
|
||||
type_check.cpp
|
||||
version.cpp
|
||||
websocket.cpp
|
||||
write_streambuf.cpp
|
||||
detail/base64.cpp
|
||||
detail/empty_base_optimization.cpp
|
||||
;
|
||||
@@ -32,13 +38,14 @@ unit-test http-tests :
|
||||
main.cpp
|
||||
http/basic_headers.cpp
|
||||
http/basic_parser_v1.cpp
|
||||
http/body_type.cpp
|
||||
http/empty_body.cpp
|
||||
http/error.cpp
|
||||
http/headers.cpp
|
||||
http/message.cpp
|
||||
http/message_v1.cpp
|
||||
http/parse_error.cpp
|
||||
http/parser.cpp
|
||||
http/parser_v1.cpp
|
||||
http/read.cpp
|
||||
http/reason.cpp
|
||||
http/resume_context.cpp
|
||||
@@ -47,6 +54,7 @@ unit-test http-tests :
|
||||
http/status.cpp
|
||||
http/streambuf_body.cpp
|
||||
http/string_body.cpp
|
||||
http/type_check.cpp
|
||||
http/write.cpp
|
||||
;
|
||||
|
||||
|
@@ -16,7 +16,6 @@
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace test {
|
||||
|
||||
struct test_allocator_info
|
||||
{
|
||||
@@ -327,16 +326,22 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void testStream()
|
||||
{
|
||||
streambuf sb;
|
||||
sb << "x";
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
testPrepare();
|
||||
testStreambuf();
|
||||
testSpecial();
|
||||
testAllocator();
|
||||
testStream();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(basic_streambuf,core,beast);
|
||||
|
||||
} // test
|
||||
} // beast
|
||||
|
@@ -12,7 +12,6 @@
|
||||
#include <functional>
|
||||
|
||||
namespace beast {
|
||||
namespace test {
|
||||
|
||||
class bind_handler_test : public detail::unit_test::suite
|
||||
{
|
||||
@@ -33,5 +32,4 @@ public:
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(bind_handler,core,beast);
|
||||
|
||||
} // test
|
||||
} // beast
|
||||
|
@@ -16,7 +16,6 @@
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
namespace test {
|
||||
|
||||
class buffer_cat_test : public detail::unit_test::suite
|
||||
{
|
||||
@@ -77,5 +76,4 @@ public:
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(buffer_cat,core,beast);
|
||||
|
||||
} // test
|
||||
} // beast
|
||||
|
25
test/buffer_concepts.cpp
Normal file
25
test/buffer_concepts.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// 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/buffer_concepts.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace {
|
||||
struct T
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
static_assert(is_ConstBufferSequence<detail::ConstBufferSequence>::value, "");
|
||||
static_assert(! is_ConstBufferSequence<T>::value, "");
|
||||
|
||||
static_assert(is_MutableBufferSequence<detail::MutableBufferSequence>::value, "");
|
||||
static_assert(! is_MutableBufferSequence<T>::value, "");
|
||||
|
||||
} // beast
|
@@ -14,7 +14,6 @@
|
||||
#include <iterator>
|
||||
|
||||
namespace beast {
|
||||
namespace test {
|
||||
|
||||
class buffers_adapter_test : public detail::unit_test::suite
|
||||
{
|
||||
@@ -158,5 +157,4 @@ public:
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(buffers_adapter,core,beast);
|
||||
|
||||
} // test
|
||||
} // beast
|
||||
|
@@ -13,7 +13,6 @@
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace test {
|
||||
|
||||
class consuming_buffers_test : public beast::detail::unit_test::suite
|
||||
{
|
||||
@@ -89,7 +88,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(consuming_buffers,asio,beast);
|
||||
BEAST_DEFINE_TESTSUITE(consuming_buffers,core,beast);
|
||||
|
||||
} // test
|
||||
} // beast
|
||||
|
@@ -47,7 +47,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(base64,detail,beast);
|
||||
BEAST_DEFINE_TESTSUITE(base64,core,beast);
|
||||
|
||||
} // test
|
||||
} // beast
|
||||
|
@@ -103,7 +103,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(empty_base_optimization,detail,beast);
|
||||
BEAST_DEFINE_TESTSUITE(empty_base_optimization,core,beast);
|
||||
|
||||
} // test
|
||||
} // beast
|
||||
|
@@ -6,4 +6,23 @@
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <beast/to_string.hpp>
|
||||
|
||||
#include <beast/detail/unit_test/suite.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class to_string_test : public beast::detail::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void run()
|
||||
{
|
||||
expect(to_string(boost::asio::const_buffers_1("x", 1)) == "x");
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(to_string,core,beast);
|
||||
|
||||
} // beast
|
||||
|
||||
|
23
test/handler_concepts.cpp
Normal file
23
test/handler_concepts.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// 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/handler_concepts.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace {
|
||||
struct T
|
||||
{
|
||||
void operator()(int);
|
||||
};
|
||||
}
|
||||
|
||||
static_assert(is_CompletionHandler<T, void(int)>::value, "");
|
||||
static_assert(! is_CompletionHandler<T, void(void)>::value, "");
|
||||
|
||||
} // beast
|
@@ -6,4 +6,4 @@
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/http.hpp>
|
9
test/http/body_type.cpp
Normal file
9
test/http/body_type.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/body_type.hpp>
|
9
test/http/body_writer.cpp
Normal file
9
test/http/body_writer.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/body_type.hpp>
|
@@ -13,7 +13,7 @@
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/message_v1.hpp>
|
||||
#include <beast/http/rfc2616.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <cstdint>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
class parser_test : public beast::detail::unit_test::suite
|
||||
class parser_v1_test : public beast::detail::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void run() override
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(parser,http,beast);
|
||||
BEAST_DEFINE_TESTSUITE(parser_v1,http,beast);
|
||||
|
||||
} // http
|
||||
} // beast
|
@@ -14,7 +14,6 @@
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace test {
|
||||
|
||||
class prepare_buffers_test : public beast::detail::unit_test::suite
|
||||
{
|
||||
@@ -95,7 +94,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(prepare_buffers,asio,beast);
|
||||
BEAST_DEFINE_TESTSUITE(prepare_buffers,core,beast);
|
||||
|
||||
} // test
|
||||
} // beast
|
||||
|
@@ -17,8 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_EXAMPLE_SIG_WAIT_H_INCLUDED
|
||||
#define BEAST_EXAMPLE_SIG_WAIT_H_INCLUDED
|
||||
#ifndef BEAST_TEST_SIG_WAIT_H_INCLUDED
|
||||
#define BEAST_TEST_SIG_WAIT_H_INCLUDED
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <condition_variable>
|
||||
|
@@ -13,7 +13,6 @@
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace test {
|
||||
|
||||
class static_streambuf_test : public beast::detail::unit_test::suite
|
||||
{
|
||||
@@ -146,7 +145,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(static_streambuf,asio,beast);
|
||||
BEAST_DEFINE_TESTSUITE(static_streambuf,core,beast);
|
||||
|
||||
} // test
|
||||
} // beastp
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#include <beast/detail/unit_test/suite.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace websocket {
|
||||
|
||||
class static_string_test : public beast::detail::unit_test::suite
|
||||
{
|
||||
@@ -185,7 +184,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(static_string,websocket,beast);
|
||||
BEAST_DEFINE_TESTSUITE(static_string,core,beast);
|
||||
|
||||
} // websocket
|
||||
} // beast
|
||||
|
30
test/stream_concepts.cpp
Normal file
30
test/stream_concepts.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// 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/stream_concepts.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
using stream_type = boost::asio::ip::tcp::socket;
|
||||
|
||||
static_assert(has_get_io_service<stream_type>::value, "");
|
||||
static_assert(is_AsyncReadStream<stream_type>::value, "");
|
||||
static_assert(is_AsyncWriteStream<stream_type>::value, "");
|
||||
static_assert(is_AsyncStream<stream_type>::value, "");
|
||||
static_assert(is_SyncReadStream<stream_type>::value, "");
|
||||
static_assert(is_SyncWriteStream<stream_type>::value, "");
|
||||
static_assert(is_SyncStream<stream_type>::value, "");
|
||||
|
||||
static_assert(! has_get_io_service<int>::value, "");
|
||||
static_assert(! is_AsyncReadStream<int>::value, "");
|
||||
static_assert(! is_AsyncWriteStream<int>::value, "");
|
||||
static_assert(! is_SyncReadStream<int>::value, "");
|
||||
static_assert(! is_SyncWriteStream<int>::value, "");
|
||||
|
||||
} // beast
|
@@ -7,3 +7,4 @@
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <beast/to_string.hpp>
|
||||
|
||||
|
9
test/version.cpp
Normal file
9
test/version.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/version.hpp>
|
9
test/websocket.cpp
Normal file
9
test/websocket.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/websocket.hpp>
|
@@ -85,7 +85,7 @@ public:
|
||||
|
||||
template<class MutableBufferSequence, class ReadHandler>
|
||||
typename async_completion<ReadHandler,
|
||||
void(std::size_t, error_code)>::result_type
|
||||
void(error_code, std::size_t)>::result_type
|
||||
async_read_some(MutableBufferSequence const& buffers,
|
||||
ReadHandler&& handler)
|
||||
{
|
||||
@@ -120,7 +120,7 @@ public:
|
||||
|
||||
template<class ConstBuffeSequence, class WriteHandler>
|
||||
typename async_completion<WriteHandler,
|
||||
void(std::size_t, error_code)>::result_type
|
||||
void(error_code, std::size_t)>::result_type
|
||||
async_write_some(ConstBuffeSequence const& buffers,
|
||||
WriteHandler&& handler)
|
||||
{
|
||||
|
Reference in New Issue
Block a user