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_reference.h" 8 9 #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h" 10 #include "core/fxcrt/fx_stream.h" 11 #include "third_party/base/ptr_util.h" 12 #include "third_party/base/stl_util.h" 13 14 CPDF_Reference::CPDF_Reference(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum) 15 : m_pObjList(pDoc), m_RefObjNum(objnum) {} 16 17 CPDF_Reference::~CPDF_Reference() {} 18 19 CPDF_Object::Type CPDF_Reference::GetType() const { 20 return REFERENCE; 21 } 22 23 ByteString CPDF_Reference::GetString() const { 24 CPDF_Object* obj = SafeGetDirect(); 25 return obj ? obj->GetString() : ByteString(); 26 } 27 28 float CPDF_Reference::GetNumber() const { 29 CPDF_Object* obj = SafeGetDirect(); 30 return obj ? obj->GetNumber() : 0; 31 } 32 33 int CPDF_Reference::GetInteger() const { 34 CPDF_Object* obj = SafeGetDirect(); 35 return obj ? obj->GetInteger() : 0; 36 } 37 38 CPDF_Dictionary* CPDF_Reference::GetDict() const { 39 CPDF_Object* obj = SafeGetDirect(); 40 return obj ? obj->GetDict() : nullptr; 41 } 42 43 bool CPDF_Reference::IsReference() const { 44 return true; 45 } 46 47 CPDF_Reference* CPDF_Reference::AsReference() { 48 return this; 49 } 50 51 const CPDF_Reference* CPDF_Reference::AsReference() const { 52 return this; 53 } 54 55 std::unique_ptr<CPDF_Object> CPDF_Reference::Clone() const { 56 return CloneObjectNonCyclic(false); 57 } 58 59 std::unique_ptr<CPDF_Object> CPDF_Reference::CloneNonCyclic( 60 bool bDirect, 61 std::set<const CPDF_Object*>* pVisited) const { 62 pVisited->insert(this); 63 if (bDirect) { 64 auto* pDirect = GetDirect(); 65 return pDirect && !pdfium::ContainsKey(*pVisited, pDirect) 66 ? pDirect->CloneNonCyclic(true, pVisited) 67 : nullptr; 68 } 69 return pdfium::MakeUnique<CPDF_Reference>(m_pObjList.Get(), m_RefObjNum); 70 } 71 72 CPDF_Object* CPDF_Reference::SafeGetDirect() const { 73 CPDF_Object* obj = GetDirect(); 74 return (obj && !obj->IsReference()) ? obj : nullptr; 75 } 76 77 void CPDF_Reference::SetRef(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum) { 78 m_pObjList = pDoc; 79 m_RefObjNum = objnum; 80 } 81 82 CPDF_Object* CPDF_Reference::GetDirect() const { 83 return m_pObjList ? m_pObjList->GetOrParseIndirectObject(m_RefObjNum) 84 : nullptr; 85 } 86 87 bool CPDF_Reference::WriteTo(IFX_ArchiveStream* archive) const { 88 return archive->WriteString(" ") && archive->WriteDWord(GetRefObjNum()) && 89 archive->WriteString(" 0 R "); 90 } 91