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