SString.h 中还有个实用的 ACE_Tokenizer 类,帮你把 buf 根据特定的分隔符拆分。
唯一需要注意的就是 buf 必须为 non-const char,因为 ACE_Tokenizer 内部有可能修改此 buf。
---------------------------
#include <ace/Log_Msg.h> // ACE_DEBUG
#include <ace/SString.h>
int ACE_MAIN(int, ACE_TCHAR *[])
{
ACE_TCHAR buf[30];
ACE_OS::strcpy(buf, ACE_TEXT("dog/cat/pig"));
ACE_Tokenizer tok(buf);
tok.delimiter_replace(ACE_TEXT('/'), ACE_TEXT('\0'));
for (ACE_TCHAR *p = tok.next(); p; p = tok.next())
ACE_DEBUG((LM_DEBUG, ACE_TEXT("%s\n"), p));
return 0;
}
---------------------------
dog
cat
pig
---------------------------
在此基础上,我们可以实现一个简单的 Command 系统。你只需要写对应的 Command Func 并添加到 CmdDispatcher 中即可。
---------------------------
/* KCommand.h */
#include <ace/Log_Msg.h>
#include <ace/SString.h>
class KCommand
{
public:
enum { MAX_PARAM = 80 };
KCommand();
KCommand(ACE_TCHAR *cmd);
~KCommand();
void parse_cmd(ACE_TCHAR *cmd);
ssize_t param_cnt() { return param_cnt_; }
ACE_TCHAR *param(ssize_t n);
private:
ACE_TCHAR *param_[MAX_PARAM];
ssize_t param_cnt_;
private:
KCommand(const KCommand&);
const KCommand& operator =(const KCommand&);
};
class KCmdDispatcher
{
public:
static KCmdDispatcher *instance();
public:
enum { MAX_CMD = 100 };
typedef void (*CMD_FUNC)(KCommand &);
void dispatch(KCommand &cmd);
void add_cmd(const ACE_TCHAR* cmd, CMD_FUNC func);
private:
struct {
const ACE_TCHAR* key;
CMD_FUNC func;
} cmd_map_[MAX_CMD];
ssize_t cnt_;
private:
KCmdDispatcher() : cnt_(0) {};
};
---------------------------
/* KCommand.cpp */
#include "KCommand.h"
// ---------- KCommand ------------
KCommand::KCommand()
{
}
KCommand::KCommand(ACE_TCHAR *cmd)
{
parse_cmd(cmd);
}
KCommand::~KCommand()
{
}
void KCommand::parse_cmd(ACE_TCHAR *cmd)
{
param_cnt_ = 0;
if (cmd == NULL) return;
ACE_Tokenizer tok(cmd);
tok.delimiter_replace(ACE_TEXT(' '), ACE_TEXT('\0'));
for (ACE_TCHAR *p = tok.next(); p; p = tok.next())
param_[param_cnt_++] = p;
}
ACE_TCHAR *KCommand::param(ssize_t n)
{
if (n >= param_cnt_) return NULL;
return param_[0];
}
// ---------- KCmdDispatcher ------------
KCmdDispatcher *KCmdDispatcher::instance()
{
static KCmdDispatcher *inst = NULL;
if (inst == NULL) inst = new KCmdDispatcher();
return inst;
}
void KCmdDispatcher::dispatch(KCommand &cmd)
{
if ( cmd.param_cnt() == 0 ) return;
ACE_TCHAR *key = cmd.param(0);
for ( ssize_t i = 0; i < this->cnt_; i++ )
{
if ( ACE_OS::strcmp(key, this->cmd_map_[i].key) == 0 )
{
cmd_map_[i].func(cmd);
continue;
}
}
}
void KCmdDispatcher::add_cmd(const ACE_TCHAR* cmd, CMD_FUNC func)
{
this->cmd_map_[this->cnt_].key = cmd;
this->cmd_map_[this->cnt_].func = func;
this->cnt_++;
}
---------------------------
/* Main.cpp */
#include "KCommand.h"
void KCmd_NICK(KCommand &cmd)
{
if (cmd.param_cnt() >= 2)
{
ACE_DEBUG((LM_DEBUG, ACE_TEXT("nickname = %s\n"), cmd.param(1)));
}
else
{
ACE_DEBUG((LM_DEBUG, ACE_TEXT("Error: NICK <nickname>\n")));
}
}
int ACE_MAIN(int, ACE_TCHAR *[])
{
KCmdDispatcher::instance()->add_cmd(ACE_TEXT("NICK"), KCmd_NICK);
ACE_TCHAR buf[80];
ACE_OS::strcpy(buf, ACE_TEXT("NICK kasicass"));
KCommand cmd(buf);
KCmdDispatcher::instance()->dispatch(cmd);
return 0;
}
---------------------------
nickname = kasicass
---------------------------
评论