C++程序  |  786行  |  16.56 KB

// 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 _FPDF_OBJECTS_
#define _FPDF_OBJECTS_
#ifndef _FXCRT_EXTENSION_
#include "../fxcrt/fx_ext.h"
#endif
class CPDF_Document;
class CPDF_IndirectObjects;
class CPDF_Null;
class CPDF_Boolean;
class CPDF_Number;
class CPDF_String;
class CPDF_Stream;
class CPDF_StreamAcc;
class CPDF_StreamFilter;
class CPDF_Array;
class CPDF_Dictionary;
class CPDF_Reference;
class IPDF_DocParser;
class IFX_FileRead;
class CPDF_CryptoHandler;
#define PDFOBJ_INVALID		0
#define	PDFOBJ_BOOLEAN		1
#define PDFOBJ_NUMBER		2
#define PDFOBJ_STRING		3
#define PDFOBJ_NAME			4
#define PDFOBJ_ARRAY		5
#define PDFOBJ_DICTIONARY	6
#define PDFOBJ_STREAM		7
#define PDFOBJ_NULL			8
#define PDFOBJ_REFERENCE	9
typedef IFX_FileStream* (*FPDF_LPFCloneStreamCallback)(CPDF_Stream *pStream, FX_LPVOID pUserData);
class CPDF_Object : public CFX_Object
{
public:

    int						GetType() const
    {
        return m_Type;
    }

    FX_DWORD				GetObjNum() const
    {
        return m_ObjNum;
    }

    FX_BOOL					IsIdentical(CPDF_Object* pObj) const;

    CPDF_Object*			Clone(FX_BOOL bDirect = FALSE) const;

    CPDF_Object*			CloneRef(CPDF_IndirectObjects* pObjs) const;

    CPDF_Object*			GetDirect() const;

    void					Release();

    CFX_ByteString			GetString() const;

    CFX_ByteStringC			GetConstString() const;

    CFX_WideString			GetUnicodeText(CFX_CharMap* pCharMap = NULL) const;

    FX_FLOAT				GetNumber() const;

    FX_FLOAT				GetNumber16() const;

    int						GetInteger() const;

    CPDF_Dictionary*		GetDict() const;

    CPDF_Array*				GetArray() const;

    void					SetString(const CFX_ByteString& str);

    void					SetUnicodeText(FX_LPCWSTR pUnicodes, int len = -1);

    int						GetDirectType() const;

    FX_BOOL					IsModified() const
    {
        return FALSE;
    }
protected:
    FX_DWORD				m_Type;
    CPDF_Object()
    {
        m_ObjNum = 0;
    }

    FX_DWORD 				m_ObjNum;

    void					Destroy();


    ~CPDF_Object() {}
    friend class			CPDF_IndirectObjects;
    friend class			CPDF_Parser;
    friend class			CPDF_SyntaxParser;
private:
    CPDF_Object(const CPDF_Object& src) {}
    CPDF_Object* CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visited) const;
};
class CPDF_Boolean : public CPDF_Object
{
public:

    static CPDF_Boolean*	Create(FX_BOOL value)
    {
        return FX_NEW CPDF_Boolean(value);
    }

    CPDF_Boolean()
    {
        m_Type = PDFOBJ_BOOLEAN;
    }

    CPDF_Boolean(FX_BOOL value)
    {
        m_Type = PDFOBJ_BOOLEAN;
        m_bValue = value;
    }

    FX_BOOL					Identical(CPDF_Boolean* pOther) const
    {
        return m_bValue == pOther->m_bValue;
    }
protected:

    FX_BOOL					m_bValue;
    friend class			CPDF_Object;
};
class CPDF_Number : public CPDF_Object
{
public:

    static CPDF_Number*		Create(int value)
    {
        return FX_NEW CPDF_Number(value);
    }

    static CPDF_Number*		Create(FX_FLOAT value)
    {
        return FX_NEW CPDF_Number(value);
    }

    static CPDF_Number*		Create(FX_BSTR str)
    {
        return FX_NEW CPDF_Number(str);
    }

    static CPDF_Number*		Create(FX_BOOL bInteger, void* pData)
    {
        return FX_NEW CPDF_Number(bInteger, pData);
    }

    CPDF_Number()
    {
        m_Type = PDFOBJ_NUMBER;
    }

    CPDF_Number(FX_BOOL bInteger, void* pData);

    CPDF_Number(int value);

    CPDF_Number(FX_FLOAT value);

    CPDF_Number(FX_BSTR str);

    FX_BOOL					Identical(CPDF_Number* pOther) const;

    CFX_ByteString			GetString() const;

    void					SetString(FX_BSTR str);

    FX_BOOL					IsInteger() const
    {
        return m_bInteger;
    }

    int						GetInteger() const
    {
        return m_bInteger ? m_Integer : (int)m_Float;
    }

    FX_FLOAT				GetNumber() const
    {
        return m_bInteger ? (FX_FLOAT)m_Integer : m_Float;
    }

    void					SetNumber(FX_FLOAT value);

    FX_FLOAT			GetNumber16() const
    {
        return GetNumber();
    }

    FX_FLOAT				GetFloat() const
    {
        return m_bInteger ? (FX_FLOAT)m_Integer : m_Float;
    }
protected:

    FX_BOOL					m_bInteger;

    union {

        int					m_Integer;

        FX_FLOAT			m_Float;
    };
    friend class			CPDF_Object;
};
class CPDF_String : public CPDF_Object
{
public:

    static CPDF_String*		Create(const CFX_ByteString& str, FX_BOOL bHex = FALSE)
    {
        return FX_NEW CPDF_String(str, bHex);
    }

    static CPDF_String*		Create(const CFX_WideString& str)
    {
        return FX_NEW CPDF_String(str);
    }

    CPDF_String()
    {
        m_Type = PDFOBJ_STRING;
        m_bHex = FALSE;
    }

    CPDF_String(const CFX_ByteString& str, FX_BOOL bHex = FALSE) : m_String(str)
    {
        m_Type = PDFOBJ_STRING;
        m_bHex = bHex;
    }

    CPDF_String(const CFX_WideString& str);

    CFX_ByteString&			GetString()
    {
        return m_String;
    }

    FX_BOOL					Identical(CPDF_String* pOther) const
    {
        return m_String == pOther->m_String;
    }

    FX_BOOL					IsHex() const
    {
        return m_bHex;
    }
protected:

    CFX_ByteString			m_String;

    FX_BOOL					m_bHex;
    friend class			CPDF_Object;
};
class CPDF_Name : public CPDF_Object
{
public:

    static CPDF_Name*		Create(const CFX_ByteString& str)
    {
        return FX_NEW CPDF_Name(str);
    }

    static CPDF_Name*		Create(FX_BSTR str)
    {
        return FX_NEW CPDF_Name(str);
    }

    static CPDF_Name*		Create(FX_LPCSTR str)
    {
        return FX_NEW CPDF_Name(str);
    }

    CPDF_Name(const CFX_ByteString& str) : m_Name(str)
    {
        m_Type = PDFOBJ_NAME;
    }

    CPDF_Name(FX_BSTR str) : m_Name(str)
    {
        m_Type = PDFOBJ_NAME;
    }

    CPDF_Name(FX_LPCSTR str) : m_Name(str)
    {
        m_Type = PDFOBJ_NAME;
    }

    CFX_ByteString&			GetString()
    {
        return m_Name;
    }

    FX_BOOL					Identical(CPDF_Name* pOther) const
    {
        return m_Name == pOther->m_Name;
    }
protected:

    CFX_ByteString			m_Name;
    friend class			CPDF_Object;
};
class CPDF_Array : public CPDF_Object
{
public:

    static CPDF_Array*		Create()
    {
        return FX_NEW CPDF_Array();
    }

    CPDF_Array()
    {
        m_Type = PDFOBJ_ARRAY;
    }

    FX_DWORD				GetCount() const
    {
        return m_Objects.GetSize();
    }

    CPDF_Object*			GetElement(FX_DWORD index) const;

    CPDF_Object*			GetElementValue(FX_DWORD index) const;



    CFX_AffineMatrix		GetMatrix();

    CFX_FloatRect			GetRect();




    CFX_ByteString			GetString(FX_DWORD index) const;

    CFX_ByteStringC			GetConstString(FX_DWORD index) const;

    int						GetInteger(FX_DWORD index) const;

    FX_FLOAT				GetNumber(FX_DWORD index) const;

    CPDF_Dictionary*		GetDict(FX_DWORD index) const;

    CPDF_Stream*			GetStream(FX_DWORD index) const;

    CPDF_Array*				GetArray(FX_DWORD index) const;

    FX_FLOAT				GetFloat(FX_DWORD index) const
    {
        return GetNumber(index);
    }




    void					SetAt(FX_DWORD index, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL);


    void					InsertAt(FX_DWORD index, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL);

    void					RemoveAt(FX_DWORD index);


    void					Add(CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL);



    void					AddNumber(FX_FLOAT f);

    void					AddInteger(int i);

    void					AddString(const CFX_ByteString& str);

    void					AddName(const CFX_ByteString& str);

    void					AddReference(CPDF_IndirectObjects* pDoc, FX_DWORD objnum);

    void					AddReference(CPDF_IndirectObjects* pDoc, CPDF_Object* obj)
    {
        AddReference(pDoc, obj->GetObjNum());
    }


    FX_FLOAT			GetNumber16(FX_DWORD index) const
    {
        return GetNumber(index);
    }

    void					AddNumber16(FX_FLOAT value)
    {
        AddNumber(value);
    }

    FX_BOOL					Identical(CPDF_Array* pOther) const;
protected:

    ~CPDF_Array();

    CFX_PtrArray			m_Objects;
    friend class			CPDF_Object;
};
class CPDF_Dictionary : public CPDF_Object
{
public:

    static CPDF_Dictionary*	Create()
    {
        return FX_NEW CPDF_Dictionary();
    }

    CPDF_Dictionary()
    {
        m_Type = PDFOBJ_DICTIONARY;
    }



    CPDF_Object*			GetElement(FX_BSTR key) const;

    CPDF_Object*			GetElementValue(FX_BSTR key) const;





    CFX_ByteString			GetString(FX_BSTR key) const;

    CFX_ByteStringC			GetConstString(FX_BSTR key) const;

    CFX_ByteString			GetString(FX_BSTR key, FX_BSTR default_str) const;

    CFX_ByteStringC			GetConstString(FX_BSTR key, FX_BSTR default_str) const;

    CFX_WideString			GetUnicodeText(FX_BSTR key, CFX_CharMap* pCharMap = NULL) const;

    int						GetInteger(FX_BSTR key) const;

    int						GetInteger(FX_BSTR key, int default_int) const;

    FX_BOOL					GetBoolean(FX_BSTR key, FX_BOOL bDefault = FALSE) const;

    FX_FLOAT				GetNumber(FX_BSTR key) const;

    CPDF_Dictionary*		GetDict(FX_BSTR key) const;

    CPDF_Stream*			GetStream(FX_BSTR key) const;

    CPDF_Array*				GetArray(FX_BSTR key) const;

    CFX_FloatRect			GetRect(FX_BSTR key) const;

    CFX_AffineMatrix		GetMatrix(FX_BSTR key) const;

    FX_FLOAT				GetFloat(FX_BSTR key) const
    {
        return GetNumber(key);
    }


    FX_BOOL					KeyExist(FX_BSTR key) const;

    FX_POSITION				GetStartPos() const;

    CPDF_Object*			GetNextElement(FX_POSITION& pos, CFX_ByteString& key) const;

    void					SetAt(FX_BSTR key, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL);



    void					SetAtName(FX_BSTR key, const CFX_ByteString& name);


    void					SetAtString(FX_BSTR key, const CFX_ByteString& string);


    void					SetAtInteger(FX_BSTR key, int i);


    void					SetAtNumber(FX_BSTR key, FX_FLOAT f);

    void					SetAtReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum);

    void					SetAtReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, CPDF_Object* obj)
    {
        SetAtReference(key, pDoc, obj->GetObjNum());
    }

    void					AddReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum);

    void					AddReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, CPDF_Object* obj)
    {
        AddReference(key, pDoc, obj->GetObjNum());
    }

    void					SetAtRect(FX_BSTR key, const CFX_FloatRect& rect);

    void					SetAtMatrix(FX_BSTR key, const CFX_AffineMatrix& matrix);

    void					SetAtBoolean(FX_BSTR key, FX_BOOL bValue);



    void					RemoveAt(FX_BSTR key);


    void					ReplaceKey(FX_BSTR oldkey, FX_BSTR newkey);

    FX_BOOL					Identical(CPDF_Dictionary* pDict) const;

    int						GetCount() const
    {
        return m_Map.GetCount();
    }

    void					AddValue(FX_BSTR key, CPDF_Object* pObj);
protected:

    ~CPDF_Dictionary();

    CFX_CMapByteStringToPtr	m_Map;

    friend class			CPDF_Object;
};
class CPDF_Stream : public CPDF_Object
{
public:

    static CPDF_Stream*		Create(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict)
    {
        return FX_NEW CPDF_Stream(pData, size, pDict);
    }

    CPDF_Stream(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict);

    CPDF_Dictionary*		GetDict() const
    {
        return m_pDict;
    }

    void					SetData(FX_LPCBYTE pData, FX_DWORD size, FX_BOOL bCompressed, FX_BOOL bKeepBuf);

    void					InitStream(FX_BYTE* pData, FX_DWORD size, CPDF_Dictionary* pDict);

    void					InitStream(IFX_FileRead *pFile, CPDF_Dictionary* pDict);

    FX_BOOL					Identical(CPDF_Stream* pOther) const;

    CPDF_StreamFilter*		GetStreamFilter(FX_BOOL bRaw = FALSE) const;



    FX_DWORD				GetRawSize() const
    {
        return m_dwSize;
    }

    FX_BOOL					ReadRawData(FX_FILESIZE start_pos, FX_LPBYTE pBuf, FX_DWORD buf_size) const;


    FX_BOOL					IsMemoryBased() const
    {
        return m_GenNum == (FX_DWORD) - 1;
    }

    CPDF_Stream*			Clone(FX_BOOL bDirect, FPDF_LPFCloneStreamCallback lpfCallback, FX_LPVOID pUserData) const;
protected:

    ~CPDF_Stream();

    CPDF_Dictionary*		m_pDict;

    FX_DWORD				m_dwSize;

    FX_DWORD				m_GenNum;

    union {

        FX_LPBYTE			m_pDataBuf;

        IFX_FileRead*		m_pFile;
    };

    FX_FILESIZE				m_FileOffset;

    CPDF_CryptoHandler*		m_pCryptoHandler;

    void					InitStream(CPDF_Dictionary* pDict);
    friend class			CPDF_Object;
    friend class			CPDF_StreamAcc;
    friend class			CPDF_AttachmentAcc;
};
class CPDF_StreamAcc : public CFX_Object
{
public:

    CPDF_StreamAcc();

    ~CPDF_StreamAcc();

    void					LoadAllData(const CPDF_Stream* pStream, FX_BOOL bRawAccess = FALSE,
                                        FX_DWORD estimated_size = 0, FX_BOOL bImageAcc = FALSE);

    const CPDF_Stream*		GetStream() const
    {
        return m_pStream;
    }

    CPDF_Dictionary*		GetDict() const
    {
        return m_pStream->GetDict();
    }

    FX_LPCBYTE				GetData() const;

    FX_DWORD				GetSize() const;

    FX_LPBYTE				DetachData();

    const CFX_ByteString&	GetImageDecoder()
    {
        return m_ImageDecoder;
    }

    const CPDF_Dictionary*	GetImageParam()
    {
        return m_pImageParam;
    }
protected:

    FX_LPBYTE				m_pData;

    FX_DWORD				m_dwSize;

    FX_BOOL					m_bNewBuf;

    CFX_ByteString			m_ImageDecoder;

    CPDF_Dictionary*		m_pImageParam;

    const CPDF_Stream*		m_pStream;

    FX_LPBYTE				m_pSrcData;
};
CFX_DataFilter* FPDF_CreateFilter(FX_BSTR name, const CPDF_Dictionary* pParam, int width = 0, int height = 0);
#define FPDF_FILTER_BUFFER_SIZE		20480
class CPDF_StreamFilter : public CFX_Object
{
public:

    ~CPDF_StreamFilter();

    FX_DWORD			ReadBlock(FX_LPBYTE buffer, FX_DWORD size);

    FX_DWORD			GetSrcPos()
    {
        return m_SrcOffset;
    }

    const CPDF_Stream*	GetStream()
    {
        return m_pStream;
    }
protected:

    CPDF_StreamFilter() {}

    FX_DWORD			ReadLeftOver(FX_LPBYTE buffer, FX_DWORD buf_size);

    const CPDF_Stream*	m_pStream;

    CFX_DataFilter*		m_pFilter;

    CFX_BinaryBuf*		m_pBuffer;

    FX_DWORD			m_BufOffset;

    FX_DWORD			m_SrcOffset;

    FX_BYTE				m_SrcBuffer[FPDF_FILTER_BUFFER_SIZE];
    friend class CPDF_Stream;
};
class CPDF_Null : public CPDF_Object
{
public:

    static CPDF_Null*		Create()
    {
        return FX_NEW CPDF_Null();
    }

    CPDF_Null()
    {
        m_Type = PDFOBJ_NULL;
    }
};
class CPDF_Reference : public CPDF_Object
{
public:

    static CPDF_Reference*	Create(CPDF_IndirectObjects* pDoc, int objnum)
    {
        return FX_NEW CPDF_Reference(pDoc, objnum);
    }

    CPDF_Reference(CPDF_IndirectObjects* pDoc, int objnum)
    {
        m_Type = PDFOBJ_REFERENCE;
        m_pObjList = pDoc;
        m_RefObjNum = objnum;
    }

    CPDF_IndirectObjects*	GetObjList() const
    {
        return m_pObjList;
    }

    FX_DWORD				GetRefObjNum() const
    {
        return m_RefObjNum;
    }

    void					SetRef(CPDF_IndirectObjects* pDoc, FX_DWORD objnum);

    FX_BOOL					Identical(CPDF_Reference* pOther) const
    {
        return m_RefObjNum == pOther->m_RefObjNum;
    }
protected:

    CPDF_IndirectObjects*	m_pObjList;

    FX_DWORD				m_RefObjNum;
    friend class			CPDF_Object;
};
class CPDF_IndirectObjects : public CFX_Object
{
public:

    CPDF_IndirectObjects(IPDF_DocParser* pParser);

    ~CPDF_IndirectObjects();

    CPDF_Object*			GetIndirectObject(FX_DWORD objnum, struct PARSE_CONTEXT* pContext = NULL);

    int						GetIndirectType(FX_DWORD objnum);

    FX_DWORD				AddIndirectObject(CPDF_Object* pObj);

    void					ReleaseIndirectObject(FX_DWORD objnum);

    void					InsertIndirectObject(FX_DWORD objnum, CPDF_Object* pObj);

    FX_DWORD				GetLastObjNum() const;

    FX_POSITION				GetStartPosition() const
    {
        return m_IndirectObjs.GetStartPosition();
    }

    void					GetNextAssoc(FX_POSITION& rPos, FX_DWORD& objnum, CPDF_Object*& pObject) const
    {
        m_IndirectObjs.GetNextAssoc(rPos, (void*&)objnum, (void*&)pObject);
    }
protected:

    CFX_MapPtrToPtr			m_IndirectObjs;

    IPDF_DocParser*			m_pParser;

    FX_DWORD				m_LastObjNum;
};
#endif