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.h
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#ifndef CORE_FPDFAPI_PARSER_CPDF_ARRAY_H_
8#define CORE_FPDFAPI_PARSER_CPDF_ARRAY_H_
9
10#include <stddef.h>
11
12#include <optional>
13#include <set>
14#include <type_traits>
15#include <utility>
16#include <vector>
17
18#include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
19#include "core/fpdfapi/parser/cpdf_object.h"
20#include "core/fxcrt/check.h"
21#include "core/fxcrt/fx_coordinates.h"
22#include "core/fxcrt/retain_ptr.h"
23
24// Arrays never contain nullptrs for objects within bounds, but some of the
25// methods will tolerate out-of-bounds indices and return nullptr for those
26// cases.
27class CPDF_Array final : public CPDF_Object {
28 public:
30
32
33 // CPDF_Object:
34 Type GetType() const override;
35 RetainPtr<CPDF_Object> Clone() const override;
36 CPDF_Array* AsMutableArray() override;
37 bool WriteTo(IFX_ArchiveStream* archive,
38 const CPDF_Encryptor* encryptor) const override;
39
40 bool IsEmpty() const { return m_Objects.empty(); }
41 size_t size() const { return m_Objects.size(); }
42
43 // The Get*ObjectAt() methods tolerate out-of-bounds indices and return
44 // nullptr in those cases. Otherwise, for in-bound indices, the result
45 // is never nullptr.
47 RetainPtr<const CPDF_Object> GetObjectAt(size_t index) const;
48
49 // The Get*DirectObjectAt() methods tolerate out-of-bounds indices and
50 // return nullptr in those cases. Furthermore, for reference objects that
51 // do not correspond to a valid indirect object, nullptr is returned.
53 RetainPtr<const CPDF_Object> GetDirectObjectAt(size_t index) const;
54
55 // The Get*At() methods tolerate out-of-bounds indices and return nullptr
56 // in those cases. Furthermore, these safely coerce to the sub-class,
57 // returning nullptr if the object at the location is of a different type.
58 ByteString GetByteStringAt(size_t index) const;
59 WideString GetUnicodeTextAt(size_t index) const;
60 bool GetBooleanAt(size_t index, bool bDefault) const;
61 int GetIntegerAt(size_t index) const;
62 float GetFloatAt(size_t index) const;
64 RetainPtr<const CPDF_Dictionary> GetDictAt(size_t index) const;
65 RetainPtr<CPDF_Stream> GetMutableStreamAt(size_t index);
66 RetainPtr<const CPDF_Stream> GetStreamAt(size_t index) const;
68 RetainPtr<const CPDF_Array> GetArrayAt(size_t index) const;
69 RetainPtr<const CPDF_Number> GetNumberAt(size_t index) const;
70 RetainPtr<const CPDF_String> GetStringAt(size_t index) const;
71
72 CFX_FloatRect GetRect() const;
73 CFX_Matrix GetMatrix() const;
74
75 std::optional<size_t> Find(const CPDF_Object* pThat) const;
76 bool Contains(const CPDF_Object* pThat) const;
77
78 // Creates object owned by the array, and returns a retained pointer to it.
79 // We have special cases for objects that can intern strings from
80 // a ByteStringPool. Prefer using these templates over direct calls
81 // to Append()/SetAt()/InsertAt() since by creating a new object with no
82 // previous references, they ensure cycles can not be introduced.
83 template <typename T, typename... Args>
84 typename std::enable_if<!CanInternStrings<T>::value, RetainPtr<T>>::type
85 AppendNew(Args&&... args) {
86 static_assert(!std::is_same<T, CPDF_Stream>::value,
87 "Cannot append a CPDF_Stream directly. Add it indirectly as "
88 "a `CPDF_Reference` instead.");
89 return pdfium::WrapRetain(static_cast<T*>(
90 AppendInternal(pdfium::MakeRetain<T>(std::forward<Args>(args)...))));
91 }
92 template <typename T, typename... Args>
93 typename std::enable_if<CanInternStrings<T>::value, RetainPtr<T>>::type
94 AppendNew(Args&&... args) {
95 return pdfium::WrapRetain(static_cast<T*>(AppendInternal(
96 pdfium::MakeRetain<T>(m_pPool, std::forward<Args>(args)...))));
97 }
98 template <typename T, typename... Args>
99 typename std::enable_if<!CanInternStrings<T>::value, RetainPtr<T>>::type
100 SetNewAt(size_t index, Args&&... args) {
101 static_assert(!std::is_same<T, CPDF_Stream>::value,
102 "Cannot set a CPDF_Stream directly. Add it indirectly as a "
103 "`CPDF_Reference` instead.");
104 return pdfium::WrapRetain(static_cast<T*>(SetAtInternal(
105 index, pdfium::MakeRetain<T>(std::forward<Args>(args)...))));
106 }
107 template <typename T, typename... Args>
108 typename std::enable_if<CanInternStrings<T>::value, RetainPtr<T>>::type
109 SetNewAt(size_t index, Args&&... args) {
110 return pdfium::WrapRetain(static_cast<T*>(SetAtInternal(
111 index, pdfium::MakeRetain<T>(m_pPool, std::forward<Args>(args)...))));
112 }
113 template <typename T, typename... Args>
114 typename std::enable_if<!CanInternStrings<T>::value, RetainPtr<T>>::type
115 InsertNewAt(size_t index, Args&&... args) {
116 static_assert(!std::is_same<T, CPDF_Stream>::value,
117 "Cannot insert a CPDF_Stream directly. Add it indirectly as "
118 "a `CPDF_Reference` instead.");
119 return pdfium::WrapRetain(static_cast<T*>(InsertAtInternal(
120 index, pdfium::MakeRetain<T>(std::forward<Args>(args)...))));
121 }
122 template <typename T, typename... Args>
123 typename std::enable_if<CanInternStrings<T>::value, RetainPtr<T>>::type
124 InsertNewAt(size_t index, Args&&... args) {
125 return pdfium::WrapRetain(static_cast<T*>(InsertAtInternal(
126 index, pdfium::MakeRetain<T>(m_pPool, std::forward<Args>(args)...))));
127 }
128
129 // Adds non-null `object` to the end of the array, growing as appropriate.
130 void Append(RetainPtr<CPDF_Object> object);
131 void Append(RetainPtr<CPDF_Stream> stream) = delete;
132
133 // Overwrites the object at `index` with non-null `object`, if it is
134 // in bounds. Otherwise, `index` is out of bounds, and `object` is
135 // not stored.
136 void SetAt(size_t index, RetainPtr<CPDF_Object> object);
137 void SetAt(size_t index, RetainPtr<CPDF_Stream> stream) = delete;
138
139 // Inserts non-null `object` at `index` and shifts by one position all of the
140 // objects beyond it like std::vector::insert(), if `index` is less than or
141 // equal to the current array size. Otherwise, `index` is out of bounds,
142 // and `object` is not stored.
143 void InsertAt(size_t index, RetainPtr<CPDF_Object> object);
144 void InsertAt(size_t index, RetainPtr<CPDF_Stream> stream) = delete;
145
146 void Clear();
147 void RemoveAt(size_t index);
148 void ConvertToIndirectObjectAt(size_t index,
150 bool IsLocked() const { return !!m_LockCount; }
151
152 private:
153 friend class CPDF_ArrayLocker;
154
155 CPDF_Array();
156 explicit CPDF_Array(const WeakPtr<ByteStringPool>& pPool);
157 ~CPDF_Array() override;
158
159 // No guarantees about result lifetime, use with caution.
160 const CPDF_Object* GetObjectAtInternal(size_t index) const;
161 CPDF_Object* GetMutableObjectAtInternal(size_t index);
162 CPDF_Object* AppendInternal(RetainPtr<CPDF_Object> pObj);
163 CPDF_Object* SetAtInternal(size_t index, RetainPtr<CPDF_Object> pObj);
164 CPDF_Object* InsertAtInternal(size_t index, RetainPtr<CPDF_Object> pObj);
165
167 bool bDirect,
168 std::set<const CPDF_Object*>* pVisited) const override;
169
170 std::vector<RetainPtr<CPDF_Object>> m_Objects;
171 WeakPtr<ByteStringPool> m_pPool;
172 mutable uint32_t m_LockCount = 0;
173};
174
176 public:
177 FX_STACK_ALLOCATED();
179
180 explicit CPDF_ArrayLocker(const CPDF_Array* pArray);
181 explicit CPDF_ArrayLocker(RetainPtr<CPDF_Array> pArray);
182 explicit CPDF_ArrayLocker(RetainPtr<const CPDF_Array> pArray);
184
186 CHECK(m_pArray->IsLocked());
187 return m_pArray->m_Objects.begin();
188 }
190 CHECK(m_pArray->IsLocked());
191 return m_pArray->m_Objects.end();
192 }
193
194 private:
195 RetainPtr<const CPDF_Array> const m_pArray;
196};
197
199 return obj ? obj->AsMutableArray() : nullptr;
200}
201
202inline const CPDF_Array* ToArray(const CPDF_Object* obj) {
203 return obj ? obj->AsArray() : nullptr;
204}
205
207 return RetainPtr<CPDF_Array>(ToArray(obj.Get()));
208}
209
210inline RetainPtr<const CPDF_Array> ToArray(RetainPtr<const CPDF_Object> obj) {
211 return RetainPtr<const CPDF_Array>(ToArray(obj.Get()));
212}
213
214#endif // CORE_FPDFAPI_PARSER_CPDF_ARRAY_H_
fxcrt::ByteString ByteString
Definition bytestring.h:180
#define DCHECK
Definition check.h:33
CPDF_ArrayLocker(RetainPtr< CPDF_Array > pArray)
const_iterator begin() const
Definition cpdf_array.h:185
const_iterator end() const
Definition cpdf_array.h:189
CPDF_ArrayLocker(const CPDF_Array *pArray)
CPDF_ArrayLocker(RetainPtr< const CPDF_Array > pArray)
size_t size() const
Definition cpdf_array.h:41
void Append(RetainPtr< CPDF_Stream > stream)=delete
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
bool IsEmpty() const
Definition cpdf_array.h:40
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)
std::enable_if<!CanInternStrings< T >::value, RetainPtr< T > >::type AppendNew(Args &&... args)
Definition cpdf_array.h:85
WideString GetUnicodeTextAt(size_t index) const
RetainPtr< CPDF_Array > GetMutableArrayAt(size_t index)
RetainPtr< CPDF_Object > Clone() const override
std::enable_if< CanInternStrings< T >::value, RetainPtr< T > >::type AppendNew(Args &&... args)
Definition cpdf_array.h:94
RetainPtr< const CPDF_Dictionary > GetDictAt(size_t index) const
std::vector< RetainPtr< CPDF_Object > >::const_iterator const_iterator
Definition cpdf_array.h:29
std::enable_if<!CanInternStrings< T >::value, RetainPtr< T > >::type InsertNewAt(size_t index, Args &&... args)
Definition cpdf_array.h:115
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
std::enable_if< CanInternStrings< T >::value, RetainPtr< T > >::type InsertNewAt(size_t index, Args &&... args)
Definition cpdf_array.h:124
std::enable_if<!CanInternStrings< T >::value, RetainPtr< T > >::type SetNewAt(size_t index, Args &&... args)
Definition cpdf_array.h:100
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 SetAt(size_t index, RetainPtr< CPDF_Stream > stream)=delete
void InsertAt(size_t index, RetainPtr< CPDF_Object > object)
ByteString GetByteStringAt(size_t index) const
std::enable_if< CanInternStrings< T >::value, RetainPtr< T > >::type SetNewAt(size_t index, Args &&... args)
Definition cpdf_array.h:109
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 InsertAt(size_t index, RetainPtr< CPDF_Stream > stream)=delete
void RemoveAt(size_t index)
float GetFloatAt(size_t index) const
CPDF_Creator(CPDF_Document *pDoc, RetainPtr< IFX_RetainableWriteStream > archive)
bool SetFileVersion(int32_t fileVersion)
void RemoveSecurity()
bool Create(uint32_t flags)
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
const CPDF_Array * AsArray() const
virtual CPDF_Array * AsMutableArray()
virtual FX_FILESIZE CurrentOffset() const =0
static RetainPtr< IFX_SeekableReadStream > CreateFromFilename(const char *filename)
Definition fx_stream.cpp:68
virtual FX_FILESIZE GetPosition()
Definition fx_stream.cpp:80
virtual bool ReadBlockAtOffset(pdfium::span< uint8_t > buffer, FX_FILESIZE offset)=0
virtual bool IsEOF()
Definition fx_stream.cpp:76
virtual bool Flush()=0
virtual FX_FILESIZE GetSize()=0
bool WriteFilesize(FX_FILESIZE size)
Definition fx_stream.cpp:61
bool WriteByte(uint8_t byte)
Definition fx_stream.cpp:50
bool WriteString(ByteStringView str)
Definition fx_stream.cpp:46
virtual ~IFX_WriteStream()=default
bool WriteDWord(uint32_t i)
Definition fx_stream.cpp:54
virtual bool WriteBlock(pdfium::span< const uint8_t > data)=0
static ByteString Format(const char *pFormat,...)
ByteString & operator=(ByteString &&that) noexcept
T * get() const noexcept
UnownedPtr(const UnownedPtr< U > &that)
Definition unowned_ptr.h:99
bool operator==(const UnownedPtr &that) const
operator T*() const noexcept
UnownedPtr(UnownedPtr< U > &&that) noexcept
UnownedPtr & operator=(UnownedPtr< U > &&that) noexcept
constexpr UnownedPtr(const UnownedPtr &that) noexcept=default
constexpr UnownedPtr(T *pObj) noexcept
Definition unowned_ptr.h:84
UnownedPtr & operator=(T *that) noexcept
bool operator==(std::nullptr_t ptr) const
UnownedPtr & operator=(UnownedPtr &&that) noexcept
UnownedPtr & operator=(std::nullptr_t) noexcept
UnownedPtr & operator=(const UnownedPtr< U > &that) noexcept
T * operator->() const
constexpr UnownedPtr() noexcept=default
bool operator<(const UnownedPtr &that) const
UnownedPtr & operator=(const UnownedPtr &that) noexcept=default
T & operator*() const
constexpr UnownedPtr(UnownedPtr &&that) noexcept
Definition unowned_ptr.h:92
constexpr UnownedPtr(std::nullptr_t ptr)
Definition unowned_ptr.h:82
#define GSL_POINTER
#define TRIVIAL_ABI
CPDF_Array * ToArray(CPDF_Object *obj)
Definition cpdf_array.h:198
const CPDF_Array * ToArray(const CPDF_Object *obj)
Definition cpdf_array.h:202
RetainPtr< CPDF_Array > ToArray(RetainPtr< CPDF_Object > obj)
Definition cpdf_array.h:206
#define FPDFCREATE_INCREMENTAL
#define FPDFCREATE_NO_ORIGINAL
void * FX_Random_MT_Start(uint32_t dwSeed)
Definition fx_random.cpp:87
void FX_Random_MT_Close(void *pContext)
pdfium::CheckedNumeric< FX_FILESIZE > FX_SAFE_FILESIZE
#define FX_FILESIZE
Definition fx_types.h:19
UnownedPtr< T > WrapUnowned(T *that)
#define CHECK(cvref)
#define CONSTRUCT_VIA_MAKE_RETAIN
Definition retain_ptr.h:222
fxcrt::ByteStringView ByteStringView
#define UNOWNED_PTR_EXCLUSION
fxcrt::WideString WideString
Definition widestring.h:207