Skip to content

Commit 1221ce8

Browse files
committed
Initial implementation of boost::network::message.
1 parent bd41f3c commit 1221ce8

File tree

10 files changed

+295
-51
lines changed

10 files changed

+295
-51
lines changed

boost/network/message.hpp

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -34,48 +34,64 @@
3434
*/
3535
namespace boost { namespace network {
3636

37-
/** The common message type.
38-
*/
39-
struct message : message_base {
40-
// Nested types
41-
typedef iterator_range<
42-
shared_container_iterator<std::multimap<std::string, std::string> > >
43-
headers_range;
44-
45-
// Mutators
46-
virtual void set_destination(std::string const & destination);
47-
virtual void set_source(std::string const & source);
48-
virtual void append_header(std::string const & name,
49-
std::string const & value);
50-
virtual void remove_headers(std::string const & name);
51-
virtual void remove_headers();
52-
virtual void set_body(std::string const & body);
53-
virtual void append_body(std::string const & data);
54-
55-
// Retrievers
56-
virtual void get_destination(std::string & destination);
57-
virtual void get_source(std::string & source);
58-
virtual void get_headers(function<void(std::string const &, std::string const &)> inserter);
59-
virtual void get_headers(std::string const & name, function<void(std::string const &, std::string const &)> inserter);
60-
virtual void get_headers(function<bool(std::string const &, std::string const &)> predicate, function<void(std::string const &, std::string const &)> inserter);
61-
virtual void get_body(std::string const & body);
62-
virtual void get_body(function<void(iterator_range<char const *>)> chunk_reader, size_t size);
63-
void swap(message & other);
64-
virtual ~message();
65-
};
66-
67-
inline void swap(message & left, message & right) {
68-
left.swap(right);
69-
}
70-
71-
template <class Directive>
72-
message_base & operator<< (message_base & msg, Directive directive) {
73-
directive(msg);
74-
return msg;
75-
}
76-
37+
struct message_pimpl;
38+
39+
/** The common message type.
40+
*/
41+
struct message : message_base {
42+
// Nested types
43+
typedef iterator_range<
44+
shared_container_iterator<std::multimap<std::string, std::string> > >
45+
headers_range;
46+
47+
// Constructors
48+
message();
49+
message(message const & other);
50+
51+
// Assignment
52+
message & operator=(message other);
53+
54+
// Mutators
55+
virtual void set_destination(std::string const & destination);
56+
virtual void set_source(std::string const & source);
57+
virtual void append_header(std::string const & name,
58+
std::string const & value);
59+
virtual void remove_headers(std::string const & name);
60+
virtual void remove_headers();
61+
virtual void set_body(std::string const & body);
62+
virtual void append_body(std::string const & data);
63+
64+
// Retrievers
65+
virtual void get_destination(std::string & destination);
66+
virtual void get_source(std::string & source);
67+
virtual void get_headers(function<void(std::string const &, std::string const &)> inserter);
68+
virtual void get_headers(std::string const & name, function<void(std::string const &, std::string const &)> inserter);
69+
virtual void get_headers(function<bool(std::string const &, std::string const &)> predicate, function<void(std::string const &, std::string const &)> inserter);
70+
virtual void get_body(std::string & body);
71+
virtual void get_body(function<void(iterator_range<char const *>)> chunk_reader, size_t size);
72+
void swap(message & other);
73+
74+
// Destructor
75+
virtual ~message();
76+
private:
77+
message_pimpl * pimpl;
78+
};
79+
80+
inline void swap(message & left, message & right) {
81+
left.swap(right);
82+
}
83+
84+
template <class Directive>
85+
message_base & operator<< (message_base & msg, Directive directive) {
86+
directive(msg);
87+
return msg;
88+
}
89+
7790
} // namespace network
7891
} // namespace boost
7992

80-
#endif // __NETWORK_MESSAGE_HPP__
93+
#ifdef BOOST_NETWORK_NO_LIB
94+
#include <boost/network/message/message.ipp>
95+
#endif
8196

97+
#endif // __NETWORK_MESSAGE_HPP__

boost/network/message.ipp

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
#ifndef BOOST_NETWORK_MESSAGE_IPP_20111020
2+
#define BOOST_NETWORK_MESSAGE_IPP_20111020
3+
4+
// Copyright 2011 Dean Michael Berris (dberris@google.com).
5+
// Copyright 2011 Google, Inc.
6+
// Distributed under the Boost Software License, Version 1.0.
7+
// (See accompanying file LICENSE_1_0.txt or copy at
8+
// http://www.boost.org/LICENSE_1_0.txt)
9+
10+
#include <iterator>
11+
#include <utility>
12+
#include <algorithm>
13+
#include <boost/network/message.hpp>
14+
15+
namespace boost { namespace network {
16+
17+
struct message_pimpl {
18+
message_pimpl() :
19+
destination_(),
20+
source_(),
21+
headers_(),
22+
body_(),
23+
body_read_pos(0)
24+
{}
25+
26+
void set_destination(std::string const & destination) {
27+
destination_ = destination;
28+
}
29+
30+
void set_source(std::string const & source) {
31+
source_ = source;
32+
}
33+
34+
void append_header(std::string const & name,
35+
std::string const & value) {
36+
headers_.insert(std::make_pair(name, value));
37+
}
38+
39+
void remove_headers(std::string const & name) {
40+
headers_.erase(name);
41+
}
42+
43+
void remove_headers() {
44+
std::multimap<std::string,std::string>().swap(headers_);
45+
}
46+
47+
void set_body(std::string const & body) {
48+
body_ = body;
49+
}
50+
51+
void append_body(std::string const & data) {
52+
body_.append(data);
53+
}
54+
55+
// Retrievers
56+
void get_destination(std::string & destination) {
57+
destination = destination_;
58+
}
59+
60+
void get_source(std::string & source) {
61+
source = source_;
62+
}
63+
64+
void get_headers(function<void(std::string const &, std::string const &)> inserter) {
65+
std::multimap<std::string, std::string>::const_iterator it = headers_.begin(),
66+
end = headers_.end();
67+
for (; it != end; ++it) inserter(it->first, it->second);
68+
}
69+
70+
void get_headers(std::string const & name,
71+
function<void(std::string const &, std::string const &)> inserter) {
72+
std::multimap<std::string, std::string>::const_iterator it = headers_.find(name),
73+
end= headers_.end();
74+
while (it != end) {
75+
inserter(it->first, it->second);
76+
++it;
77+
}
78+
}
79+
80+
void get_headers(function<bool(std::string const &, std::string const &)> predicate,
81+
function<void(std::string const &, std::string const &)> inserter) {
82+
std::multimap<std::string, std::string>::const_iterator it = headers_.begin(),
83+
end = headers_.end();
84+
while (it != end) {
85+
if (predicate(it->first, it->second))
86+
inserter(it->first, it->second);
87+
++it;
88+
}
89+
}
90+
91+
void get_body(std::string & body) {
92+
body = body_;
93+
}
94+
95+
void get_body(function<void(iterator_range<char const *>)> chunk_reader, size_t size) {
96+
static char const * nullptr_ = 0;
97+
if (body_read_pos == body_.size())
98+
chunk_reader(boost::make_iterator_range(nullptr_, nullptr_));
99+
std::string::const_iterator it = body_.begin(),
100+
end = body_.end();
101+
std::advance(it, body_read_pos);
102+
size_t max_size = std::distance(it, end);
103+
size_t max_read = std::min(max_size, size);
104+
std::string::const_iterator start = it;
105+
end = start;
106+
std::advance(end, max_read);
107+
body_read_pos += max_read;
108+
chunk_reader(boost::make_iterator_range(&(*start), &(*end)));
109+
}
110+
111+
message_pimpl * clone() {
112+
message_pimpl * other = new(std::nothrow) message_pimpl;
113+
other->destination_ = this->destination_;
114+
other->source_ = this->source_;
115+
other->headers_ = this->headers_;
116+
other->body_ = this->body_;
117+
return other;
118+
}
119+
120+
private:
121+
std::string destination_, source_;
122+
std::multimap<std::string, std::string> headers_;
123+
// TODO: use Boost.IOStreams here later on.
124+
std::string body_;
125+
size_t body_read_pos;
126+
};
127+
128+
message::message()
129+
: pimpl(new (std::nothrow) message_pimpl)
130+
{}
131+
132+
message::message(message const & other)
133+
: pimpl(other.pimpl->clone())
134+
{}
135+
136+
message& message::operator=(message other) {
137+
*pimpl = *other.pimpl;
138+
}
139+
140+
message::~message() {
141+
delete pimpl;
142+
}
143+
144+
void message::set_destination(std::string const & destination) {
145+
pimpl->set_destination(destination);
146+
}
147+
148+
void message::set_source(std::string const & source) {
149+
pimpl->set_source(source);
150+
}
151+
152+
void message::append_header(std::string const & name,
153+
std::string const & value) {
154+
pimpl->append_header(name, value);
155+
}
156+
157+
void message::remove_headers(std::string const & name) {
158+
pimpl->remove_headers(name);
159+
}
160+
161+
void message::remove_headers() {
162+
pimpl->remove_headers();
163+
}
164+
165+
void message::set_body(std::string const & body) {
166+
pimpl->set_body(body);
167+
}
168+
169+
void message::append_body(std::string const & data) {
170+
pimpl->append_body(data);
171+
}
172+
173+
void message::get_destination(std::string & destination) {
174+
pimpl->get_destination(destination);
175+
}
176+
177+
void message::get_source(std::string & source) {
178+
pimpl->get_source(source);
179+
}
180+
181+
void message::get_headers(function<void(std::string const &, std::string const &)> inserter) {
182+
pimpl->get_headers(inserter);
183+
}
184+
185+
void message::get_headers(std::string const & name,
186+
function<void(std::string const &, std::string const &)> inserter) {
187+
pimpl->get_headers(name, inserter);
188+
}
189+
190+
void message::get_headers(function<bool(std::string const &, std::string const &)> predicate,
191+
function<void(std::string const &, std::string const &)> inserter) {
192+
pimpl->get_headers(predicate, inserter);
193+
}
194+
195+
void message::get_body(std::string & body) {
196+
pimpl->get_body(body);
197+
}
198+
199+
void message::get_body(function<void(iterator_range<char const *>)> chunk_reader, size_t size) {
200+
pimpl->get_body(chunk_reader, size);
201+
}
202+
203+
void message::swap(message & other) {
204+
std::swap(this->pimpl, other.pimpl);
205+
}
206+
207+
} /* network */
208+
209+
} /* boost */
210+
211+
#endif /* BOOST_NETWORK_MESSAGE_IPP_20111020 */

boost/network/message_base.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct message_base {
2929
virtual void get_headers(function<void(std::string const &, std::string const &)> inserter) = 0;
3030
virtual void get_headers(std::string const & name, function<void(std::string const &, std::string const &)> inserter) = 0;
3131
virtual void get_headers(function<bool(std::string const &, std::string const &)> predicate, function<void(std::string const &, std::string const &)> inserter) = 0;
32-
virtual void get_body(std::string const & body) = 0;
32+
virtual void get_body(std::string & body) = 0;
3333
virtual void get_body(function<void(iterator_range<char const *>)> chunk_reader, size_t size) = 0;
3434

3535
// Destructor

boost/network/protocol/http/request.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ struct request : request_base {
5858
virtual void get_headers(function<void(std::string const &, std::string const &)> inserter);
5959
virtual void get_headers(std::string const & name, function<void(std::string const &, std::string const &)> inserter);
6060
virtual void get_headers(function<bool(std::string const &, std::string const &)> predicate, function<void(std::string const &, std::string const &)> inserter);
61-
virtual void get_body(std::string const & body);
61+
virtual void get_body(std::string & body);
6262
virtual void get_body(function<void(iterator_range<char const *>)> chunk_reader, size_t size);
63-
63+
6464
// From request_base...
6565
// Setters
6666
virtual void set_method(std::string const & method);
@@ -103,4 +103,3 @@ request_base & operator<< (request_base & request,
103103
#include <boost/network/protocol/http/request_concept.hpp>
104104

105105
#endif // __NETWORK_PROTOCOL_HTTP_REQUEST_20070908-1_HPP__
106-

boost/network/protocol/http/response.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ struct response : response_base {
4949
virtual void get_headers(function<void(std::string const &, std::string const &)> inserter);
5050
virtual void get_headers(std::string const & name, function<void(std::string const &, std::string const &)> inserter);
5151
virtual void get_headers(function<bool(std::string const &, std::string const &)> predicate, function<void(std::string const &, std::string const &)> inserter);
52-
virtual void get_body(std::string const & body);
52+
virtual void get_body(std::string & body);
5353
virtual void get_body(function<void(iterator_range<char const *>)> chunk_reader, size_t size);
5454

5555
// From response_base...

boost/network/uri/uri.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,6 @@ inline
300300
bool operator == (const uri &lhs, const uri &rhs) {
301301
return std::equal(lhs.begin(), lhs.end(), rhs.begin());
302302
}
303-
} // namespace uri
304-
} // namespace network
305303

306304
inline
307305
network::uri::uri::iterator begin(network::uri::uri &uri_) {
@@ -327,6 +325,9 @@ inline
327325
void swap(network::uri::uri &lhs, network::uri::uri &rhs) {
328326
lhs.swap(rhs);
329327
}
328+
329+
} // namespace uri
330+
} // namespace network
330331
} // namespace boost
331332

332333

libs/network/build/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ find_package( Boost 1.43.0 COMPONENTS unit_test_framework system regex thread fi
33

44
add_library(cppnetlib-uri STATIC ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/parse_uri_impl.cpp)
55
add_library(cppnetlib-server-parsers STATIC ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/server_request_parsers_impl.cpp)
6-
6+
add_library(cppnetlib-message STATIC ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/message.cpp)

libs/network/src/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ add_library(cppnetlib-server-parsers ${CPP-NETLIB_HTTP_SERVER_SRCS})
1515

1616
set(CPP-NETLIB_HTTP_CLIENT_SRCS client.cpp)
1717
add_library(cppnetlib-client-connections ${CPP-NETLIB_HTTP_CLIENT_SRCS})
18+
19+
set(CPP-NETLIB_MESSAGE_SRCS message.cpp)
20+
add_library(cppnetlib-message ${CPP-NETLIB_MESSAGE_SRCS})

libs/network/src/message.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2011 Dean Michael Berris (dberris@google.com).
2+
// Copyright 2011 Google, Inc.
3+
// Distributed under the Boost Software License, Version 1.0.
4+
// (See accompanying file LICENSE_1_0.txt or copy at
5+
// http://www.boost.org/LICENSE_1_0.txt)
6+
7+
// This is the conglomeration of all message-related implementation files. All
8+
// we're doing is including all the .ipp files that are relevant.
9+
10+
#ifdef BOOST_NETWORK_NO_LIB
11+
#undef BOOST_NETWORK_NO_LIB
12+
#endif
13+
14+
#include <boost/network/message.ipp>

0 commit comments

Comments
 (0)