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