Add message swap members and free functions

This commit is contained in:
Vinnie Falco
2016-05-28 07:56:38 -04:00
parent db68ce4d97
commit e8019fa9d4
7 changed files with 125 additions and 4 deletions

View File

@ -4,10 +4,8 @@
* Use beast::error_code instead of nested types
* Tidy up use of GENERATING_DOCS
* Remove obsolete RFC2616 functions
* Add HTTP field value parser containers:
- ext_list
- param_list
- token_list
* Add message swap members and free functions
* Add HTTP field value parser containers: ext_list, param_list, token_list
API Changes:

View File

@ -44,3 +44,5 @@ HTTP:
* Custom HTTP error codes for various situations
* Branch prediction hints in parser
* Check basic_parser_v1 against rfc7230 for leading message whitespace
* Fix the order of message constructor parameters:
body first then headers (since body is constructed with arguments more often)

View File

@ -56,6 +56,7 @@
<member><link linkend="beast.ref.http__parse">parse</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__swap">swap</link></member>
<member><link linkend="beast.ref.http__write">write</link></member>
</simplelist>
<bridgehead renderas="sect3">Constants</bridgehead>

View File

@ -24,12 +24,30 @@ struct request_fields
{
std::string method;
std::string url;
protected:
void
swap(request_fields& other)
{
using std::swap;
swap(method, other.method);
swap(url, other.url);
}
};
struct response_fields
{
int status;
std::string reason;
protected:
void
swap(response_fields& other)
{
using std::swap;
swap(status, other.status);
swap(reason, other.reason);
}
};
} // detail
@ -125,7 +143,14 @@ struct message
{
}
/// Swap this message for another message.
void
swap(message& other);
private:
using base = typename std::conditional<isRequest,
detail::request_fields, detail::response_fields>::type;
template<class... Un, size_t... IUn>
message(std::piecewise_construct_t,
std::tuple<Un...>& tu, beast::detail::index_sequence<IUn...>)
@ -145,6 +170,27 @@ private:
}
};
template<bool isRequest, class Body, class Headers>
void
message<isRequest, Body, Headers>::
swap(message& other)
{
using std::swap;
base::swap(other);
swap(headers, other.headers);
swap(body, other.body);
}
/// Swap one message for another message.
template<bool isRequest, class Body, class Headers>
inline
void
swap(message<isRequest, Body, Headers>& lhs,
message<isRequest, Body, Headers>& rhs)
{
lhs.swap(rhs);
}
/// A typical HTTP request
template<class Body,
class Headers = basic_headers<std::allocator<char>>>

View File

@ -48,8 +48,32 @@ struct message_v1 : message<isRequest, Body, Headers>
std::forward<Argn>(argn)...)
{
}
/// Swap this message for another message.
void
swap(message_v1& other);
};
template<bool isRequest, class Body, class Headers>
void
message_v1<isRequest, Body, Headers>::
swap(message_v1& other)
{
using std::swap;
message<isRequest, Body, Headers>::swap(other);
swap(version, other.version);
}
/// Swap one message for another message.
template<bool isRequest, class Body, class Headers>
inline
void
swap(message_v1<isRequest, Body, Headers>& lhs,
message_v1<isRequest, Body, Headers>& rhs)
{
lhs.swap(rhs);
}
/// A typical HTTP/1 request
template<class Body,
class Headers = basic_headers<std::allocator<char>>>

View File

@ -9,6 +9,7 @@
#include <beast/http/message.hpp>
#include <beast/http/headers.hpp>
#include <beast/http/string_body.hpp>
#include <beast/unit_test/suite.hpp>
#include <type_traits>
@ -126,9 +127,30 @@ public:
}
}
void testSwap()
{
message<true, string_body, headers> m1;
message<true, string_body, headers> m2;
m1.url = "u";
m1.body = "1";
m1.headers.insert("h", "v");
m2.method = "G";
m2.body = "2";
swap(m1, m2);
expect(m1.method == "G");
expect(m2.method.empty());
expect(m1.url.empty());
expect(m2.url == "u");
expect(m1.body == "2");
expect(m2.body == "1");
expect(! m1.headers.exists("h"));
expect(m2.headers.exists("h"));
}
void run() override
{
testConstruction();
testSwap();
}
};

View File

@ -8,6 +8,8 @@
// Test that header file is self-contained.
#include <beast/http/message_v1.hpp>
#include <beast/http/headers.hpp>
#include <beast/http/string_body.hpp>
#include <beast/unit_test/suite.hpp>
#include <beast/http/empty_body.hpp>
@ -78,10 +80,36 @@ public:
expect(! is_keep_alive(m));
}
void testSwap()
{
message_v1<false, string_body, headers> m1;
message_v1<false, string_body, headers> m2;
m1.status = 200;
m1.version = 10;
m1.body = "1";
m1.headers.insert("h", "v");
m2.status = 404;
m2.reason = "OK";
m2.body = "2";
m2.version = 11;
swap(m1, m2);
expect(m1.status == 404);
expect(m2.status == 200);
expect(m1.reason == "OK");
expect(m2.reason.empty());
expect(m1.version == 11);
expect(m2.version == 10);
expect(m1.body == "2");
expect(m2.body == "1");
expect(! m1.headers.exists("h"));
expect(m2.headers.exists("h"));
}
void run() override
{
testFreeFunctions();
testPrepare();
testSwap();
}
};