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