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