summaryrefslogtreecommitdiff
path: root/src/messageparser.cc
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2012-03-30 11:14:00 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2012-03-30 11:14:00 +0200
commit69cb3c171df31efab500ae87146c35ace6f92db3 (patch)
treea21495e4a2cafea196087547aff52edb57b8558b /src/messageparser.cc
parentf3403c20af7c36ce9ccd157f66187525917eeb7a (diff)
Rename message parser to correct file name.
Diffstat (limited to 'src/messageparser.cc')
-rw-r--r--src/messageparser.cc228
1 files changed, 228 insertions, 0 deletions
diff --git a/src/messageparser.cc b/src/messageparser.cc
new file mode 100644
index 0000000..86583e0
--- /dev/null
+++ b/src/messageparser.cc
@@ -0,0 +1,228 @@
+/* -*- 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 <stdlib.h>
+#include <stdio.h>
+#include <list>
+#include <vector>
+
+typedef std::vector<std::string> TokenVector;
+typedef std::list<TokenVector> MsgTokensList;
+
+inline static void parse_into_msg_tokens(std::string& data,
+ MsgTokensList& msgTokensList) {
+ TokenVector tokenVector;
+ 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());
+ tokenVector.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()) {
+ tokenVector.push_back(token);
+ }
+ msgTokensList.push_back(tokenVector);
+ tokenVector.clear();
+ token.clear();
+ break;
+ default:
+// printf("Appending %c\n", ch);
+ token += ch;
+ break;
+ }
+ prev_ch = ch;
+ }
+
+ if(!token.empty()) {
+ tokenVector.push_back(token);
+ token.clear();
+ }
+
+ if(!tokenVector.empty()) {
+ msgTokensList.push_back(tokenVector);
+ tokenVector.clear();
+ }
+}
+
+inline static void create_msg_list(MsgTokensList& msgTokensList, MsgList& msgList) {
+ MsgTokensList::iterator it_msg;
+ for(it_msg = msgTokensList.begin(); it_msg != msgTokensList.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.parentid = atoi(t[3].c_str());
+ printf("addcmd: %s %s %d\n", m.add.title, m.add.desc, m.add.parentid);
+ 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.parentid = atoi(t[2].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;
+ };
+ msgList.push_back(m);
+ }
+}
+
+MsgList parse_msg(std::string data) {
+ printf("Parsing: %s\n", data.c_str());
+
+ MsgTokensList msgTokensList;
+ parse_into_msg_tokens(data, msgTokensList);
+
+ MsgList msgList;
+ create_msg_list(msgTokensList, msgList);
+
+ return msgList;
+}
+
+std::string msg_tostring(msg_t m) {
+ char* buf = NULL;
+ switch(m.cmd) {
+ case cmd::add: {
+ asprintf(&buf, "add %d \"%s\" \"%s\" %d;",
+ m.add.id,
+ m.add.title, m.add.desc,
+ m.add.parentid);
+ break;
+ }
+ case cmd::del: {
+ asprintf(&buf, "del %d;", m.del.id);
+ break;
+ }
+ case cmd::move: {
+ asprintf(&buf, "move %d %d;", m.move.id, m.move.parentid);
+ 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;
+}
+
+#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*/