/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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$
 */

#if !defined(XERCESC_INCLUDE_GUARD_DOMDOCUMENTIMPL_HPP)
#define XERCESC_INCLUDE_GUARD_DOMDOCUMENTIMPL_HPP

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/RefArrayOf.hpp>
#include <xercesc/util/RefStackOf.hpp>
#include <xercesc/util/RefHash2KeysTableOf.hpp>
#include <xercesc/util/StringPool.hpp>
#include <xercesc/util/KeyRefPair.hpp>
#include <xercesc/util/XMLChar.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMUserDataHandler.hpp>
#include <xercesc/dom/DOMMemoryManager.hpp>
#include "DOMNodeBase.hpp"
#include "DOMNodeImpl.hpp"
#include "DOMStringPool.hpp"
#include "DOMParentNode.hpp"
#include "DOMDeepNodeListPool.hpp"

namespace XERCES_CPP_NAMESPACE {


class DOMAttrImpl;
class DOMCDATASectionImpl;
class DOMCommentImpl;
class DOMConfiguration;
class DOMDeepNodeListImpl;
class DOMDocumentFragmentImpl;
class DOMDocumentTypeImpl;
class DOMElementImpl;
class DOMEntityImpl;
class DOMEntityReferenceImpl;
class DOMNotationImpl;
class DOMProcessingInstructionImpl;
class DOMTextImpl;
class DOMNodeIteratorImpl;
class DOMNormalizer;
class DOMTreeWalkerImpl;
class DOMNodeFilter;
class DOMNodeFilterImpl;
class DOMImplementation;
class DOMNodeIDMap;
class DOMRangeImpl;
class DOMBuffer;
class MemoryManager;
class XPathNSResolver;
class XPathExpression;

typedef RefVectorOf<DOMRangeImpl>        Ranges;
typedef RefVectorOf<DOMNodeIteratorImpl>     NodeIterators;
typedef KeyRefPair<void, DOMUserDataHandler> DOMUserDataRecord;
typedef RefStackOf<DOMNode>               DOMNodePtr;

class CDOM_EXPORT DOMDocumentImpl: public XMemory, public DOMMemoryManager, public DOMDocument,
        public HasDOMNodeImpl, public HasDOMParentImpl {
public:
    // -----------------------------------------------------------------------
    //  data
    // -----------------------------------------------------------------------
    DOMNodeImpl           fNode;           // Implements common node functionality.
    DOMParentNode         fParent;         // Implements common parent node functionality
    DOMNodeIDMap*         fNodeIDMap;     // for use by GetElementsById().

public:
    DOMDocumentImpl(DOMImplementation* domImpl, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
    DOMDocumentImpl(const XMLCh*     namespaceURI,     //DOM Level 2
                    const XMLCh*     qualifiedName,
                    DOMDocumentType* doctype,
                    DOMImplementation* domImpl,
                    MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
    virtual ~DOMDocumentImpl();

    void                         setDocumentType(DOMDocumentType *doctype);

public:
    // Add all functions that are pure virtual in DOMNODE
    DOMNODE_FUNCTIONS;

    // Add accessors for implementation bits.
    DOMNODEIMPL_DECL;
    DOMPARENTIMPL_DECL;

public:
    // Add all functions that are pure virtual in DOMDocument
    virtual DOMAttr*             createAttribute(const XMLCh *name);
    virtual DOMCDATASection*     createCDATASection(const XMLCh *data);
    virtual DOMComment*          createComment(const XMLCh *data);
    virtual DOMDocumentFragment* createDocumentFragment();
    virtual DOMDocumentType*     createDocumentType(const XMLCh *name);
    virtual DOMDocumentType*     createDocumentType(const XMLCh *qName,
                                                    const XMLCh *publicId,
                                                    const XMLCh *systemId);
    virtual DOMElement*          createElement(const XMLCh * tagName);
    virtual DOMElement*          createElementNoCheck(const XMLCh *tagName);
    virtual DOMEntity*           createEntity(const XMLCh * name);
    virtual DOMEntityReference*  createEntityReference(const XMLCh * name);
    virtual DOMNotation*         createNotation(const XMLCh * name);
    virtual DOMProcessingInstruction* createProcessingInstruction(const XMLCh * target, const XMLCh * data);
    virtual DOMText*             createTextNode(const XMLCh * data);
    virtual DOMDocumentType*     getDoctype() const;
    virtual DOMElement*          getDocumentElement() const;
    virtual DOMNodeList*         getElementsByTagName(const XMLCh * tagname) const;
    virtual DOMImplementation*   getImplementation() const;
    bool                         isXMLName(const XMLCh * s);
    virtual DOMNodeIterator*     createNodeIterator(DOMNode *root,
                                                    DOMNodeFilter::ShowType whatToShow,
                                                    DOMNodeFilter* filter,
                                                    bool entityReferenceExpansion);
    virtual DOMTreeWalker*       createTreeWalker(DOMNode *root,
                                                  DOMNodeFilter::ShowType whatToShow,
                                                  DOMNodeFilter* filter,
                                                  bool entityReferenceExpansion);


    virtual DOMRange*            createRange();
    virtual Ranges*              getRanges() const;  //non-standard api
    virtual NodeIterators*       getNodeIterators() const;  //non-standard api
    virtual void                 removeRange(DOMRangeImpl* range); //non-standard api
    virtual void                 removeNodeIterator(DOMNodeIteratorImpl* nodeIterator); //non-standard api

    virtual DOMXPathExpression* createExpression(const XMLCh *expression,
                                                 const DOMXPathNSResolver *resolver);
    virtual DOMXPathNSResolver* createNSResolver(const DOMNode *nodeResolver);
    virtual DOMXPathResult* evaluate(const XMLCh *expression,
                                     const DOMNode *contextNode,
                                     const DOMXPathNSResolver *resolver,
                                     DOMXPathResult::ResultType type,
                                     DOMXPathResult* result);


    // Extension to be called by the Parser
    DOMEntityReference*  createEntityReferenceByParser(const XMLCh * name);

    // Add all functions that are pure virtual in DOMMemoryManager
    virtual XMLSize_t getMemoryAllocationBlockSize() const;
    virtual void setMemoryAllocationBlockSize(XMLSize_t size);
    virtual void* allocate(XMLSize_t amount);
    virtual void* allocate(XMLSize_t amount, DOMMemoryManager::NodeObjectType type);
    // try to remove the block from the list of allocated memory
    virtual void release(void* oldBuffer);
    virtual void release(DOMNode* object, DOMMemoryManager::NodeObjectType type);
    virtual XMLCh* cloneString(const XMLCh *src);

    //
    // Functions to keep track of document mutations, so that node list chached
    //   information can be invalidated.  One global changes counter per document.
    //
    virtual void                 changed();
    virtual int                  changes() const;

    /**
     * Sets whether the DOM implementation performs error checking
     * upon operations. Turning off error checking only affects
     * the following DOM checks:
     * <ul>
     * <li>Checking strings to make sure that all characters are
     *     legal XML characters
     * <li>Hierarchy checking such as allowed children, checks for
     *     cycles, etc.
     * </ul>
     * <p>
     * Turning off error checking does <em>not</em> turn off the
     * following checks:
     * <ul>
     * <li>Read only checks
     * <li>Checks related to DOM events
     * </ul>
     */
    inline void setErrorChecking(bool check) {
        errorChecking = check;
    }

    /**
     * Returns true if the DOM implementation performs error checking.
     */
    inline bool getErrorChecking() const {
        return errorChecking;
    }

    //Introduced in DOM Level 2
    virtual DOMNode*             importNode(const DOMNode *source, bool deep);
    virtual DOMElement*          createElementNS(const XMLCh *namespaceURI,
                                                 const XMLCh *qualifiedName);
    virtual DOMElement*          createElementNS(const XMLCh *namespaceURI,
                                                 const XMLCh *qualifiedName,
                                                 const XMLFileLoc lineNo,
                                                 const XMLFileLoc columnNo);
    virtual DOMAttr*             createAttributeNS(const XMLCh *namespaceURI,
                                                   const XMLCh *qualifiedName);
    virtual DOMNodeList*         getElementsByTagNameNS(const XMLCh *namespaceURI,
                                                        const XMLCh *localName) const;
    virtual DOMElement*          getElementById(const XMLCh *elementId) const;

    //Introduced in DOM Level 3
    virtual const XMLCh*         getInputEncoding() const;
    virtual const XMLCh*         getXmlEncoding() const;
    virtual bool                 getXmlStandalone() const;
    virtual void                 setXmlStandalone(bool standalone);
    virtual const XMLCh*         getXmlVersion() const;
    virtual void                 setXmlVersion(const XMLCh* version);
    virtual const XMLCh*         getDocumentURI() const;
    virtual void                 setDocumentURI(const XMLCh* documentURI);
    virtual bool                 getStrictErrorChecking() const;
    virtual void                 setStrictErrorChecking(bool strictErrorChecking);
    virtual DOMNode*             adoptNode(DOMNode* source);
    virtual void                 normalizeDocument();
    virtual DOMConfiguration*    getDOMConfig() const;

    void                         setInputEncoding(const XMLCh* actualEncoding);
    void                         setXmlEncoding(const XMLCh* encoding);
    // helper functions to prevent storing userdata pointers on every node.
    void*                        setUserData(DOMNodeImpl* n,
                                            const XMLCh* key,
                                            void* data,
                                            DOMUserDataHandler* handler);
    void*                        getUserData(const DOMNodeImpl* n,
                                             const XMLCh* key) const;
    void                         callUserDataHandlers(const DOMNodeImpl* n,
                                                      DOMUserDataHandler::DOMOperationType operation,
                                                      const DOMNode* src,
                                                      DOMNode* dst) const;
    void                         transferUserData(DOMNodeImpl* n1, DOMNodeImpl* n2);

    DOMNode*                     renameNode(DOMNode* n,
                                            const XMLCh* namespaceURI,
                                            const XMLCh* name);

    //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".
    static  int                  indexofQualifiedName(const XMLCh * qName);
    static  bool                 isKidOK(const DOMNode *parent, const DOMNode *child);

    inline DOMNodeIDMap*         getNodeIDMap() {return fNodeIDMap;};


    //
    // Memory Management Functions.  All memory is allocated by and owned by
    //                               a document, and is not recovered until the
    //                               document itself is deleted.
    //
    const XMLCh*                 getPooledString(const XMLCh*);
    const XMLCh*                 getPooledNString(const XMLCh*, XMLSize_t);
    void                         deleteHeap();
    void                         releaseDocNotifyUserData(DOMNode* object);
    void                         releaseBuffer(DOMBuffer* buffer);
    DOMBuffer*                   popBuffer(XMLSize_t nMinSize);
    MemoryManager*               getMemoryManager() const;

    // Factory methods for getting/creating node lists.
    // Because nothing is ever deleted, the implementation caches and recycles
    //  previously used instances of DOMDeepNodeList
    //
    DOMNodeList*                 getDeepNodeList(const DOMNode *rootNode, const XMLCh *tagName);
    DOMNodeList*                 getDeepNodeList(const DOMNode *rootNode,    //DOM Level 2
                                                 const XMLCh *namespaceURI,
                                                 const XMLCh *localName);

protected:
    //Internal helper functions
    virtual DOMNode*             importNode(const DOMNode *source, bool deep, bool cloningNode);

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMDocumentImpl(const DOMDocumentImpl &);
    DOMDocumentImpl & operator = (const DOMDocumentImpl &);

protected:
    // -----------------------------------------------------------------------
    //  data
    // -----------------------------------------------------------------------
    // New data introduced in DOM Level 3
    const XMLCh*          fInputEncoding;
    const XMLCh*          fXmlEncoding;
    bool                  fXmlStandalone;
    const XMLCh*          fXmlVersion;
    const XMLCh*          fDocumentURI;
    DOMConfiguration*     fDOMConfiguration;

    XMLStringPool         fUserDataTableKeys;
    RefHash2KeysTableOf<DOMUserDataRecord, PtrHasher>* fUserDataTable;


    // Per-Document heap Variables.
    //   The heap consists of one or more biggish blocks which are
    //   sub-allocated for individual allocations of nodes, strings, etc.
    //   The big blocks form a linked list, allowing them to be located for deletion.
    //
    //   There is no provision for deleting suballocated blocks, other than
    //     deleting the entire heap when the document is deleted.
    //
    //   There is no header on individual sub-allocated blocks.
    //   The header on big blocks consists only of a single back pointer to
    //    the previously allocated big block (our linked list of big blocks)
    //
    //
    //   revisit - this heap should be encapsulated into its own
    //                  class, rather than hanging naked on Document.
    //
    void*                 fCurrentBlock;
    void*                 fCurrentSingletonBlock;
    char*                 fFreePtr;
    XMLSize_t             fFreeBytesRemaining,
                          fHeapAllocSize;

    // To recycle the DOMNode pointer
    RefArrayOf<DOMNodePtr>* fRecycleNodePtr;

    // To recycle DOMBuffer pointer
    RefStackOf<DOMBuffer>* fRecycleBufferPtr;

    // Pool of DOMNodeList for getElementsByTagName
    DOMDeepNodeListPool<DOMDeepNodeListImpl>* fNodeListPool;

    // Other data
    DOMDocumentType*      fDocType;
    DOMElement*           fDocElement;

    DOMStringPoolEntry**  fNameTable;
    XMLSize_t             fNameTableSize;

    DOMNormalizer*        fNormalizer;
    Ranges*               fRanges;
    NodeIterators*        fNodeIterators;
    MemoryManager*        fMemoryManager;   // configurable memory manager
    DOMImplementation*    fDOMImplementation;

    int                   fChanges;
    bool                  errorChecking;    // Bypass error checking.

};

inline MemoryManager* DOMDocumentImpl::getMemoryManager() const
{
    return fMemoryManager;
}

inline const XMLCh*  DOMDocumentImpl::getPooledString(const XMLCh *in)
{
  if (in == 0)
    return 0;
  XMLSize_t n = XMLString::stringLen(in);

  DOMStringPoolEntry    **pspe;
  DOMStringPoolEntry    *spe;

  XMLSize_t inHash = XMLString::hash(in, fNameTableSize);
  pspe = &fNameTable[inHash];
  while (*pspe != 0)
  {
    if ((*pspe)->fLength == n && XMLString::equals((*pspe)->fString, in))
      return (*pspe)->fString;
    pspe = &((*pspe)->fNext);
  }

  // This string hasn't been seen before.  Add it to the pool.
  //

  // Compute size to allocate.  Note that there's 1 char of string
  // declared in the struct, so we don't need to add one again to
  // account for the trailing null.
  //
  XMLSize_t sizeToAllocate = sizeof(DOMStringPoolEntry) + n*sizeof(XMLCh);
  *pspe = spe = (DOMStringPoolEntry *)allocate(sizeToAllocate);
  spe->fLength = n;
  spe->fNext = 0;
  XMLString::copyString((XMLCh*)spe->fString, in);

  return spe->fString;
}

inline const XMLCh* DOMDocumentImpl::getPooledNString(const XMLCh *in, XMLSize_t n)
{
  if (in == 0)
    return 0;

  DOMStringPoolEntry    **pspe;
  DOMStringPoolEntry    *spe;

  XMLSize_t inHash = XMLString::hashN(in, n, fNameTableSize);
  pspe = &fNameTable[inHash];
  while (*pspe != 0)
  {
    if ((*pspe)->fLength == n && XMLString::equalsN((*pspe)->fString, in, n))
      return (*pspe)->fString;
    pspe = &((*pspe)->fNext);
  }

  // This string hasn't been seen before.  Add it to the pool.
  //

  // Compute size to allocate.  Note that there's 1 char of string
  // declared in the struct, so we don't need to add one again to
  // account for the trailing null.
  //
  XMLSize_t sizeToAllocate = sizeof(DOMStringPoolEntry) + n*sizeof(XMLCh);
  *pspe = spe = (DOMStringPoolEntry *)allocate(sizeToAllocate);
  spe->fLength = n;
  spe->fNext = 0;
  XMLString::copyNString((XMLCh*)spe->fString, in, n);

  return spe->fString;
}

inline int DOMDocumentImpl::indexofQualifiedName(const XMLCh* name)
{
  int i = 0;
  int colon = -1;
  int colon_count = 0;
  for (; *name != 0; ++i, ++name)
  {
    if (*name == chColon)
    {
      ++colon_count;
      colon = i;
    }
  }

  if (i == 0 || colon == 0 || colon == (i - 1) || colon_count > 1)
    return -1;

  return colon != -1 ? colon : 0;
}

}

// ---------------------------------------------------------------------------
//
//  Operator new.  Global overloaded version, lets any object be allocated on
//                 the heap owned by a document.
//
// ---------------------------------------------------------------------------
inline void * operator new(size_t amt, xercesc::DOMDocumentImpl *doc, xercesc::DOMMemoryManager::NodeObjectType type)
{
    void *p = doc->allocate(amt, type);
    return p;
}

inline void * operator new(size_t amt, xercesc::DOMDocument *doc, xercesc::DOMMemoryManager::NodeObjectType type)
{
    xercesc::DOMMemoryManager* mgr=(xercesc::DOMMemoryManager*)doc->getFeature(xercesc::XMLUni::fgXercescInterfaceDOMMemoryManager,0);
    void* p=0;
    if(mgr)
        p = mgr->allocate(amt, type);
    return p;
}

inline void * operator new(size_t amt, xercesc::DOMDocumentImpl *doc)
{
    void* p = doc->allocate(amt);
    return p;
}

inline void * operator new(size_t amt, xercesc::DOMDocument *doc)
{
    xercesc::DOMMemoryManager* mgr=(xercesc::DOMMemoryManager*)doc->getFeature(xercesc::XMLUni::fgXercescInterfaceDOMMemoryManager,0);
    void* p=0;
    if(mgr)
        p = mgr->allocate(amt);
    return p;
}

inline void operator delete(void* /*ptr*/, xercesc::DOMDocumentImpl * /*doc*/, xercesc::DOMMemoryManager::NodeObjectType /*type*/)
{
    return;
}
inline void operator delete(void* /*ptr*/, xercesc::DOMDocument * /*doc*/, xercesc::DOMMemoryManager::NodeObjectType /*type*/)
{
    return;
}

inline void operator delete(void* /*ptr*/, xercesc::DOMDocumentImpl * /*doc*/)
{
    return;
}
inline void operator delete(void* /*ptr*/, xercesc::DOMDocument * /*doc*/)
{
    return;
}

#endif
