summaryrefslogtreecommitdiff
path: root/src/nodetree.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/nodetree.cc')
-rw-r--r--src/nodetree.cc266
1 files changed, 128 insertions, 138 deletions
diff --git a/src/nodetree.cc b/src/nodetree.cc
index a2499ea..f0877ff 100644
--- a/src/nodetree.cc
+++ b/src/nodetree.cc
@@ -34,6 +34,7 @@
#include "hugin.hpp"
#include "xml_encode_decode.h"
+#include "exceptions.h"
#define ROOT_PARENT_ID -1
@@ -75,22 +76,14 @@ std::string Node::toXML(std::string prefix)
static void concatNodeIdLists(NodeIdList& pre, NodeIdList& post)
{
pre.insert(pre.end(), post.begin(), post.end());
- //for(NodeIdList::iterator it = post.begin();
- //it != post.end(); it++)
- //{
- // pre.push_back(
- //}
}
NodeTree::NodeTree()
{
- root = NULL;
- nextid = 10;
}
NodeTree::~NodeTree()
{
- // cleanup tree
}
nodeid_t NodeTree::createId()
@@ -106,7 +99,7 @@ nodeid_t NodeTree::createId()
return nodeid;
}
-bool NodeTree::hasId(nodeid_t nodeid)
+bool NodeTree::hasId(nodeid_t nodeid) const
{
return id2node.find(nodeid) != id2node.end();
}
@@ -115,11 +108,15 @@ static nodeid_t rootid = -1;
NodeIdList NodeTree::insertAsChild(nodeid_t parentid, nodeid_t id,
node_t data, nodeid_t insertBeforeId)
- throw (std::exception)
{
NodeIdList affectedNodes;
- // Initialize
+ if(parentid == id)
+ {
+ throw Error::NewParentIsSelf(); // Node and new parent are the same node.
+ }
+
+ // Initialized?
if(!root)
{
rootid = id;
@@ -130,62 +127,46 @@ NodeIdList NodeTree::insertAsChild(nodeid_t parentid, nodeid_t id,
}
else
{
- try
+ if(!hasId(parentid))
{
- Node* parent = id2node.at(parentid);
- Node* child = createNode(id);
- //DEBUG(nodetree, "!!!!!!!id in insert: %d\n", data.id);
- child->data = data;
- insertChild(parent, child, insertBeforeId);
-
- //affectedNodes.push_back(parentid);
- affectedNodes.push_back(id);
- NodeIdList ancestors = ancestorList(id);
- concatNodeIdLists(affectedNodes, ancestors);
- }
- catch(std::exception& e)
- {
- throw e;
+ throw Error::MissingParent();
}
+
+ Node* parent = id2node.at(parentid);
+ Node* child = createNode(id);
+
+ child->data = data;
+ insertChild(parent, child, insertBeforeId);
+ affectedNodes.push_back(id);
+
+ NodeIdList ancestors = ancestorList(id);
+ concatNodeIdLists(affectedNodes, ancestors);
}
- //DEBUG(nodetree, "Child %d added to %d, affecting %d nodes\n",
- // id, parentid, affectedNodes.size());
return affectedNodes;
}
NodeIdList NodeTree::remove(nodeid_t id)
- throw (std::exception)
{
+ if(!hasId(id))
+ {
+ throw Error::NoSuchId();
+ }
+
NodeIdList affectedNodes;
affectedNodes.push_back(id);
NodeIdList ancestors = ancestorList(id);
concatNodeIdLists(affectedNodes, ancestors);
- //DEBUG(nodetree, "Removing %d\n", id);
- //DEBUG(nodetree, "!!!!!affected nodes %d\n", affectedNodes.size());
-
- Node* node = id2node[id];
-
- //DEBUG(nodetree, "node: %p, id %d, parent %p\n", node, node->data.id, node->parent);
+ Node* node = id2node.at(id);
- //DEBUG(nodetree, "!!!!!size %d\n", node->parent->children.size());
node->parent->children.remove(node);
- for(NodeList::iterator it = node->parent->children.begin();
- it != node->parent->children.end();
- it++)
- {
- //DEBUG(nodetree, "%p\n", *it);
- }
- //DEBUG(nodetree, "!!!!!size %d\n", node->parent->children.size());
NodeIdList idlist = bfs(id);
NodeIdList::reverse_iterator it = idlist.rbegin();
while(it != idlist.rend())
{
node_t node = data(*it);
- //Node* n = id2node[node.id];
- //delete(n);
it++;
}
@@ -208,112 +189,114 @@ static bool findNode(Node *needle, Node *haystack)
}
NodeIdList NodeTree::move(nodeid_t id, nodeid_t toid, nodeid_t beforeId)
- throw (std::exception)
{
NodeIdList affectedNodes;
- try
+ if(id == toid)
{
- Node* child = id2node.at(id);
- Node* newparent = id2node.at(toid);
+ throw Error::NewParentIsSelf(); // Node and new parent are the same node.
+ }
- // Test if new parent is a child of the node itself...
- if(findNode(newparent, child))
- {
- throw std::exception();
- }
+ if(!hasId(id))
+ {
+ throw Error::NoSuchId();
+ }
- if(!child->parent)
- {
- throw std::exception();
- }
+ Node* child = id2node.at(id);
- child->parent->children.remove(child);
- bool inserted{false};
- for(auto it = newparent->children.begin();
- it != newparent->children.end();
- ++it)
- {
- if((*it)->id == beforeId)
- {
- newparent->children.insert(it, child);
- inserted = true;
- }
- }
- if(!inserted)
- {
- // beforeId was not found in parent - inserting last instead.
- newparent->children.push_back(child);
- }
+ if(!hasId(toid))
+ {
+ throw Error::MissingParent();
+ }
- child->parent = newparent;
+ Node* newparent = id2node.at(toid);
- affectedNodes.push_back(id);
- // affectedNodes.push_back(child->parent->id);
- NodeIdList ancestors = ancestorList(id);
- concatNodeIdLists(affectedNodes, ancestors);
- affectedNodes.push_back(toid);
- ancestors = ancestorList(toid);
+ // Test if new parent is a child of the node itself...
+ if(findNode(newparent, child))
+ {
+ throw Error::NewParentIsChildOfSelf();
+ }
+
+ if(!child->parent)
+ {
+ throw Error::System("Node does not have a parent.");
+ }
+
+ child->parent->children.remove(child);
+ bool inserted{false};
+ for(auto it = newparent->children.begin();
+ it != newparent->children.end();
+ ++it)
+ {
+ if((*it)->id == beforeId)
+ {
+ newparent->children.insert(it, child);
+ inserted = true;
+ }
}
- catch(std::exception& e)
+ if(!inserted)
{
- throw e;
+ // beforeId was not found in parent - inserting last instead.
+ newparent->children.push_back(child);
}
+ child->parent = newparent;
+
+ affectedNodes.push_back(id);
+
+ NodeIdList ancestors = ancestorList(id);
+ concatNodeIdLists(affectedNodes, ancestors);
+ affectedNodes.push_back(toid);
+ ancestors = ancestorList(toid);
+
return affectedNodes;
}
NodeIdList NodeTree::updateData(nodeid_t id, const std::string &name,
const std::string &value)
- throw (std::exception)
{
+ if(!hasId(id))
+ {
+ throw Error::NoSuchId();
+ }
+
NodeIdList affectedNodes;
- try
- {
- Node* node = id2node.at(id);
- node->data.attributes[name] = value;
+ Node* node = id2node.at(id);
+ node->data.attributes[name] = value;
- affectedNodes.push_back(id);
- NodeIdList ancestors = ancestorList(id);
- concatNodeIdLists(affectedNodes, ancestors);
- }
- catch(std::exception& e)
- {
- throw e;
- }
+ affectedNodes.push_back(id);
+ NodeIdList ancestors = ancestorList(id);
+ concatNodeIdLists(affectedNodes, ancestors);
return affectedNodes;
}
node_t NodeTree::data(nodeid_t id)
- throw (std::exception)
{
+ if(!hasId(id))
+ {
+ throw Error::NoSuchId();
+ }
+
node_t t;
- try
+ Node* node = id2node.at(id);
+ node_t tmp = node->data;
+ t.id = node->id;
+ t.attributes = tmp.attributes;
+
+ if(node->parent)
{
- Node* node = id2node.at(id);
- node_t tmp = node->data;
- t.id = node->id;
- t.attributes = tmp.attributes;
- //DEBUG(nodetree, "!!!!t.id and tmp.id in data: %d and %d\n", t.id, tmp.id);
- if(node->parent)
- {
- t.parentid = node->parent->id;
- }
- else
- {
- if(t.id != rootid)
- {
- throw std::exception();
- }
- t.parentid = -1;
- }
+ t.parentid = node->parent->id;
}
- catch(std::exception& e)
+ else
{
- throw e;
+ if(t.id != rootid)
+ {
+ throw Error::System("Node has no parent, but node is not root.");
+ }
+ t.parentid = -1;
}
return t;
@@ -321,8 +304,12 @@ node_t NodeTree::data(nodeid_t id)
// bfs search from id in tree
NodeIdList NodeTree::bfs(nodeid_t id)
- throw (std::exception)
{
+ if(!hasId(id))
+ {
+ throw Error::NoSuchId();
+ }
+
NodeIdList lst;
lst.push_back(id);
@@ -353,35 +340,36 @@ NodeIdList NodeTree::bfs(nodeid_t id)
}
NodeIdList NodeTree::ancestorList(nodeid_t id)
- throw (std::exception)
{
NodeIdList ancestors;
- try
+ if(!hasId(id))
{
- Node* current = id2node.at(id);
- while(current->parent)
- {
- ancestors.push_back(current->parent->id);
- current = current->parent;
- }
+ throw Error::NoSuchId();
}
- catch(std::exception& e)
+
+ Node* current = id2node.at(id);
+ auto origin = current;
+ while(current->parent)
{
- throw e;
+ ancestors.push_back(current->parent->id);
+ current = current->parent;
+ if(current == origin)
+ {
+ throw Error::System("Cycle detected.");
+ }
}
- //DEBUG(nodetree, "Collected %d ancestors to %u\n", ancestors.size(), id);
- //for(NodeIdList::iterator it = ancestors.begin();
- // it != ancestors.end(); it++)
- //{
- // DEBUG(nodetree, "\tancestor %u\n", *it);
- //}
return ancestors;
}
Node* NodeTree::createNode(nodeid_t id)
{
+ if(hasId(id))
+ {
+ throw Error::IdAlreadyExists();
+ }
+
Node* node = new Node();
node->parent = NULL;
node->id = id;
@@ -425,6 +413,7 @@ static void printNode(Node* node, std::string prefix)
{
return;
}
+
node_t t = node->data;
DEBUG(nodetree, "%s- %u - %s (%p)\n", prefix.c_str(), (int)node->id,
t.attributes["title"].c_str(), node);
@@ -444,12 +433,13 @@ void NodeTree::toStdOut()
std::string NodeTree::toXML()
{
- Node *root = id2node.at(rootid);
-
std::string xml;
xml += "<?xml version='1.0' encoding='UTF-8'?>\n";
xml += "<nodetree nextid=\""+id2str(nextid)+"\">\n";
- xml += root->toXML(" ");
+ if(root)
+ {
+ xml += root->toXML(" ");
+ }
xml += "</nodetree>";
return xml;