c0065def470a6b4cdc30b33ab36fa01ae97d0966
[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 CORE_INCLUDE_FPDFAPI_FPDF_OBJECTS_H_
8 #define CORE_INCLUDE_FPDFAPI_FPDF_OBJECTS_H_
9
10 #include "../fxcrt/fx_ext.h"
11
12 class CPDF_Array;
13 class CPDF_Boolean;
14 class CPDF_CryptoHandler;
15 class CPDF_Dictionary;
16 class CPDF_Document;
17 class CPDF_IndirectObjects;
18 class CPDF_Null;
19 class CPDF_Number;
20 class CPDF_Parser;
21 class CPDF_Reference;
22 class CPDF_Stream;
23 class CPDF_StreamAcc;
24 class CPDF_StreamFilter;
25 class CPDF_String;
26 class 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
39 typedef IFX_FileStream* (*FPDF_LPFCloneStreamCallback)(CPDF_Stream *pStream, FX_LPVOID pUserData);
40 class CPDF_Object 
41 {
42 public:
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     }
94 protected:
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;
108 private:
109     CPDF_Object(const CPDF_Object& src) {}
110     CPDF_Object* CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visited) const;
111 };
112 class CPDF_Boolean : public CPDF_Object
113 {
114 public:
115
116     static CPDF_Boolean*        Create(FX_BOOL value)
117     {
118         return FX_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     }
128 protected:
129
130     FX_BOOL                                     m_bValue;
131     friend class                        CPDF_Object;
132 };
133 class CPDF_Number : public CPDF_Object
134 {
135 public:
136
137     static CPDF_Number*         Create(int value)
138     {
139         return FX_NEW CPDF_Number(value);
140     }
141
142     static CPDF_Number*         Create(FX_FLOAT value)
143     {
144         return FX_NEW CPDF_Number(value);
145     }
146
147     static CPDF_Number*         Create(FX_BSTR str)
148     {
149         return FX_NEW CPDF_Number(str);
150     }
151
152     static CPDF_Number*         Create(FX_BOOL bInteger, void* pData)
153     {
154         return FX_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     }
199 protected:
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 };
211 class CPDF_String : public CPDF_Object
212 {
213 public:
214
215     static CPDF_String*         Create(const CFX_ByteString& str, FX_BOOL bHex = FALSE)
216     {
217         return FX_NEW CPDF_String(str, bHex);
218     }
219
220     static CPDF_String*         Create(const CFX_WideString& str)
221     {
222         return FX_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     }
247 protected:
248
249     CFX_ByteString                      m_String;
250
251     FX_BOOL                                     m_bHex;
252     friend class                        CPDF_Object;
253 };
254 class CPDF_Name : public CPDF_Object
255 {
256 public:
257
258     static CPDF_Name*           Create(const CFX_ByteString& str)
259     {
260         return FX_NEW CPDF_Name(str);
261     }
262
263     static CPDF_Name*           Create(FX_BSTR str)
264     {
265         return FX_NEW CPDF_Name(str);
266     }
267
268     static CPDF_Name*           Create(FX_LPCSTR str)
269     {
270         return FX_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     }
286 protected:
287
288     CFX_ByteString                      m_Name;
289     friend class                        CPDF_Object;
290 };
291 class CPDF_Array : public CPDF_Object
292 {
293 public:
294
295     static CPDF_Array*          Create()
296     {
297         return FX_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;
381 protected:
382
383     ~CPDF_Array();
384
385     CFX_PtrArray                        m_Objects;
386     friend class                        CPDF_Object;
387 };
388 class CPDF_Dictionary : public CPDF_Object
389 {
390 public:
391
392     static CPDF_Dictionary*     Create()
393     {
394         return FX_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);
497 protected:
498
499     ~CPDF_Dictionary();
500
501     CFX_CMapByteStringToPtr     m_Map;
502
503     friend class                        CPDF_Object;
504 };
505 class CPDF_Stream : public CPDF_Object
506 {
507 public:
508
509     static CPDF_Stream*         Create(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict)
510     {
511         return FX_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;
547 protected:
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 };
573 class CPDF_StreamAcc 
574 {
575 public:
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     }
609 protected:
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 };
625 CFX_DataFilter* FPDF_CreateFilter(FX_BSTR name, const CPDF_Dictionary* pParam, int width = 0, int height = 0);
626 #define FPDF_FILTER_BUFFER_SIZE         20480
627 class CPDF_StreamFilter 
628 {
629 public:
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     }
644 protected:
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 };
663 class CPDF_Null : public CPDF_Object
664 {
665 public:
666
667     static CPDF_Null*           Create()
668     {
669         return FX_NEW CPDF_Null();
670     }
671
672     CPDF_Null() : CPDF_Object(PDFOBJ_NULL) { }
673 };
674 class CPDF_Reference : public CPDF_Object
675 {
676 public:
677
678     static CPDF_Reference*      Create(CPDF_IndirectObjects* pDoc, int objnum)
679     {
680         return FX_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     }
703 protected:
704
705     CPDF_IndirectObjects*       m_pObjList;
706
707     FX_DWORD                            m_RefObjNum;
708     friend class                        CPDF_Object;
709 };
710 class CPDF_IndirectObjects 
711 {
712 public:
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     }
739 protected:
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_