summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2012-05-17 11:43:16 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2012-05-17 11:43:16 +0200
commit4873e6df45424d2132dc9685f76bcbe2d9dd447e (patch)
tree85fb65d5c01ebcbda99fe24932088e551d527e75
parent640dadc93410e1caf9fef1ed0b9c606ea68187c1 (diff)
Make persistent store (XML).
-rw-r--r--src/taskmanager.cc68
-rw-r--r--src/taskmanager.h6
-rw-r--r--src/tasktree.cc58
-rw-r--r--src/tasktree.h19
-rw-r--r--src/xmlparser.cc83
-rw-r--r--src/xmlparser.h27
6 files changed, 164 insertions, 97 deletions
diff --git a/src/taskmanager.cc b/src/taskmanager.cc
index 87cf2b0..6ebffd5 100644
--- a/src/taskmanager.cc
+++ b/src/taskmanager.cc
@@ -44,29 +44,45 @@ static bool isProtected(taskid_t id)
return id < FIRST_TASK_ID;
}
-TaskManager::TaskManager() {
+TaskManager::TaskManager(std::string file) {
idCount = FIRST_TASK_ID;
- task_t t;
- t.title = "root";
- t.id = ROOT_ID;
- tree.insertAsChild(0, ROOT_ID, t);
+ this->file = file;
+
+ FILE *fp = fopen(file.c_str(), "r");
+ if(fp) {
+ std::string xml;
+ while(!feof(fp)) {
+ char buf[64];
+ size_t sz = fread(buf, 1, sizeof(buf), fp);
+ xml.append(buf, sz);
+ }
+ tree.fromXML(xml);
+ fclose(fp);
+ } else {
- t.title = "Finished";
- t.id = FINISHED_ID;
- tree.insertAsChild(ROOT_ID, FINISHED_ID, t);
+ // Create new basis config
+ task_t t;
+ t.title = "root";
+ t.id = ROOT_ID;
+ tree.insertAsChild(0, ROOT_ID, t);
- t.title = "Backlog";
- t.id = BACKLOG_ID;
- tree.insertAsChild(ROOT_ID, BACKLOG_ID, t);
+ t.title = "Finished";
+ t.id = FINISHED_ID;
+ tree.insertAsChild(ROOT_ID, FINISHED_ID, t);
- t.title = "Lost+Found";
- t.id = LOSTFOUND_ID;
- tree.insertAsChild(ROOT_ID, LOSTFOUND_ID, t);
+ t.title = "Backlog";
+ t.id = BACKLOG_ID;
+ tree.insertAsChild(ROOT_ID, BACKLOG_ID, t);
- t.title = "Projects";
- t.id = PROJECTS_ID;
- tree.insertAsChild(ROOT_ID, PROJECTS_ID, t);
+ t.title = "Lost+Found";
+ t.id = LOSTFOUND_ID;
+ tree.insertAsChild(ROOT_ID, LOSTFOUND_ID, t);
+
+ t.title = "Projects";
+ t.id = PROJECTS_ID;
+ tree.insertAsChild(ROOT_ID, PROJECTS_ID, t);
+ }
tree.toStdOut();
}
@@ -96,6 +112,8 @@ TaskIdList TaskManager::moveTask(taskid_t id, taskid_t to)
throw e;
}
+ flushTasks();
+
return affectedTasks;
}
@@ -115,6 +133,8 @@ TaskIdList TaskManager::removeTask(taskid_t id)
throw e;
}
+ flushTasks();
+
return affectedTasks;
}
@@ -132,6 +152,8 @@ TaskIdList TaskManager::updateTask(taskid_t id, task_t t)
throw e;
}
+ flushTasks();
+
return affectedTasks;
}
@@ -152,6 +174,8 @@ TaskIdList TaskManager::createTask(taskid_t parentid, taskid_t *pid)
throw e;
}
+ flushTasks();
+
return affectedTasks;
}
@@ -188,6 +212,16 @@ TaskIdList TaskManager::ancestorList(taskid_t id)
}
*/
+void TaskManager::flushTasks()
+{
+ FILE *fp = fopen(file.c_str(), "w");
+ if(!fp) return;
+ std::string xml = tree.toXML();
+ fwrite(xml.c_str(), xml.size(), 1, fp);
+ fclose(fp);
+}
+
+
#if 0
TaskList tasklist;
diff --git a/src/taskmanager.h b/src/taskmanager.h
index dc0cf1c..fbd38ec 100644
--- a/src/taskmanager.h
+++ b/src/taskmanager.h
@@ -38,7 +38,7 @@
class TaskManager {
public:
- TaskManager();
+ TaskManager(std::string file = "/tmp/munia.xml");
~TaskManager();
TaskIdList createTask(taskid_t parentid, taskid_t *id) throw (std::exception);
@@ -52,11 +52,15 @@ public:
task_t task(taskid_t t);
+ void flushTasks();
+
private:
// TaskIdList ancestorList(taskid_t task);
taskid_t createId();
taskid_t idCount;
task_t nextTask();
+
+ std::string file;
};
extern TaskManager task_manager;
diff --git a/src/tasktree.cc b/src/tasktree.cc
index fc84efa..2576600 100644
--- a/src/tasktree.cc
+++ b/src/tasktree.cc
@@ -27,10 +27,39 @@
*/
#include "tasktree.h"
+#include "xmlparser.h"
+
#include "debug.h"
+#include "xml_encode_decode.h"
+
#define ROOT_PARENT_ID -1
+static inline std::string id2str(taskid_t id)
+{
+ char buf[32];
+ sprintf(buf, "%u", id);
+ return buf;
+}
+
+std::string node::toXML(std::string prefix)
+{
+ std::string xml;
+
+ xml += prefix + "<task id=\""+id2str(id)+"\">\n";
+ xml += prefix + " <title>" + xml_encode(data.title) + "</title>\n";
+ xml += prefix + " <children>\n";
+ NodeList::iterator ni = children.begin();
+ while(ni != children.end()) {
+ xml += (*ni)->toXML(prefix + " ");
+ ni++;
+ }
+ xml += prefix + " </children>\n";
+ xml += prefix + "</task>\n";
+
+ return xml;
+}
+
static void concatTaskIdLists(TaskIdList& pre, TaskIdList& post) {
pre.insert(pre.end(), post.begin(), post.end());
// for(TaskIdList::iterator it = post.begin();
@@ -187,7 +216,7 @@ task_t TaskTree::data(taskid_t id)
try {
node_t* node = id2node.at(id);
task_t tmp = node->data;
- t.id = tmp.id;
+ t.id = node->id;
t.title = tmp.title;
// printf("!!!!t.id and tmp.id in data: %d and %d\n", t.id, tmp.id);
if(node->parent) t.parentid = node->parent->id;
@@ -267,14 +296,18 @@ node_t* TaskTree::createNode(taskid_t id) {
}
void TaskTree::insertChild(node_t* parent, node_t* child) {
- parent->children.push_back(child);
+ if(parent) parent->children.push_back(child);
+ else {
+ rootid = child->id;
+ root = child;
+ }
child->parent = parent;
}
static void printNode(node_t* node, std::string prefix) {
if(!node) return;
task_t t = node->data;
- printf("%s- %u - %s (%p)\n", prefix.c_str(), t.id, t.title.c_str(), node);
+ printf("%s- %u - %s (%p)\n", prefix.c_str(), node->id, t.title.c_str(), node);
NodeList::iterator it;
for(it = node->children.begin(); it != node->children.end(); it++) {
@@ -287,6 +320,25 @@ void TaskTree::toStdOut() {
printNode(root, "");
}
+std::string TaskTree::toXML()
+{
+ node_t *root = id2node.at(rootid);
+
+ std::string xml;
+ xml += "<?xml version='1.0' encoding='UTF-8'?>\n";
+ xml += "<tasktree>\n";
+ xml += root->toXML(" ");
+ xml += "</tasktree>";
+
+ return xml;
+}
+
+void TaskTree::fromXML(std::string xml)
+{
+ XmlParser p(this);
+ p.parse(xml.c_str(), xml.size());
+}
+
#ifdef TEST_TASKTREE
//Additional dependency files
diff --git a/src/tasktree.h b/src/tasktree.h
index d82b9a4..64ce0b6 100644
--- a/src/tasktree.h
+++ b/src/tasktree.h
@@ -34,18 +34,24 @@
#include "task.h"
-typedef struct node node_t;
+class node;
+typedef std::list<class node*> NodeList;
-typedef std::list<struct node*> NodeList;
-
-struct node {
+class node
+{
+public:
taskid_t id;
- node_t* parent;
+ node* parent;
task_t data;
NodeList children;
+
+ std::string toXML(std::string prefix);
};
+typedef node node_t;
+
class TaskTree {
+ friend class XmlParser;
public:
TaskTree();
~TaskTree();
@@ -62,6 +68,9 @@ public:
void toStdOut();
+ std::string toXML();
+ void fromXML(std::string xml);
+
private:
node_t* createNode(taskid_t id);
void insertChild(node_t* parent, node_t* child);
diff --git a/src/xmlparser.cc b/src/xmlparser.cc
index 97a8bdb..112ea00 100644
--- a/src/xmlparser.cc
+++ b/src/xmlparser.cc
@@ -31,73 +31,50 @@
#include "xml_encode_decode.h"
-XmlParser::XmlParser(std::string filename) {
- // open file handler
- fp = fopen(filename.c_str(), "r");
- if(!fp) {
- fprintf(stderr, "Could not open file\n");
- }
-
- task = NULL;
- tasklist.clear();
+#define NOID 0xffffffff
- open_tagtype = none;
+XmlParser::XmlParser(TaskTree *t) : tree(t)
+{
}
-XmlParser::~XmlParser() {
- // close file handler
- fclose(fp);
- if(task) delete task;
+XmlParser::~XmlParser()
+{
}
-void XmlParser::characterData(std::string& data) {
- characterbuf += data;
-
- /*
- switch(open_tagtype) {
- case title:
- // task->title += xml_decode(data);
- break;
- case desc:
- // task->desc += xml_decode(data);
- break;
- default:
- break;
- }
- */
+void XmlParser::characterData(const std::string &data)
+{
+ cdata += data;
}
-void XmlParser::startTag(std::string name, attributes_t &attr) {
- // printf("start: %s\n", name.c_str());
- characterbuf.clear();
+void XmlParser::startTag(std::string name, attributes_t &attr)
+{
if(name == "task") {
- if(task) delete task;
+ taskid_t id = atoi(xml_decode(attr["id"]).c_str());
+
+ node_t* parent = NULL;
+ if(parents.size() != 0) parent = tree->id2node.at(parents.top());
+
+ node = tree->createNode(id);
+ tree->insertChild(parent, node);
+ }
- task = new task_t();
- task->id = atoi(xml_decode(attr["id"]).c_str());
- // task->parent_id = atoi(xml_decode(attr["parent_id"]).c_str());
+ if(name == "children") {
+ parents.push(node->id);
}
+ cdata = "";
}
-void XmlParser::endTag(std::string name) {
- // printf("end: %s\n", name.c_str());
- if (name == "task") {
- // if(task) tasklist.push_back(*task);
- }
- else if (name == "title") {
- if(task) task->title = characterbuf;
- // open_tagtype = title;
+void XmlParser::endTag(std::string name)
+{
+ if(name == "task") {
}
- else if (name == "desc") {
- if(task) task->desc = characterbuf;
- // open_tagtype = desc;
+
+ if(name == "children") {
+ parents.pop();
}
- // open_tagtype = none;
-}
-int XmlParser::readData(char* data, size_t size) {
- if(!fp) return 0; // Could not read file
-
- return fread(data, 1, size, fp);
+ if (name == "title") {
+ node->data.title = cdata;
+ }
}
diff --git a/src/xmlparser.h b/src/xmlparser.h
index a92a515..6f05650 100644
--- a/src/xmlparser.h
+++ b/src/xmlparser.h
@@ -31,32 +31,23 @@
#include "task.h"
#include "saxparser.h"
+#include <stack>
+#include "tasktree.h"
+
class XmlParser : public SAXParser {
public:
- XmlParser(std::string filename);
+ XmlParser(TaskTree *tree);
~XmlParser();
void startTag(std::string name, attributes_t &attr);
void endTag(std::string name);
- void characterData(std::string& data);
-
- TaskIdList tasklist;
-
-protected:
- int readData(char* data, size_t size);
+ void characterData(const std::string &data);
private:
- FILE* fp;
- task_t* task;
- std::string characterbuf;
-
- enum tag_t {
- title,
- desc,
- none
- };
-
- tag_t open_tagtype;
+ std::stack<taskid_t> parents;
+ std::string cdata;
+ node_t *node;
+ TaskTree *tree;
};
#endif/*__MUNIA_XMLPARSER_H__*/