1 // Copyright 2016 The PDFium Authors 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_FPDFAPI_PARSER_CPDF_INDIRECT_OBJECT_HOLDER_H_ 8 #define CORE_FPDFAPI_PARSER_CPDF_INDIRECT_OBJECT_HOLDER_H_ 9 10 #include <stdint.h> 11 12 #include <map> 13 #include <type_traits> 14 #include <utility> 15 16 #include "core/fpdfapi/parser/cpdf_object.h" 17 #include "core/fxcrt/retain_ptr.h" 18 #include "core/fxcrt/string_pool_template.h" 19 #include "core/fxcrt/weak_ptr.h" 20 21 class CPDF_IndirectObjectHolder { 22 public: 23 using const_iterator = 24 std::map<uint32_t, RetainPtr<CPDF_Object>>::const_iterator; 25 26 CPDF_IndirectObjectHolder(); 27 virtual ~CPDF_IndirectObjectHolder(); 28 29 RetainPtr<CPDF_Object> GetOrParseIndirectObject(uint32_t objnum); 30 RetainPtr<const CPDF_Object> GetIndirectObject(uint32_t objnum) const; 31 RetainPtr<CPDF_Object> GetMutableIndirectObject(uint32_t objnum); 32 void DeleteIndirectObject(uint32_t objnum); 33 34 // Creates and adds a new object retained by the indirect object holder, 35 // and returns a retained pointer to it. 36 template <typename T, typename... Args> NewIndirect(Args &&...args)37 RetainPtr<T> NewIndirect(Args&&... args) { 38 auto obj = New<T>(std::forward<Args>(args)...); 39 AddIndirectObject(obj); 40 return obj; 41 } 42 43 // Creates and adds a new object not retained by the indirect object holder, 44 // but which can intern strings from it. We have a special cast to handle 45 // objects that can intern strings from our ByteStringPool. 46 template <typename T, typename... Args> New(Args &&...args)47 typename std::enable_if<CanInternStrings<T>::value, RetainPtr<T>>::type New( 48 Args&&... args) { 49 return pdfium::MakeRetain<T>(m_pByteStringPool, 50 std::forward<Args>(args)...); 51 } 52 template <typename T, typename... Args> New(Args &&...args)53 typename std::enable_if<!CanInternStrings<T>::value, RetainPtr<T>>::type New( 54 Args&&... args) { 55 return pdfium::MakeRetain<T>(std::forward<Args>(args)...); 56 } 57 58 // Always Retains |pObj|, returns its new object number. 59 uint32_t AddIndirectObject(RetainPtr<CPDF_Object> pObj); 60 61 // If higher generation number, retains |pObj| and returns true. 62 bool ReplaceIndirectObjectIfHigherGeneration(uint32_t objnum, 63 RetainPtr<CPDF_Object> pObj); 64 GetLastObjNum()65 uint32_t GetLastObjNum() const { return m_LastObjNum; } SetLastObjNum(uint32_t objnum)66 void SetLastObjNum(uint32_t objnum) { m_LastObjNum = objnum; } 67 GetByteStringPool()68 WeakPtr<ByteStringPool> GetByteStringPool() const { 69 return m_pByteStringPool; 70 } 71 begin()72 const_iterator begin() const { return m_IndirectObjs.begin(); } end()73 const_iterator end() const { return m_IndirectObjs.end(); } 74 75 protected: 76 virtual RetainPtr<CPDF_Object> ParseIndirectObject(uint32_t objnum); 77 78 private: 79 friend class CPDF_Reference; 80 81 const CPDF_Object* GetIndirectObjectInternal(uint32_t objnum) const; 82 CPDF_Object* GetOrParseIndirectObjectInternal(uint32_t objnum); 83 84 uint32_t m_LastObjNum = 0; 85 std::map<uint32_t, RetainPtr<CPDF_Object>> m_IndirectObjs; 86 WeakPtr<ByteStringPool> m_pByteStringPool; 87 }; 88 89 #endif // CORE_FPDFAPI_PARSER_CPDF_INDIRECT_OBJECT_HOLDER_H_ 90