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
CPDF_Reference(CPDF_IndirectObjectHolder * pDoc,uint32_t objnum)14 CPDF_Reference::CPDF_Reference(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum)
15 : m_pObjList(pDoc), m_RefObjNum(objnum) {}
16
~CPDF_Reference()17 CPDF_Reference::~CPDF_Reference() {}
18
GetType() const19 CPDF_Object::Type CPDF_Reference::GetType() const {
20 return kReference;
21 }
22
GetString() const23 ByteString CPDF_Reference::GetString() const {
24 const CPDF_Object* obj = SafeGetDirect();
25 return obj ? obj->GetString() : ByteString();
26 }
27
GetNumber() const28 float CPDF_Reference::GetNumber() const {
29 const CPDF_Object* obj = SafeGetDirect();
30 return obj ? obj->GetNumber() : 0;
31 }
32
GetInteger() const33 int CPDF_Reference::GetInteger() const {
34 const CPDF_Object* obj = SafeGetDirect();
35 return obj ? obj->GetInteger() : 0;
36 }
37
GetDict()38 CPDF_Dictionary* CPDF_Reference::GetDict() {
39 CPDF_Object* obj = SafeGetDirect();
40 return obj ? obj->GetDict() : nullptr;
41 }
42
GetDict() const43 const CPDF_Dictionary* CPDF_Reference::GetDict() const {
44 const CPDF_Object* obj = SafeGetDirect();
45 return obj ? obj->GetDict() : nullptr;
46 }
47
IsReference() const48 bool CPDF_Reference::IsReference() const {
49 return true;
50 }
51
AsReference()52 CPDF_Reference* CPDF_Reference::AsReference() {
53 return this;
54 }
55
AsReference() const56 const CPDF_Reference* CPDF_Reference::AsReference() const {
57 return this;
58 }
59
Clone() const60 RetainPtr<CPDF_Object> CPDF_Reference::Clone() const {
61 return CloneObjectNonCyclic(false);
62 }
63
CloneNonCyclic(bool bDirect,std::set<const CPDF_Object * > * pVisited) const64 RetainPtr<CPDF_Object> CPDF_Reference::CloneNonCyclic(
65 bool bDirect,
66 std::set<const CPDF_Object*>* pVisited) const {
67 pVisited->insert(this);
68 if (bDirect) {
69 auto* pDirect = GetDirect();
70 return pDirect && !pdfium::ContainsKey(*pVisited, pDirect)
71 ? pDirect->CloneNonCyclic(true, pVisited)
72 : nullptr;
73 }
74 return pdfium::MakeRetain<CPDF_Reference>(m_pObjList.Get(), m_RefObjNum);
75 }
76
SafeGetDirect()77 CPDF_Object* CPDF_Reference::SafeGetDirect() {
78 CPDF_Object* obj = GetDirect();
79 return (obj && !obj->IsReference()) ? obj : nullptr;
80 }
81
SafeGetDirect() const82 const CPDF_Object* CPDF_Reference::SafeGetDirect() const {
83 const CPDF_Object* obj = GetDirect();
84 return (obj && !obj->IsReference()) ? obj : nullptr;
85 }
86
SetRef(CPDF_IndirectObjectHolder * pDoc,uint32_t objnum)87 void CPDF_Reference::SetRef(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum) {
88 m_pObjList = pDoc;
89 m_RefObjNum = objnum;
90 }
91
GetDirect()92 CPDF_Object* CPDF_Reference::GetDirect() {
93 return m_pObjList ? m_pObjList->GetOrParseIndirectObject(m_RefObjNum)
94 : nullptr;
95 }
96
GetDirect() const97 const CPDF_Object* CPDF_Reference::GetDirect() const {
98 return m_pObjList ? m_pObjList->GetOrParseIndirectObject(m_RefObjNum)
99 : nullptr;
100 }
101
WriteTo(IFX_ArchiveStream * archive,const CPDF_Encryptor * encryptor) const102 bool CPDF_Reference::WriteTo(IFX_ArchiveStream* archive,
103 const CPDF_Encryptor* encryptor) const {
104 return archive->WriteString(" ") && archive->WriteDWord(GetRefObjNum()) &&
105 archive->WriteString(" 0 R ");
106 }
107
MakeReference(CPDF_IndirectObjectHolder * holder) const108 RetainPtr<CPDF_Object> CPDF_Reference::MakeReference(
109 CPDF_IndirectObjectHolder* holder) const {
110 ASSERT(holder == m_pObjList);
111 // Do not allow reference to reference, just create other reference for same
112 // object.
113 return pdfium::MakeRetain<CPDF_Reference>(holder, GetRefObjNum());
114 }
115