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