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