AdcCommand.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006-2010 Jacek Sieka, arnetheduck on gmail point com
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 #ifndef ADCHPP_ADC_COMMAND_H
00020 #define ADCHPP_ADC_COMMAND_H
00021 
00022 #include "common.h"
00023 #include "Exception.h"
00024 #include "Util.h"
00025 #include "Buffer.h"
00026 
00027 namespace adchpp {
00028 
00029 STANDARD_EXCEPTION(ParseException);
00030 
00031 class AdcCommand : private boost::noncopyable {
00032 public:
00033     template<uint32_t T>
00034     struct Type {
00035         enum { CMD = T };
00036     };
00037 
00038     enum Error {
00039         ERROR_GENERIC = 0,
00040         ERROR_HUB_GENERIC = 10,
00041         ERROR_HUB_FULL = 11,
00042         ERROR_HUB_DISABLED = 12,
00043         ERROR_LOGIN_GENERIC = 20,
00044         ERROR_NICK_INVALID = 21,
00045         ERROR_NICK_TAKEN = 22,
00046         ERROR_BAD_PASSWORD = 23,
00047         ERROR_CID_TAKEN = 24,
00048         ERROR_COMMAND_ACCESS = 25,
00049         ERROR_REGGED_ONLY = 26,
00050         ERROR_INVALID_PID = 27,
00051         ERROR_BANNED_GENERIC = 30,
00052         ERROR_PERM_BANNED = 31,
00053         ERROR_TEMP_BANNED = 32,
00054         ERROR_PROTOCOL_GENERIC = 40,
00055         ERROR_PROTOCOL_UNSUPPORTED = 41,
00056         ERROR_CONNECT_FAILED = 42,
00057         ERROR_INF_MISSING = 43,
00058         ERROR_BAD_STATE = 44,
00059         ERROR_FEATURE_MISSING = 45,
00060         ERROR_BAD_IP = 46,
00061         ERROR_NO_HUB_HASH = 47,
00062         ERROR_TRANSFER_GENERIC = 50,
00063         ERROR_FILE_NOT_AVAILABLE = 51,
00064         ERROR_FILE_PART_NOT_AVAILABLE = 52,
00065         ERROR_SLOTS_FULL = 53,
00066         ERROR_NO_CLIENT_HASH = 54
00067     };
00068 
00069     enum Severity {
00070         SEV_SUCCESS = 0,
00071         SEV_RECOVERABLE = 1,
00072         SEV_FATAL = 2
00073     };
00074 
00075     enum Priority {
00076         PRIORITY_NORMAL,        
00077         PRIORITY_LOW,           
00078         PRIORITY_IGNORE         
00079     };
00080 
00081     static const char TYPE_BROADCAST = 'B';
00082     static const char TYPE_CLIENT = 'C';
00083     static const char TYPE_DIRECT = 'D';
00084     static const char TYPE_ECHO = 'E';
00085     static const char TYPE_FEATURE = 'F';
00086     static const char TYPE_INFO = 'I';
00087     static const char TYPE_HUB = 'H';
00088     static const char TYPE_UDP = 'U';
00089 
00090     // Known commands...
00091 #define C(n, a, b, c) static const uint32_t CMD_##n = (((uint32_t)a) | (((uint32_t)b)<<8) | (((uint32_t)c)<<16)); typedef Type<CMD_##n> n
00092     // Base commands
00093     C(SUP, 'S','U','P');
00094     C(STA, 'S','T','A');
00095     C(INF, 'I','N','F');
00096     C(MSG, 'M','S','G');
00097     C(SCH, 'S','C','H');
00098     C(RES, 'R','E','S');
00099     C(CTM, 'C','T','M');
00100     C(RCM, 'R','C','M');
00101     C(GPA, 'G','P','A');
00102     C(PAS, 'P','A','S');
00103     C(QUI, 'Q','U','I');
00104     C(GET, 'G','E','T');
00105     C(GFI, 'G','F','I');
00106     C(SND, 'S','N','D');
00107     C(SID, 'S','I','D');
00108     // Extensions
00109     C(CMD, 'C','M','D');
00110     C(NAT, 'N','A','T');
00111     C(RNT, 'R','N','T');
00112 #undef C
00113 
00114     static const uint32_t HUB_SID = static_cast<uint32_t>(-1);
00115     static const uint32_t INVALID_SID = static_cast<uint32_t>(-2);
00116 
00117     static uint32_t toSID(const std::string& aSID) { return *reinterpret_cast<const uint32_t*>(aSID.data()); }
00118     static std::string fromSID(const uint32_t aSID) { return std::string(reinterpret_cast<const char*>(&aSID), sizeof(aSID)); }
00119     static void appendSID(std::string& str, uint32_t aSID) { str.append(reinterpret_cast<const char*>(&aSID), sizeof(aSID)); }
00120 
00121     static uint32_t toCMD(uint8_t a, uint8_t b, uint8_t c) { return (((uint32_t)a) | (((uint32_t)b)<<8) | (((uint32_t)c)<<16)); }
00122     static uint32_t toCMD(const char* str) { return toCMD(str[0], str[1], str[2]); }
00123 
00124     static uint16_t toField(const char* x) { return *((uint16_t*)x); }
00125     static std::string fromField(const uint16_t aField) { return std::string(reinterpret_cast<const char*>(&aField), sizeof(aField)); }
00126 
00127     static uint32_t toFourCC(const char* x) { return *reinterpret_cast<const uint32_t*>(x); }
00128     static std::string fromFourCC(uint32_t x) { return std::string(reinterpret_cast<const char*>(&x), sizeof(x)); }
00129 
00130     ADCHPP_DLL AdcCommand();
00131     ADCHPP_DLL explicit AdcCommand(Severity sev, Error err, const std::string& desc, char aType = TYPE_INFO);
00132     explicit AdcCommand(uint32_t cmd, char aType = TYPE_INFO, uint32_t aFrom = HUB_SID) : cmdInt(cmd), priority(PRIORITY_NORMAL), from(aFrom), type(aType) { }
00133     explicit AdcCommand(const std::string& aLine) throw(ParseException) : cmdInt(0), priority(PRIORITY_NORMAL), type(0) { parse(aLine); }
00134     explicit AdcCommand(const BufferPtr& buffer_) throw(ParseException) : buffer(buffer_), cmdInt(0), priority(PRIORITY_NORMAL), type(0) { parse((const char*)buffer->data(), buffer->size()); }
00135 
00136     void parse(const std::string& str) throw(ParseException) { parse(str.data(), str.size()); }
00137     ADCHPP_DLL void parse(const char* buf, size_t len) throw(ParseException);
00138     uint32_t getCommand() const { return cmdInt; }
00139     char getType() const { return type; }
00140     std::string getFourCC() const { std::string tmp(4, 0); tmp[0] = type; tmp[1] = cmd[0]; tmp[2] = cmd[1]; tmp[3] = cmd[2]; return tmp; }
00141     StringList& getParameters() { return parameters; }
00142     const StringList& getParameters() const { return parameters; }
00143     ADCHPP_DLL std::string toString() const;
00144 
00145     AdcCommand& addParam(const std::string& param) {
00146         parameters.push_back(param);
00147         return *this;
00148     }
00149 
00150     AdcCommand& addParam(const std::string& name, const std::string& value) {
00151         return addParam(name + value);
00152     }
00153 
00154     const std::string& getParam(size_t n) const {
00155         return getParameters().size() > n ? getParameters()[n] : Util::emptyString;
00156     }
00157 
00158     void resetBuffer() { buffer.reset(); }
00159 
00160     const std::string& getFeatures() const { return features; }
00161 
00163     ADCHPP_DLL bool getParam(const char* name, size_t start, std::string& ret) const;
00164     ADCHPP_DLL bool delParam(const char* name, size_t start);
00165 
00166     ADCHPP_DLL bool hasFlag(const char* name, size_t start) const;
00167 
00168     bool operator==(uint32_t aCmd) const { return cmdInt == aCmd; }
00169 
00170     ADCHPP_DLL static void escape(const std::string& s, std::string& out);
00171 
00172     ADCHPP_DLL const BufferPtr& getBuffer() const;
00173 
00174     uint32_t getTo() const { return to; }
00175     void setTo(uint32_t aTo) { to = aTo; }
00176     uint32_t getFrom() const { return from; }
00177     void setFrom(uint32_t aFrom) { from = aFrom; }
00178 
00179     Priority getPriority() const { return priority; }
00180     void setPriority(Priority priority_) { priority = priority_; }
00181 
00182 private:
00183     StringList parameters;
00184     std::string features;
00185 
00186     mutable BufferPtr buffer;
00187 
00188     union {
00189         char cmdChar[4];
00190         uint8_t cmd[4];
00191         uint32_t cmdInt;
00192     };
00193 
00194     Priority priority;
00195     uint32_t from;
00196     uint32_t to;
00197     char type;
00198 };
00199 
00200 class Client;
00201 class Entity;
00202 
00203 template<class T>
00204 class CommandHandler {
00205 public:
00206     bool dispatch(Entity& c, AdcCommand& cmd) {
00207 #define C(n) case AdcCommand::CMD_##n: return ((T*)this)->handle(AdcCommand::n(), c, cmd); break;
00208         switch(cmd.getCommand()) {
00209             C(SUP);
00210             C(STA);
00211             C(INF);
00212             C(MSG);
00213             C(SCH);
00214             C(RES);
00215             C(CTM);
00216             C(RCM);
00217             C(GPA);
00218             C(PAS);
00219             C(QUI);
00220             C(GET);
00221             C(GFI);
00222             C(SND);
00223             C(SID);
00224             C(CMD);
00225             default:
00226                 dcdebug("Unknown ADC command: %.50s\n", cmd.toString().c_str());
00227                 return true;
00228 #undef C
00229         }
00230     }
00231 };
00232 
00233 }
00234 
00235 #endif // ADC_COMMAND_H
Generated on Sat Nov 27 23:37:53 2010 for adchpp by  doxygen 1.6.3