// 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 _FXCRT_XML_INT_
#define _FXCRT_XML_INT_
class CXML_DataBufAcc : public IFX_BufferRead, public CFX_Object
{
public:
    CXML_DataBufAcc(FX_LPCBYTE pBuffer, size_t size, IFX_Allocator* pAllocator = NULL)
        : m_pAllocator(pAllocator)
        , m_pBuffer(pBuffer)
        , m_dwSize(size)
        , m_dwCurPos(0)
    {
    }
    virtual ~CXML_DataBufAcc() {}
    virtual void			Release()
    {
        if (m_pAllocator) {
            FX_DeleteAtAllocator(this, m_pAllocator, CXML_DataBufAcc);
        } else {
            delete this;
        }
    }
    virtual FX_BOOL			IsEOF()
    {
        return m_dwCurPos >= m_dwSize;
    }
    virtual FX_FILESIZE		GetPosition()
    {
        return (FX_FILESIZE)m_dwCurPos;
    }
    virtual size_t			ReadBlock(void* buffer, size_t size)
    {
        return 0;
    }
    virtual FX_BOOL			ReadNextBlock(FX_BOOL bRestart = FALSE)
    {
        if (bRestart) {
            m_dwCurPos = 0;
        }
        if (m_dwCurPos < m_dwSize) {
            m_dwCurPos = m_dwSize;
            return TRUE;
        }
        return FALSE;
    }
    virtual FX_LPCBYTE		GetBlockBuffer()
    {
        return m_pBuffer;
    }
    virtual size_t			GetBlockSize()
    {
        return m_dwSize;
    }
    virtual FX_FILESIZE		GetBlockOffset()
    {
        return 0;
    }
protected:
    IFX_Allocator*	m_pAllocator;
    FX_LPCBYTE		m_pBuffer;
    size_t			m_dwSize;
    size_t			m_dwCurPos;
};
#define FX_XMLDATASTREAM_BufferSize		(32 * 1024)
class CXML_DataStmAcc : public IFX_BufferRead, public CFX_Object
{
public:
    CXML_DataStmAcc(IFX_FileRead *pFileRead, IFX_Allocator* pAllocator = NULL)
        : m_pAllocator(pAllocator)
        , m_pFileRead(pFileRead)
        , m_pBuffer(NULL)
        , m_nStart(0)
        , m_dwSize(0)
    {
        FXSYS_assert(m_pFileRead != NULL);
    }
    virtual ~CXML_DataStmAcc()
    {
        if (m_pBuffer) {
            FX_Allocator_Free(m_pAllocator, m_pBuffer);
        }
    }
    virtual void			Release()
    {
        if (m_pAllocator) {
            FX_DeleteAtAllocator(this, m_pAllocator, CXML_DataStmAcc);
        } else {
            delete this;
        }
    }
    virtual FX_BOOL			IsEOF()
    {
        return m_nStart + (FX_FILESIZE)m_dwSize >= m_pFileRead->GetSize();
    }
    virtual FX_FILESIZE		GetPosition()
    {
        return m_nStart + (FX_FILESIZE)m_dwSize;
    }
    virtual size_t			ReadBlock(void* buffer, size_t size)
    {
        return 0;
    }
    virtual FX_BOOL			ReadNextBlock(FX_BOOL bRestart = FALSE)
    {
        if (bRestart) {
            m_nStart = 0;
        }
        FX_FILESIZE nLength = m_pFileRead->GetSize();
        m_nStart += (FX_FILESIZE)m_dwSize;
        if (m_nStart >= nLength) {
            return FALSE;
        }
        m_dwSize = (size_t)FX_MIN(FX_XMLDATASTREAM_BufferSize, nLength - m_nStart);
        if (!m_pBuffer) {
            m_pBuffer = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, m_dwSize);
            if (!m_pBuffer) {
                return FALSE;
            }
        }
        return m_pFileRead->ReadBlock(m_pBuffer, m_nStart, m_dwSize);
    }
    virtual FX_LPCBYTE		GetBlockBuffer()
    {
        return (FX_LPCBYTE)m_pBuffer;
    }
    virtual size_t			GetBlockSize()
    {
        return m_dwSize;
    }
    virtual FX_FILESIZE		GetBlockOffset()
    {
        return m_nStart;
    }
protected:
    IFX_Allocator*	m_pAllocator;
    IFX_FileRead	*m_pFileRead;
    FX_LPBYTE		m_pBuffer;
    FX_FILESIZE		m_nStart;
    size_t			m_dwSize;
};
class CXML_Parser
{
public:
    CXML_Parser(IFX_Allocator* pAllocator = NULL) : m_pAllocator(pAllocator) {}
    ~CXML_Parser();
    IFX_Allocator*	m_pAllocator;
    IFX_BufferRead*	m_pDataAcc;
    FX_BOOL			m_bOwnedStream;
    FX_FILESIZE		m_nOffset;
    FX_BOOL			m_bSaveSpaceChars;
    FX_LPCBYTE		m_pBuffer;
    size_t			m_dwBufferSize;
    FX_FILESIZE		m_nBufferOffset;
    size_t			m_dwIndex;
    FX_BOOL			Init(FX_LPBYTE pBuffer, size_t size);
    FX_BOOL			Init(IFX_FileRead *pFileRead);
    FX_BOOL			Init(IFX_BufferRead *pBuffer);
    FX_BOOL			Init(FX_BOOL bOwndedStream);
    FX_BOOL			ReadNextBlock();
    FX_BOOL			IsEOF();
    FX_BOOL			HaveAvailData();
    void			SkipWhiteSpaces();
    void			GetName(CFX_ByteStringL &space, CFX_ByteStringL &name);
    void			GetAttrValue(CFX_WideStringL &value);
    FX_DWORD		GetCharRef();
    void			GetTagName(CFX_ByteStringL &space, CFX_ByteStringL &name, FX_BOOL &bEndTag, FX_BOOL bStartTag = FALSE);
    void			SkipLiterals(FX_BSTR str);
    CXML_Element*	ParseElement(CXML_Element* pParent, FX_BOOL bStartTag = FALSE);
    void			InsertContentSegment(FX_BOOL bCDATA, FX_WSTR content, CXML_Element* pElement);
    void			InsertCDATASegment(CFX_UTF8Decoder& decoder, CXML_Element* pElement);
};
void FX_XML_SplitQualifiedName(FX_BSTR bsFullName, CFX_ByteStringC &bsSpace, CFX_ByteStringC &bsName);
#endif
