PoDoFo 1.2.0
Loading...
Searching...
No Matches
PdfArray.h
1// SPDX-FileCopyrightText: 2006 Dominik Seichter <domseichter@web.de>
2// SPDX-FileCopyrightText: 2020 Francesco Pretto <ceztko@gmail.com>
3// SPDX-License-Identifier: LGPL-2.0-or-later OR MPL-2.0
4
5#ifndef PDF_ARRAY_H
6#define PDF_ARRAY_H
7
8#include "PdfDeclarations.h"
9#include "PdfDataContainer.h"
10
11namespace PoDoFo {
12
13class PdfArray;
15using PdfArrayList = std::vector<PdfObject>;
16
18template <typename TObject, typename TListIterator>
19class PdfArrayIndirectIterableBase final : public PdfIndirectIterableBase
20{
21 friend class PdfArray;
22
23public:
25
26private:
28
29public:
30 class Iterator final
31 {
33 public:
34 using difference_type = void;
35 using value_type = TObject*;
36 using pointer = void;
37 using reference = void;
38 using iterator_category = std::forward_iterator_tag;
39 public:
40 Iterator();
41 private:
42 Iterator(TListIterator&& iterator, PdfIndirectObjectList* objects);
43 public:
44 Iterator(const Iterator&) = default;
45 Iterator& operator=(const Iterator&) = default;
46 bool operator==(const Iterator& rhs) const;
47 bool operator!=(const Iterator& rhs) const;
48 Iterator& operator++();
49 Iterator operator++(int);
50 value_type operator*();
51 value_type operator->();
52 private:
53 value_type resolve();
54 private:
55 TListIterator m_iterator;
56 PdfIndirectObjectList* m_objects;
57 };
58
59public:
60 Iterator begin() const;
61 Iterator end() const;
62
63private:
64 PdfArray* m_arr;
65};
66
69
76class PODOFO_API PdfArray final : public PdfDataContainer
77{
78 friend class PdfObject;
79 friend class PdfTokenizer;
80
81public:
82 using size_type = size_t;
83 using value_type = PdfObject;
84 using reference = value_type&;
85 using const_reference = const value_type&;
86 using iterator = PdfObject*;
87 using const_iterator = const PdfObject*;
88 using reverse_iterator = std::reverse_iterator<iterator>;
89 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
90
92 PdfArray();
93
97 PdfArray(const PdfArray& rhs);
98 PdfArray(PdfArray&& rhs) noexcept;
99
100 ~PdfArray();
101
102 template <typename TReal, typename = std::enable_if_t<std::is_floating_point_v<TReal>>>
103 static PdfArray FromReals(cspan<TReal> reals);
104
105 template <typename TInt, typename = std::enable_if_t<std::is_integral_v<TInt>>>
106 static PdfArray FromNumbers(cspan<TInt> numbers);
107
108 static PdfArray FromBools(cspan<bool> bools);
109
113 PdfArray& operator=(const PdfArray& rhs);
114 PdfArray& operator=(PdfArray&& rhs) noexcept;
115
117 unsigned GetSize() const;
118
120 bool IsEmpty() const;
121
123 void Clear();
124
126 const PdfStatefulEncrypt* encrypt, charbuff& buffer) const override;
127
128 template <typename T>
129 const typename ObjectAdapter<T>::TRet GetAtAs(unsigned idx) const;
130
131 template <typename T>
132 typename ObjectAdapter<T>::TRet GetAtAs(unsigned idx);
133
134 template <typename T>
135 const typename ObjectAdapter<T>::TRet GetAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback = { }) const;
136
137 template <typename T>
138 typename ObjectAdapter<T>::TRet GetAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback = { });
139
140 template <typename T>
141 bool TryGetAtAs(unsigned idx, T& value) const;
142
143 template <typename T>
144 bool TryGetAtAs(unsigned idx, T& value);
145
154 const PdfObject* FindAt(unsigned idx) const;
155 PdfObject* FindAt(unsigned idx);
156
157 const PdfObject& MustFindAt(unsigned idx) const;
158 PdfObject& MustFindAt(unsigned idx);
159
160 template <typename T>
161 const typename ObjectAdapter<T>::TRet FindAtAs(unsigned idx) const;
162
163 template <typename T>
164 typename ObjectAdapter<T>::TRet FindAtAs(unsigned idx);
165
166 template <typename T>
167 const typename ObjectAdapter<T>::TRet FindAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback = { }) const;
168
169 template <typename T>
170 typename ObjectAdapter<T>::TRet FindAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback = { });
171
172 template <typename T>
173 bool TryFindAtAs(unsigned idx, T& value) const;
174
175 template <typename T>
176 bool TryFindAtAs(unsigned idx, T& value);
177
178 void RemoveAt(unsigned idx);
179
180 PdfObject& Add(const PdfObject& obj);
181
182 PdfObject& Add(PdfObject&& obj);
183
184 void AddIndirect(const PdfObject& obj);
185
186 PdfObject& AddIndirectSafe(const PdfObject& obj);
187
188 PdfObject& SetAt(unsigned idx, const PdfObject& obj);
189
190 PdfObject& SetAt(unsigned idx, PdfObject&& obj);
191
192 void SetAtIndirect(unsigned idx, const PdfObject* obj);
193
194 PdfObject& SetAtIndirectSafe(unsigned idx, const PdfObject& obj);
195
196 PdfArrayIndirectIterable GetIndirectIterator();
197
198 PdfArrayConstIndirectIterable GetIndirectIterator() const;
199
203 void Resize(unsigned count, const PdfObject& val = PdfObject());
204
205 void Reserve(unsigned n);
206
210 void SwapAt(unsigned atIndex, unsigned toIndex);
211
215 void MoveTo(unsigned atIndex, unsigned toIndex);
216
217public:
219 size_t size() const;
220
221 PdfObject& operator[](size_type idx);
222 const PdfObject& operator[](size_type idx) const;
223
227 iterator begin();
228
232 const_iterator begin() const;
233
237 iterator end();
238
242 const_iterator end() const;
243
247 reverse_iterator rbegin();
248
252 const_reverse_iterator rbegin() const;
253
257 reverse_iterator rend();
258
262 const_reverse_iterator rend() const;
263
264 void resize(size_t size);
265
266 void reserve(size_t size);
267
268 iterator insert(const iterator& pos, const PdfObject& obj);
269 iterator insert(const iterator& pos, PdfObject&& obj);
270
271 template<typename InputIterator>
272 inline void insert(const iterator& pos, const InputIterator& first, const InputIterator& last);
273
274 void erase(const iterator& pos);
275 void erase(const iterator& first, const iterator& last);
276
279 reference front();
280
283 const_reference front() const;
284
287 reference back();
288
291 const_reference back() const;
292
293public:
294 bool operator==(const PdfArray& rhs) const;
295 bool operator!=(const PdfArray& rhs) const;
296
297protected:
298 void resetDirty() override;
299 void setChildrenParent() override;
300
301private:
302 // Append a new "null" object to the back
303 PdfObject& EmplaceBackNoDirtySet();
304
305private:
306 PdfObject& add(PdfObject&& obj);
307 iterator insertAt(const iterator& pos, PdfObject&& obj);
308 PdfObject& getAt(unsigned idx) const;
309 PdfObject* findAt(unsigned idx) const;
311 const PdfStatefulEncrypt* encrypt, charbuff& buffer) const;
312
313private:
316 void ensureCapacity(size_t size);
317
319 void reallocate(unsigned capacity);
320
322 void eraseAt(unsigned index, unsigned count);
323
325 static void relocateBackPointers(PdfObject* data, unsigned count);
326
328 void addAt(unsigned index, const PdfObject& obj);
329
330 void copyFrom(const PdfArray& rhs);
331 void moveFrom(PdfArray&& rhs);
332 void destroyAll();
333
334private:
335 PdfObject* m_data;
336 unsigned m_size;
337 unsigned m_capacity;
338};
339
340template<typename TReal, typename>
341PdfArray PdfArray::FromReals(cspan<TReal> reals)
342{
344 arr.reserve(reals.size());
345 for (unsigned i = 0; i < reals.size(); i++)
346 arr.Add(PdfObject(static_cast<double>(reals[i])));
347
348 return arr;
349}
350
351template<typename TInt, typename>
352PdfArray PdfArray::FromNumbers(cspan<TInt> numbers)
353{
354 PdfArray arr;
355 arr.reserve(numbers.size());
356 for (unsigned i = 0; i < numbers.size(); i++)
357 arr.Add(PdfObject(static_cast<int64_t>(numbers[i])));
358
359 return arr;
360}
361
362template<typename T>
363const typename ObjectAdapter<T>::TRet PdfArray::GetAtAs(unsigned idx) const
364{
365 return ObjectAdapter<T>::Get(const_cast<const PdfObject&>(getAt(idx)));
366}
367
368template<typename T>
369typename ObjectAdapter<T>::TRet PdfArray::GetAtAs(unsigned idx)
370{
371 return ObjectAdapter<T>::Get(getAt(idx));
372}
373
374template<typename T>
375const typename ObjectAdapter<T>::TRet PdfArray::GetAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback) const
376{
377 return ObjectAdapter<T>::Get(const_cast<const PdfObject&>(getAt(idx)), fallback);
378}
379
380template<typename T>
381typename ObjectAdapter<T>::TRet PdfArray::GetAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback)
382{
383 return ObjectAdapter<T>::Get(getAt(idx), fallback);
384}
385
386template<typename T>
387bool PdfArray::TryGetAtAs(unsigned idx, T& value) const
388{
389 if (ObjectAdapter<T>::TryGet(const_cast<const PdfObject&>(getAt(idx)), value))
390 {
391 return true;
392 }
393 else
394 {
395 value = { };
396 return false;
397 }
398}
399
400template<typename T>
401bool PdfArray::TryGetAtAs(unsigned idx, T& value)
402{
403 if (ObjectAdapter<T>::TryGet(getAt(idx), value))
404 {
405 return true;
406 }
407 else
408 {
409 value = { };
410 return false;
411 }
412}
413
414template<typename T>
415const typename ObjectAdapter<T>::TRet PdfArray::FindAtAs(unsigned idx) const
416{
417 return ObjectAdapter<T>::Get(MustFindAt(idx));
418}
419
420template<typename T>
421inline typename ObjectAdapter<T>::TRet PdfArray::FindAtAs(unsigned idx)
422{
423 return ObjectAdapter<T>::Get(MustFindAt(idx));
424}
425
426template<typename T>
427const typename ObjectAdapter<T>::TRet PdfArray::FindAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback) const
428{
429 auto obj = findAt(idx);
430 if (obj == nullptr)
431 return fallback;
432 else
433 return ObjectAdapter<T>::Get(const_cast<const PdfObject&>(*obj), fallback);
434}
435
436template<typename T>
437inline typename ObjectAdapter<T>::TRet PdfArray::FindAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback)
438{
439 auto obj = findAt(idx);
440 if (obj == nullptr)
441 return fallback;
442 else
443 return ObjectAdapter<T>::Get(*obj, fallback);
444}
445
446template<typename T>
447bool PdfArray::TryFindAtAs(unsigned idx, T& value) const
448{
449 auto obj = findAt(idx);
450 if (obj != nullptr && ObjectAdapter<T>::TryGet(const_cast<const PdfObject&>(*obj), value))
451 {
452 return true;
453 }
454 else
455 {
456 value = { };
457 return false;
458 }
459}
460
461template<typename T>
462inline bool PdfArray::TryFindAtAs(unsigned idx, T& value)
463{
464 auto obj = findAt(idx);
465 if (obj != nullptr && ObjectAdapter<T>::TryGet(*obj, value))
466 {
467 return true;
468 }
469 else
470 {
471 value = { };
472 return false;
473 }
474}
475
476template<typename InputIterator>
477void PdfArray::insert(const PdfArray::iterator& pos,
478 const InputIterator& first,
479 const InputIterator& last)
480{
481 AssertMutable();
482 InputIterator it1 = first;
483 iterator it2 = pos;
484 for (; it1 != last; it1++, it2++)
485 it2 = insertAt(it2, PdfObject(*it1));
486
487 SetDirty();
488}
489
490template<typename TObject, typename TListIterator>
491PdfArrayIndirectIterableBase<TObject, TListIterator>::PdfArrayIndirectIterableBase()
492 : m_arr(nullptr) { }
493
494template<typename TObject, typename TListIterator>
495PdfArrayIndirectIterableBase<TObject, TListIterator>::PdfArrayIndirectIterableBase(PdfArray& arr)
496 : PdfIndirectIterableBase(arr), m_arr(&arr) { }
497
498template<typename TObject, typename TListIterator>
499typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator PdfArrayIndirectIterableBase<TObject, TListIterator>::begin() const
500{
501 if (m_arr == nullptr)
502 return Iterator();
503 else
504 return Iterator(m_arr->begin(), GetObjects());
505}
506
507template<typename TObject, typename TListIterator>
508typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator PdfArrayIndirectIterableBase<TObject, TListIterator>::end() const
509{
510 if (m_arr == nullptr)
511 return Iterator();
512 else
513 return Iterator(m_arr->end(), GetObjects());
514}
515
516template<typename TObject, typename TListIterator>
517PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::Iterator() : m_objects(nullptr) { }
518
519template<typename TObject, typename TListIterator>
520PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::Iterator(TListIterator&& iterator, PdfIndirectObjectList* objects)
521 : m_iterator(std::move(iterator)), m_objects(objects) { }
522
523template<typename TObject, typename TListIterator>
524bool PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator==(const Iterator& rhs) const
525{
526 return m_iterator == rhs.m_iterator;
527}
528
529template<typename TObject, typename TListIterator>
530bool PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator!=(const Iterator& rhs) const
531{
532 return m_iterator != rhs.m_iterator;
533}
534
535template<typename TObject, typename TListIterator>
536typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator& PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator++()
537{
538 m_iterator++;
539 return *this;
540}
541
542template<typename TObject, typename TListIterator>
543typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator++(int)
544{
545 auto copy = *this;
546 m_iterator++;
547 return copy;
548}
549
550template<typename TObject, typename TListIterator>
551typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::value_type PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator*()
552{
553 return resolve();
554}
555
556template<typename TObject, typename TListIterator>
557typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::value_type PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator->()
558{
559 return resolve();
560}
561
562template<typename TObject, typename TListIterator>
563typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::value_type PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::resolve()
564{
565 TObject& robj = *m_iterator;
566 TObject* indirectobj;
567 PdfReference ref;
568 if (m_objects != nullptr
569 && robj.TryGetReference(ref)
570 && ref.IsIndirect()
571 && (indirectobj = GetObject(*m_objects, ref)) != nullptr)
572 {
573 return indirectobj;
574 }
575 else
576 {
577 return &robj;
578 }
579}
580
581};
582
583#endif // PDF_ARRAY_H
This file should be included as the FIRST file in every header of PoDoFo lib.
An interface for writing blocks of data to a data source.
Definition OutputStream.h:15
Helper class to iterate through array indirect objects.
Definition PdfArray.h:20
This class represents a PdfArray Use it for all arrays that are written to a PDF file.
Definition PdfArray.h:77
PdfArray()
Create an empty array.
Definition PdfArray.cpp:13
A PdfDataProvider object with a PdfObject owner, specialized in holding objects.
Definition PdfDataContainer.h:18
A list of PdfObjects that constitutes the indirect object list of the document The PdfParser will rea...
Definition PdfIndirectObjectList.h:34
This class represents a PDF indirect Object in memory.
Definition PdfObject.h:31
A simple tokenizer for PDF files and PDF content streams.
Definition PdfTokenizer.h:47
Convenient type for char array storage and/or buffer with std::string compatibility.
Definition basetypes.h:30
All classes, functions, types and enums of PoDoFo are members of these namespace.
Definition basetypes.h:13
PdfWriteFlags
Specify additional options for writing the PDF.
Definition PdfDeclarations.h:136
std::vector< PdfObject > PdfArrayList
Definition PdfArray.h:15