Skip to content

Commit

Permalink
Initial value semantics support for request.
Browse files Browse the repository at this point in the history
In this commit we implement some support for partial value semantics.
This is important so that we can put the request objects into a
container and compare two requests whether they are semantically equal
value-wise.
  • Loading branch information
deanberris committed Mar 14, 2012
1 parent e7e7df6 commit 84e46e6
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 3 deletions.
11 changes: 9 additions & 2 deletions boost/network/protocol/http/request/request.hpp
Expand Up @@ -18,15 +18,14 @@ namespace boost { namespace network { namespace http {
struct request_pimpl;

struct request : request_base {
// FIXME Implement all these!

// We support full value semantics.
request();
explicit request(std::string const & url);
explicit request(uri::uri const & url);
request(request const &);
request& operator=(request);
void swap(request & other);
bool equals(request const &other) const;

// From message_base...
// Mutators
Expand Down Expand Up @@ -82,6 +81,14 @@ inline void swap(request &l, request &r) {
l.swap(r);
}

inline bool operator==(request const &l, request const &r) {
return l.equals(r);
}

inline bool operator!=(request const &l, request const &r) {
return !l.equals(r);
}

} // namespace http

} // namespace network
Expand Down
14 changes: 13 additions & 1 deletion boost/network/protocol/http/request/request.ipp
Expand Up @@ -27,7 +27,7 @@ struct request_pimpl {
, headers_()
{}

request_pimpl* clone() {
request_pimpl* clone() const {
return new (std::nothrow) request_pimpl(*this);
}

Expand Down Expand Up @@ -94,6 +94,13 @@ struct request_pimpl {
read_offset_ += bytes;
}

bool equals(request_pimpl const &other) const {
return uri_ == other.uri_ &&
read_offset_ == other.read_offset_ &&
source_ == other.source_ &&
headers_ == other.headers_;
}

private:
typedef std::multimap<std::string, std::string> headers_type;

Expand Down Expand Up @@ -130,6 +137,11 @@ request& request::operator=(request rhs) {
rhs.swap(*this);
}

bool request::equals(request const &other) const {
return pimpl_->equals(*other.pimpl_) &&
request_storage_base::equals(other);
}

void request::swap(request & other) {
std::swap(this->pimpl_, other.pimpl_);
}
Expand Down
1 change: 1 addition & 0 deletions boost/network/protocol/http/request/request_base.hpp
Expand Up @@ -31,6 +31,7 @@ struct request_storage_base {
virtual size_t read(char *destination, size_t offset, size_t size) const;
virtual void flatten(std::string &destination) const;
virtual void clear();
virtual bool equals(request_storage_base const &other) const;
virtual ~request_storage_base();

private:
Expand Down
18 changes: 18 additions & 0 deletions boost/network/protocol/http/request/request_base.ipp
Expand Up @@ -24,6 +24,7 @@ struct request_storage_base_pimpl {
size_t read(char *destination, size_t offset, size_t size) const;
void flatten(std::string &destination) const;
void clear();
bool equals(request_storage_base_pimpl const &other) const;
~request_storage_base_pimpl();

private:
Expand Down Expand Up @@ -63,6 +64,10 @@ void request_storage_base::clear() {
pimpl_->clear();
}

bool request_storage_base::equals(request_storage_base const &other) const {
return pimpl_->equals(*other.pimpl_);
}

request_storage_base_pimpl::request_storage_base_pimpl(size_t chunk_size)
: chunk_size_(chunk_size)
, chunks_()
Expand Down Expand Up @@ -154,6 +159,19 @@ void request_storage_base_pimpl::clear() {
chunks_vector().swap(chunks_);
}

bool request_storage_base_pimpl::equals(request_storage_base_pimpl const &other) const {
if (other.chunk_size_ != chunk_size_) return false;
if (other.chunks_.size() != chunks_.size()) return false;
chunks_vector::const_iterator chunk_iterator = chunks_.begin();
chunks_vector::const_iterator other_iterator = other.chunks_.begin();
for (; chunk_iterator != chunks_.begin() && other_iterator != other.chunks_.end();
++chunk_iterator, ++other_iterator) {
if (chunk_iterator->second != other_iterator->second) return false;
if (strncmp(chunk_iterator->first, other_iterator->first, chunk_iterator->second)) return false;
}
return true;
}

request_storage_base_pimpl::~request_storage_base_pimpl() {
clear();
}
Expand Down
24 changes: 24 additions & 0 deletions libs/network/test/http/request_test.cpp
Expand Up @@ -18,6 +18,30 @@ BOOST_AUTO_TEST_CASE(request_construction) {
http::request other(request);
}

BOOST_AUTO_TEST_CASE(request_value_semantics) {
// First let's default construct a request.
http::request original;
// Next let's copy the request.
http::request copy(original);
// Next let's compare the requests.
BOOST_CHECK(original == copy);
// Next let's assign the original to another request.
http::request assigned;
assigned = original;
// Next we modify the assigned object and make sure it's not the same as the
// original.
assigned.set_uri("http://www.google.com/");
std::string original_uri, assigned_uri;
original.get_uri(original_uri);
assigned.get_uri(assigned_uri);
BOOST_CHECK_NE(original_uri, assigned_uri);
BOOST_CHECK(original != assigned);
// Next we swap the assigned and copy.
std::swap(assigned, copy);
BOOST_CHECK(copy != assigned);
BOOST_CHECK(assigned == original);
}

BOOST_AUTO_TEST_CASE(request_uri_test) {
http::request request;
request.set_uri("http://www.google.com/");
Expand Down

0 comments on commit 84e46e6

Please sign in to comment.