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 _FPDF_OBJECTS_
8#define _FPDF_OBJECTS_
9#ifndef _FXCRT_EXTENSION_
10#include "../fxcrt/fx_ext.h"
11#endif
12class CPDF_Document;
13class CPDF_IndirectObjects;
14class CPDF_Null;
15class CPDF_Boolean;
16class CPDF_Number;
17class CPDF_String;
18class CPDF_Stream;
19class CPDF_StreamAcc;
20class CPDF_StreamFilter;
21class CPDF_Array;
22class CPDF_Dictionary;
23class CPDF_Reference;
24class IPDF_DocParser;
25class IFX_FileRead;
26class CPDF_CryptoHandler;
27#define PDFOBJ_INVALID		0
28#define	PDFOBJ_BOOLEAN		1
29#define PDFOBJ_NUMBER		2
30#define PDFOBJ_STRING		3
31#define PDFOBJ_NAME			4
32#define PDFOBJ_ARRAY		5
33#define PDFOBJ_DICTIONARY	6
34#define PDFOBJ_STREAM		7
35#define PDFOBJ_NULL			8
36#define PDFOBJ_REFERENCE	9
37typedef IFX_FileStream* (*FPDF_LPFCloneStreamCallback)(CPDF_Stream *pStream, FX_LPVOID pUserData);
38class CPDF_Object : public CFX_Object
39{
40public:
41
42    int						GetType() const
43    {
44        return m_Type;
45    }
46
47    FX_DWORD				GetObjNum() const
48    {
49        return m_ObjNum;
50    }
51
52    FX_BOOL					IsIdentical(CPDF_Object* pObj) const;
53
54    CPDF_Object*			Clone(FX_BOOL bDirect = FALSE) const;
55
56    CPDF_Object*			CloneRef(CPDF_IndirectObjects* pObjs) const;
57
58    CPDF_Object*			GetDirect() const;
59
60    void					Release();
61
62    CFX_ByteString			GetString() const;
63
64    CFX_ByteStringC			GetConstString() const;
65
66    CFX_WideString			GetUnicodeText(CFX_CharMap* pCharMap = NULL) const;
67
68    FX_FLOAT				GetNumber() const;
69
70    FX_FLOAT				GetNumber16() const;
71
72    int						GetInteger() const;
73
74    CPDF_Dictionary*		GetDict() const;
75
76    CPDF_Array*				GetArray() const;
77
78    void					SetString(const CFX_ByteString& str);
79
80    void					SetUnicodeText(FX_LPCWSTR pUnicodes, int len = -1);
81
82    int						GetDirectType() const;
83
84    FX_BOOL					IsModified() const
85    {
86        return FALSE;
87    }
88protected:
89    FX_DWORD				m_Type;
90    CPDF_Object()
91    {
92        m_ObjNum = 0;
93    }
94
95    FX_DWORD 				m_ObjNum;
96
97    void					Destroy();
98
99
100    ~CPDF_Object() {}
101    friend class			CPDF_IndirectObjects;
102    friend class			CPDF_Parser;
103    friend class			CPDF_SyntaxParser;
104private:
105    CPDF_Object(const CPDF_Object& src) {}
106    CPDF_Object* CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visited) const;
107};
108class CPDF_Boolean : public CPDF_Object
109{
110public:
111
112    static CPDF_Boolean*	Create(FX_BOOL value)
113    {
114        return FX_NEW CPDF_Boolean(value);
115    }
116
117    CPDF_Boolean()
118    {
119        m_Type = PDFOBJ_BOOLEAN;
120    }
121
122    CPDF_Boolean(FX_BOOL value)
123    {
124        m_Type = PDFOBJ_BOOLEAN;
125        m_bValue = value;
126    }
127
128    FX_BOOL					Identical(CPDF_Boolean* pOther) const
129    {
130        return m_bValue == pOther->m_bValue;
131    }
132protected:
133
134    FX_BOOL					m_bValue;
135    friend class			CPDF_Object;
136};
137class CPDF_Number : public CPDF_Object
138{
139public:
140
141    static CPDF_Number*		Create(int value)
142    {
143        return FX_NEW CPDF_Number(value);
144    }
145
146    static CPDF_Number*		Create(FX_FLOAT value)
147    {
148        return FX_NEW CPDF_Number(value);
149    }
150
151    static CPDF_Number*		Create(FX_BSTR str)
152    {
153        return FX_NEW CPDF_Number(str);
154    }
155
156    static CPDF_Number*		Create(FX_BOOL bInteger, void* pData)
157    {
158        return FX_NEW CPDF_Number(bInteger, pData);
159    }
160
161    CPDF_Number()
162    {
163        m_Type = PDFOBJ_NUMBER;
164    }
165
166    CPDF_Number(FX_BOOL bInteger, void* pData);
167
168    CPDF_Number(int value);
169
170    CPDF_Number(FX_FLOAT value);
171
172    CPDF_Number(FX_BSTR str);
173
174    FX_BOOL					Identical(CPDF_Number* pOther) const;
175
176    CFX_ByteString			GetString() const;
177
178    void					SetString(FX_BSTR str);
179
180    FX_BOOL					IsInteger() const
181    {
182        return m_bInteger;
183    }
184
185    int						GetInteger() const
186    {
187        return m_bInteger ? m_Integer : (int)m_Float;
188    }
189
190    FX_FLOAT				GetNumber() const
191    {
192        return m_bInteger ? (FX_FLOAT)m_Integer : m_Float;
193    }
194
195    void					SetNumber(FX_FLOAT value);
196
197    FX_FLOAT			GetNumber16() const
198    {
199        return GetNumber();
200    }
201
202    FX_FLOAT				GetFloat() const
203    {
204        return m_bInteger ? (FX_FLOAT)m_Integer : m_Float;
205    }
206protected:
207
208    FX_BOOL					m_bInteger;
209
210    union {
211
212        int					m_Integer;
213
214        FX_FLOAT			m_Float;
215    };
216    friend class			CPDF_Object;
217};
218class CPDF_String : public CPDF_Object
219{
220public:
221
222    static CPDF_String*		Create(const CFX_ByteString& str, FX_BOOL bHex = FALSE)
223    {
224        return FX_NEW CPDF_String(str, bHex);
225    }
226
227    static CPDF_String*		Create(const CFX_WideString& str)
228    {
229        return FX_NEW CPDF_String(str);
230    }
231
232    CPDF_String()
233    {
234        m_Type = PDFOBJ_STRING;
235        m_bHex = FALSE;
236    }
237
238    CPDF_String(const CFX_ByteString& str, FX_BOOL bHex = FALSE) : m_String(str)
239    {
240        m_Type = PDFOBJ_STRING;
241        m_bHex = bHex;
242    }
243
244    CPDF_String(const CFX_WideString& str);
245
246    CFX_ByteString&			GetString()
247    {
248        return m_String;
249    }
250
251    FX_BOOL					Identical(CPDF_String* pOther) const
252    {
253        return m_String == pOther->m_String;
254    }
255
256    FX_BOOL					IsHex() const
257    {
258        return m_bHex;
259    }
260protected:
261
262    CFX_ByteString			m_String;
263
264    FX_BOOL					m_bHex;
265    friend class			CPDF_Object;
266};
267class CPDF_Name : public CPDF_Object
268{
269public:
270
271    static CPDF_Name*		Create(const CFX_ByteString& str)
272    {
273        return FX_NEW CPDF_Name(str);
274    }
275
276    static CPDF_Name*		Create(FX_BSTR str)
277    {
278        return FX_NEW CPDF_Name(str);
279    }
280
281    static CPDF_Name*		Create(FX_LPCSTR str)
282    {
283        return FX_NEW CPDF_Name(str);
284    }
285
286    CPDF_Name(const CFX_ByteString& str) : m_Name(str)
287    {
288        m_Type = PDFOBJ_NAME;
289    }
290
291    CPDF_Name(FX_BSTR str) : m_Name(str)
292    {
293        m_Type = PDFOBJ_NAME;
294    }
295
296    CPDF_Name(FX_LPCSTR str) : m_Name(str)
297    {
298        m_Type = PDFOBJ_NAME;
299    }
300
301    CFX_ByteString&			GetString()
302    {
303        return m_Name;
304    }
305
306    FX_BOOL					Identical(CPDF_Name* pOther) const
307    {
308        return m_Name == pOther->m_Name;
309    }
310protected:
311
312    CFX_ByteString			m_Name;
313    friend class			CPDF_Object;
314};
315class CPDF_Array : public CPDF_Object
316{
317public:
318
319    static CPDF_Array*		Create()
320    {
321        return FX_NEW CPDF_Array();
322    }
323
324    CPDF_Array()
325    {
326        m_Type = PDFOBJ_ARRAY;
327    }
328
329    FX_DWORD				GetCount() const
330    {
331        return m_Objects.GetSize();
332    }
333
334    CPDF_Object*			GetElement(FX_DWORD index) const;
335
336    CPDF_Object*			GetElementValue(FX_DWORD index) const;
337
338
339
340    CFX_AffineMatrix		GetMatrix();
341
342    CFX_FloatRect			GetRect();
343
344
345
346
347    CFX_ByteString			GetString(FX_DWORD index) const;
348
349    CFX_ByteStringC			GetConstString(FX_DWORD index) const;
350
351    int						GetInteger(FX_DWORD index) const;
352
353    FX_FLOAT				GetNumber(FX_DWORD index) const;
354
355    CPDF_Dictionary*		GetDict(FX_DWORD index) const;
356
357    CPDF_Stream*			GetStream(FX_DWORD index) const;
358
359    CPDF_Array*				GetArray(FX_DWORD index) const;
360
361    FX_FLOAT				GetFloat(FX_DWORD index) const
362    {
363        return GetNumber(index);
364    }
365
366
367
368
369    void					SetAt(FX_DWORD index, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL);
370
371
372    void					InsertAt(FX_DWORD index, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL);
373
374    void					RemoveAt(FX_DWORD index);
375
376
377    void					Add(CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL);
378
379
380
381    void					AddNumber(FX_FLOAT f);
382
383    void					AddInteger(int i);
384
385    void					AddString(const CFX_ByteString& str);
386
387    void					AddName(const CFX_ByteString& str);
388
389    void					AddReference(CPDF_IndirectObjects* pDoc, FX_DWORD objnum);
390
391    void					AddReference(CPDF_IndirectObjects* pDoc, CPDF_Object* obj)
392    {
393        AddReference(pDoc, obj->GetObjNum());
394    }
395
396
397    FX_FLOAT			GetNumber16(FX_DWORD index) const
398    {
399        return GetNumber(index);
400    }
401
402    void					AddNumber16(FX_FLOAT value)
403    {
404        AddNumber(value);
405    }
406
407    FX_BOOL					Identical(CPDF_Array* pOther) const;
408protected:
409
410    ~CPDF_Array();
411
412    CFX_PtrArray			m_Objects;
413    friend class			CPDF_Object;
414};
415class CPDF_Dictionary : public CPDF_Object
416{
417public:
418
419    static CPDF_Dictionary*	Create()
420    {
421        return FX_NEW CPDF_Dictionary();
422    }
423
424    CPDF_Dictionary()
425    {
426        m_Type = PDFOBJ_DICTIONARY;
427    }
428
429
430
431    CPDF_Object*			GetElement(FX_BSTR key) const;
432
433    CPDF_Object*			GetElementValue(FX_BSTR key) const;
434
435
436
437
438
439    CFX_ByteString			GetString(FX_BSTR key) const;
440
441    CFX_ByteStringC			GetConstString(FX_BSTR key) const;
442
443    CFX_ByteString			GetString(FX_BSTR key, FX_BSTR default_str) const;
444
445    CFX_ByteStringC			GetConstString(FX_BSTR key, FX_BSTR default_str) const;
446
447    CFX_WideString			GetUnicodeText(FX_BSTR key, CFX_CharMap* pCharMap = NULL) const;
448
449    int						GetInteger(FX_BSTR key) const;
450
451    int						GetInteger(FX_BSTR key, int default_int) const;
452
453    FX_BOOL					GetBoolean(FX_BSTR key, FX_BOOL bDefault = FALSE) const;
454
455    FX_FLOAT				GetNumber(FX_BSTR key) const;
456
457    CPDF_Dictionary*		GetDict(FX_BSTR key) const;
458
459    CPDF_Stream*			GetStream(FX_BSTR key) const;
460
461    CPDF_Array*				GetArray(FX_BSTR key) const;
462
463    CFX_FloatRect			GetRect(FX_BSTR key) const;
464
465    CFX_AffineMatrix		GetMatrix(FX_BSTR key) const;
466
467    FX_FLOAT				GetFloat(FX_BSTR key) const
468    {
469        return GetNumber(key);
470    }
471
472
473    FX_BOOL					KeyExist(FX_BSTR key) const;
474
475    FX_POSITION				GetStartPos() const;
476
477    CPDF_Object*			GetNextElement(FX_POSITION& pos, CFX_ByteString& key) const;
478
479    void					SetAt(FX_BSTR key, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL);
480
481
482
483    void					SetAtName(FX_BSTR key, const CFX_ByteString& name);
484
485
486    void					SetAtString(FX_BSTR key, const CFX_ByteString& string);
487
488
489    void					SetAtInteger(FX_BSTR key, int i);
490
491
492    void					SetAtNumber(FX_BSTR key, FX_FLOAT f);
493
494    void					SetAtReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum);
495
496    void					SetAtReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, CPDF_Object* obj)
497    {
498        SetAtReference(key, pDoc, obj->GetObjNum());
499    }
500
501    void					AddReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum);
502
503    void					AddReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, CPDF_Object* obj)
504    {
505        AddReference(key, pDoc, obj->GetObjNum());
506    }
507
508    void					SetAtRect(FX_BSTR key, const CFX_FloatRect& rect);
509
510    void					SetAtMatrix(FX_BSTR key, const CFX_AffineMatrix& matrix);
511
512    void					SetAtBoolean(FX_BSTR key, FX_BOOL bValue);
513
514
515
516    void					RemoveAt(FX_BSTR key);
517
518
519    void					ReplaceKey(FX_BSTR oldkey, FX_BSTR newkey);
520
521    FX_BOOL					Identical(CPDF_Dictionary* pDict) const;
522
523    int						GetCount() const
524    {
525        return m_Map.GetCount();
526    }
527
528    void					AddValue(FX_BSTR key, CPDF_Object* pObj);
529protected:
530
531    ~CPDF_Dictionary();
532
533    CFX_CMapByteStringToPtr	m_Map;
534
535    friend class			CPDF_Object;
536};
537class CPDF_Stream : public CPDF_Object
538{
539public:
540
541    static CPDF_Stream*		Create(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict)
542    {
543        return FX_NEW CPDF_Stream(pData, size, pDict);
544    }
545
546    CPDF_Stream(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict);
547
548    CPDF_Dictionary*		GetDict() const
549    {
550        return m_pDict;
551    }
552
553    void					SetData(FX_LPCBYTE pData, FX_DWORD size, FX_BOOL bCompressed, FX_BOOL bKeepBuf);
554
555    void					InitStream(FX_BYTE* pData, FX_DWORD size, CPDF_Dictionary* pDict);
556
557    void					InitStream(IFX_FileRead *pFile, CPDF_Dictionary* pDict);
558
559    FX_BOOL					Identical(CPDF_Stream* pOther) const;
560
561    CPDF_StreamFilter*		GetStreamFilter(FX_BOOL bRaw = FALSE) const;
562
563
564
565    FX_DWORD				GetRawSize() const
566    {
567        return m_dwSize;
568    }
569
570    FX_BOOL					ReadRawData(FX_FILESIZE start_pos, FX_LPBYTE pBuf, FX_DWORD buf_size) const;
571
572
573    FX_BOOL					IsMemoryBased() const
574    {
575        return m_GenNum == (FX_DWORD) - 1;
576    }
577
578    CPDF_Stream*			Clone(FX_BOOL bDirect, FPDF_LPFCloneStreamCallback lpfCallback, FX_LPVOID pUserData) const;
579protected:
580
581    ~CPDF_Stream();
582
583    CPDF_Dictionary*		m_pDict;
584
585    FX_DWORD				m_dwSize;
586
587    FX_DWORD				m_GenNum;
588
589    union {
590
591        FX_LPBYTE			m_pDataBuf;
592
593        IFX_FileRead*		m_pFile;
594    };
595
596    FX_FILESIZE				m_FileOffset;
597
598    CPDF_CryptoHandler*		m_pCryptoHandler;
599
600    void					InitStream(CPDF_Dictionary* pDict);
601    friend class			CPDF_Object;
602    friend class			CPDF_StreamAcc;
603    friend class			CPDF_AttachmentAcc;
604};
605class CPDF_StreamAcc : public CFX_Object
606{
607public:
608
609    CPDF_StreamAcc();
610
611    ~CPDF_StreamAcc();
612
613    void					LoadAllData(const CPDF_Stream* pStream, FX_BOOL bRawAccess = FALSE,
614                                        FX_DWORD estimated_size = 0, FX_BOOL bImageAcc = FALSE);
615
616    const CPDF_Stream*		GetStream() const
617    {
618        return m_pStream;
619    }
620
621    CPDF_Dictionary*		GetDict() const
622    {
623        return m_pStream->GetDict();
624    }
625
626    FX_LPCBYTE				GetData() const;
627
628    FX_DWORD				GetSize() const;
629
630    FX_LPBYTE				DetachData();
631
632    const CFX_ByteString&	GetImageDecoder()
633    {
634        return m_ImageDecoder;
635    }
636
637    const CPDF_Dictionary*	GetImageParam()
638    {
639        return m_pImageParam;
640    }
641protected:
642
643    FX_LPBYTE				m_pData;
644
645    FX_DWORD				m_dwSize;
646
647    FX_BOOL					m_bNewBuf;
648
649    CFX_ByteString			m_ImageDecoder;
650
651    CPDF_Dictionary*		m_pImageParam;
652
653    const CPDF_Stream*		m_pStream;
654
655    FX_LPBYTE				m_pSrcData;
656};
657CFX_DataFilter* FPDF_CreateFilter(FX_BSTR name, const CPDF_Dictionary* pParam, int width = 0, int height = 0);
658#define FPDF_FILTER_BUFFER_SIZE		20480
659class CPDF_StreamFilter : public CFX_Object
660{
661public:
662
663    ~CPDF_StreamFilter();
664
665    FX_DWORD			ReadBlock(FX_LPBYTE buffer, FX_DWORD size);
666
667    FX_DWORD			GetSrcPos()
668    {
669        return m_SrcOffset;
670    }
671
672    const CPDF_Stream*	GetStream()
673    {
674        return m_pStream;
675    }
676protected:
677
678    CPDF_StreamFilter() {}
679
680    FX_DWORD			ReadLeftOver(FX_LPBYTE buffer, FX_DWORD buf_size);
681
682    const CPDF_Stream*	m_pStream;
683
684    CFX_DataFilter*		m_pFilter;
685
686    CFX_BinaryBuf*		m_pBuffer;
687
688    FX_DWORD			m_BufOffset;
689
690    FX_DWORD			m_SrcOffset;
691
692    FX_BYTE				m_SrcBuffer[FPDF_FILTER_BUFFER_SIZE];
693    friend class CPDF_Stream;
694};
695class CPDF_Null : public CPDF_Object
696{
697public:
698
699    static CPDF_Null*		Create()
700    {
701        return FX_NEW CPDF_Null();
702    }
703
704    CPDF_Null()
705    {
706        m_Type = PDFOBJ_NULL;
707    }
708};
709class CPDF_Reference : public CPDF_Object
710{
711public:
712
713    static CPDF_Reference*	Create(CPDF_IndirectObjects* pDoc, int objnum)
714    {
715        return FX_NEW CPDF_Reference(pDoc, objnum);
716    }
717
718    CPDF_Reference(CPDF_IndirectObjects* pDoc, int objnum)
719    {
720        m_Type = PDFOBJ_REFERENCE;
721        m_pObjList = pDoc;
722        m_RefObjNum = objnum;
723    }
724
725    CPDF_IndirectObjects*	GetObjList() const
726    {
727        return m_pObjList;
728    }
729
730    FX_DWORD				GetRefObjNum() const
731    {
732        return m_RefObjNum;
733    }
734
735    void					SetRef(CPDF_IndirectObjects* pDoc, FX_DWORD objnum);
736
737    FX_BOOL					Identical(CPDF_Reference* pOther) const
738    {
739        return m_RefObjNum == pOther->m_RefObjNum;
740    }
741protected:
742
743    CPDF_IndirectObjects*	m_pObjList;
744
745    FX_DWORD				m_RefObjNum;
746    friend class			CPDF_Object;
747};
748class CPDF_IndirectObjects : public CFX_Object
749{
750public:
751
752    CPDF_IndirectObjects(IPDF_DocParser* pParser);
753
754    ~CPDF_IndirectObjects();
755
756    CPDF_Object*			GetIndirectObject(FX_DWORD objnum, struct PARSE_CONTEXT* pContext = NULL);
757
758    int						GetIndirectType(FX_DWORD objnum);
759
760    FX_DWORD				AddIndirectObject(CPDF_Object* pObj);
761
762    void					ReleaseIndirectObject(FX_DWORD objnum);
763
764    void					InsertIndirectObject(FX_DWORD objnum, CPDF_Object* pObj);
765
766    FX_DWORD				GetLastObjNum() const;
767
768    FX_POSITION				GetStartPosition() const
769    {
770        return m_IndirectObjs.GetStartPosition();
771    }
772
773    void					GetNextAssoc(FX_POSITION& rPos, FX_DWORD& objnum, CPDF_Object*& pObject) const
774    {
775        m_IndirectObjs.GetNextAssoc(rPos, (void*&)objnum, (void*&)pObject);
776    }
777protected:
778
779    CFX_MapPtrToPtr			m_IndirectObjs;
780
781    IPDF_DocParser*			m_pParser;
782
783    FX_DWORD				m_LastObjNum;
784};
785#endif
786