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 _FXCRT_XML_INT_
8#define _FXCRT_XML_INT_
9class CXML_DataBufAcc : public IFX_BufferRead, public CFX_Object
10{
11public:
12    CXML_DataBufAcc(FX_LPCBYTE pBuffer, size_t size, IFX_Allocator* pAllocator = NULL)
13        : m_pAllocator(pAllocator)
14        , m_pBuffer(pBuffer)
15        , m_dwSize(size)
16        , m_dwCurPos(0)
17    {
18    }
19    virtual ~CXML_DataBufAcc() {}
20    virtual void			Release()
21    {
22        if (m_pAllocator) {
23            FX_DeleteAtAllocator(this, m_pAllocator, CXML_DataBufAcc);
24        } else {
25            delete this;
26        }
27    }
28    virtual FX_BOOL			IsEOF()
29    {
30        return m_dwCurPos >= m_dwSize;
31    }
32    virtual FX_FILESIZE		GetPosition()
33    {
34        return (FX_FILESIZE)m_dwCurPos;
35    }
36    virtual size_t			ReadBlock(void* buffer, size_t size)
37    {
38        return 0;
39    }
40    virtual FX_BOOL			ReadNextBlock(FX_BOOL bRestart = FALSE)
41    {
42        if (bRestart) {
43            m_dwCurPos = 0;
44        }
45        if (m_dwCurPos < m_dwSize) {
46            m_dwCurPos = m_dwSize;
47            return TRUE;
48        }
49        return FALSE;
50    }
51    virtual FX_LPCBYTE		GetBlockBuffer()
52    {
53        return m_pBuffer;
54    }
55    virtual size_t			GetBlockSize()
56    {
57        return m_dwSize;
58    }
59    virtual FX_FILESIZE		GetBlockOffset()
60    {
61        return 0;
62    }
63protected:
64    IFX_Allocator*	m_pAllocator;
65    FX_LPCBYTE		m_pBuffer;
66    size_t			m_dwSize;
67    size_t			m_dwCurPos;
68};
69#define FX_XMLDATASTREAM_BufferSize		(32 * 1024)
70class CXML_DataStmAcc : public IFX_BufferRead, public CFX_Object
71{
72public:
73    CXML_DataStmAcc(IFX_FileRead *pFileRead, IFX_Allocator* pAllocator = NULL)
74        : m_pAllocator(pAllocator)
75        , m_pFileRead(pFileRead)
76        , m_pBuffer(NULL)
77        , m_nStart(0)
78        , m_dwSize(0)
79    {
80        FXSYS_assert(m_pFileRead != NULL);
81    }
82    virtual ~CXML_DataStmAcc()
83    {
84        if (m_pBuffer) {
85            FX_Allocator_Free(m_pAllocator, m_pBuffer);
86        }
87    }
88    virtual void			Release()
89    {
90        if (m_pAllocator) {
91            FX_DeleteAtAllocator(this, m_pAllocator, CXML_DataStmAcc);
92        } else {
93            delete this;
94        }
95    }
96    virtual FX_BOOL			IsEOF()
97    {
98        return m_nStart + (FX_FILESIZE)m_dwSize >= m_pFileRead->GetSize();
99    }
100    virtual FX_FILESIZE		GetPosition()
101    {
102        return m_nStart + (FX_FILESIZE)m_dwSize;
103    }
104    virtual size_t			ReadBlock(void* buffer, size_t size)
105    {
106        return 0;
107    }
108    virtual FX_BOOL			ReadNextBlock(FX_BOOL bRestart = FALSE)
109    {
110        if (bRestart) {
111            m_nStart = 0;
112        }
113        FX_FILESIZE nLength = m_pFileRead->GetSize();
114        m_nStart += (FX_FILESIZE)m_dwSize;
115        if (m_nStart >= nLength) {
116            return FALSE;
117        }
118        m_dwSize = (size_t)FX_MIN(FX_XMLDATASTREAM_BufferSize, nLength - m_nStart);
119        if (!m_pBuffer) {
120            m_pBuffer = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, m_dwSize);
121            if (!m_pBuffer) {
122                return FALSE;
123            }
124        }
125        return m_pFileRead->ReadBlock(m_pBuffer, m_nStart, m_dwSize);
126    }
127    virtual FX_LPCBYTE		GetBlockBuffer()
128    {
129        return (FX_LPCBYTE)m_pBuffer;
130    }
131    virtual size_t			GetBlockSize()
132    {
133        return m_dwSize;
134    }
135    virtual FX_FILESIZE		GetBlockOffset()
136    {
137        return m_nStart;
138    }
139protected:
140    IFX_Allocator*	m_pAllocator;
141    IFX_FileRead	*m_pFileRead;
142    FX_LPBYTE		m_pBuffer;
143    FX_FILESIZE		m_nStart;
144    size_t			m_dwSize;
145};
146class CXML_Parser
147{
148public:
149    CXML_Parser(IFX_Allocator* pAllocator = NULL) : m_pAllocator(pAllocator) {}
150    ~CXML_Parser();
151    IFX_Allocator*	m_pAllocator;
152    IFX_BufferRead*	m_pDataAcc;
153    FX_BOOL			m_bOwnedStream;
154    FX_FILESIZE		m_nOffset;
155    FX_BOOL			m_bSaveSpaceChars;
156    FX_LPCBYTE		m_pBuffer;
157    size_t			m_dwBufferSize;
158    FX_FILESIZE		m_nBufferOffset;
159    size_t			m_dwIndex;
160    FX_BOOL			Init(FX_LPBYTE pBuffer, size_t size);
161    FX_BOOL			Init(IFX_FileRead *pFileRead);
162    FX_BOOL			Init(IFX_BufferRead *pBuffer);
163    FX_BOOL			Init(FX_BOOL bOwndedStream);
164    FX_BOOL			ReadNextBlock();
165    FX_BOOL			IsEOF();
166    FX_BOOL			HaveAvailData();
167    void			SkipWhiteSpaces();
168    void			GetName(CFX_ByteStringL &space, CFX_ByteStringL &name);
169    void			GetAttrValue(CFX_WideStringL &value);
170    FX_DWORD		GetCharRef();
171    void			GetTagName(CFX_ByteStringL &space, CFX_ByteStringL &name, FX_BOOL &bEndTag, FX_BOOL bStartTag = FALSE);
172    void			SkipLiterals(FX_BSTR str);
173    CXML_Element*	ParseElement(CXML_Element* pParent, FX_BOOL bStartTag = FALSE);
174    void			InsertContentSegment(FX_BOOL bCDATA, FX_WSTR content, CXML_Element* pElement);
175    void			InsertCDATASegment(CFX_UTF8Decoder& decoder, CXML_Element* pElement);
176};
177void FX_XML_SplitQualifiedName(FX_BSTR bsFullName, CFX_ByteStringC &bsSpace, CFX_ByteStringC &bsName);
178#endif
179