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