1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #ifndef XFA_FDE_XML_CFX_SAXREADER_H_
8 #define XFA_FDE_XML_CFX_SAXREADER_H_
9 
10 #include <memory>
11 #include <stack>
12 
13 #include "core/fxcrt/fx_basic.h"
14 
15 class CXFA_SAXContext;
16 
17 class CFX_SAXItem {
18  public:
19   enum class Type {
20     Unknown = 0,
21     Instruction,
22     Declaration,
23     Comment,
24     Tag,
25     Text,
26     CharData,
27   };
28 
CFX_SAXItem(uint32_t id)29   explicit CFX_SAXItem(uint32_t id)
30       : m_pNode(nullptr), m_eNode(Type::Unknown), m_dwID(id), m_bSkip(false) {}
31 
32   CXFA_SAXContext* m_pNode;
33   Type m_eNode;
34   const uint32_t m_dwID;
35   bool m_bSkip;
36 };
37 
38 class CFX_SAXFile {
39  public:
40   CFX_SAXFile();
41   ~CFX_SAXFile();
42 
43   bool StartFile(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
44                  uint32_t dwStart,
45                  uint32_t dwLen);
46   bool ReadNextBlock();
47   void Reset();
48 
49   CFX_RetainPtr<IFX_SeekableReadStream> m_pFile;
50   uint32_t m_dwStart;
51   uint32_t m_dwEnd;
52   uint32_t m_dwCur;
53   uint8_t* m_pBuf;
54   uint32_t m_dwBufSize;
55   uint32_t m_dwBufIndex;
56 };
57 
58 class CFX_SAXCommentContext;
59 enum class CFX_SaxMode;
60 
61 enum CFX_SaxParseMode {
62   CFX_SaxParseMode_NotConvert_amp = 1 << 0,
63   CFX_SaxParseMode_NotConvert_lt = 1 << 1,
64   CFX_SaxParseMode_NotConvert_gt = 1 << 2,
65   CFX_SaxParseMode_NotConvert_apos = 1 << 3,
66   CFX_SaxParseMode_NotConvert_quot = 1 << 4,
67   CFX_SaxParseMode_NotConvert_sharp = 1 << 5,
68   CFX_SaxParseMode_NotSkipSpace = 1 << 6
69 };
70 
71 class CXFA_SAXReaderHandler;
72 
73 class CFX_SAXReader {
74  public:
75   CFX_SAXReader();
76   ~CFX_SAXReader();
77 
78   int32_t StartParse(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
79                      uint32_t dwStart = 0,
80                      uint32_t dwLen = -1,
81                      uint32_t dwParseMode = 0);
82   int32_t ContinueParse(IFX_Pause* pPause = nullptr);
83   void SkipCurrentNode();
84   void SetHandler(CXFA_SAXReaderHandler* pHandler);
85   void AppendData(uint8_t ch);
86   void AppendName(uint8_t ch);
87   void ParseText();
88   void ParseNodeStart();
89   void ParseInstruction();
90   void ParseDeclOrComment();
91   void ParseDeclNode();
92   void ParseComment();
93   void ParseCommentContent();
94   void ParseTagName();
95   void ParseTagAttributeName();
96   void ParseTagAttributeEqual();
97   void ParseTagAttributeValue();
98   void ParseMaybeClose();
99   void ParseTagClose();
100   void ParseTagEnd();
101   void ParseTargetData();
102 
103  private:
104   void Reset();
105   void Push();
106   void Pop();
107   CFX_SAXItem* GetCurrentItem() const;
108   bool SkipSpace(uint8_t ch);
109   void SkipNode();
110   void NotifyData();
111   void NotifyEnter();
112   void NotifyAttribute();
113   void NotifyBreak();
114   void NotifyClose();
115   void NotifyEnd();
116   void NotifyTargetData();
117   void ReallocDataBuffer();
118   void ReallocNameBuffer();
119   void ParseChar(uint8_t ch);
120 
121   CFX_SAXFile m_File;
122   CXFA_SAXReaderHandler* m_pHandler;
123   int32_t m_iState;
124   std::stack<std::unique_ptr<CFX_SAXItem>> m_Stack;
125   uint32_t m_dwItemID;
126   CFX_SaxMode m_eMode;
127   CFX_SaxMode m_ePrevMode;
128   bool m_bCharData;
129   uint8_t m_CurByte;
130   uint32_t m_dwDataOffset;
131   CFX_ArrayTemplate<uint8_t> m_SkipStack;
132   uint8_t m_SkipChar;
133   uint32_t m_dwNodePos;
134   uint8_t* m_pszData;
135   int32_t m_iDataSize;
136   int32_t m_iDataLength;
137   int32_t m_iEntityStart;
138   int32_t m_iDataPos;
139   uint8_t* m_pszName;
140   int32_t m_iNameSize;
141   int32_t m_iNameLength;
142   uint32_t m_dwParseMode;
143   CFX_SAXCommentContext* m_pCommentContext;
144 };
145 
146 #endif  // XFA_FDE_XML_CFX_SAXREADER_H_
147