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