deepnodelistimpl.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 212 行

CPP
212
字号
/* * Copyright 1999-2002,2004 The Apache Software Foundation. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: DeepNodeListImpl.cpp,v 1.5 2004/09/08 13:55:43 peiyongz Exp $ */#include "DeepNodeListImpl.hpp"#include "NodeVector.hpp"#include "NodeImpl.hpp"#include "ElementImpl.hpp"#include "DStringPool.hpp"#include "DocumentImpl.hpp"#include <limits.h>XERCES_CPP_NAMESPACE_BEGINstatic DOMString *kAstr = 0;static XMLRegisterCleanup kAstrCleanup;DeepNodeListImpl::DeepNodeListImpl(NodeImpl *rootNod, const DOMString &tagNam){    changes = 0;    this->rootNode = rootNod;    this->tagName = tagNam;    MemoryManager* manager= rootNod->getDocument()->getMemoryManager();    nodes=new (manager) NodeVector(manager);    matchAll = tagName.equals(DStringPool::getStaticString("*"                                                         , &kAstr                                                         , reinitDeepNodeListImpl                                                         , kAstrCleanup));    this->namespaceURI = null;	//DOM Level 2    this->matchAllURI = false;	//DOM Level 2    this->matchURIandTagname = false;	//DOM Level 2};//DOM Level 2DeepNodeListImpl::DeepNodeListImpl(NodeImpl *rootNod,    const DOMString &fNamespaceURI, const DOMString &localName){    changes = 0;    this->rootNode = rootNod;    this->tagName = localName;    MemoryManager* manager = rootNod->getDocument()->getMemoryManager();    nodes=new (manager) NodeVector(manager);    matchAll = tagName.equals(DStringPool::getStaticString("*"                                                         , &kAstr                                                         , reinitDeepNodeListImpl                                                         , kAstrCleanup));    this->namespaceURI = fNamespaceURI;    this->matchAllURI = fNamespaceURI.equals(DStringPool::getStaticString("*"                                                                        , &kAstr                                                                        , reinitDeepNodeListImpl                                                                        , kAstrCleanup));    this->matchURIandTagname = true;};DeepNodeListImpl::~DeepNodeListImpl(){    delete nodes;};unsigned int DeepNodeListImpl::getLength(){    // Preload all matching elements. (Stops when we run out of subtree!)    item(INT_MAX);    return nodes->size();};// Start from the first child and count forward, 0-based. index>length-1// should return null.//// 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.NodeImpl *DeepNodeListImpl::item(unsigned int index){    NodeImpl *thisNode;    if(rootNode->changes() != changes)    {        nodes->reset();     // Tree changed. Do it all from scratch!        changes = rootNode->changes();    }    if(index< nodes->size())      // In the cache        return nodes->elementAt((int) index);    else                        // Not yet seen    {        if(nodes->size()==0)     // Pick up where we left off            thisNode=rootNode; // (Which may be the beginning)        else            thisNode=nodes->lastElement();        while(thisNode!=null && index >= nodes->size() && thisNode!=null)        {            thisNode=nextMatchingElementAfter(thisNode);            if(thisNode!=null)                nodes->addElement(thisNode);        }        return thisNode;           // Either what we want, or null (not avail.)    }};/* Iterative tree-walker. When you have a Parent link, there's often noneed to resort to recursion. NOTE THAT only Element nodes are matchedsince we're specifically supporting getElementsByTagName().*/NodeImpl *DeepNodeListImpl::nextMatchingElementAfter(NodeImpl *current){    NodeImpl *next;    while (current != null)    {        // Look down to first child.        if (current->hasChildNodes())        {            current = current->getFirstChild();        }        // Look right to sibling (but not from root!)        else        {            if (current != rootNode && null != (next = current->getNextSibling()))            {                current = next;            }            // Look up and right (but not past root!)            else            {                next = null;                for (; current != rootNode; // Stop when we return to starting point                current = current->getParentNode())                {                    next = current->getNextSibling();                    if (next != null)                        break;                }                current = next;            }        }        // Have we found an Element with the right tagName?        // ("*" matches anything.)        if (current != null && current != rootNode && current->isElementImpl()) {	    if (!matchURIandTagname) {	//DOM Level 1		if (matchAll || ((ElementImpl *)current)->getTagName().equals(tagName))		    return current;	    } else {	//DOM Level 2		if (!matchAllURI && !(current -> getNamespaceURI().equals(namespaceURI)))		    continue;		if (matchAll || current -> getLocalName().equals(tagName))		    return current;	    }	}        // Otherwise continue walking the tree    }    // Fell out of tree-walk; no more instances found    return null;};////  unreferenced()      The RefCountedImpl base class calls back to this function//                      when the ref count goes to zero.////void DeepNodeListImpl::unreferenced(){//    delete this;      DeepNodeListImpl* ptr = this;      delete ptr;};// -----------------------------------------------------------------------//  Notification that lazy data has been deleted// -----------------------------------------------------------------------void DeepNodeListImpl::reinitDeepNodeListImpl() {	delete kAstr;	kAstr = 0;}XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?