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