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/Makefile.am | 2 +- src/msgparser.cc | 154 ++++++++++++++++++++++++++++++++++++++++++++---------- src/task_proto.cc | 7 ++- 3 files changed, 131 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 1aff748..d16b041 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,7 +4,7 @@ bin_PROGRAMS = muniad muniad_LDADD = $(LIBWEBSOCKETS_LIBS) -muniad_CXXFLAGS = $(LIBWEBSOCKETS_CFLAGS) +muniad_CXXFLAGS = $(LIBWEBSOCKETS_CFLAGS) -I/usr/local/include muniad_SOURCES = \ muniad.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; } diff --git a/src/task_proto.cc b/src/task_proto.cc index f1d22d1..39232dd 100644 --- a/src/task_proto.cc +++ b/src/task_proto.cc @@ -172,8 +172,10 @@ int callback_lws_task(struct libwebsocket_context * context, char buf[1024]; size_t buf_len = 0; - msg_t m = parse_msg(data)[0]; - + MsgVector msglist = parse_msg(data); + MsgVector::iterator it_msg; + for(it_msg = msglist.begin(); it_msg != msglist.end(); it_msg++) { + msg_t m = *it_msg; switch(m.cmd) { case cmd::add: { printf("Handling add cmd:\n"); @@ -279,6 +281,7 @@ int callback_lws_task(struct libwebsocket_context * context, libwebsocket_callback_on_writable_all_protocol(libwebsockets_get_protocol(wsi)); //libwebsocket_rx_flow_control(wsi, 0); } + } break; /* * this just demonstrates how to use the protocol filter. If you won't -- cgit v1.2.3