• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/fpdfapi/parser/cpdf_reference.h"
8 
9 #include "core/fpdfapi/parser/cpdf_dictionary.h"
10 #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
11 #include "core/fxcrt/fx_stream.h"
12 #include "third_party/base/check_op.h"
13 #include "third_party/base/containers/contains.h"
14 
CPDF_Reference(CPDF_IndirectObjectHolder * pDoc,uint32_t objnum)15 CPDF_Reference::CPDF_Reference(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum)
16     : m_pObjList(pDoc), m_RefObjNum(objnum) {}
17 
18 CPDF_Reference::~CPDF_Reference() = default;
19 
GetType() const20 CPDF_Object::Type CPDF_Reference::GetType() const {
21   return kReference;
22 }
23 
GetString() const24 ByteString CPDF_Reference::GetString() const {
25   const CPDF_Object* obj = FastGetDirect();
26   return obj ? obj->GetString() : ByteString();
27 }
28 
GetNumber() const29 float CPDF_Reference::GetNumber() const {
30   const CPDF_Object* obj = FastGetDirect();
31   return obj ? obj->GetNumber() : 0;
32 }
33 
GetInteger() const34 int CPDF_Reference::GetInteger() const {
35   const CPDF_Object* obj = FastGetDirect();
36   return obj ? obj->GetInteger() : 0;
37 }
38 
GetDictInternal() const39 const CPDF_Dictionary* CPDF_Reference::GetDictInternal() const {
40   const CPDF_Object* obj = FastGetDirect();
41   return obj ? obj->GetDictInternal() : nullptr;
42 }
43 
AsMutableReference()44 CPDF_Reference* CPDF_Reference::AsMutableReference() {
45   return this;
46 }
47 
Clone() const48 RetainPtr<CPDF_Object> CPDF_Reference::Clone() const {
49   return CloneObjectNonCyclic(false);
50 }
51 
CloneNonCyclic(bool bDirect,std::set<const CPDF_Object * > * pVisited) const52 RetainPtr<CPDF_Object> CPDF_Reference::CloneNonCyclic(
53     bool bDirect,
54     std::set<const CPDF_Object*>* pVisited) const {
55   pVisited->insert(this);
56   if (!bDirect) {
57     return pdfium::MakeRetain<CPDF_Reference>(m_pObjList, m_RefObjNum);
58   }
59   RetainPtr<const CPDF_Object> pDirect = GetDirect();
60   return pDirect && !pdfium::Contains(*pVisited, pDirect.Get())
61              ? pDirect->CloneNonCyclic(true, pVisited)
62              : nullptr;
63 }
64 
FastGetDirect() const65 const CPDF_Object* CPDF_Reference::FastGetDirect() const {
66   if (!m_pObjList)
67     return nullptr;
68   const CPDF_Object* obj =
69       m_pObjList->GetOrParseIndirectObjectInternal(m_RefObjNum);
70   return (obj && !obj->IsReference()) ? obj : nullptr;
71 }
72 
SetRef(CPDF_IndirectObjectHolder * pDoc,uint32_t objnum)73 void CPDF_Reference::SetRef(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum) {
74   m_pObjList = pDoc;
75   m_RefObjNum = objnum;
76 }
77 
GetDirectInternal() const78 const CPDF_Object* CPDF_Reference::GetDirectInternal() const {
79   return m_pObjList ? m_pObjList->GetOrParseIndirectObjectInternal(m_RefObjNum)
80                     : nullptr;
81 }
82 
WriteTo(IFX_ArchiveStream * archive,const CPDF_Encryptor * encryptor) const83 bool CPDF_Reference::WriteTo(IFX_ArchiveStream* archive,
84                              const CPDF_Encryptor* encryptor) const {
85   return archive->WriteString(" ") && archive->WriteDWord(GetRefObjNum()) &&
86          archive->WriteString(" 0 R ");
87 }
88 
MakeReference(CPDF_IndirectObjectHolder * holder) const89 RetainPtr<CPDF_Reference> CPDF_Reference::MakeReference(
90     CPDF_IndirectObjectHolder* holder) const {
91   DCHECK_EQ(holder, m_pObjList);
92   // Do not allow reference to reference, just create other reference for same
93   // object.
94   return pdfium::MakeRetain<CPDF_Reference>(holder, GetRefObjNum());
95 }
96