Skip to content

Commit 158004f

Browse files
committed
WIP: Working on wrapper implementations.
1 parent b754939 commit 158004f

File tree

6 files changed

+381
-143
lines changed

6 files changed

+381
-143
lines changed

boost/network/message/directives/header.hpp

Lines changed: 28 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,44 @@
1-
2-
// Copyright Dean Michael Berris 2007-2010.
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-
71
#ifndef __NETWORK_MESSAGE_DIRECTIVES_HEADER_HPP__
82
#define __NETWORK_MESSAGE_DIRECTIVES_HEADER_HPP__
93

10-
#include <boost/thread/future.hpp>
11-
#include <boost/mpl/if.hpp>
12-
#include <boost/mpl/or.hpp>
13-
#include <boost/variant/variant.hpp>
14-
#include <boost/variant/apply_visitor.hpp>
15-
#include <boost/variant/static_visitor.hpp>
16-
17-
namespace boost { namespace network {
18-
19-
namespace impl {
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)
209

21-
template <class KeyType, class ValueType>
22-
struct header_directive {
10+
#include <boost/network/message_base.hpp>
2311

24-
explicit header_directive(KeyType const & header_name,
25-
ValueType const & header_value) :
26-
_header_name(header_name),
27-
_header_value(header_value)
28-
{ };
12+
namespace boost { namespace network {
2913

30-
template <class Message>
31-
struct pod_directive {
32-
template <class T1, class T2>
33-
static void eval(Message const & message, T1 const & key, T2 const & value) {
34-
typedef typename Message::headers_container_type::value_type value_type;
35-
value_type value_ = { key, value };
36-
message.headers.insert(message.headers.end(), value_);
37-
}
38-
};
14+
namespace impl {
3915

40-
template <class Message>
41-
struct normal_directive {
42-
template <class T1, class T2>
43-
static void eval(Message const & message, T1 const & key, T2 const & value) {
44-
typedef typename Message::headers_container_type::value_type value_type;
45-
message.add_header(value_type(key, value));
46-
}
47-
};
16+
template <class KeyType, class ValueType>
17+
struct header_directive {
4818

49-
template <class Message>
50-
struct directive_impl :
51-
mpl::if_<
52-
is_base_of<
53-
tags::pod,
54-
typename Message::tag
55-
>,
56-
pod_directive<Message>,
57-
normal_directive<Message>
58-
>::type
59-
{};
19+
explicit header_directive(KeyType const & header_name,
20+
ValueType const & header_value) :
21+
_header_name(header_name),
22+
_header_value(header_value)
23+
{ };
6024

61-
template <class Message>
62-
void operator() (Message const & msg) const {
63-
typedef typename Message::headers_container_type::value_type value_type;
64-
directive_impl<Message>::eval(msg, _header_name, _header_value);
65-
}
25+
void operator() (message_base & msg) const {
26+
msg.append_header(_header_name, _header_value);
27+
}
6628

67-
private:
29+
private:
6830

69-
KeyType const & _header_name;
70-
ValueType const & _header_value;
71-
};
31+
KeyType const & _header_name;
32+
ValueType const & _header_value;
33+
};
7234

73-
} // namespace impl
35+
} // namespace impl
7436

75-
template <class T1, class T2>
76-
inline impl::header_directive<T1, T2>
77-
header(T1 const & header_name, T2 const & header_value) {
78-
return impl::header_directive<T1, T2>(header_name, header_value);
79-
}
37+
template <class T1, class T2>
38+
inline impl::header_directive<T1, T2>
39+
header(T1 const & header_name, T2 const & header_value) {
40+
return impl::header_directive<T1, T2>(header_name, header_value);
41+
}
8042
} // namespace network
8143
} // namespace boost
8244

boost/network/message/wrappers/headers.hpp

Lines changed: 43 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -13,87 +13,53 @@
1313

1414
namespace boost { namespace network {
1515

16-
/// Template metaprogram to get the range type for a message
17-
template <class Message>
18-
struct headers_range {
19-
typedef typename headers_container<typename Message::tag>::type headers_container_type;
20-
typedef typename
21-
boost::iterator_range<typename headers_container_type::const_iterator>
22-
type;
23-
};
24-
25-
template <class Tag>
26-
struct basic_message;
27-
28-
/** headers wrapper for messages.
29-
*
30-
* This exposes an interface similar to a map, indexable
31-
* using operator[] taking a string as the index and returns
32-
* a range of iterators (std::pair<iterator, iterator>)
33-
* whose keys are all equal to the index string.
34-
*
35-
* This type is also convertible to a
36-
* headers_range<basic_message<tag> >::type
37-
* Which allows for full range support.
38-
*
39-
* The type is also convertible to a
40-
* headers_container<Tag>::type
41-
* Which copies the headers from the wrapped message.
42-
*
43-
*/
44-
namespace impl {
45-
template <class Tag>
46-
struct headers_wrapper : public detail::wrapper_base_const<Tag, basic_message<Tag> > {
47-
typedef Tag tag;
48-
typedef basic_message<Tag> message_type;
49-
typedef typename string<Tag>::type string_type;
50-
typedef typename headers_range<message_type>::type range_type;
51-
typedef typename headers_container<Tag>::type headers_container_type;
52-
typedef typename headers_container_type::const_iterator const_iterator;
53-
typedef typename headers_container_type::iterator iterator;
54-
typedef detail::wrapper_base_const<Tag, basic_message<Tag> > wrapper_base;
55-
56-
explicit headers_wrapper(basic_message<Tag> const & message_)
57-
: wrapper_base(message_)
58-
{ };
59-
60-
range_type operator[] (string_type const & key) const {
61-
return headers_wrapper<Tag>::_message.headers().equal_range(key);
62-
};
63-
64-
typename message_type::headers_container_type::size_type count(string_type const & key) const {
65-
return headers_wrapper<Tag>::_message.headers().count(key);
66-
};
67-
68-
const_iterator begin() const {
69-
return headers_wrapper<Tag>::_message.headers().begin();
70-
};
71-
72-
const_iterator end() const {
73-
return headers_wrapper<Tag>::_message.headers().end();
74-
};
75-
76-
operator range_type () {
77-
return make_iterator_range(headers_wrapper<Tag>::_message.headers().begin(), headers_wrapper<Tag>::_message.headers().end());
78-
};
79-
80-
operator headers_container_type () {
81-
return headers_wrapper<Tag>::_message.headers();
82-
}
83-
84-
};
85-
} // namespace impl
86-
87-
/// Factory method to create the right wrapper object
88-
template <class Tag>
89-
inline impl::headers_wrapper<Tag>
90-
headers(basic_message<Tag> const & message_) {
91-
return impl::headers_wrapper<Tag>(message_);
92-
}
16+
namespace impl {
17+
18+
/** headers wrapper for messages.
19+
*
20+
* This exposes an interface similar to a map, indexable
21+
* using operator[] taking a string as the index and returns
22+
* a range of iterators (std::pair<iterator, iterator>)
23+
* whose keys are all equal to the index string.
24+
*
25+
* This type is also convertible to a
26+
* headers_range<basic_message<tag> >::type
27+
* Which allows for full range support.
28+
*
29+
* The type is also convertible to a
30+
* headers_container<Tag>::type
31+
* Which copies the headers from the wrapped message.
32+
*
33+
*/
34+
struct headers_wrapper {
35+
typedef std::multimap<std::string, std::string> container_type;
36+
typedef shared_container_iterator<container_type> iterator;
37+
typedef iterator_range<shared_container_iterator<container_type> >
38+
range_type;
39+
40+
explicit headers_wrapper(message_base & message);
41+
range_type operator[] (std::string const & key) const;
42+
container_type::size_type count() const;
43+
private:
44+
void init_cache_all();
45+
mutable shared_ptr<container_type> cache_;
46+
};
47+
48+
} // namespace impl
49+
50+
/// Factory method to create the right wrapper object
51+
inline impl::headers_wrapper
52+
headers(message_base & message_) {
53+
return impl::headers_wrapper(message_);
54+
}
9355

9456
} // namespace network
9557

9658
} // namespace boost
9759

60+
#ifdef BOOST_NETWORK_NO_LIB
61+
#include <boost/network/message/wrappers/headers.ipp>
62+
#endif
63+
9864
#endif // __NETWORK_MESSAGE_WRAPPERS_HEADERS_HPP__
9965

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#ifndef BOOST_NETWORK_MESSAGE_WRAPPERS_HEADERS_IPP_20110911
2+
#define BOOST_NETWORK_MESSAGE_WRAPPERS_HEADERS_IPP_20110911
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 <boost/network/message/wrappers/headers.hpp>
11+
12+
namespace boost { namespace network {
13+
14+
headers_wrapper::headers_wrapper(message_base & message)
15+
: message_(message)
16+
{}
17+
18+
range_type headers_wrapper::operator[] (std::string const & key) const {
19+
cache_.reset(new (std::nothrow) container_type);
20+
if (!cache_.get())
21+
BOOST_THROW_EXCEPTION(std::runtime_error(
22+
"Cannot allocate cache multimap for headers wrapper."));
23+
message_.get_headers(
24+
key,
25+
std::inserter(*cache_, cache_->end()));
26+
return make_shared_container_range(cache_);
27+
}
28+
29+
headers_wrapper::container_type::size_type
30+
headers_wrapper::count(string_type const & key) const {
31+
this->init_cache_all();
32+
return cache_->size();
33+
}
34+
35+
headers_wrapper::iterator headers_wrapper::begin() const {
36+
this->init_cache_all();
37+
return make_shared_container_iterator(cache_->begin());
38+
}
39+
40+
headers_wrapper::iterator headers_wrapper::end() const {
41+
this->init_cache_all();
42+
return make_shared_container_iterator(cache_->end());
43+
};
44+
45+
headers_wrapper::operator headers_wrapper::range_type () {
46+
this->init_cache_all();
47+
return make_shared_container_range(cache_);
48+
};
49+
50+
headers_wrapper::operator headers_wrapper::container_type () {
51+
this->init_cache_all();
52+
return *cache_;
53+
}
54+
55+
void headers_wrapper::init_cache_all() {
56+
if (!cache_.get()) {
57+
cache_.reset(new (std::nothrow) container_type);
58+
if (!cache_.get())
59+
BOOST_THROW_EXCEPTION(std::runtime_error(
60+
"Cannot allocate cache multimap for headers wrapper."));
61+
message_.get_headers(std::inserter(*cache_, cache_->end()));
62+
}
63+
}
64+
65+
} /* network */
66+
67+
} /* boost */
68+
69+
#endif /* BOOST_NETWORK_MESSAGE_WRAPPERS_HEADERS_IPP_20110911 */

boost/network/message_base.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#ifndef BOOST_NETWORK_MESSAGE_BASE_HPP_20110910
2+
#define BOOST_NETWORK_MESSAGE_BASE_HPP_20110910
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+
namespace boost { namespace network {
11+
12+
struct message_base {
13+
// Mutators
14+
virtual void set_destination(std::string const & destination) = 0;
15+
virtual void set_source(std::string const & source) = 0;
16+
virtual void append_header(std::string const & name,
17+
std::string const & value) = 0;
18+
virtual void remove_headers(std::string const & name) = 0;
19+
virtual void set_body(std::string const & body) = 0;
20+
virtual void append_body(std::string const & data) = 0;
21+
22+
// Retrievers
23+
virtual void get_destination(std::string & destination) = 0;
24+
virtual void get_source(std::string & source) = 0;
25+
virtual void get_headers(function<void(std::string const &, std::string const &)> inserter) = 0;
26+
virtual void get_headers(std::string const & name, function<void(std::string const &, std::string const &)> inserter) = 0;
27+
virtual void get_headers(function<bool(std::string const &, std::string const &)> predicate, function<void(std::string const &, std::string const &)> inserter) = 0;
28+
virtual void get_body(std::string const & body) = 0;
29+
virtual void get_body(function<void(iterator_range<char const *>)> chunk_reader, size_t size) = 0;
30+
31+
// Destructor
32+
virtual ~message_base() = 0; // pure virtual
33+
};
34+
35+
} /* network */
36+
37+
} /* boost */
38+
39+
#endif /* BOOST_NETWORK_MESSAGE_BASE_HPP_20110910 */

0 commit comments

Comments
 (0)