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