// Start from the first child and count forward, 0-based. index>length-1 // should return 0. // // Attempts to do only work actually requested, cache work already // done, and to flush that cache when the tree has changed. // // LIMITATION: ????? Unable to tell relevant tree-changes from // irrelevant ones. Doing so in a really useful manner would seem // to involve a tree-walk in its own right, or maintaining our data // in a parallel tree. DOMNode *DOMDeepNodeListImpl::cacheItem(XMLSize_t index) { XMLSize_t currentIndexPlus1 = fCurrentIndexPlus1; DOMNode *currentNode = fCurrentNode; if (castToParentImpl(fRootNode)->changes() != fChanges) { // Tree changed. Do it all from scratch! currentIndexPlus1 = 0; currentNode = (DOMNode *)fRootNode; fChanges = castToParentImpl(fRootNode)->changes(); } else if (currentIndexPlus1 > index+1) { // Interested in something before cached node. Do it all from scratch! currentIndexPlus1 = 0; currentNode = (DOMNode *)fRootNode; } else if (index+1 == currentIndexPlus1) { // What luck! User is interested in cached node. return currentNode; } DOMNode *nextNode = 0; // revisit - ???? How efficient is this loop? ???? // Start at the place in the tree at which we're // currently pointing and count off nodes until we // reach the node of interest or the end of the tree. while (currentIndexPlus1 < index+1 && currentNode != 0) { nextNode = nextMatchingElementAfter(currentNode); if (nextNode == 0) break; currentNode = nextNode; currentIndexPlus1++; } fCurrentNode = currentNode; fCurrentIndexPlus1 = currentIndexPlus1; // If we found a node at the requested index, make that the current node if (nextNode != 0) { return currentNode; } // If we didn't find a node at the requested index, return 0 return 0; }
DOMDocumentFragmentImpl::DOMDocumentFragmentImpl(const DOMDocumentFragmentImpl &other, bool deep) : fNode(other.fNode), fParent(other.fParent) { if (deep) castToParentImpl(this)->cloneChildren(&other); }
DOMCDATASectionImpl::DOMCDATASectionImpl(const DOMCDATASectionImpl &other, bool) : fNode(*castToNodeImpl(&other)), fParent(*castToParentImpl(&other)), fChild(*castToChildImpl(&other)), fCharacterData(other.fCharacterData) { // revisit. SOmething nees to make "deep" work. }
DOMNode *DOMNodeListImpl::item(XMLSize_t index) const{ if (fNode) { DOMNode *node = castToParentImpl(fNode)->fFirstChild; for(XMLSize_t i=0; i<index && node!=0; ++i) node = castToChildImpl(node)->nextSibling; return node; } return 0; }
XMLSize_t DOMNodeListImpl::getLength() const{ XMLSize_t count = 0; if (fNode) { DOMNode *node = castToParentImpl(fNode)->fFirstChild; while(node != 0){ ++count; node = castToChildImpl(node)->nextSibling; } } return count; }