// 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
