diff options
Diffstat (limited to 'src/core')
| -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;  | 
