Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cpdf_array.cpp
Go to the documentation of this file.
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_array.h"
8
9#include <set>
10#include <utility>
11
12#include "core/fpdfapi/parser/cpdf_boolean.h"
13#include "core/fpdfapi/parser/cpdf_dictionary.h"
14#include "core/fpdfapi/parser/cpdf_name.h"
15#include "core/fpdfapi/parser/cpdf_number.h"
16#include "core/fpdfapi/parser/cpdf_reference.h"
17#include "core/fpdfapi/parser/cpdf_stream.h"
18#include "core/fpdfapi/parser/cpdf_string.h"
19#include "core/fxcrt/check.h"
20#include "core/fxcrt/containers/contains.h"
21#include "core/fxcrt/fx_stream.h"
22#include "core/fxcrt/notreached.h"
23
24CPDF_Array::CPDF_Array() = default;
25
26CPDF_Array::CPDF_Array(const WeakPtr<ByteStringPool>& pPool) : m_pPool(pPool) {}
27
29 // Break cycles for cyclic references.
31 for (auto& it : m_Objects) {
32 if (it->GetObjNum() == kInvalidObjNum)
33 it.Leak();
34 }
35}
36
38 return kArray;
39}
40
42 return this;
43}
44
46 return CloneObjectNonCyclic(false);
47}
48
50 bool bDirect,
51 std::set<const CPDF_Object*>* pVisited) const {
52 pVisited->insert(this);
53 auto pCopy = pdfium::MakeRetain<CPDF_Array>();
54 for (const auto& pValue : m_Objects) {
55 if (!pdfium::Contains(*pVisited, pValue.Get())) {
56 std::set<const CPDF_Object*> visited(*pVisited);
57 if (auto obj = pValue->CloneNonCyclic(bDirect, &visited))
58 pCopy->m_Objects.push_back(std::move(obj));
59 }
60 }
61 return pCopy;
62}
63
65 CFX_FloatRect rect;
66 if (m_Objects.size() != 4)
67 return rect;
68
69 rect.left = GetFloatAt(0);
70 rect.bottom = GetFloatAt(1);
71 rect.right = GetFloatAt(2);
72 rect.top = GetFloatAt(3);
73 return rect;
74}
75
77 if (m_Objects.size() != 6)
78 return CFX_Matrix();
79
80 return CFX_Matrix(GetFloatAt(0), GetFloatAt(1), GetFloatAt(2), GetFloatAt(3),
81 GetFloatAt(4), GetFloatAt(5));
82}
83
84std::optional<size_t> CPDF_Array::Find(const CPDF_Object* pThat) const {
85 for (size_t i = 0; i < size(); ++i) {
86 if (GetDirectObjectAt(i) == pThat)
87 return i;
88 }
89 return std::nullopt;
90}
91
92bool CPDF_Array::Contains(const CPDF_Object* pThat) const {
93 return Find(pThat).has_value();
94}
95
96CPDF_Object* CPDF_Array::GetMutableObjectAtInternal(size_t index) {
97 return index < m_Objects.size() ? m_Objects[index].Get() : nullptr;
98}
99
100const CPDF_Object* CPDF_Array::GetObjectAtInternal(size_t index) const {
101 return const_cast<CPDF_Array*>(this)->GetMutableObjectAtInternal(index);
102}
103
105 return pdfium::WrapRetain(GetMutableObjectAtInternal(index));
106}
107
108RetainPtr<const CPDF_Object> CPDF_Array::GetObjectAt(size_t index) const {
109 return pdfium::WrapRetain(GetObjectAtInternal(index));
110}
111
113 return const_cast<CPDF_Array*>(this)->GetMutableDirectObjectAt(index);
114}
115
117 RetainPtr<CPDF_Object> pObj = GetMutableObjectAt(index);
118 return pObj ? pObj->GetMutableDirect() : nullptr;
119}
120
122 if (index >= m_Objects.size())
123 return ByteString();
124 return m_Objects[index]->GetString();
125}
126
128 if (index >= m_Objects.size())
129 return WideString();
130 return m_Objects[index]->GetUnicodeText();
131}
132
133bool CPDF_Array::GetBooleanAt(size_t index, bool bDefault) const {
134 if (index >= m_Objects.size())
135 return bDefault;
136 const CPDF_Object* p = m_Objects[index].Get();
137 return ToBoolean(p) ? p->GetInteger() != 0 : bDefault;
138}
139
140int CPDF_Array::GetIntegerAt(size_t index) const {
141 if (index >= m_Objects.size())
142 return 0;
143 return m_Objects[index]->GetInteger();
144}
145
146float CPDF_Array::GetFloatAt(size_t index) const {
147 if (index >= m_Objects.size())
148 return 0;
149 return m_Objects[index]->GetNumber();
150}
151
153 RetainPtr<CPDF_Object> p = GetMutableDirectObjectAt(index);
154 if (!p)
155 return nullptr;
156 CPDF_Dictionary* pDict = p->AsMutableDictionary();
157 if (pDict)
158 return pdfium::WrapRetain(pDict);
159 CPDF_Stream* pStream = p->AsMutableStream();
160 if (pStream)
161 return pStream->GetMutableDict();
162 return nullptr;
163}
164
165RetainPtr<const CPDF_Dictionary> CPDF_Array::GetDictAt(size_t index) const {
166 return const_cast<CPDF_Array*>(this)->GetMutableDictAt(index);
167}
168
169RetainPtr<CPDF_Stream> CPDF_Array::GetMutableStreamAt(size_t index) {
170 return ToStream(GetMutableDirectObjectAt(index));
171}
172
173RetainPtr<const CPDF_Stream> CPDF_Array::GetStreamAt(size_t index) const {
174 return const_cast<CPDF_Array*>(this)->GetMutableStreamAt(index);
175}
176
178 return ToArray(GetMutableDirectObjectAt(index));
179}
180
181RetainPtr<const CPDF_Array> CPDF_Array::GetArrayAt(size_t index) const {
182 return const_cast<CPDF_Array*>(this)->GetMutableArrayAt(index);
183}
184
185RetainPtr<const CPDF_Number> CPDF_Array::GetNumberAt(size_t index) const {
186 return ToNumber(GetObjectAt(index));
187}
188
189RetainPtr<const CPDF_String> CPDF_Array::GetStringAt(size_t index) const {
190 return ToString(GetObjectAt(index));
191}
192
195 m_Objects.clear();
196}
197
198void CPDF_Array::RemoveAt(size_t index) {
200 if (index < m_Objects.size())
201 m_Objects.erase(m_Objects.begin() + index);
202}
203
205 CPDF_IndirectObjectHolder* pHolder) {
207 if (index >= m_Objects.size())
208 return;
209
210 if (!m_Objects[index] || m_Objects[index]->IsReference())
211 return;
212
213 pHolder->AddIndirectObject(m_Objects[index]);
214 m_Objects[index] = m_Objects[index]->MakeReference(pHolder);
215}
216
217void CPDF_Array::SetAt(size_t index, RetainPtr<CPDF_Object> object) {
218 (void)SetAtInternal(index, std::move(object));
219}
220
221void CPDF_Array::InsertAt(size_t index, RetainPtr<CPDF_Object> object) {
222 (void)InsertAtInternal(index, std::move(object));
223}
224
226 (void)AppendInternal(std::move(object));
227}
228
229CPDF_Object* CPDF_Array::SetAtInternal(size_t index,
230 RetainPtr<CPDF_Object> pObj) {
232 CHECK(pObj);
233 CHECK(pObj->IsInline());
234 CHECK(!pObj->IsStream());
235 if (index >= m_Objects.size())
236 return nullptr;
237
238 CPDF_Object* pRet = pObj.Get();
239 m_Objects[index] = std::move(pObj);
240 return pRet;
241}
242
243CPDF_Object* CPDF_Array::InsertAtInternal(size_t index,
244 RetainPtr<CPDF_Object> pObj) {
246 CHECK(pObj);
247 CHECK(pObj->IsInline());
248 CHECK(!pObj->IsStream());
249 if (index > m_Objects.size())
250 return nullptr;
251
252 CPDF_Object* pRet = pObj.Get();
253 m_Objects.insert(m_Objects.begin() + index, std::move(pObj));
254 return pRet;
255}
256
257CPDF_Object* CPDF_Array::AppendInternal(RetainPtr<CPDF_Object> pObj) {
259 CHECK(pObj);
260 CHECK(pObj->IsInline());
261 CHECK(!pObj->IsStream());
262 CPDF_Object* pRet = pObj.Get();
263 m_Objects.push_back(std::move(pObj));
264 return pRet;
265}
266
268 const CPDF_Encryptor* encryptor) const {
269 if (!archive->WriteString("["))
270 return false;
271
272 for (size_t i = 0; i < size(); ++i) {
273 if (!GetObjectAt(i)->WriteTo(archive, encryptor))
274 return false;
275 }
276 return archive->WriteString("]");
277}
278
280 : m_pArray(pArray) {
281 m_pArray->m_LockCount++;
282}
283
285 : m_pArray(std::move(pArray)) {
286 m_pArray->m_LockCount++;
287}
288
290 : m_pArray(std::move(pArray)) {
291 m_pArray->m_LockCount++;
292}
293
295 m_pArray->m_LockCount--;
296}
fxcrt::ByteString ByteString
Definition bytestring.h:180
constexpr CFX_Matrix()=default
CPDF_ArrayLocker(RetainPtr< CPDF_Array > pArray)
CPDF_ArrayLocker(const CPDF_Array *pArray)
CPDF_ArrayLocker(RetainPtr< const CPDF_Array > pArray)
bool GetBooleanAt(size_t index, bool bDefault) const
void SetAt(size_t index, RetainPtr< CPDF_Object > object)
RetainPtr< CPDF_Dictionary > GetMutableDictAt(size_t index)
RetainPtr< CPDF_Object > CloneNonCyclic(bool bDirect, std::set< const CPDF_Object * > *pVisited) const override
RetainPtr< const CPDF_Object > GetDirectObjectAt(size_t index) const
RetainPtr< const CPDF_Stream > GetStreamAt(size_t index) const
Type GetType() const override
CPDF_Array * AsMutableArray() override
RetainPtr< const CPDF_Object > GetObjectAt(size_t index) const
RetainPtr< CPDF_Object > GetMutableObjectAt(size_t index)
WideString GetUnicodeTextAt(size_t index) const
RetainPtr< CPDF_Array > GetMutableArrayAt(size_t index)
RetainPtr< CPDF_Object > Clone() const override
RetainPtr< const CPDF_Dictionary > GetDictAt(size_t index) const
std::vector< RetainPtr< CPDF_Object > >::const_iterator const_iterator
Definition cpdf_array.h:29
bool IsLocked() const
Definition cpdf_array.h:150
RetainPtr< CPDF_Stream > GetMutableStreamAt(size_t index)
bool Contains(const CPDF_Object *pThat) const
void ConvertToIndirectObjectAt(size_t index, CPDF_IndirectObjectHolder *pHolder)
std::optional< size_t > Find(const CPDF_Object *pThat) const
bool WriteTo(IFX_ArchiveStream *archive, const CPDF_Encryptor *encryptor) const override
RetainPtr< CPDF_Object > GetMutableDirectObjectAt(size_t index)
CFX_Matrix GetMatrix() const
~CPDF_Array() override
int GetIntegerAt(size_t index) const
void InsertAt(size_t index, RetainPtr< CPDF_Object > object)
ByteString GetByteStringAt(size_t index) const
void Append(RetainPtr< CPDF_Object > object)
RetainPtr< const CPDF_String > GetStringAt(size_t index) const
RetainPtr< const CPDF_Array > GetArrayAt(size_t index) const
RetainPtr< const CPDF_Number > GetNumberAt(size_t index) const
CFX_FloatRect GetRect() const
void RemoveAt(size_t index)
float GetFloatAt(size_t index) const
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
virtual int GetInteger() const
uint32_t m_ObjNum
static constexpr uint32_t kInvalidObjNum
Definition cpdf_object.h:52
RetainPtr< CPDF_Dictionary > GetMutableDict()
RetainPtr< CPDF_Object > CloneObjectNonCyclic(bool bDirect) const
bool WriteString(ByteStringView str)
Definition fx_stream.cpp:46
ByteString()=default
WideString()=default
const CPDF_Boolean * ToBoolean(const CPDF_Object *obj)
#define CHECK(cvref)
fxcrt::WideString WideString
Definition widestring.h:207