00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 #ifndef IRCMESSAGE_H
00017 #define IRCMESSAGE_H
00018 
00019 #ifndef USE_PCH
00020 #include <map>
00021 #include <string>
00022 #include <vector>
00023 #include "debug.h"
00024 #include <libcw/dbstreambuf.h>  
00025 #ifdef CWDEBUG
00026 #include <libcwd/buf2str.h>
00027 #endif
00028 #endif
00029 
00030 #include "Keyword.h"
00031 #include "Prefix.h"
00032 
00033 class ClientSession;
00034 class ServerSession;
00035 class MsgPart;
00036 
00037 
00038 
00039 
00040 
00041 class MessageIn {
00042 public:
00043 
00044   class Part {
00045   private:
00046     char const* M_ptr;          
00047     size_t M_len;               
00048   public:
00049 
00050     Part(void) { }
00051 
00052     Part(char const* start, char const* end) : M_ptr(start), M_len(end - start) { }
00053 
00054     void set(char const* start, char const* end) { M_ptr = start; M_len = end - start; }
00055 
00056     void clear(void) { M_ptr = NULL; }
00057 
00058     char const* start(void) const { return M_ptr; }
00059 
00060     char const* end(void) const { return M_ptr + M_len; }
00061 
00062     size_t len(void) const { return M_len; }
00063 #ifdef CWDEBUG
00064 
00065     friend std::ostream& operator<<(std::ostream& os, Part const& part)
00066         { return os << '"' << libcwd::buf2str(part.M_ptr, part.M_len) << '"'; }
00067 #endif
00068   };
00069 
00070 public:
00071   typedef std::vector<Part> params_type;        
00072 
00073 private:
00074   msg_block_ct M_msg_block;             
00075   char const* M_end;                    
00076   Part M_prefix;                        
00077   Part M_command;                       
00078   int M_key;                            
00079   Keyword const* M_keyword_ptr;         
00080   params_type M_params;                 
00081 
00082 protected:
00083 
00084   MessageIn(void);
00085 
00086 public:
00087 
00088   void init(msg_block_ct msg_block);
00089 
00090 
00091   bool uninitialized(void) const { return M_msg_block.get_size() == 0; }
00092 
00093 
00094   bool is_numeric(void) const { return M_command.start() && std::isdigit(*M_command.start()); }
00095 
00096 
00097   int numeric(void) const { ASSERT(is_numeric()); return M_key; }
00098 
00099 
00100   int key(void) const { return M_key; }
00101 
00102 
00103   params_type::size_type params_size(void) const { return M_params.size(); }
00104 
00105 
00106   params_type const& params(void) const { return M_params; }
00107 
00108 
00109   std::string param(size_t n) const
00110   {
00111     std::string result;
00112     if (n < M_params.size())
00113       result.assign(M_params[n].start(), M_params[n].len());
00114     return result;
00115   }
00116 
00117 
00118   MsgPart params(size_t n) const;
00119 
00120 
00121   bool has_prefix(void) const { return M_prefix.start(); }
00122 
00123 
00124   std::string prefix_str(void) const { ASSERT(has_prefix()); return std::string(M_prefix.start(), M_prefix.len()); }
00125 
00126 
00127   Part prefix_part(void) const { ASSERT(has_prefix()); return M_prefix; }
00128 
00129 
00130   Prefix prefix(void) const
00131       { return has_prefix() ? (is_server_message() ? Prefix(priv_server_session(), prefix_str()) : Prefix(priv_client_session(), prefix_str())) : Prefix(); }
00132 
00133 
00134   std::string command_str(void) const { return M_command.start() ? std::string(M_command.start(), M_command.len()) : ""; }
00135 
00136 
00137   Part const& command_part(void) const { return M_command; }
00138 
00139 
00140   char const* uppercase_command(void) const { ASSERT(M_key < 0); return M_keyword_ptr->name; }
00141 
00142 
00143   char const* end(void) const { return M_end; }
00144 
00145 protected:
00146 
00147   virtual bool is_server_message(void) const = 0;
00148 
00149 
00150   virtual ServerSession& priv_server_session(void) const = 0;
00151 
00152   virtual ClientSession& priv_client_session(void) const = 0;
00153 };
00154 
00155 
00156 
00157 
00158 class MsgPart : public MessageIn::Part {
00159 private:
00160   msg_block_ct M_msg_block;     
00161 public:
00162 
00163   MsgPart(msg_block_ct const& msg_block) : M_msg_block(msg_block) { }
00164 
00165   MsgPart(msg_block_ct const& msg_block, Part const& part) : MessageIn::Part(part), M_msg_block(msg_block) { }
00166 };
00167 
00168 inline MsgPart MessageIn::params(size_t n) const
00169 {
00170   MsgPart result(M_msg_block);
00171   if (n < M_params.size())
00172   {
00173     char const* start = M_params[n].start();
00174     if (n == M_params.size() - 1 && start[-1] == ':')
00175       --start;
00176     result.set(start, M_end);
00177   }
00178   else
00179     result.clear();
00180   return result;
00181 }
00182 
00183 
00184 
00185 
00186 
00187 class ClientMessageIn : public MessageIn {
00188   private:
00189     ClientSession* M_client_session;            
00190   public:
00191 
00192     ClientMessageIn(ClientSession* client_session) : M_client_session(client_session) { }
00193 #ifdef CWDEBUG
00194 
00195     ClientMessageIn(ClientMessageIn const& msg) : MessageIn(msg), M_client_session(msg.M_client_session)
00196         { Dout(dc::objects, "Copy-constructing ClientMessageIn from " << msg); }
00197 
00198     ~ClientMessageIn() { Dout(dc::objects, "Destructing ClientMessageIn " << *this); }
00199 #endif
00200 
00201 
00202     ClientSession& client_session(void) const { return *M_client_session; }
00203 
00204   protected:
00205     virtual bool is_server_message(void) const { return false; }
00206 
00207     virtual ClientSession& priv_client_session(void) const { return client_session(); }
00208     virtual ServerSession& priv_server_session(void) const { DoutFatal(dc::core, "Calling MessageIn::server_session() for ClientMessageIn"); }
00209 };
00210 
00211 
00212 
00213 
00214 
00215 class ServerMessageIn : public MessageIn {
00216   private:
00217     ServerSession* M_server_session;            
00218   public:
00219 
00220     ServerMessageIn(ServerSession* server_session) : M_server_session(server_session) { }
00221 #ifdef CWDEBUG
00222 
00223     ServerMessageIn(ServerMessageIn const& msg) : MessageIn(msg), M_server_session(msg.M_server_session)
00224         { Dout(dc::objects, "Copy-constructing ServerMessageIn from " << msg); }
00225 #endif
00226 
00227     ~ServerMessageIn() { Dout(dc::objects, "Destructing ServerMessageIn " << *this); }
00228 
00229 
00230     
00231     
00232     
00233     
00234     ServerSession& server_session(void) const { return *M_server_session; }
00235 
00236   protected:
00237     virtual bool is_server_message(void) const { return true; }
00238 
00239     virtual ClientSession& priv_client_session(void) const { DoutFatal(dc::core, "Calling ServerMessageIn::priv_client_session()"); }
00240     virtual ServerSession& priv_server_session(void) const { return server_session(); }
00241 };
00242 
00243 #endif // IRCMESSAGE_H