// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#ifndef XFA_FDE_XML_FDE_XML_IMP_H_
#define XFA_FDE_XML_FDE_XML_IMP_H_

#include "core/fxcrt/include/fx_system.h"
#include "xfa/fde/xml/fde_xml.h"
#include "xfa/fgas/crt/fgas_memory.h"
#include "xfa/fgas/crt/fgas_stream.h"

class CFDE_BlockBuffer;
class CFDE_XMLInstruction;
class CFDE_XMLElement;
class CFDE_XMLText;
class CFDE_XMLDoc;
class CFDE_XMLDOMParser;
class CFDE_XMLParser;
class CFDE_XMLSAXParser;
class CFDE_XMLSyntaxParser;

class CFDE_XMLNode : public CFX_Target {
 public:
  enum NodeItem {
    Root = 0,
    Parent,
    FirstSibling,
    PriorSibling,
    NextSibling,
    LastSibling,
    FirstNeighbor,
    PriorNeighbor,
    NextNeighbor,
    LastNeighbor,
    FirstChild,
    LastChild
  };

  CFDE_XMLNode();

  virtual void Release() { delete this; }
  virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Unknown; }
  virtual int32_t CountChildNodes() const;
  virtual CFDE_XMLNode* GetChildNode(int32_t index) const;
  virtual int32_t GetChildNodeIndex(CFDE_XMLNode* pNode) const;
  virtual CFDE_XMLNode* GetPath(const FX_WCHAR* pPath,
                                int32_t iLength = -1,
                                FX_BOOL bQualifiedName = TRUE) const;
  virtual int32_t InsertChildNode(CFDE_XMLNode* pNode, int32_t index = -1);
  virtual void RemoveChildNode(CFDE_XMLNode* pNode);
  virtual void DeleteChildren();
  virtual CFDE_XMLNode* GetNodeItem(CFDE_XMLNode::NodeItem eItem) const;
  virtual int32_t GetNodeLevel() const;
  virtual FX_BOOL InsertNodeItem(CFDE_XMLNode::NodeItem eItem,
                                 CFDE_XMLNode* pNode);
  virtual CFDE_XMLNode* RemoveNodeItem(CFDE_XMLNode::NodeItem eItem);
  virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
  virtual void SaveXMLNode(IFX_Stream* pXMLStream);

 public:
  ~CFDE_XMLNode();
  void CloneChildren(CFDE_XMLNode* pClone);
  CFDE_XMLNode* m_pParent;
  CFDE_XMLNode* m_pChild;
  CFDE_XMLNode* m_pPrior;
  CFDE_XMLNode* m_pNext;
};
class CFDE_XMLInstruction : public CFDE_XMLNode {
 public:
  CFDE_XMLInstruction(const CFX_WideString& wsTarget);
  virtual void Release() { delete this; }
  virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Instruction; }
  virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
  virtual void GetTargetName(CFX_WideString& wsTarget) const {
    wsTarget = m_wsTarget;
  }
  virtual int32_t CountAttributes() const;
  virtual FX_BOOL GetAttribute(int32_t index,
                               CFX_WideString& wsAttriName,
                               CFX_WideString& wsAttriValue) const;
  virtual FX_BOOL HasAttribute(const FX_WCHAR* pwsAttriName) const;
  virtual void GetString(const FX_WCHAR* pwsAttriName,
                         CFX_WideString& wsAttriValue,
                         const FX_WCHAR* pwsDefValue = NULL) const;
  virtual void SetString(const CFX_WideString& wsAttriName,
                         const CFX_WideString& wsAttriValue);
  virtual int32_t GetInteger(const FX_WCHAR* pwsAttriName,
                             int32_t iDefValue = 0) const;
  virtual void SetInteger(const FX_WCHAR* pwsAttriName, int32_t iAttriValue);
  virtual FX_FLOAT GetFloat(const FX_WCHAR* pwsAttriName,
                            FX_FLOAT fDefValue = 0) const;
  virtual void SetFloat(const FX_WCHAR* pwsAttriName, FX_FLOAT fAttriValue);
  virtual void RemoveAttribute(const FX_WCHAR* pwsAttriName);
  virtual int32_t CountData() const;
  virtual FX_BOOL GetData(int32_t index, CFX_WideString& wsData) const;
  virtual void AppendData(const CFX_WideString& wsData);
  virtual void RemoveData(int32_t index);

 public:
  ~CFDE_XMLInstruction() {}
  CFX_WideString m_wsTarget;
  CFX_WideStringArray m_Attributes;
  CFX_WideStringArray m_TargetData;
};
class CFDE_XMLElement : public CFDE_XMLNode {
 public:
  CFDE_XMLElement(const CFX_WideString& wsTag);
  virtual void Release() { delete this; }
  virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Element; }
  virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
  virtual void GetTagName(CFX_WideString& wsTag) const;
  virtual void GetLocalTagName(CFX_WideString& wsTag) const;
  virtual void GetNamespacePrefix(CFX_WideString& wsPrefix) const;
  virtual void GetNamespaceURI(CFX_WideString& wsNamespace) const;
  virtual int32_t CountAttributes() const;
  virtual FX_BOOL GetAttribute(int32_t index,
                               CFX_WideString& wsAttriName,
                               CFX_WideString& wsAttriValue) const;
  virtual FX_BOOL HasAttribute(const FX_WCHAR* pwsAttriName) const;
  virtual void GetString(const FX_WCHAR* pwsAttriName,
                         CFX_WideString& wsAttriValue,
                         const FX_WCHAR* pwsDefValue = NULL) const;
  virtual void SetString(const CFX_WideString& wsAttriName,
                         const CFX_WideString& wsAttriValue);
  virtual int32_t GetInteger(const FX_WCHAR* pwsAttriName,
                             int32_t iDefValue = 0) const;
  virtual void SetInteger(const FX_WCHAR* pwsAttriName, int32_t iAttriValue);
  virtual FX_FLOAT GetFloat(const FX_WCHAR* pwsAttriName,
                            FX_FLOAT fDefValue = 0) const;
  virtual void SetFloat(const FX_WCHAR* pwsAttriName, FX_FLOAT fAttriValue);
  virtual void RemoveAttribute(const FX_WCHAR* pwsAttriName);
  virtual void GetTextData(CFX_WideString& wsText) const;
  virtual void SetTextData(const CFX_WideString& wsText);

 public:
  ~CFDE_XMLElement();
  CFX_WideString m_wsTag;
  CFX_WideStringArray m_Attributes;
};
class CFDE_XMLText : public CFDE_XMLNode {
 public:
  CFDE_XMLText(const CFX_WideString& wsText);
  virtual void Release() { delete this; }
  virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Text; }
  virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
  virtual void GetText(CFX_WideString& wsText) const { wsText = m_wsText; }
  virtual void SetText(const CFX_WideString& wsText) { m_wsText = wsText; }

 public:
  ~CFDE_XMLText() {}
  CFX_WideString m_wsText;
};
class CFDE_XMLDeclaration : public CFDE_XMLNode {
 public:
  CFDE_XMLDeclaration() : CFDE_XMLNode() {}
};
class CFDE_XMLCharData : public CFDE_XMLDeclaration {
 public:
  CFDE_XMLCharData(const CFX_WideString& wsCData);

  virtual void Release() { delete this; }
  virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_CharData; }
  virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
  virtual void GetCharData(CFX_WideString& wsCharData) const {
    wsCharData = m_wsCharData;
  }
  virtual void SetCharData(const CFX_WideString& wsCData) {
    m_wsCharData = wsCData;
  }

 public:
  ~CFDE_XMLCharData() {}

  CFX_WideString m_wsCharData;
};
class CFDE_XMLDoc : public CFX_Target {
 public:
  CFDE_XMLDoc();
  ~CFDE_XMLDoc();
  virtual void Release() { delete this; }
  virtual FX_BOOL LoadXML(IFX_Stream* pXMLStream,
                          int32_t iXMLPlaneSize = 8192,
                          int32_t iTextDataSize = 256,
                          FDE_XMLREADERHANDLER* pHandler = NULL);
  virtual FX_BOOL LoadXML(CFDE_XMLParser* pXMLParser);
  virtual int32_t DoLoad(IFX_Pause* pPause = NULL);
  virtual void CloseXML();
  virtual CFDE_XMLNode* GetRoot() const { return m_pRoot; }
  virtual void SaveXML(IFX_Stream* pXMLStream = NULL, FX_BOOL bSaveBOM = TRUE);
  virtual void SaveXMLNode(IFX_Stream* pXMLStream, CFDE_XMLNode* pNode);

 protected:
  IFX_Stream* m_pStream;
  int32_t m_iStatus;
  CFDE_XMLNode* m_pRoot;
  CFDE_XMLSyntaxParser* m_pSyntaxParser;
  CFDE_XMLParser* m_pXMLParser;
  void Reset(FX_BOOL bInitRoot);
  void ReleaseParser();
};
typedef CFX_StackTemplate<CFDE_XMLNode*> CFDE_XMLDOMNodeStack;

class CFDE_XMLParser {
 public:
  virtual ~CFDE_XMLParser() {}

  virtual void Release() = 0;
  virtual int32_t DoParser(IFX_Pause* pPause) = 0;
};

class CFDE_XMLDOMParser : public CFDE_XMLParser, public CFX_Target {
 public:
  CFDE_XMLDOMParser(CFDE_XMLNode* pRoot, CFDE_XMLSyntaxParser* pParser);
  ~CFDE_XMLDOMParser();

  virtual void Release() { delete this; }
  virtual int32_t DoParser(IFX_Pause* pPause);

 private:
  CFDE_XMLSyntaxParser* m_pParser;
  CFDE_XMLNode* m_pParent;
  CFDE_XMLNode* m_pChild;
  CFDE_XMLDOMNodeStack m_NodeStack;
  CFX_WideString m_ws1;
  CFX_WideString m_ws2;
};
class CFDE_XMLTAG : public CFX_Target {
 public:
  CFDE_XMLTAG() : eType(FDE_XMLNODE_Unknown) {}
  CFDE_XMLTAG(const CFDE_XMLTAG& src)
      : wsTagName(src.wsTagName), eType(src.eType) {}
  CFX_WideString wsTagName;
  FDE_XMLNODETYPE eType;
};
typedef CFX_ObjectStackTemplate<CFDE_XMLTAG> CFDE_XMLTagStack;
class CFDE_XMLSAXParser : public CFDE_XMLParser, public CFX_Target {
 public:
  CFDE_XMLSAXParser(FDE_XMLREADERHANDLER* pHandler,
                    CFDE_XMLSyntaxParser* pParser);
  ~CFDE_XMLSAXParser();

  virtual void Release() { delete this; }
  virtual int32_t DoParser(IFX_Pause* pPause);

 private:
  void Push(const CFDE_XMLTAG& xmlTag);
  void Pop();
  FDE_XMLREADERHANDLER* m_pHandler;
  CFDE_XMLSyntaxParser* m_pParser;
  CFDE_XMLTagStack m_TagStack;
  CFDE_XMLTAG* m_pTagTop;
  CFX_WideString m_ws1;
  CFX_WideString m_ws2;
};

class CFDE_BlockBuffer : public CFX_Target {
 public:
  CFDE_BlockBuffer(int32_t iAllocStep = 1024 * 1024);
  ~CFDE_BlockBuffer();

  FX_BOOL InitBuffer(int32_t iBufferSize = 1024 * 1024);
  FX_BOOL IsInitialized() { return m_iBufferSize / m_iAllocStep >= 1; }
  void ReleaseBuffer() { delete this; }
  FX_WCHAR* GetAvailableBlock(int32_t& iIndexInBlock);
  inline int32_t GetAllocStep() const { return m_iAllocStep; }
  inline int32_t& GetDataLengthRef() { return m_iDataLength; }
  inline void Reset(FX_BOOL bReserveData = TRUE) {
    if (!bReserveData) {
      m_iStartPosition = 0;
    }
    m_iDataLength = 0;
  }
  void SetTextChar(int32_t iIndex, FX_WCHAR ch);
  int32_t DeleteTextChars(int32_t iCount, FX_BOOL bDirection = TRUE);
  void GetTextData(CFX_WideString& wsTextData,
                   int32_t iStart = 0,
                   int32_t iLength = -1) const;

 protected:
  inline void TextDataIndex2BufIndex(const int32_t iIndex,
                                     int32_t& iBlockIndex,
                                     int32_t& iInnerIndex) const;
  void ClearBuffer();
  CFX_PtrArray m_BlockArray;
  int32_t m_iDataLength;
  int32_t m_iBufferSize;
  int32_t m_iAllocStep;
  int32_t m_iStartPosition;
};

#define FDE_XMLSYNTAXMODE_Text 0
#define FDE_XMLSYNTAXMODE_Node 1
#define FDE_XMLSYNTAXMODE_Target 2
#define FDE_XMLSYNTAXMODE_Tag 3
#define FDE_XMLSYNTAXMODE_AttriName 4
#define FDE_XMLSYNTAXMODE_AttriEqualSign 5
#define FDE_XMLSYNTAXMODE_AttriQuotation 6
#define FDE_XMLSYNTAXMODE_AttriValue 7
#define FDE_XMLSYNTAXMODE_Entity 8
#define FDE_XMLSYNTAXMODE_EntityDecimal 9
#define FDE_XMLSYNTAXMODE_EntityHex 10
#define FDE_XMLSYNTAXMODE_CloseInstruction 11
#define FDE_XMLSYNTAXMODE_BreakElement 12
#define FDE_XMLSYNTAXMODE_CloseElement 13
#define FDE_XMLSYNTAXMODE_SkipDeclNode 14
#define FDE_XMLSYNTAXMODE_DeclCharData 15
#define FDE_XMLSYNTAXMODE_SkipComment 16
#define FDE_XMLSYNTAXMODE_SkipCommentOrDecl 17
#define FDE_XMLSYNTAXMODE_SkipCData 18
#define FDE_XMLSYNTAXMODE_TargetData 19

class CFDE_XMLSyntaxParser : public CFX_Target {
 public:
  CFDE_XMLSyntaxParser();
  ~CFDE_XMLSyntaxParser();
  void Release() { delete this; }
  void Init(IFX_Stream* pStream,
            int32_t iXMLPlaneSize,
            int32_t iTextDataSize = 256);
  uint32_t DoSyntaxParse();
  int32_t GetStatus() const;
  int32_t GetCurrentPos() const {
    return m_iParsedChars + (m_pStart - m_pBuffer);
  }
  FX_FILESIZE GetCurrentBinaryPos() const;
  int32_t GetCurrentNodeNumber() const { return m_iCurrentNodeNum; }
  int32_t GetLastNodeNumber() const { return m_iLastNodeNum; }

  void GetTargetName(CFX_WideString& wsTarget) const {
    m_BlockBuffer.GetTextData(wsTarget, 0, m_iTextDataLength);
  }
  void GetTagName(CFX_WideString& wsTag) const {
    m_BlockBuffer.GetTextData(wsTag, 0, m_iTextDataLength);
  }
  void GetAttributeName(CFX_WideString& wsAttriName) const {
    m_BlockBuffer.GetTextData(wsAttriName, 0, m_iTextDataLength);
  }
  void GetAttributeValue(CFX_WideString& wsAttriValue) const {
    m_BlockBuffer.GetTextData(wsAttriValue, 0, m_iTextDataLength);
  }
  void GetTextData(CFX_WideString& wsText) const {
    m_BlockBuffer.GetTextData(wsText, 0, m_iTextDataLength);
  }
  void GetTargetData(CFX_WideString& wsData) const {
    m_BlockBuffer.GetTextData(wsData, 0, m_iTextDataLength);
  }

 protected:
  IFX_Stream* m_pStream;
  int32_t m_iXMLPlaneSize;
  int32_t m_iCurrentPos;
  int32_t m_iCurrentNodeNum;
  int32_t m_iLastNodeNum;
  int32_t m_iParsedChars;
  int32_t m_iParsedBytes;
  FX_WCHAR* m_pBuffer;
  int32_t m_iBufferChars;
  FX_BOOL m_bEOS;
  FX_WCHAR* m_pStart;
  FX_WCHAR* m_pEnd;
  FDE_XMLNODE m_CurNode;
  CFDE_XMLNodeStack m_XMLNodeStack;
  CFDE_BlockBuffer m_BlockBuffer;
  int32_t m_iAllocStep;
  int32_t& m_iDataLength;
  FX_WCHAR* m_pCurrentBlock;
  int32_t m_iIndexInBlock;
  int32_t m_iTextDataLength;
  uint32_t m_dwStatus;
  uint32_t m_dwMode;
  FX_WCHAR m_wQuotationMark;
  int32_t m_iEntityStart;
  CFX_DWordStack m_SkipStack;
  FX_WCHAR m_SkipChar;
  inline void ParseTextChar(FX_WCHAR ch);
};

#endif  // XFA_FDE_XML_FDE_XML_IMP_H_
