www.pudn.com > DCPlusPlus-src.zip > AdcCommand.h
/*
* Copyright (C) 2001-2004 Jacek Sieka, j_s at telia com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _COMMAND_H
#define _COMMAND_H
class Command {
public:
template
struct Type {
enum { CMD = T };
};
static const char TYPE_ACTIVE = 'A';
static const char TYPE_BROADCAST = 'B';
static const char TYPE_CLIENT = 'C';
static const char TYPE_DIRECT = 'D';
static const char TYPE_INFO = 'I';
static const char TYPE_HUB = 'H';
static const char TYPE_PASSIVE = 'P';
static const char TYPE_UDP = 'U';
#define CMD(n, a, b, c) static const u_int32_t CMD_##n = (((u_int32_t)a) | (((u_int32_t)b)<<8) | (((u_int32_t)c)<<16)); typedef Type n;
CMD(SUP, 'S','U','P');
CMD(STA, 'S','T','A');
CMD(INF, 'I','N','F');
CMD(MSG, 'M','S','G');
CMD(SCH, 'S','C','H');
CMD(RES, 'R','E','S');
CMD(CTM, 'C','T','M');
CMD(GPA, 'G','P','A');
CMD(PAS, 'P','A','S');
CMD(QUI, 'Q','U','I');
CMD(DSC, 'D','S','C');
CMD(GET, 'G','E','T');
CMD(GFI, 'G','F','I');
CMD(SND, 'S','N','D');
CMD(NTD, 'N','T','D');
#undef CMD
template
explicit Command(const T&) : cmdInt(T::CMD), type(TYPE_CLIENT) { }
//explicit Command(u_int32_t cmd) : cmdInt(cmd), type(0) { }
explicit Command(const string& aLine, bool nmdc = false) : cmdInt(0), type(TYPE_CLIENT) {
parse(aLine, nmdc);
}
void parse(const string& aLine, bool nmdc = false);
u_int32_t getCommand() const { return cmdInt; }
char getType() const { return type; }
StringList& getParameters() { return parameters; }
const StringList& getParameters() const { return parameters; }
string toString(bool nmdc = false) const {
string tmp;
if(nmdc) {
tmp += "$ADC";
} else {
tmp += getType();
}
tmp += cmdChar;
if(getType() != TYPE_CLIENT) {
tmp += ' ';
tmp += from.toBase32();
}
if(getType() == TYPE_DIRECT) {
tmp += ' ';
tmp += to.toBase32();
}
for(StringIterC i = getParameters().begin(); i != getParameters().end(); ++i) {
tmp += ' ';
tmp += escape(*i);
}
if(nmdc) {
tmp += '|';
} else {
tmp += '$';
}
return tmp;
}
void addParam(const string& name, const string& value) {
parameters.push_back(name);
parameters.back() += value;
}
void addParam(const string& str) {
parameters.push_back(str);
}
const string& getParam(size_t n) const {
return getParameters().size() > n ? getParameters()[n] : Util::emptyString;
}
/** Return a named parameter where the name is a two-letter code */
bool getParam(const char* name, size_t start, string& ret) const {
for(string::size_type i = start; i < getParameters().size(); ++i) {
if(toCode(name) == toCode(getParameters()[i].c_str())) {
ret = getParameters()[i].substr(2);
return true;
}
}
return false;
}
bool hasFlag(const char* name, size_t start) const {
for(string::size_type i = start; i < getParameters().size(); ++i) {
if(toCode(name) == toCode(getParameters()[i].c_str()) &&
getParameters()[i][2] == '1' &&
getParameters()[i].size() == 3) {
return true;
}
}
return false;
}
static u_int16_t toCode(const char* x) { return *((u_int16_t*)x); }
bool operator==(u_int32_t aCmd) { return cmdInt == aCmd; }
static string escape(const string& str) {
string tmp = str;
string::size_type i = 0;
while( (i = tmp.find_first_of(" \n\\", i)) != string::npos) {
tmp.insert(i, 1, '\\');
i+=2;
}
return tmp;
}
const CID& getTo() const { return to; }
const CID& getFrom() const { return from; }
private:
StringList parameters;
union {
char cmdChar[4];
u_int8_t cmd[4];
u_int32_t cmdInt;
};
char type;
CID from;
CID to;
};
template
class CommandHandler {
public:
void dispatch(const string& aLine, bool nmdc = false) {
Command c(aLine, nmdc);
#define CMD(n) case Command::CMD_##n: ((T*)this)->handle(Command::n(), c); break;
switch(c.getCommand()) {
CMD(SUP);
CMD(STA);
CMD(INF);
CMD(MSG);
CMD(SCH);
CMD(RES);
CMD(CTM);
CMD(GPA);
CMD(PAS);
CMD(QUI);
CMD(DSC);
CMD(GET);
CMD(GFI);
CMD(SND);
CMD(NTD);
default: break;
}
}
};
#endif // _COMMAND_H
/**
* @file
* $Id: AdcCommand.h,v 1.8 2004/09/06 12:32:41 arnetheduck Exp $
*/