Better message tokenization

master
Tomatix 5 years ago
parent 7e628017b8
commit a24c4ddf53
  1. 41
      IRCClient/IRCBase.cpp

@ -965,8 +965,12 @@ void IRCBasePriv::parseIncoming(const std::string& line)
std::string msg;
IRCPrefix sender(hostname);
if (line[0] == ':') {
// :server.addr cmd arg :msg
/*
* Tokenize the message. Two formats may occur:
* :server.addr cmd arg :msg
* cmd arg :msg
*/
{
enum class S {
Prefix,
Command,
@ -976,21 +980,23 @@ void IRCBasePriv::parseIncoming(const std::string& line)
auto it = line.begin() + 1;
auto next = [&it, &line] {
return std::find(it, line.end(), ' ');
};
if (line[0] != ':') {
// Set up parser for the format: "cmd arg :msg"
it = line.begin();
parseState = S::Command;
}
while (it != line.end()) {
auto end = next();
auto next = std::find(it, line.end(), ' ');
switch (parseState) {
case S::Prefix:
sender = IRCPrefix(std::string(it, end));
sender = IRCPrefix(std::string(it, next));
parseState = S::Command;
break;
case S::Command:
command = std::string(it, end);
command = std::string(it, next);
parseState = S::Argument;
break;
@ -1001,28 +1007,19 @@ void IRCBasePriv::parseIncoming(const std::string& line)
[[fallthrough]];
}
else {
args.emplace_back(it, end);
args.emplace_back(it, next);
break;
}
case S::Message:
end = line.end();
msg = std::string(it, end);
next = line.end();
msg = std::string(it, next);
break;
}
it = (end == line.end()) ? end : end + 1;
it = (next == line.end()) ? next : next + 1;
}
}
else {
// cmd :msg
auto wsIt = std::find(line.begin(), line.end(), ' ');
auto colonIt = std::find(wsIt, line.end(), ':');
command = std::string(line.begin(), wsIt);
if (colonIt != line.end()) {
msg = std::string(colonIt + 1, line.end());
}
}
}
if constexpr (DumpReadData) {
std::cout << fmt::format("[RCV] cmd=\"{}\" msg=\"{}\" argc={} ", command, msg, args.size());

Loading…
Cancel
Save