Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:27:01

0001 /*
0002  * Licensed to the Apache Software Foundation (ASF) under one or more
0003  * contributor license agreements.  See the NOTICE file distributed with
0004  * this work for additional information regarding copyright ownership.
0005  * The ASF licenses this file to You under the Apache License, Version 2.0
0006  * (the "License"); you may not use this file except in compliance with
0007  * the License.  You may obtain a copy of the License at
0008  *
0009  *      http://www.apache.org/licenses/LICENSE-2.0
0010  *
0011  * Unless required by applicable law or agreed to in writing, software
0012  * distributed under the License is distributed on an "AS IS" BASIS,
0013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014  * See the License for the specific language governing permissions and
0015  * limitations under the License.
0016  */
0017 
0018 /*
0019  * $Id$
0020  */
0021 
0022 #if !defined(XERCESC_INCLUDE_GUARD_DOMDOCUMENTIMPL_HPP)
0023 #define XERCESC_INCLUDE_GUARD_DOMDOCUMENTIMPL_HPP
0024 
0025 //
0026 //  This file is part of the internal implementation of the C++ XML DOM.
0027 //  It should NOT be included or used directly by application programs.
0028 //
0029 //  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
0030 //  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
0031 //  name is substituded for the *.
0032 //
0033 
0034 #include <xercesc/util/RefArrayOf.hpp>
0035 #include <xercesc/util/RefStackOf.hpp>
0036 #include <xercesc/util/RefHash2KeysTableOf.hpp>
0037 #include <xercesc/util/StringPool.hpp>
0038 #include <xercesc/util/KeyRefPair.hpp>
0039 #include <xercesc/util/XMLChar.hpp>
0040 #include <xercesc/dom/DOMDocument.hpp>
0041 #include <xercesc/dom/DOMUserDataHandler.hpp>
0042 #include <xercesc/dom/DOMMemoryManager.hpp>
0043 #include "DOMNodeBase.hpp"
0044 #include "DOMNodeImpl.hpp"
0045 #include "DOMStringPool.hpp"
0046 #include "DOMParentNode.hpp"
0047 #include "DOMDeepNodeListPool.hpp"
0048 
0049 XERCES_CPP_NAMESPACE_BEGIN
0050 
0051 
0052 class DOMAttrImpl;
0053 class DOMCDATASectionImpl;
0054 class DOMCommentImpl;
0055 class DOMConfiguration;
0056 class DOMDeepNodeListImpl;
0057 class DOMDocumentFragmentImpl;
0058 class DOMDocumentTypeImpl;
0059 class DOMElementImpl;
0060 class DOMEntityImpl;
0061 class DOMEntityReferenceImpl;
0062 class DOMNotationImpl;
0063 class DOMProcessingInstructionImpl;
0064 class DOMTextImpl;
0065 class DOMNodeIteratorImpl;
0066 class DOMNormalizer;
0067 class DOMTreeWalkerImpl;
0068 class DOMNodeFilter;
0069 class DOMNodeFilterImpl;
0070 class DOMImplementation;
0071 class DOMNodeIDMap;
0072 class DOMRangeImpl;
0073 class DOMBuffer;
0074 class MemoryManager;
0075 class XPathNSResolver;
0076 class XPathExpression;
0077 
0078 typedef RefVectorOf<DOMRangeImpl>        Ranges;
0079 typedef RefVectorOf<DOMNodeIteratorImpl>     NodeIterators;
0080 typedef KeyRefPair<void, DOMUserDataHandler> DOMUserDataRecord;
0081 typedef RefStackOf<DOMNode>               DOMNodePtr;
0082 
0083 class CDOM_EXPORT DOMDocumentImpl: public XMemory, public DOMMemoryManager, public DOMDocument,
0084         public HasDOMNodeImpl, public HasDOMParentImpl {
0085 public:
0086     // -----------------------------------------------------------------------
0087     //  data
0088     // -----------------------------------------------------------------------
0089     DOMNodeImpl           fNode;           // Implements common node functionality.
0090     DOMParentNode         fParent;         // Implements common parent node functionality
0091     DOMNodeIDMap*         fNodeIDMap;     // for use by GetElementsById().
0092 
0093 public:
0094     DOMDocumentImpl(DOMImplementation* domImpl, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
0095     DOMDocumentImpl(const XMLCh*     namespaceURI,     //DOM Level 2
0096                     const XMLCh*     qualifiedName,
0097                     DOMDocumentType* doctype,
0098                     DOMImplementation* domImpl,
0099                     MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
0100     virtual ~DOMDocumentImpl();
0101 
0102     void                         setDocumentType(DOMDocumentType *doctype);
0103 
0104 public:
0105     // Add all functions that are pure virtual in DOMNODE
0106     DOMNODE_FUNCTIONS;
0107 
0108     // Add accessors for implementation bits.
0109     DOMNODEIMPL_DECL;
0110     DOMPARENTIMPL_DECL;
0111 
0112 public:
0113     // Add all functions that are pure virtual in DOMDocument
0114     virtual DOMAttr*             createAttribute(const XMLCh *name);
0115     virtual DOMCDATASection*     createCDATASection(const XMLCh *data);
0116     virtual DOMComment*          createComment(const XMLCh *data);
0117     virtual DOMDocumentFragment* createDocumentFragment();
0118     virtual DOMDocumentType*     createDocumentType(const XMLCh *name);
0119     virtual DOMDocumentType*     createDocumentType(const XMLCh *qName,
0120                                                     const XMLCh *publicId,
0121                                                     const XMLCh *systemId);
0122     virtual DOMElement*          createElement(const XMLCh * tagName);
0123     virtual DOMElement*          createElementNoCheck(const XMLCh *tagName);
0124     virtual DOMEntity*           createEntity(const XMLCh * name);
0125     virtual DOMEntityReference*  createEntityReference(const XMLCh * name);
0126     virtual DOMNotation*         createNotation(const XMLCh * name);
0127     virtual DOMProcessingInstruction* createProcessingInstruction(const XMLCh * target, const XMLCh * data);
0128     virtual DOMText*             createTextNode(const XMLCh * data);
0129     virtual DOMDocumentType*     getDoctype() const;
0130     virtual DOMElement*          getDocumentElement() const;
0131     virtual DOMNodeList*         getElementsByTagName(const XMLCh * tagname) const;
0132     virtual DOMImplementation*   getImplementation() const;
0133     bool                         isXMLName(const XMLCh * s);
0134     virtual DOMNodeIterator*     createNodeIterator(DOMNode *root,
0135                                                     DOMNodeFilter::ShowType whatToShow,
0136                                                     DOMNodeFilter* filter,
0137                                                     bool entityReferenceExpansion);
0138     virtual DOMTreeWalker*       createTreeWalker(DOMNode *root,
0139                                                   DOMNodeFilter::ShowType whatToShow,
0140                                                   DOMNodeFilter* filter,
0141                                                   bool entityReferenceExpansion);
0142 
0143 
0144     virtual DOMRange*            createRange();
0145     virtual Ranges*              getRanges() const;  //non-standard api
0146     virtual NodeIterators*       getNodeIterators() const;  //non-standard api
0147     virtual void                 removeRange(DOMRangeImpl* range); //non-standard api
0148     virtual void                 removeNodeIterator(DOMNodeIteratorImpl* nodeIterator); //non-standard api
0149 
0150     virtual DOMXPathExpression* createExpression(const XMLCh *expression,
0151                                                  const DOMXPathNSResolver *resolver);
0152     virtual DOMXPathNSResolver* createNSResolver(const DOMNode *nodeResolver);
0153     virtual DOMXPathResult* evaluate(const XMLCh *expression,
0154                                      const DOMNode *contextNode,
0155                                      const DOMXPathNSResolver *resolver,
0156                                      DOMXPathResult::ResultType type,
0157                                      DOMXPathResult* result);
0158 
0159 
0160     // Extension to be called by the Parser
0161     DOMEntityReference*  createEntityReferenceByParser(const XMLCh * name);
0162 
0163     // Add all functions that are pure virtual in DOMMemoryManager
0164     virtual XMLSize_t getMemoryAllocationBlockSize() const;
0165     virtual void setMemoryAllocationBlockSize(XMLSize_t size);
0166     virtual void* allocate(XMLSize_t amount);
0167     virtual void* allocate(XMLSize_t amount, DOMMemoryManager::NodeObjectType type);
0168     // try to remove the block from the list of allocated memory
0169     virtual void release(void* oldBuffer);
0170     virtual void release(DOMNode* object, DOMMemoryManager::NodeObjectType type);
0171     virtual XMLCh* cloneString(const XMLCh *src);
0172 
0173     //
0174     // Functions to keep track of document mutations, so that node list chached
0175     //   information can be invalidated.  One global changes counter per document.
0176     //
0177     virtual void                 changed();
0178     virtual int                  changes() const;
0179 
0180     /**
0181      * Sets whether the DOM implementation performs error checking
0182      * upon operations. Turning off error checking only affects
0183      * the following DOM checks:
0184      * <ul>
0185      * <li>Checking strings to make sure that all characters are
0186      *     legal XML characters
0187      * <li>Hierarchy checking such as allowed children, checks for
0188      *     cycles, etc.
0189      * </ul>
0190      * <p>
0191      * Turning off error checking does <em>not</em> turn off the
0192      * following checks:
0193      * <ul>
0194      * <li>Read only checks
0195      * <li>Checks related to DOM events
0196      * </ul>
0197      */
0198     inline void setErrorChecking(bool check) {
0199         errorChecking = check;
0200     }
0201 
0202     /**
0203      * Returns true if the DOM implementation performs error checking.
0204      */
0205     inline bool getErrorChecking() const {
0206         return errorChecking;
0207     }
0208 
0209     //Introduced in DOM Level 2
0210     virtual DOMNode*             importNode(const DOMNode *source, bool deep);
0211     virtual DOMElement*          createElementNS(const XMLCh *namespaceURI,
0212                                                  const XMLCh *qualifiedName);
0213     virtual DOMElement*          createElementNS(const XMLCh *namespaceURI,
0214                                                  const XMLCh *qualifiedName,
0215                                                  const XMLFileLoc lineNo,
0216                                                  const XMLFileLoc columnNo);
0217     virtual DOMAttr*             createAttributeNS(const XMLCh *namespaceURI,
0218                                                    const XMLCh *qualifiedName);
0219     virtual DOMNodeList*         getElementsByTagNameNS(const XMLCh *namespaceURI,
0220                                                         const XMLCh *localName) const;
0221     virtual DOMElement*          getElementById(const XMLCh *elementId) const;
0222 
0223     //Introduced in DOM Level 3
0224     virtual const XMLCh*         getInputEncoding() const;
0225     virtual const XMLCh*         getXmlEncoding() const;
0226     virtual bool                 getXmlStandalone() const;
0227     virtual void                 setXmlStandalone(bool standalone);
0228     virtual const XMLCh*         getXmlVersion() const;
0229     virtual void                 setXmlVersion(const XMLCh* version);
0230     virtual const XMLCh*         getDocumentURI() const;
0231     virtual void                 setDocumentURI(const XMLCh* documentURI);
0232     virtual bool                 getStrictErrorChecking() const;
0233     virtual void                 setStrictErrorChecking(bool strictErrorChecking);
0234     virtual DOMNode*             adoptNode(DOMNode* source);
0235     virtual void                 normalizeDocument();
0236     virtual DOMConfiguration*    getDOMConfig() const;
0237 
0238     void                         setInputEncoding(const XMLCh* actualEncoding);
0239     void                         setXmlEncoding(const XMLCh* encoding);
0240     // helper functions to prevent storing userdata pointers on every node.
0241     void*                        setUserData(DOMNodeImpl* n,
0242                                             const XMLCh* key,
0243                                             void* data,
0244                                             DOMUserDataHandler* handler);
0245     void*                        getUserData(const DOMNodeImpl* n,
0246                                              const XMLCh* key) const;
0247     void                         callUserDataHandlers(const DOMNodeImpl* n,
0248                                                       DOMUserDataHandler::DOMOperationType operation,
0249                                                       const DOMNode* src,
0250                                                       DOMNode* dst) const;
0251     void                         transferUserData(DOMNodeImpl* n1, DOMNodeImpl* n2);
0252 
0253     DOMNode*                     renameNode(DOMNode* n,
0254                                             const XMLCh* namespaceURI,
0255                                             const XMLCh* name);
0256 
0257     //Return the index > 0 of ':' in the given qualified name qName="prefix:localName".
0258     //Return 0 if there is no ':', or -1 if qName is malformed such as ":abcd".
0259     static  int                  indexofQualifiedName(const XMLCh * qName);
0260     static  bool                 isKidOK(const DOMNode *parent, const DOMNode *child);
0261 
0262     inline DOMNodeIDMap*         getNodeIDMap() {return fNodeIDMap;};
0263 
0264 
0265     //
0266     // Memory Management Functions.  All memory is allocated by and owned by
0267     //                               a document, and is not recovered until the
0268     //                               document itself is deleted.
0269     //
0270     const XMLCh*                 getPooledString(const XMLCh*);
0271     const XMLCh*                 getPooledNString(const XMLCh*, XMLSize_t);
0272     void                         deleteHeap();
0273     void                         releaseDocNotifyUserData(DOMNode* object);
0274     void                         releaseBuffer(DOMBuffer* buffer);
0275     DOMBuffer*                   popBuffer(XMLSize_t nMinSize);
0276     MemoryManager*               getMemoryManager() const;
0277 
0278     // Factory methods for getting/creating node lists.
0279     // Because nothing is ever deleted, the implementation caches and recycles
0280     //  previously used instances of DOMDeepNodeList
0281     //
0282     DOMNodeList*                 getDeepNodeList(const DOMNode *rootNode, const XMLCh *tagName);
0283     DOMNodeList*                 getDeepNodeList(const DOMNode *rootNode,    //DOM Level 2
0284                                                  const XMLCh *namespaceURI,
0285                                                  const XMLCh *localName);
0286 
0287 protected:
0288     //Internal helper functions
0289     virtual DOMNode*             importNode(const DOMNode *source, bool deep, bool cloningNode);
0290 
0291 private:
0292     // -----------------------------------------------------------------------
0293     // Unimplemented constructors and operators
0294     // -----------------------------------------------------------------------
0295     DOMDocumentImpl(const DOMDocumentImpl &);
0296     DOMDocumentImpl & operator = (const DOMDocumentImpl &);
0297 
0298 protected:
0299     // -----------------------------------------------------------------------
0300     //  data
0301     // -----------------------------------------------------------------------
0302     // New data introduced in DOM Level 3
0303     const XMLCh*          fInputEncoding;
0304     const XMLCh*          fXmlEncoding;
0305     bool                  fXmlStandalone;
0306     const XMLCh*          fXmlVersion;
0307     const XMLCh*          fDocumentURI;
0308     DOMConfiguration*     fDOMConfiguration;
0309 
0310     XMLStringPool         fUserDataTableKeys;
0311     RefHash2KeysTableOf<DOMUserDataRecord, PtrHasher>* fUserDataTable;
0312 
0313 
0314     // Per-Document heap Variables.
0315     //   The heap consists of one or more biggish blocks which are
0316     //   sub-allocated for individual allocations of nodes, strings, etc.
0317     //   The big blocks form a linked list, allowing them to be located for deletion.
0318     //
0319     //   There is no provision for deleting suballocated blocks, other than
0320     //     deleting the entire heap when the document is deleted.
0321     //
0322     //   There is no header on individual sub-allocated blocks.
0323     //   The header on big blocks consists only of a single back pointer to
0324     //    the previously allocated big block (our linked list of big blocks)
0325     //
0326     //
0327     //   revisit - this heap should be encapsulated into its own
0328     //                  class, rather than hanging naked on Document.
0329     //
0330     void*                 fCurrentBlock;
0331     void*                 fCurrentSingletonBlock;
0332     char*                 fFreePtr;
0333     XMLSize_t             fFreeBytesRemaining,
0334                           fHeapAllocSize;
0335 
0336     // To recycle the DOMNode pointer
0337     RefArrayOf<DOMNodePtr>* fRecycleNodePtr;
0338 
0339     // To recycle DOMBuffer pointer
0340     RefStackOf<DOMBuffer>* fRecycleBufferPtr;
0341 
0342     // Pool of DOMNodeList for getElementsByTagName
0343     DOMDeepNodeListPool<DOMDeepNodeListImpl>* fNodeListPool;
0344 
0345     // Other data
0346     DOMDocumentType*      fDocType;
0347     DOMElement*           fDocElement;
0348 
0349     DOMStringPoolEntry**  fNameTable;
0350     XMLSize_t             fNameTableSize;
0351 
0352     DOMNormalizer*        fNormalizer;
0353     Ranges*               fRanges;
0354     NodeIterators*        fNodeIterators;
0355     MemoryManager*        fMemoryManager;   // configurable memory manager
0356     DOMImplementation*    fDOMImplementation;
0357 
0358     int                   fChanges;
0359     bool                  errorChecking;    // Bypass error checking.
0360 
0361 };
0362 
0363 inline MemoryManager* DOMDocumentImpl::getMemoryManager() const
0364 {
0365     return fMemoryManager;
0366 }
0367 
0368 inline const XMLCh*  DOMDocumentImpl::getPooledString(const XMLCh *in)
0369 {
0370   if (in == 0)
0371     return 0;
0372   XMLSize_t n = XMLString::stringLen(in);
0373 
0374   DOMStringPoolEntry    **pspe;
0375   DOMStringPoolEntry    *spe;
0376 
0377   XMLSize_t inHash = XMLString::hash(in, fNameTableSize);
0378   pspe = &fNameTable[inHash];
0379   while (*pspe != 0)
0380   {
0381     if ((*pspe)->fLength == n && XMLString::equals((*pspe)->fString, in))
0382       return (*pspe)->fString;
0383     pspe = &((*pspe)->fNext);
0384   }
0385 
0386   // This string hasn't been seen before.  Add it to the pool.
0387   //
0388 
0389   // Compute size to allocate.  Note that there's 1 char of string
0390   // declared in the struct, so we don't need to add one again to
0391   // account for the trailing null.
0392   //
0393   XMLSize_t sizeToAllocate = sizeof(DOMStringPoolEntry) + n*sizeof(XMLCh);
0394   *pspe = spe = (DOMStringPoolEntry *)allocate(sizeToAllocate);
0395   spe->fLength = n;
0396   spe->fNext = 0;
0397   XMLString::copyString((XMLCh*)spe->fString, in);
0398 
0399   return spe->fString;
0400 }
0401 
0402 inline const XMLCh* DOMDocumentImpl::getPooledNString(const XMLCh *in, XMLSize_t n)
0403 {
0404   if (in == 0)
0405     return 0;
0406 
0407   DOMStringPoolEntry    **pspe;
0408   DOMStringPoolEntry    *spe;
0409 
0410   XMLSize_t inHash = XMLString::hashN(in, n, fNameTableSize);
0411   pspe = &fNameTable[inHash];
0412   while (*pspe != 0)
0413   {
0414     if ((*pspe)->fLength == n && XMLString::equalsN((*pspe)->fString, in, n))
0415       return (*pspe)->fString;
0416     pspe = &((*pspe)->fNext);
0417   }
0418 
0419   // This string hasn't been seen before.  Add it to the pool.
0420   //
0421 
0422   // Compute size to allocate.  Note that there's 1 char of string
0423   // declared in the struct, so we don't need to add one again to
0424   // account for the trailing null.
0425   //
0426   XMLSize_t sizeToAllocate = sizeof(DOMStringPoolEntry) + n*sizeof(XMLCh);
0427   *pspe = spe = (DOMStringPoolEntry *)allocate(sizeToAllocate);
0428   spe->fLength = n;
0429   spe->fNext = 0;
0430   XMLString::copyNString((XMLCh*)spe->fString, in, n);
0431 
0432   return spe->fString;
0433 }
0434 
0435 inline int DOMDocumentImpl::indexofQualifiedName(const XMLCh* name)
0436 {
0437   int i = 0;
0438   int colon = -1;
0439   int colon_count = 0;
0440   for (; *name != 0; ++i, ++name)
0441   {
0442     if (*name == chColon)
0443     {
0444       ++colon_count;
0445       colon = i;
0446     }
0447   }
0448 
0449   if (i == 0 || colon == 0 || colon == (i - 1) || colon_count > 1)
0450     return -1;
0451 
0452   return colon != -1 ? colon : 0;
0453 }
0454 
0455 XERCES_CPP_NAMESPACE_END
0456 
0457 // ---------------------------------------------------------------------------
0458 //
0459 //  Operator new.  Global overloaded version, lets any object be allocated on
0460 //                 the heap owned by a document.
0461 //
0462 // ---------------------------------------------------------------------------
0463 inline void * operator new(size_t amt, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocumentImpl *doc, XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager::NodeObjectType type)
0464 {
0465     void *p = doc->allocate(amt, type);
0466     return p;
0467 }
0468 
0469 inline void * operator new(size_t amt, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc, XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager::NodeObjectType type)
0470 {
0471     XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager* mgr=(XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager*)doc->getFeature(XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgXercescInterfaceDOMMemoryManager,0);
0472     void* p=0;
0473     if(mgr)
0474         p = mgr->allocate(amt, type);
0475     return p;
0476 }
0477 
0478 inline void * operator new(size_t amt, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocumentImpl *doc)
0479 {
0480     void* p = doc->allocate(amt);
0481     return p;
0482 }
0483 
0484 inline void * operator new(size_t amt, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc)
0485 {
0486     XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager* mgr=(XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager*)doc->getFeature(XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgXercescInterfaceDOMMemoryManager,0);
0487     void* p=0;
0488     if(mgr)
0489         p = mgr->allocate(amt);
0490     return p;
0491 }
0492 
0493 // ---------------------------------------------------------------------------
0494 //  For DOM:
0495 //  Bypass compiler warning:
0496 //    no matching operator delete found; memory will not be freed if initialization throws an exception
0497 // ---------------------------------------------------------------------------
0498 #if !defined(XERCES_NO_MATCHING_DELETE_OPERATOR)
0499 inline void operator delete(void* /*ptr*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocumentImpl * /*doc*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager::NodeObjectType /*type*/)
0500 {
0501     return;
0502 }
0503 inline void operator delete(void* /*ptr*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * /*doc*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager::NodeObjectType /*type*/)
0504 {
0505     return;
0506 }
0507 
0508 inline void operator delete(void* /*ptr*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocumentImpl * /*doc*/)
0509 {
0510     return;
0511 }
0512 inline void operator delete(void* /*ptr*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * /*doc*/)
0513 {
0514     return;
0515 }
0516 #endif
0517 
0518 #endif