/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set et sw=2 ts=2: */ /*************************************************************************** * msgparser.cc * * Fri Feb 24 14:59:34 CET 2012 * Copyright 2012 Jonas Suhr Christensen * jsc@umbraculum.org ****************************************************************************/ /* * This file is part of Munia. * * Munia 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. * * Munia 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 Munia; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "msgparser.h" #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); offset += title.length() + 1; std::string desc = data.substr(offset, data.find(' ', offset) - offset); offset += desc.length() + 1; std::string x_str = data.substr(offset, data.find(' ', offset) - offset); int x = atoi(x_str.c_str()); offset += x_str.length() + 1; std::string y_str = data.substr(offset, data.find(' ', offset) - offset); int y = atoi(y_str.c_str()); sprintf(m.add.title, "%s", desc.c_str()); sprintf(m.add.desc, "%s", desc.c_str()); m.add.x = x; m.add.y = y; } inline void parse_del(msg_t& m, std::string data) { int offset = 0; std::string id_str = data.substr(offset, data.find(' ', offset) - offset); int id = atoi(id_str.c_str()); m.del.id = id; } inline void parse_move(msg_t& m, std::string data) { int offset = 1; std::string s_id = data.substr(offset, data.find(' ', offset) - offset); int id = atoi(s_id.c_str()); offset += s_id.length() + 1; std::string x_str = data.substr(offset, data.find(' ', offset) - offset); int x = atoi(x_str.c_str()); offset += x_str.length() + 1; std::string y_str = data.substr(offset, data.find(' ', offset) - offset); int y = atoi(y_str.c_str()); m.move.id = id; m.move.x = x; m.move.y = y; } */ MsgVector parse_msg(std::string data) { 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(size_t 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; break; } 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 ';': if(inside_quote) { // printf("Appending %c\n", ch); token += ch; break; } // 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; } if(!token.empty()) { tokens.push_back(token); token.clear(); } if(!tokens.empty()) { msglist.push_back(tokens); tokens.clear(); } // 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() != 3+1) { printf("Wrong number of parameters\n"); continue; } sprintf(m.add.title, "%s", t[1].c_str()); sprintf(m.add.desc, "%s", t[2].c_str()); m.add.parent_id = atoi(t[3].c_str()); // m.add.x = atoi(t[3].c_str()); // m.add.y = atoi(t[4].c_str()); // printf("addcmd: %s %s %d %d\n", m.add.title, m.add.desc, m.add.x, m.add.y); 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() != 2+1) { printf("Wrong number of parameters\n"); continue; } m.move.id = atoi(t[1].c_str()); m.move.parent_id = atoi(t[2].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; } m.update.id = atoi(t[1].c_str()); sprintf(m.update.title, "%s", t[2].c_str()); sprintf(m.update.desc, "%s", t[3].c_str()); break; } default: break; }; v.push_back(m); } return v; } msg_t create_msg(cmd::cmd_t type, task_t t) { msg_t m; m.cmd = type; switch(type) { case cmd::add: { m.add.id = t.id; m.add.parent_id = t.parent_id; // m.add.x = t.x; // m.add.y = t.y; // m.add.title = t.title.c_str(); // m.add.desc = t.desc.c_str(); snprintf(m.add.title, sizeof(m.add.title), "%s", t.title.c_str()); snprintf(m.add.desc, sizeof(m.add.desc), "%s", t.desc.c_str()); break; } case cmd::del: { m.del.id = t.id; break; } case cmd::move: { m.move.id = t.id; // m.move.x = t.x; // m.move.y = t.y; m.move.parent_id = t.parent_id; break; } case cmd::update: { m.update.id = t.id; // m.update.title = t.title; // m.update.desc = t.desc; snprintf(m.update.title, sizeof(m.update.title), "%s", t.title.c_str()); snprintf(m.update.desc, sizeof(m.update.desc), "%s", t.desc.c_str()); // printf("msg: %d, %s, %s\n", m.update.id, m.update.title, m.update.desc); break; }; default: break; } return m; } //#define BUF_SIZE 4096 std::string msg_tostring(msg_t m) { // char buf[4096]; // buf[0] = '\0'; char* buf = NULL; switch(m.cmd) { case cmd::add: { // printf("msg: %d, %d, %d, %s, %s\n", m.add.id, m.add.x, m.add.y, m.add.title, m.add.desc); // snprintf(buf, BUF_SIZE, "add %d %s %s %d %d;", // asprintf(&buf, "add %d \"%s\" \"%s\" %d %d;", // m.add.id, // m.add.title, m.add.desc, // m.add.x, m.add.y); asprintf(&buf, "add %d \"%s\" \"%s\" %d;", m.add.id, m.add.title, m.add.desc, m.add.parent_id); break; } case cmd::del: { // snprintf(buf, BUF_SIZE, "del %d;", m.del.id); asprintf(&buf, "del %d;", m.del.id); break; } case cmd::move: { // snprintf(buf, BUF_SIZE, "move %d %d %d;", m.move.id, m.move.x, m.move.y); asprintf(&buf, "move %d %d;", m.move.id, m.move.parent_id); break; } case cmd::update: { //todo asprintf(&buf, "update %d \"%s\" \"%s\";", m.update.id, m.update.title, m.update.desc); break; }; default: break; } std::string r; if(buf) { r = buf; free(buf); } return r; // return buf; } #ifdef TEST_MSGPARSER //Additional dependency files //deps: //Required cflags (autoconf vars may be used) //cflags: //Required link options (autoconf vars may be used) //libs: #include "test.h" TEST_BEGIN; // TODO: Put some testcode here (see test.h for usable macros). TEST_TRUE(false, "No tests yet!"); TEST_END; #endif/*TEST_MSGPARSER*/