message.h

Go to the documentation of this file.
00001 /* vim: set et sw=3 tw=0 fo=croqlaw cino=t0:
00002  *
00003  * Astxx, the Asterisk C++ API and Utility Library.
00004  * Copyright (C) 2005-2007  Matthew A. Nicholson
00005  * Copyright (C) 2005-2007  Digium, Inc.
00006  * 
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License version 2.1 as published by the Free Software Foundation.
00010  * 
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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                // have to use a multimap here because messages can contain 
00071                // multiple headers with the same key
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                   // put the main header first
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                      // don't repeat the main header
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

Generated on Thu Jul 3 01:32:42 2008 for Astxx by  doxygen 1.5.6