message.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00029 #ifndef ASTXX_MANAGER_MESSAGE_H
00030 #define ASTXX_MANAGER_MESSAGE_H
00031
00032 #include <astxx/manager/error.h>
00033 #include <map>
00034 #include <string>
00035 #include <sstream>
00036
00037 namespace astxx {
00038 namespace manager {
00039 namespace message {
00043 class header_missing : public manager::error {
00044 public:
00045 explicit header_missing(const std::string& header) throw() : manager::error("missing " + header + " header"), m_header(header) { }
00046 virtual ~header_missing() throw() { }
00047
00049 std::string header() const { return m_header; }
00050
00051 private:
00052 std::string m_header;
00053
00054 };
00055
00067 template<typename message_traits>
00068 class basic_message {
00069 public:
00070
00071
00072 typedef std::multimap<std::string, std::string> header_t;
00073 typedef std::pair<std::string, std::string> header_pair_t;
00074
00075 message_traits traits;
00076
00078 std::string data;
00079
00080 public:
00081
00085 basic_message(const std::string& value) {
00086 this->operator[](traits.main_header()) = value;
00087 }
00088
00092 explicit basic_message(const header_t& headers) : headers(headers) { }
00093
00097 explicit basic_message(const std::map<std::string, std::string>& headers) : headers(headers.begin(), headers.end()) { }
00098
00103 explicit basic_message(const header_t::iterator begin, const header_t::iterator end) : headers(begin, end) { }
00104
00115 std::string& operator[](const std::string& key) {
00116 std::pair<header_t::iterator, header_t::iterator> ii = headers.equal_range(key);
00117 if (ii.first != ii.second)
00118 return ii.first->second;
00119
00120 return headers.insert(std::make_pair(key, ""))->second;
00121 }
00122
00129 bool operator==(const std::string& s) const {
00130 return (main_header() == s);
00131 }
00132
00139 bool operator!=(const std::string& s) const {
00140 return !(*this == s);
00141 }
00142
00147 header_t::iterator insert(const header_pair_t& pair) {
00148 return headers.insert(pair);
00149 }
00150
00155 void insert(header_t::iterator begin, header_t::iterator end) {
00156 return headers.insert(begin, end);
00157 }
00158
00164 std::pair<header_t::iterator, header_t::iterator> equal_range(const std::string& key) {
00165 return headers.equal_range(key);
00166 }
00167
00171 header_t::iterator begin() {
00172 return headers.begin();
00173 }
00174
00178 header_t::iterator end() {
00179 return headers.end();
00180 }
00181
00187 std::string format() {
00188 if (this->operator[](traits.main_header()).empty()) {
00189 throw message::header_missing(traits.main_header());
00190 }
00191
00192 std::stringstream ss;
00193
00194
00195 ss << traits.main_header() << ": " << this->operator[](traits.main_header()) << "\r\n";
00196
00197 for (header_t::iterator i = headers.begin(); i != headers.end(); ++i) {
00198
00199 if (i->first != traits.main_header()) {
00200 ss << i->first << ": " << i->second << "\r\n";
00201 }
00202 }
00203
00204 ss << "\r\n";
00205
00206 return ss.str();
00207 }
00208
00217 std::string main_header() const {
00218 std::pair<header_t::const_iterator, header_t::const_iterator> ii = headers.equal_range(traits.main_header());
00219 if (ii.first != ii.second)
00220 return ii.first->second;
00221
00222 throw message::header_missing(traits.main_header());
00223 }
00224
00225 private:
00226 header_t headers;
00227
00228 };
00229
00236 template<typename message_traits>
00237 bool operator==(const std::string& s, const basic_message<message_traits>& m) {
00238 return (s == m.main_header());
00239 }
00240
00247 template<typename message_traits>
00248 bool operator!=(const std::string& s, const basic_message<message_traits>& m) {
00249 return !(s == m);
00250 }
00251
00252 class message_traits {
00253 public:
00254 explicit message_traits(const std::string& key) : key(key) { }
00255 std::string main_header() const { return key; }
00256
00257 private:
00258 std::string key;
00259 };
00260
00261 class action_traits : public message_traits {
00262 public:
00263 action_traits() : message_traits("Action") { }
00264 };
00265
00266 class response_traits : public message_traits {
00267 public:
00268 response_traits() : message_traits("Response") { }
00269 };
00270
00271 class event_traits : public message_traits {
00272 public:
00273 event_traits() : message_traits("Event") { }
00274 };
00275
00276 typedef basic_message<action_traits> action;
00277 typedef basic_message<response_traits> response;
00278 typedef basic_message<event_traits> event;
00279 }
00280 }
00281 }
00282
00283 #endif