diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-03-03 19:16:30 +0100 |
---|---|---|
committer | Andreas Stöckel <andreas@somweyr.de> | 2015-03-03 19:16:30 +0100 |
commit | b730f4d9cc092f8ab2d7c71853431042d75d5d08 (patch) | |
tree | 9922b245fbd33ca5a60b901003e8e9b606bd5699 /src | |
parent | 2a5e714d1d222cc5e27fc442c56c1a880df573d2 (diff) | |
parent | 68c66558cd7c8e64dd0d3b934ccb58603f8b9836 (diff) |
Merge branch 'master' of ssh://somweyr.de/var/local/git/ousia
Diffstat (limited to 'src')
-rw-r--r-- | src/core/model/Document.cpp | 33 | ||||
-rw-r--r-- | src/core/model/Document.hpp | 22 |
2 files changed, 35 insertions, 20 deletions
diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp index 40c03ac..219e512 100644 --- a/src/core/model/Document.cpp +++ b/src/core/model/Document.cpp @@ -327,8 +327,10 @@ void DocumentEntity::addStructureNode(Handle<StructureNode> s, size_t i) if (par != nullptr) { if (par->isa(&RttiTypes::StructuredEntity)) { par.cast<StructuredEntity>()->removeStructureNode(s); - } else { + } else if(par->isa(&RttiTypes::AnnotationEntity)){ par.cast<AnnotationEntity>()->removeStructureNode(s); + } else if(par->isa(&RttiTypes::Document)){ + par.cast<Document>()->setRoot(nullptr); } } s->setParent(subInst); @@ -463,7 +465,7 @@ static bool matchStartAnchor(Handle<AnnotationClass> desc, template <typename Iterator> Rooted<Anchor> DocumentEntity::searchStartAnchorInField( Handle<AnnotationClass> desc, const std::string &name, Iterator begin, - Iterator end) + Iterator end, std::unordered_set<const DocumentEntity *> &visited) { for (Iterator it = begin; it != end; it++) { Handle<StructureNode> strct = *it; @@ -478,7 +480,7 @@ Rooted<Anchor> DocumentEntity::searchStartAnchorInField( // search downwards. Rooted<Anchor> a = strct.cast<StructuredEntity>()->searchStartAnchorDownwards( - desc, name); + desc, name, visited); if (a != nullptr) { return a; } @@ -488,8 +490,12 @@ Rooted<Anchor> DocumentEntity::searchStartAnchorInField( } Rooted<Anchor> DocumentEntity::searchStartAnchorDownwards( - Handle<AnnotationClass> desc, const std::string &name) + Handle<AnnotationClass> desc, const std::string &name, + std::unordered_set<const DocumentEntity *> &visited) { + if (!visited.insert(this).second) { + return nullptr; + } if (fields.empty()) { return nullptr; } @@ -497,13 +503,17 @@ Rooted<Anchor> DocumentEntity::searchStartAnchorDownwards( NodeVector<StructureNode> children = fields[fields.size() - 1]; // search it from back to front. return searchStartAnchorInField(desc, name, children.rbegin(), - children.rend()); + children.rend(), visited); } Rooted<Anchor> DocumentEntity::searchStartAnchorUpwards( Handle<AnnotationClass> desc, const std::string &name, - const DocumentEntity *child) + const DocumentEntity *child, + std::unordered_set<const DocumentEntity *> &visited) { + if (!visited.insert(this).second) { + return nullptr; + } if (fields.empty()) { return nullptr; } @@ -519,7 +529,8 @@ Rooted<Anchor> DocumentEntity::searchStartAnchorUpwards( // to the child. if (it != children.rend()) { it++; - return searchStartAnchorInField(desc, name, it, children.rend()); + return searchStartAnchorInField(desc, name, it, children.rend(), + visited); } throw OusiaException("Internal error: Child node not found in parent!"); } @@ -528,11 +539,13 @@ Rooted<Anchor> DocumentEntity::searchStartAnchor(size_t fieldIdx, Handle<AnnotationClass> desc, const std::string &name) { + std::unordered_set<const DocumentEntity *> visited; + visited.insert(this); // get the correct field. NodeVector<StructureNode> children = fields[fieldIdx]; // search it from back to front. Rooted<Anchor> a = searchStartAnchorInField(desc, name, children.rbegin(), - children.rend()); + children.rend(), visited); // if we found the Anchor, return it. if (a != nullptr) { return a; @@ -548,11 +561,11 @@ Rooted<Anchor> DocumentEntity::searchStartAnchor(size_t fieldIdx, if (subInst->getParent()->isa(&RttiTypes::StructuredEntity)) { return subInst->getParent() .cast<StructuredEntity>() - ->searchStartAnchorUpwards(desc, name, this); + ->searchStartAnchorUpwards(desc, name, this, visited); } if (subInst->getParent()->isa(&RttiTypes::AnnotationEntity)) { subInst->getParent().cast<AnnotationEntity>()->searchStartAnchorUpwards( - desc, name, this); + desc, name, this, visited); } return nullptr; } diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp index 8019379..6b2ae47 100644 --- a/src/core/model/Document.hpp +++ b/src/core/model/Document.hpp @@ -157,16 +157,18 @@ private: void invalidateSubInstance(); template <typename Iterator> - Rooted<Anchor> searchStartAnchorInField(Handle<AnnotationClass> desc, - const std::string &name, - Iterator begin, Iterator end); - - Rooted<Anchor> searchStartAnchorDownwards(Handle<AnnotationClass> desc, - const std::string &name); - - Rooted<Anchor> searchStartAnchorUpwards(Handle<AnnotationClass> desc, - const std::string &name, - const DocumentEntity *child); + Rooted<Anchor> searchStartAnchorInField( + Handle<AnnotationClass> desc, const std::string &name, Iterator begin, + Iterator end, std::unordered_set<const DocumentEntity *> &visited); + + Rooted<Anchor> searchStartAnchorDownwards( + Handle<AnnotationClass> desc, const std::string &name, + std::unordered_set<const DocumentEntity *> &visited); + + Rooted<Anchor> searchStartAnchorUpwards( + Handle<AnnotationClass> desc, const std::string &name, + const DocumentEntity *child, + std::unordered_set<const DocumentEntity *> &visited); protected: bool doValidate(Logger &logger) const; |