From 29aa15f713f9d0baded0ebdc3cb3f7be46df0ccb Mon Sep 17 00:00:00 2001 From: Jonas Suhr Christensen Date: Sat, 25 Feb 2012 11:36:16 +0100 Subject: Now handling protocol as described - with quoting with '"' and escaping of '"'. Now handling multiple cmd's in one msg. --- src/msgparser.cc | 154 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 125 insertions(+), 29 deletions(-) (limited to 'src/msgparser.cc') diff --git a/src/msgparser.cc b/src/msgparser.cc index ec41b3b..79172e9 100644 --- a/src/msgparser.cc +++ b/src/msgparser.cc @@ -29,6 +29,9 @@ #include #include +#include +#include + inline void parse_add(msg_t& m, std::string data) { int offset = 0; std::string title = data.substr(offset, data.find(' ', offset) - offset); @@ -73,39 +76,132 @@ inline void parse_move(msg_t& m, std::string data) { MsgVector parse_msg(std::string data) { - //todo: explode on ';' and handle '"' and escaping - - printf("parsing: %s\n", data.c_str()); - - msg_t m; - - std::string cmd = data.substr(0, data.find(' ')); - - if(cmd == "add") m.cmd = cmd::add; - else if(cmd == "del") m.cmd = cmd::del; - else if(cmd == "move") m.cmd = cmd::move; - else if(cmd == "update") m.cmd = cmd::update; - else m.cmd = cmd::error; + printf("Parsing: %s\n", data.c_str()); + + typedef std::vector TokenVector; + + // this name is pretty stupid as we already use the name MsgVector for something completely else + typedef std::list MsgList; + + MsgList msglist; + TokenVector tokens; + std::string token; + bool inside_quote = false; + char prev_ch = '0'; + for(int i = 0; i < data.length(); i++) { + char ch = data[i]; + + switch(ch) { + case '\"': + if(prev_ch != '\\') + inside_quote = !inside_quote; + else { + printf("Appending %c\n", ch); + token += ch; + } + break; + case ' ': + if(inside_quote) { + printf("Appending %c\n", ch); + token += ch; + continue; + } + if(token.empty()) continue; // skip multiple white spaces and pre white space + printf("Adding token %s\n", token.c_str()); + tokens.push_back(token); + token.clear(); + break; + case ';': + printf("Adding msg...\n"); + if(!token.empty()) { + tokens.push_back(token); + } + msglist.push_back(tokens); + tokens.clear(); + token.clear(); + break; + default: + printf("Appending %c\n", ch); + token += ch; + break; + } + prev_ch = ch; + } - data = data.substr(cmd.length()+1, std::string::npos); + if(!token.empty()) { + tokens.push_back(token); + token.clear(); + } - switch(m.cmd) { - case cmd::add: - parse_add(m, data); - break; - case cmd::del: - parse_del(m, data); - break; - case cmd::move: - parse_move(m, data); - break; - case cmd::update: - break; - default: - break; + if(!tokens.empty()) { + msglist.push_back(tokens); + tokens.clear(); } - MsgVector v; v.push_back(m); + printf("Number of messages: %d\n", msglist.size()); + + MsgVector v; + MsgList::iterator it_msg; + for(it_msg = msglist.begin(); it_msg != msglist.end(); it_msg++) { + TokenVector t = *it_msg; + + //malformed msg + if(t.size() < 1) continue; + + msg_t m; + + if(t[0] == "add") m.cmd = cmd::add; + else if(t[0] == "del") m.cmd = cmd::del; + else if(t[0] == "move") m.cmd = cmd::move; + else if(t[0] == "update") m.cmd = cmd::update; + else m.cmd = cmd::error; + + printf("Number of tokens %d\n", t.size()); + + switch(m.cmd) { + case cmd::add: { + if(t.size() != 4+1) { + printf("Wrong number of parameters\n"); + continue; + } + sprintf(m.add.title, "%s", t[0].c_str()); + sprintf(m.add.desc, "%s", t[1].c_str()); + m.add.x = atoi(t[2].c_str()); + m.add.y = atoi(t[3].c_str()); + break; + } + case cmd::del: { + if(t.size() != 1+1) { + printf("Wrong number of parameters\n"); + continue; + } + m.del.id = atoi(t[1].c_str()); + break; + } + case cmd::move: { + if(t.size() != 3+1) { + printf("Wrong number of parameters\n"); + continue; + } + m.move.id = atoi(t[1].c_str()); + m.move.x = atoi(t[2].c_str()); + m.move.y = atoi(t[3].c_str()); + break; + } + case cmd::update: { + if(t.size() != 3+1) { + printf("Wrong number of parameters\n"); + continue; + } + break; + } + default: + break; + }; + + v.push_back(m); + } + return v; } -- cgit v1.2.3