Home | History | Annotate | Download | only in fpdfapi
      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:
     47   int GetType() const { return m_Type; }
     48 
     49   FX_DWORD GetObjNum() const { return m_ObjNum; }
     50 
     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 
     84   FX_BOOL IsModified() const { return FALSE; }
     85 
     86   bool IsArray() const { return m_Type == PDFOBJ_ARRAY; }
     87   bool IsBoolean() const { return m_Type == PDFOBJ_BOOLEAN; }
     88   bool IsDictionary() const { return m_Type == PDFOBJ_DICTIONARY; }
     89   bool IsName() const { return m_Type == PDFOBJ_NAME; }
     90   bool IsNumber() const { return m_Type == PDFOBJ_NUMBER; }
     91   bool IsReference() const { return m_Type == PDFOBJ_REFERENCE; }
     92   bool IsStream() const { return m_Type == PDFOBJ_STREAM; }
     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:
    120   explicit CPDF_Object(FX_DWORD type)
    121       : m_Type(type), m_ObjNum(0), m_GenNum(0) {}
    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:
    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:
    142   CPDF_Boolean() : CPDF_Object(PDFOBJ_BOOLEAN), m_bValue(false) {}
    143   explicit CPDF_Boolean(FX_BOOL value)
    144       : CPDF_Object(PDFOBJ_BOOLEAN), m_bValue(value) {}
    145 
    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 };
    154 inline CPDF_Boolean* ToBoolean(CPDF_Object* obj) {
    155   return obj ? obj->AsBoolean() : nullptr;
    156 }
    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:
    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 
    177   FX_BOOL IsInteger() const { return m_bInteger; }
    178 
    179   int GetInteger() const { return m_bInteger ? m_Integer : (int)m_Float; }
    180 
    181   FX_FLOAT GetNumber() const {
    182     return m_bInteger ? (FX_FLOAT)m_Integer : m_Float;
    183   }
    184 
    185   void SetNumber(FX_FLOAT value);
    186 
    187   FX_FLOAT GetNumber16() const { return GetNumber(); }
    188 
    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 };
    203 inline CPDF_Number* ToNumber(CPDF_Object* obj) {
    204   return obj ? obj->AsNumber() : nullptr;
    205 }
    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:
    212   CPDF_String() : CPDF_Object(PDFOBJ_STRING), m_bHex(FALSE) {}
    213 
    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 
    219   CFX_ByteString& GetString() { return m_String; }
    220 
    221   FX_BOOL Identical(CPDF_String* pOther) const {
    222     return m_String == pOther->m_String;
    223   }
    224 
    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 };
    233 inline CPDF_String* ToString(CPDF_Object* obj) {
    234   return obj ? obj->AsString() : nullptr;
    235 }
    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:
    242   explicit CPDF_Name(const CFX_ByteString& str)
    243       : CPDF_Object(PDFOBJ_NAME), m_Name(str) {}
    244   explicit CPDF_Name(const CFX_ByteStringC& str)
    245       : CPDF_Object(PDFOBJ_NAME), m_Name(str) {}
    246   explicit CPDF_Name(const FX_CHAR* str)
    247       : CPDF_Object(PDFOBJ_NAME), m_Name(str) {}
    248 
    249   CFX_ByteString& GetString() { return m_Name; }
    250 
    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 };
    259 inline CPDF_Name* ToName(CPDF_Object* obj) {
    260   return obj ? obj->AsName() : nullptr;
    261 }
    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:
    268   CPDF_Array() : CPDF_Object(PDFOBJ_ARRAY) {}
    269 
    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 
    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 
    318   void AddReference(CPDF_IndirectObjectHolder* pDoc, CPDF_Object* obj) {
    319     AddReference(pDoc, obj->GetObjNum());
    320   }
    321 
    322   FX_FLOAT GetNumber16(FX_DWORD index) const { return GetNumber(index); }
    323 
    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 };
    334 inline CPDF_Array* ToArray(CPDF_Object* obj) {
    335   return obj ? obj->AsArray() : nullptr;
    336 }
    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 
    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 
    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 
    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 
    427   size_t GetCount() const { return m_Map.size(); }
    428 
    429   iterator begin() { return m_Map.begin(); }
    430 
    431   iterator end() { return m_Map.end(); }
    432 
    433   const_iterator begin() const { return m_Map.begin(); }
    434 
    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 };
    444 inline CPDF_Dictionary* ToDictionary(CPDF_Object* obj) {
    445   return obj ? obj->AsDictionary() : nullptr;
    446 }
    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 
    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 
    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 
    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 };
    497 inline CPDF_Stream* ToStream(CPDF_Object* obj) {
    498   return obj ? obj->AsStream() : nullptr;
    499 }
    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 
    515   const CPDF_Stream* GetStream() const { return m_pStream; }
    516 
    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 
    527   const CFX_ByteString& GetImageDecoder() { return m_ImageDecoder; }
    528 
    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:
    549   CPDF_Null() : CPDF_Object(PDFOBJ_NULL) {}
    550 };
    551 
    552 class CPDF_Reference : public CPDF_Object {
    553  public:
    554   CPDF_Reference(CPDF_IndirectObjectHolder* pDoc, int objnum)
    555       : CPDF_Object(PDFOBJ_REFERENCE), m_pObjList(pDoc), m_RefObjNum(objnum) {}
    556 
    557   CPDF_IndirectObjectHolder* GetObjList() const { return m_pObjList; }
    558 
    559   FX_DWORD GetRefObjNum() const { return m_RefObjNum; }
    560 
    561   void SetRef(CPDF_IndirectObjectHolder* pDoc, FX_DWORD objnum);
    562 
    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 };
    573 inline CPDF_Reference* ToReference(CPDF_Object* obj) {
    574   return obj ? obj->AsReference() : nullptr;
    575 }
    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 
    596   FX_DWORD GetLastObjNum() const { return m_LastObjNum; }
    597   iterator begin() { return m_IndirectObjs.begin(); }
    598   const_iterator begin() const { return m_IndirectObjs.cbegin(); }
    599   iterator end() { return m_IndirectObjs.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