source: icXML/icXML-devel/src/xercesc/dom/impl/DOMDocumentImpl.hpp @ 2722

Last change on this file since 2722 was 2722, checked in by cameron, 6 years ago

Original Xerces files with import mods for icxercesc

File size: 20.3 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * $Id: DOMDocumentImpl.hpp 679340 2008-07-24 10:28:29Z borisk $
20 */
21
22#if !defined(XERCESC_INCLUDE_GUARD_DOMDOCUMENTIMPL_HPP)
23#define XERCESC_INCLUDE_GUARD_DOMDOCUMENTIMPL_HPP
24
25//
26//  This file is part of the internal implementation of the C++ XML DOM.
27//  It should NOT be included or used directly by application programs.
28//
29//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
30//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
31//  name is substituded for the *.
32//
33
34#include <xercesc/util/RefArrayOf.hpp>
35#include <xercesc/util/RefStackOf.hpp>
36#include <xercesc/util/RefHash2KeysTableOf.hpp>
37#include <xercesc/util/StringPool.hpp>
38#include <xercesc/util/KeyRefPair.hpp>
39#include <xercesc/util/XMLChar.hpp>
40#include <xercesc/dom/DOMDocument.hpp>
41#include <xercesc/dom/DOMUserDataHandler.hpp>
42#include <xercesc/dom/DOMMemoryManager.hpp>
43#include "DOMNodeImpl.hpp"
44#include "DOMStringPool.hpp"
45#include "DOMParentNode.hpp"
46#include "DOMDeepNodeListPool.hpp"
47
48XERCES_CPP_NAMESPACE_BEGIN
49
50
51class DOMAttrImpl;
52class DOMCDATASectionImpl;
53class DOMCommentImpl;
54class DOMConfiguration;
55class DOMDeepNodeListImpl;
56class DOMDocumentFragmentImpl;
57class DOMDocumentTypeImpl;
58class DOMElementImpl;
59class DOMEntityImpl;
60class DOMEntityReferenceImpl;
61class DOMNotationImpl;
62class DOMProcessingInstructionImpl;
63class DOMTextImpl;
64class DOMNodeIteratorImpl;
65class DOMNormalizer;
66class DOMTreeWalkerImpl;
67class DOMNodeFilter;
68class DOMNodeFilterImpl;
69class DOMImplementation;
70class DOMNodeIDMap;
71class DOMRangeImpl;
72class DOMBuffer;
73class MemoryManager;
74class XPathNSResolver;
75class XPathExpression;
76
77typedef RefVectorOf<DOMRangeImpl>        Ranges;
78typedef RefVectorOf<DOMNodeIteratorImpl>     NodeIterators;
79typedef KeyRefPair<void, DOMUserDataHandler> DOMUserDataRecord;
80typedef RefStackOf<DOMNode>               DOMNodePtr;
81
82class CDOM_EXPORT DOMDocumentImpl: public XMemory, public DOMMemoryManager, public DOMDocument {
83public:
84    // -----------------------------------------------------------------------
85    //  data
86    // -----------------------------------------------------------------------
87    DOMNodeImpl           fNode;           // Implements common node functionality.
88    DOMParentNode         fParent;         // Implements common parent node functionality
89    DOMNodeIDMap*         fNodeIDMap;     // for use by GetElementsById().
90
91public:
92    DOMDocumentImpl(DOMImplementation* domImpl, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
93    DOMDocumentImpl(const XMLCh*     namespaceURI,     //DOM Level 2
94                    const XMLCh*     qualifiedName,
95                    DOMDocumentType* doctype,
96                    DOMImplementation* domImpl,
97                    MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
98    virtual ~DOMDocumentImpl();
99
100    void                         setDocumentType(DOMDocumentType *doctype);
101
102public:
103    // Add all functions that are pure virtual in DOMNODE
104    DOMNODE_FUNCTIONS;
105
106public:
107    // Add all functions that are pure virtual in DOMDocument
108    virtual DOMAttr*             createAttribute(const XMLCh *name);
109    virtual DOMCDATASection*     createCDATASection(const XMLCh *data);
110    virtual DOMComment*          createComment(const XMLCh *data);
111    virtual DOMDocumentFragment* createDocumentFragment();
112    virtual DOMDocumentType*     createDocumentType(const XMLCh *name);
113    virtual DOMDocumentType*     createDocumentType(const XMLCh *qName,
114                                                    const XMLCh *publicId,
115                                                    const XMLCh *systemId);
116    virtual DOMElement*          createElement(const XMLCh * tagName);
117    virtual DOMElement*          createElementNoCheck(const XMLCh *tagName);
118    virtual DOMEntity*           createEntity(const XMLCh * name);
119    virtual DOMEntityReference*  createEntityReference(const XMLCh * name);
120    virtual DOMNotation*         createNotation(const XMLCh * name);
121    virtual DOMProcessingInstruction* createProcessingInstruction(const XMLCh * target, const XMLCh * data);
122    virtual DOMText*             createTextNode(const XMLCh * data);
123    virtual DOMDocumentType*     getDoctype() const;
124    virtual DOMElement*          getDocumentElement() const;
125    virtual DOMNodeList*         getElementsByTagName(const XMLCh * tagname) const;
126    virtual DOMImplementation*   getImplementation() const;
127    bool                         isXMLName(const XMLCh * s);
128    virtual DOMNodeIterator*     createNodeIterator(DOMNode *root,
129                                                    DOMNodeFilter::ShowType whatToShow,
130                                                    DOMNodeFilter* filter,
131                                                    bool entityReferenceExpansion);
132    virtual DOMTreeWalker*       createTreeWalker(DOMNode *root,
133                                                  DOMNodeFilter::ShowType whatToShow,
134                                                  DOMNodeFilter* filter,
135                                                  bool entityReferenceExpansion);
136
137
138    virtual DOMRange*            createRange();
139    virtual Ranges*              getRanges() const;  //non-standard api
140    virtual NodeIterators*       getNodeIterators() const;  //non-standard api
141    virtual void                 removeRange(DOMRangeImpl* range); //non-standard api
142    virtual void                 removeNodeIterator(DOMNodeIteratorImpl* nodeIterator); //non-standard api
143
144    virtual DOMXPathExpression* createExpression(const XMLCh *expression,
145                                                 const DOMXPathNSResolver *resolver);
146    virtual DOMXPathNSResolver* createNSResolver(const DOMNode *nodeResolver);
147    virtual DOMXPathResult* evaluate(const XMLCh *expression,
148                                     const DOMNode *contextNode,
149                                     const DOMXPathNSResolver *resolver,
150                                     DOMXPathResult::ResultType type,
151                                     DOMXPathResult* result);
152
153
154    // Extension to be called by the Parser
155    DOMEntityReference*  createEntityReferenceByParser(const XMLCh * name);
156
157    // Add all functions that are pure virtual in DOMMemoryManager
158    virtual XMLSize_t getMemoryAllocationBlockSize() const;
159    virtual void setMemoryAllocationBlockSize(XMLSize_t size);
160    virtual void* allocate(XMLSize_t amount);
161    virtual void* allocate(XMLSize_t amount, DOMMemoryManager::NodeObjectType type);
162    virtual void release(DOMNode* object, DOMMemoryManager::NodeObjectType type);
163    virtual XMLCh* cloneString(const XMLCh *src);
164
165    //
166    // Functions to keep track of document mutations, so that node list chached
167    //   information can be invalidated.  One global changes counter per document.
168    //
169    virtual void                 changed();
170    virtual int                  changes() const;
171
172    /**
173     * Sets whether the DOM implementation performs error checking
174     * upon operations. Turning off error checking only affects
175     * the following DOM checks:
176     * <ul>
177     * <li>Checking strings to make sure that all characters are
178     *     legal XML characters
179     * <li>Hierarchy checking such as allowed children, checks for
180     *     cycles, etc.
181     * </ul>
182     * <p>
183     * Turning off error checking does <em>not</em> turn off the
184     * following checks:
185     * <ul>
186     * <li>Read only checks
187     * <li>Checks related to DOM events
188     * </ul>
189     */
190    inline void setErrorChecking(bool check) {
191        errorChecking = check;
192    }
193
194    /**
195     * Returns true if the DOM implementation performs error checking.
196     */
197    inline bool getErrorChecking() const {
198        return errorChecking;
199    }
200
201    //Introduced in DOM Level 2
202    virtual DOMNode*             importNode(const DOMNode *source, bool deep);
203    virtual DOMElement*          createElementNS(const XMLCh *namespaceURI,
204                                                 const XMLCh *qualifiedName);
205    virtual DOMElement*          createElementNS(const XMLCh *namespaceURI,
206                                                 const XMLCh *qualifiedName,
207                                                 const XMLFileLoc lineNo,
208                                                 const XMLFileLoc columnNo);
209    virtual DOMAttr*             createAttributeNS(const XMLCh *namespaceURI,
210                                                   const XMLCh *qualifiedName);
211    virtual DOMNodeList*         getElementsByTagNameNS(const XMLCh *namespaceURI,
212                                                        const XMLCh *localName) const;
213    virtual DOMElement*          getElementById(const XMLCh *elementId) const;
214
215    //Introduced in DOM Level 3
216    virtual const XMLCh*         getInputEncoding() const;
217    virtual const XMLCh*         getXmlEncoding() const;
218    virtual bool                 getXmlStandalone() const;
219    virtual void                 setXmlStandalone(bool standalone);
220    virtual const XMLCh*         getXmlVersion() const;
221    virtual void                 setXmlVersion(const XMLCh* version);
222    virtual const XMLCh*         getDocumentURI() const;
223    virtual void                 setDocumentURI(const XMLCh* documentURI);
224    virtual bool                 getStrictErrorChecking() const;
225    virtual void                 setStrictErrorChecking(bool strictErrorChecking);
226    virtual DOMNode*             adoptNode(DOMNode* source);
227    virtual void                 normalizeDocument();
228    virtual DOMConfiguration*    getDOMConfig() const;
229
230    void                         setInputEncoding(const XMLCh* actualEncoding);
231    void                         setXmlEncoding(const XMLCh* encoding);
232    // helper functions to prevent storing userdata pointers on every node.
233    void*                        setUserData(DOMNodeImpl* n,
234                                            const XMLCh* key,
235                                            void* data,
236                                            DOMUserDataHandler* handler);
237    void*                        getUserData(const DOMNodeImpl* n,
238                                             const XMLCh* key) const;
239    void                         callUserDataHandlers(const DOMNodeImpl* n,
240                                                      DOMUserDataHandler::DOMOperationType operation,
241                                                      const DOMNode* src,
242                                                      DOMNode* dst) const;
243    void                         transferUserData(DOMNodeImpl* n1, DOMNodeImpl* n2);
244
245    DOMNode*                     renameNode(DOMNode* n,
246                                            const XMLCh* namespaceURI,
247                                            const XMLCh* name);
248
249    //Return the index > 0 of ':' in the given qualified name qName="prefix:localName".
250    //Return 0 if there is no ':', or -1 if qName is malformed such as ":abcd".
251    static  int                  indexofQualifiedName(const XMLCh * qName);
252    static  bool                 isKidOK(DOMNode *parent, DOMNode *child);
253
254    inline DOMNodeIDMap*         getNodeIDMap() {return fNodeIDMap;};
255
256
257    //
258    // Memory Management Functions.  All memory is allocated by and owned by
259    //                               a document, and is not recovered until the
260    //                               document itself is deleted.
261    //
262    const XMLCh*                 getPooledString(const XMLCh*);
263    const XMLCh*                 getPooledNString(const XMLCh*, XMLSize_t);
264    void                         deleteHeap();
265    void                         releaseDocNotifyUserData(DOMNode* object);
266    void                         releaseBuffer(DOMBuffer* buffer);
267    DOMBuffer*                   popBuffer(XMLSize_t nMinSize);
268    MemoryManager*               getMemoryManager() const;
269
270    // Factory methods for getting/creating node lists.
271    // Because nothing is ever deleted, the implementation caches and recycles
272    //  previously used instances of DOMDeepNodeList
273    //
274    DOMNodeList*                 getDeepNodeList(const DOMNode *rootNode, const XMLCh *tagName);
275    DOMNodeList*                 getDeepNodeList(const DOMNode *rootNode,    //DOM Level 2
276                                                 const XMLCh *namespaceURI,
277                                                 const XMLCh *localName);
278
279protected:
280    //Internal helper functions
281    virtual DOMNode*             importNode(const DOMNode *source, bool deep, bool cloningNode);
282
283private:
284    // -----------------------------------------------------------------------
285    // Unimplemented constructors and operators
286    // -----------------------------------------------------------------------
287    DOMDocumentImpl(const DOMDocumentImpl &);
288    DOMDocumentImpl & operator = (const DOMDocumentImpl &);
289
290protected:
291    // -----------------------------------------------------------------------
292    //  data
293    // -----------------------------------------------------------------------
294    // New data introduced in DOM Level 3
295    const XMLCh*          fInputEncoding;
296    const XMLCh*          fXmlEncoding;
297    bool                  fXmlStandalone;
298    const XMLCh*          fXmlVersion;
299    const XMLCh*          fDocumentURI;
300    DOMConfiguration*     fDOMConfiguration;
301
302    XMLStringPool         fUserDataTableKeys;
303    RefHash2KeysTableOf<DOMUserDataRecord, PtrHasher>* fUserDataTable;
304
305
306    // Per-Document heap Variables.
307    //   The heap consists of one or more biggish blocks which are
308    //   sub-allocated for individual allocations of nodes, strings, etc.
309    //   The big blocks form a linked list, allowing them to be located for deletion.
310    //
311    //   There is no provision for deleting suballocated blocks, other than
312    //     deleting the entire heap when the document is deleted.
313    //
314    //   There is no header on individual sub-allocated blocks.
315    //   The header on big blocks consists only of a single back pointer to
316    //    the previously allocated big block (our linked list of big blocks)
317    //
318    //
319    //   revisit - this heap should be encapsulated into its own
320    //                  class, rather than hanging naked on Document.
321    //
322    void*                 fCurrentBlock;
323    char*                 fFreePtr;
324    XMLSize_t             fFreeBytesRemaining,
325                          fHeapAllocSize;
326
327    // To recycle the DOMNode pointer
328    RefArrayOf<DOMNodePtr>* fRecycleNodePtr;
329
330    // To recycle DOMBuffer pointer
331    RefStackOf<DOMBuffer>* fRecycleBufferPtr;
332
333    // Pool of DOMNodeList for getElementsByTagName
334    DOMDeepNodeListPool<DOMDeepNodeListImpl>* fNodeListPool;
335
336    // Other data
337    DOMDocumentType*      fDocType;
338    DOMElement*           fDocElement;
339
340    DOMStringPoolEntry**  fNameTable;
341    XMLSize_t             fNameTableSize;
342
343    DOMNormalizer*        fNormalizer;
344    Ranges*               fRanges;
345    NodeIterators*        fNodeIterators;
346    MemoryManager*        fMemoryManager;   // configurable memory manager
347    DOMImplementation*    fDOMImplementation;
348
349    int                   fChanges;
350    bool                  errorChecking;    // Bypass error checking.
351
352};
353
354inline MemoryManager* DOMDocumentImpl::getMemoryManager() const
355{
356    return fMemoryManager;
357}
358
359inline const XMLCh*  DOMDocumentImpl::getPooledString(const XMLCh *in)
360{
361  if (in == 0)
362    return 0;
363
364  DOMStringPoolEntry    **pspe;
365  DOMStringPoolEntry    *spe;
366
367  XMLSize_t inHash = XMLString::hash(in, fNameTableSize);
368  pspe = &fNameTable[inHash];
369  while (*pspe != 0)
370  {
371    if (XMLString::equals((*pspe)->fString, in))
372      return (*pspe)->fString;
373    pspe = &((*pspe)->fNext);
374  }
375
376  // This string hasn't been seen before.  Add it to the pool.
377  //
378
379  // Compute size to allocate.  Note that there's 1 char of string
380  // declared in the struct, so we don't need to add one again to
381  // account for the trailing null.
382  //
383  XMLSize_t sizeToAllocate = sizeof(DOMStringPoolEntry) + XMLString::stringLen(in)*sizeof(XMLCh);
384  *pspe = spe = (DOMStringPoolEntry *)allocate(sizeToAllocate);
385  spe->fNext = 0;
386  XMLString::copyString((XMLCh*)spe->fString, in);
387
388  return spe->fString;
389}
390
391inline const XMLCh* DOMDocumentImpl::
392getPooledNString(const XMLCh *in, XMLSize_t n)
393{
394  if (in == 0)
395    return 0;
396
397  DOMStringPoolEntry    **pspe;
398  DOMStringPoolEntry    *spe;
399
400  XMLSize_t inHash = XMLString::hashN(in, n, fNameTableSize);
401  pspe = &fNameTable[inHash];
402  while (*pspe != 0)
403  {
404    if (XMLString::equalsN((*pspe)->fString, in, n))
405      return (*pspe)->fString;
406    pspe = &((*pspe)->fNext);
407  }
408
409  // This string hasn't been seen before.  Add it to the pool.
410  //
411
412  // Compute size to allocate.  Note that there's 1 char of string
413  // declared in the struct, so we don't need to add one again to
414  // account for the trailing null.
415  //
416  XMLSize_t sizeToAllocate = sizeof(DOMStringPoolEntry) + n*sizeof(XMLCh);
417  *pspe = spe = (DOMStringPoolEntry *)allocate(sizeToAllocate);
418  spe->fNext = 0;
419  XMLString::copyNString((XMLCh*)spe->fString, in, n);
420
421  return spe->fString;
422}
423
424inline int DOMDocumentImpl::indexofQualifiedName(const XMLCh* name)
425{
426  int i = 0;
427  int colon = -1;
428  int colon_count = 0;
429  for (; *name != 0; ++i, ++name)
430  {
431    if (*name == chColon)
432    {
433      ++colon_count;
434      colon = i;
435    }
436  }
437
438  if (i == 0 || colon == 0 || colon == (i - 1) || colon_count > 1)
439    return -1;
440
441  return colon != -1 ? colon : 0;
442}
443
444XERCES_CPP_NAMESPACE_END
445
446// ---------------------------------------------------------------------------
447//
448//  Operator new.  Global overloaded version, lets any object be allocated on
449//                 the heap owned by a document.
450//
451// ---------------------------------------------------------------------------
452inline void * operator new(size_t amt, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocumentImpl *doc, XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager::NodeObjectType type)
453{
454    void *p = doc->allocate(amt, type);
455    return p;
456}
457
458inline void * operator new(size_t amt, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc, XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager::NodeObjectType type)
459{
460    XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager* mgr=(XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager*)doc->getFeature(XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgXercescInterfaceDOMMemoryManager,0);
461    void* p=0;
462    if(mgr)
463        p = mgr->allocate(amt, type);
464    return p;
465}
466
467inline void * operator new(size_t amt, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocumentImpl *doc)
468{
469    void* p = doc->allocate(amt);
470    return p;
471}
472
473inline void * operator new(size_t amt, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc)
474{
475    XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager* mgr=(XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager*)doc->getFeature(XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgXercescInterfaceDOMMemoryManager,0);
476    void* p=0;
477    if(mgr)
478        p = mgr->allocate(amt);
479    return p;
480}
481
482// ---------------------------------------------------------------------------
483//  For DOM:
484//  Bypass compiler warning:
485//    no matching operator delete found; memory will not be freed if initialization throws an exception
486// ---------------------------------------------------------------------------
487#if !defined(XERCES_NO_MATCHING_DELETE_OPERATOR)
488inline void operator delete(void* /*ptr*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocumentImpl * /*doc*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager::NodeObjectType /*type*/)
489{
490    return;
491}
492inline void operator delete(void* /*ptr*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * /*doc*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMMemoryManager::NodeObjectType /*type*/)
493{
494    return;
495}
496
497inline void operator delete(void* /*ptr*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocumentImpl * /*doc*/)
498{
499    return;
500}
501inline void operator delete(void* /*ptr*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * /*doc*/)
502{
503    return;
504}
505#endif
506
507#endif
Note: See TracBrowser for help on using the repository browser.