1 // Copyright 2016 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 #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h" 8 9 #include <algorithm> 10 #include <utility> 11 12 #include "core/fpdfapi/parser/cpdf_object.h" 13 #include "core/fpdfapi/parser/cpdf_parser.h" 14 #include "third_party/base/logging.h" 15 16 CPDF_IndirectObjectHolder::CPDF_IndirectObjectHolder() 17 : m_LastObjNum(0), 18 m_pByteStringPool(pdfium::MakeUnique<CFX_ByteStringPool>()) {} 19 20 CPDF_IndirectObjectHolder::~CPDF_IndirectObjectHolder() { 21 m_pByteStringPool.DeleteObject(); // Make weak. 22 } 23 24 CPDF_Object* CPDF_IndirectObjectHolder::GetIndirectObject( 25 uint32_t objnum) const { 26 auto it = m_IndirectObjs.find(objnum); 27 return it != m_IndirectObjs.end() ? it->second.get() : nullptr; 28 } 29 30 CPDF_Object* CPDF_IndirectObjectHolder::GetOrParseIndirectObject( 31 uint32_t objnum) { 32 if (objnum == 0) 33 return nullptr; 34 35 CPDF_Object* pObj = GetIndirectObject(objnum); 36 if (pObj) 37 return pObj->GetObjNum() != CPDF_Object::kInvalidObjNum ? pObj : nullptr; 38 39 std::unique_ptr<CPDF_Object> pNewObj = ParseIndirectObject(objnum); 40 if (!pNewObj) 41 return nullptr; 42 43 pNewObj->m_ObjNum = objnum; 44 m_LastObjNum = std::max(m_LastObjNum, objnum); 45 m_IndirectObjs[objnum] = std::move(pNewObj); 46 return m_IndirectObjs[objnum].get(); 47 } 48 49 std::unique_ptr<CPDF_Object> CPDF_IndirectObjectHolder::ParseIndirectObject( 50 uint32_t objnum) { 51 return nullptr; 52 } 53 54 CPDF_Object* CPDF_IndirectObjectHolder::AddIndirectObject( 55 std::unique_ptr<CPDF_Object> pObj) { 56 CHECK(!pObj->m_ObjNum); 57 CPDF_Object* pUnowned = pObj.get(); 58 pObj->m_ObjNum = ++m_LastObjNum; 59 if (m_IndirectObjs[m_LastObjNum]) 60 m_OrphanObjs.push_back(std::move(m_IndirectObjs[m_LastObjNum])); 61 62 m_IndirectObjs[m_LastObjNum] = std::move(pObj); 63 return pUnowned; 64 } 65 66 bool CPDF_IndirectObjectHolder::ReplaceIndirectObjectIfHigherGeneration( 67 uint32_t objnum, 68 std::unique_ptr<CPDF_Object> pObj) { 69 ASSERT(objnum); 70 if (!pObj) 71 return false; 72 73 CPDF_Object* pOldObj = GetIndirectObject(objnum); 74 if (pOldObj && pObj->GetGenNum() <= pOldObj->GetGenNum()) 75 return false; 76 77 pObj->m_ObjNum = objnum; 78 m_IndirectObjs[objnum] = std::move(pObj); 79 m_LastObjNum = std::max(m_LastObjNum, objnum); 80 return true; 81 } 82 83 void CPDF_IndirectObjectHolder::DeleteIndirectObject(uint32_t objnum) { 84 CPDF_Object* pObj = GetIndirectObject(objnum); 85 if (!pObj || pObj->GetObjNum() == CPDF_Object::kInvalidObjNum) 86 return; 87 88 m_IndirectObjs.erase(objnum); 89 } 90