blob: 5a0931f482d8403cd006dd7af4a845b345bf096f [file] [log] [blame]
// 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 = nullptr) 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 = nullptr) 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 = nullptr);
virtual FX_BOOL LoadXML(CFDE_XMLParser* pXMLParser);
virtual int32_t DoLoad(IFX_Pause* pPause = nullptr);
virtual void CloseXML();
virtual CFDE_XMLNode* GetRoot() const { return m_pRoot; }
virtual void SaveXML(IFX_Stream* pXMLStream = nullptr,
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_ArrayTemplate<FX_WCHAR*> m_BlockArray;
int32_t m_iDataLength;
int32_t m_iBufferSize;
int32_t m_iAllocStep;
int32_t m_iStartPosition;
};
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);
FDE_XmlSyntaxResult 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:
enum class FDE_XmlSyntaxState {
Text,
Node,
Target,
Tag,
AttriName,
AttriEqualSign,
AttriQuotation,
AttriValue,
Entity,
EntityDecimal,
EntityHex,
CloseInstruction,
BreakElement,
CloseElement,
SkipDeclNode,
DeclCharData,
SkipComment,
SkipCommentOrDecl,
SkipCData,
TargetData
};
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;
FDE_XmlSyntaxResult m_syntaxParserResult;
FDE_XmlSyntaxState m_syntaxParserState;
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_