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