domdocumentimpl.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,362 行 · 第 1/3 页

CPP
1,362
字号
DOMNodeList *DOMDocumentImpl::getElementsByTagName(const XMLCh *tagname) const{    // cast off the const of this because we will update the fNodeListPool    return ((DOMDocumentImpl*)this)->getDeepNodeList(this,tagname);}DOMImplementation   *DOMDocumentImpl::getImplementation() const {    return DOMImplementation::getImplementation();}DOMNode *DOMDocumentImpl::insertBefore(DOMNode *newChild, DOMNode *refChild){    // Only one such child permitted    if(        (newChild->getNodeType() == DOMNode::ELEMENT_NODE  && fDocElement!=0)        ||        (newChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE  && fDocType!=0)        )        throw DOMException(DOMException::HIERARCHY_REQUEST_ERR,0, getMemoryManager());    // if the newChild is a documenttype node created from domimplementation, set the ownerDoc first    if ((newChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE) && !newChild->getOwnerDocument())        ((DOMDocumentTypeImpl*)newChild)->setOwnerDocument(this);    fParent.insertBefore(newChild,refChild);    // If insert succeeded, cache the kid appropriately    if(newChild->getNodeType() == DOMNode::ELEMENT_NODE)        fDocElement=(DOMElement *)newChild;    else if(newChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE)        fDocType=(DOMDocumentType *)newChild;    return newChild;}DOMNode* DOMDocumentImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild) {    DOMDocumentType* tempDocType = fDocType;    DOMElement* tempDocElement = fDocElement;    if(oldChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE)        fDocType=0;    else if(oldChild->getNodeType() == DOMNode::ELEMENT_NODE)        fDocElement=0;    try {        insertBefore(newChild, oldChild);        // changed() already done.        if((oldChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE)        || (oldChild->getNodeType() == DOMNode::ELEMENT_NODE))            return fParent.removeChild(oldChild);        else            return removeChild(oldChild);    }    catch(const OutOfMemoryException&)    {        throw;    }    catch(...) {        fDocType = tempDocType;        fDocElement = tempDocElement;        throw;    }}bool DOMDocumentImpl::isXMLName(const XMLCh *s){    if (XMLString::equals(fVersion, XMLUni::fgVersion1_1))        return XMLChar1_1::isValidName(s, XMLString::stringLen(s));    else        return XMLChar1_0::isValidName(s, XMLString::stringLen(s));}DOMNode *DOMDocumentImpl::removeChild(DOMNode *oldChild){    fParent.removeChild(oldChild);    // If remove succeeded, un-cache the kid appropriately    if(oldChild->getNodeType() == DOMNode::ELEMENT_NODE)        fDocElement=0;    else if(oldChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE)        fDocType=0;    return oldChild;}void DOMDocumentImpl::setNodeValue(const XMLCh *x){    fNode.setNodeValue(x);}//Introduced in DOM Level 2DOMNode *DOMDocumentImpl::importNode(DOMNode *source, bool deep){    return importNode(source, deep, false);}DOMElement *DOMDocumentImpl::createElementNS(const XMLCh *fNamespaceURI,    const XMLCh *qualifiedName){    if(!qualifiedName || !isXMLName(qualifiedName))        throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, getMemoryManager());    //XMLCh * pooledTagName = this->fNamePool->getPooledString(qualifiedName);    return new (this, DOMDocumentImpl::ELEMENT_NS_OBJECT) DOMElementNSImpl(this, fNamespaceURI, qualifiedName);}DOMElement *DOMDocumentImpl::createElementNS(const XMLCh *fNamespaceURI,                                              const XMLCh *qualifiedName,                                              const XMLSSize_t lineNo,                                              const XMLSSize_t columnNo){    if(!qualifiedName || !isXMLName(qualifiedName))        throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, getMemoryManager());    return new (this) XSDElementNSImpl(this, fNamespaceURI, qualifiedName, lineNo, columnNo);}DOMAttr *DOMDocumentImpl::createAttributeNS(const XMLCh *fNamespaceURI,    const XMLCh *qualifiedName){    if(!qualifiedName || !isXMLName(qualifiedName))        throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, getMemoryManager());    return new (this, DOMDocumentImpl::ATTR_NS_OBJECT) DOMAttrNSImpl(this, fNamespaceURI, qualifiedName);}DOMNodeList *DOMDocumentImpl::getElementsByTagNameNS(const XMLCh *fNamespaceURI,    const XMLCh *fLocalName)  const{    // cast off the const of this because we will update the fNodeListPool    return ((DOMDocumentImpl*)this)->getDeepNodeList(this, fNamespaceURI, fLocalName);}DOMElement *DOMDocumentImpl::getElementById(const XMLCh *elementId) const{    if (fNodeIDMap == 0)        return 0;    DOMAttr *theAttr = fNodeIDMap->find(elementId);    if (theAttr == 0)        return 0;    return theAttr->getOwnerElement();}//Return the index > 0 of ':' in the given qualified name qName="prefix:localName".//Return 0 if there is no ':', or -1 if qName is malformed such as ":abcd" or "abcd:".int DOMDocumentImpl::indexofQualifiedName(const XMLCh * qName){    int qNameLen = XMLString::stringLen(qName);    int index = -1, count = 0;    for (int i = 0; i < qNameLen; ++i) {        if (qName[i] == chColon) {            index = i;            ++count;    //number of ':' found        }    }    if (qNameLen == 0 || count > 1 || index == 0 || index == qNameLen-1)        return -1;    return count == 0 ? 0 : index;}const XMLCh*     DOMDocumentImpl::getBaseURI() const{	  return fDocumentURI;}DOMRange* DOMDocumentImpl::createRange(){    DOMRangeImpl* range = new (this) DOMRangeImpl(this, fMemoryManager);    if (fRanges == 0L) {        //fRanges = new (this) Ranges(1, false);        fRanges = new (fMemoryManager) Ranges(1, false, fMemoryManager); // XMemory    }    fRanges->addElement(range);    return range;}Ranges* DOMDocumentImpl::getRanges() const{    return fRanges;}void DOMDocumentImpl::removeRange(DOMRangeImpl* range){    if (fRanges != 0) {        XMLSize_t sz = fRanges->size();        if (sz !=0) {            for (XMLSize_t i =0; i<sz; i++) {                if (fRanges->elementAt(i) == range) {                    fRanges->removeElementAt(i);                    break;                }            }        }    }}/** Uses the kidOK lookup table to check whether the proposed    tree structure is legal.    ????? It feels like there must be a more efficient solution,    but for the life of me I can't think what it would be.*/bool DOMDocumentImpl::isKidOK(DOMNode *parent, DOMNode *child){      static int kidOK[14];      if (kidOK[DOMNode::ATTRIBUTE_NODE] == 0)      {          kidOK[DOMNode::DOCUMENT_NODE] =              1 << DOMNode::ELEMENT_NODE |              1 << DOMNode::PROCESSING_INSTRUCTION_NODE |              1 << DOMNode::COMMENT_NODE |              1 << DOMNode::DOCUMENT_TYPE_NODE;          kidOK[DOMNode::DOCUMENT_FRAGMENT_NODE] =              kidOK[DOMNode::ENTITY_NODE] =              kidOK[DOMNode::ENTITY_REFERENCE_NODE] =              kidOK[DOMNode::ELEMENT_NODE] =              1 << DOMNode::ELEMENT_NODE |              1 << DOMNode::PROCESSING_INSTRUCTION_NODE |              1 << DOMNode::COMMENT_NODE |              1 << DOMNode::TEXT_NODE |              1 << DOMNode::CDATA_SECTION_NODE |              1 << DOMNode::ENTITY_REFERENCE_NODE;          kidOK[DOMNode::ATTRIBUTE_NODE] =              1 << DOMNode::TEXT_NODE |              1 << DOMNode::ENTITY_REFERENCE_NODE;          kidOK[DOMNode::PROCESSING_INSTRUCTION_NODE] =              kidOK[DOMNode::COMMENT_NODE] =              kidOK[DOMNode::TEXT_NODE] =              kidOK[DOMNode::CDATA_SECTION_NODE] =              kidOK[DOMNode::NOTATION_NODE] =              0;      }      int p=parent->getNodeType();      int ch = child->getNodeType();      return (kidOK[p] & 1<<ch) != 0;}void            DOMDocumentImpl::changed(){    fChanges++;}int             DOMDocumentImpl::changes() const{    return fChanges;}////    Delegation for functions inherited from DOMNode//           DOMNode*         DOMDocumentImpl::appendChild(DOMNode *newChild)          {return insertBefore(newChild, 0); }           DOMNamedNodeMap* DOMDocumentImpl::getAttributes() const                   {return fNode.getAttributes (); }           DOMNodeList*     DOMDocumentImpl::getChildNodes() const                   {return fParent.getChildNodes (); }           DOMNode*         DOMDocumentImpl::getFirstChild() const                   {return fParent.getFirstChild (); }           DOMNode*         DOMDocumentImpl::getLastChild() const                    {return fParent.getLastChild (); }     const XMLCh*           DOMDocumentImpl::getLocalName() const                    {return fNode.getLocalName (); }     const XMLCh*           DOMDocumentImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); }           DOMNode*         DOMDocumentImpl::getNextSibling() const                  {return fNode.getNextSibling (); }     const XMLCh*           DOMDocumentImpl::getNodeValue() const                    {return fNode.getNodeValue (); }     const XMLCh*           DOMDocumentImpl::getPrefix() const                       {return fNode.getPrefix (); }           DOMNode*         DOMDocumentImpl::getParentNode() const                   {return fNode.getParentNode (); }           DOMNode*         DOMDocumentImpl::getPreviousSibling() const              {return fNode.getPreviousSibling (); }           bool             DOMDocumentImpl::hasChildNodes() const                   {return fParent.hasChildNodes (); }           void             DOMDocumentImpl::normalize()                             {fParent.normalize (); }           bool             DOMDocumentImpl::isSupported(const XMLCh *feature, const XMLCh *version) const                                                                                     {return fNode.isSupported (feature, version); }           void             DOMDocumentImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); }           bool             DOMDocumentImpl::hasAttributes() const                   {return fNode.hasAttributes(); }           bool             DOMDocumentImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other);}           bool             DOMDocumentImpl::isEqualNode(const DOMNode* arg) const   {return fParent.isEqualNode(arg);}           void*            DOMDocumentImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)                                                                                     {return fNode.setUserData(key, data, handler); }           void*            DOMDocumentImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); }           short            DOMDocumentImpl::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); }           const XMLCh*     DOMDocumentImpl::getTextContent() const                  {return fNode.getTextContent(); }           void             DOMDocumentImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }           const XMLCh*     DOMDocumentImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); }           bool             DOMDocumentImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }           const XMLCh*     DOMDocumentImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); }           DOMNode*         DOMDocumentImpl::getInterface(const XMLCh* feature)      {return fNode.getInterface(feature); }//-----------------------------------------------------------------------////  Per Document Heap and Heap Helper functions////        revisit - this stuff should be a class of its own, rather than//                       just lying around naked in DocumentImpl.////-----------------------------------------------------------------------XMLCh * DOMDocumentImpl::cloneString(const XMLCh *src){    if (!src) return 0;    size_t   len = XMLString::stringLen(src);    len = (len + 1) * sizeof(XMLCh);    len = (len % 4) + len;    XMLCh *newStr = (XMLCh *)this->allocate(len);    XMLString::copyString(newStr, src);    return newStr;}const XMLCh *  DOMDocumentImpl::getPooledString(const XMLCh *src){    if (!src) return 0;    else return this->fNamePool->getPooledString(src);}static const int kHeapAllocSize = 0x10000;    // The chunk size to allocate from the                                              //   system allocator.static const int kMaxSubAllocationSize = 4096;   // Any request for more bytes                                                 //  than this will be handled by                                                 //  allocating directly with system.void *         DOMDocumentImpl::allocate(size_t amount){		//	Align the request size so that suballocated blocks	//	beyond this one will be maintained at the same alignment.	amount = XMLPlatformUtils::alignPointerForNewBlockAllocation(amount);    // If the request is for a largish block, hand it off to the system    //   allocator.  The block still must be linked into the list of    //   allocated blocks so that it will be deleted when the time comes.    if (amount > kMaxSubAllocationSize)    {		//	The size of the header we add to our raw blocks		size_t sizeOfHeader = XMLPlatformUtils::alignPointerForNewBlockAllocation(sizeof(void *));		//	Try to allocate the block        void* newBlock;        newBlock = fMemoryManager->allocate((sizeOfHeader + amount) * sizeof(char)); //new char[amount + sizeOfHeader];        		//	Link it into the list beyond current block, as current block		//	is still being subdivided. If there is no current block		//	then track that we have no bytes to further divide.        if (fCurrentBlock)        {            *(void **)newBlock = *(void **)fCurrentBlock;            *(void **)fCurrentBlock = newBlock;        }        else        {            fCurrentBlock = newBlock;            fFreePtr = 0;            fFreeBytesRemaining = 0;        }		        void *retPtr = (char *)newBlock + sizeOfHeader;        return retPtr;    }    //	It's a normal (sub-allocatable) request.	//	Are we out of room in our current block?	if (amount > fFreeBytesRemaining)    {        // Request doesn't fit in the current block.		// The size of the header we add to our raw blocks		size_t sizeOfHeader = XMLPlatformUtils::alignPointerForNewBlockAllocation(sizeof(void *));        // Get a new block from the system allocator.        void* newBlock;        newBlock = fMemoryManager->allocate(kHeapAllocSize * sizeof(char)); //new char[kHeapAllocSize];                *(void **)newBlock = fCurrentBlock;        fCurrentBlock = newBlock;        fFreePtr = (char *)newBlock + sizeOfHeader;        fFreeBytesRemaining = kHeapAllocSize - sizeOfHeader;    }	//	Subdivide the request off current block    void *retPtr = fFreePtr;    fFreePtr += amount;    fFreeBytesRemaining -= amount;	    return retPtr;}void    DOMDocumentImpl::deleteHeap(){    while (fCurrentBlock != 0)    {        void *nextBlock = *(void **)fCurrentBlock;        fMemoryManager->deallocate(fCurrentBlock); //delete [] (char*) fCurrentBlock;        fCurrentBlock = nextBlock;    }}DOMNodeList *DOMDocumentImpl::getDeepNodeList(const DOMNode *rootNode, const XMLCh *tagName){    if(!fNodeListPool) {        fNodeListPool = new (this) DOMDeepNodeListPool<DOMDeepNodeListImpl>(109, false);    }    DOMDeepNodeListImpl* retList = fNodeListPool->getByKey(rootNode, tagName, 0);    if (!retList) {        int id = fNodeListPool->put((void*) rootNode, (XMLCh*) tagName, 0, new (this) DOMDeepNodeListImpl(rootNode, tagName));        retList = fNodeListPool->getById(id);    }    return retList;}DOMNodeList *DOMDocumentImpl::getDeepNodeList(const DOMNode *rootNode,     //DOM Level 2                                                   const XMLCh *namespaceURI,                                                   const XMLCh *localName){    if(!fNodeListPool) {        fNodeListPool = new (this) DOMDeepNodeListPool<DOMDeepNodeListImpl>(109, false);    }    DOMDeepNodeListImpl* retList = fNodeListPool->getByKey(rootNode, localName, namespaceURI);    if (!retList) {        // the pool will adopt the DOMDeepNodeListImpl        int id = fNodeListPool->put((void*) rootNode, (XMLCh*) localName, (XMLCh*) namespaceURI, new (this) DOMDeepNodeListImpl(rootNode, namespaceURI, localName));        retList = fNodeListPool->getById(id);    }

⌨️ 快捷键说明

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