00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
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