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;
14using PdfArrayList = std::vector<PdfObject>;
15
17template <typename TObject, typename TListIterator>
18class PdfArrayIndirectIterableBase final : public PdfIndirectIterableBase
19{
20 friend class PdfArray;
21
22public:
24
25private:
27
28public:
29 class Iterator final
30 {
32 public:
33 using difference_type = void;
34 using value_type = TObject*;
35 using pointer = void;
36 using reference = void;
37 using iterator_category = std::forward_iterator_tag;
38 public:
39 Iterator();
40 private:
41 Iterator(TListIterator&& iterator, PdfIndirectObjectList* objects);
42 public:
43 Iterator(const Iterator&) = default;
44 Iterator& operator=(const Iterator&) = default;
45 bool operator==(const Iterator& rhs) const;
46 bool operator!=(const Iterator& rhs) const;
47 Iterator& operator++();
48 Iterator operator++(int);
49 value_type operator*();
50 value_type operator->();
51 private:
52 value_type resolve();
53 private:
54 TListIterator m_iterator;
55 PdfIndirectObjectList* m_objects;
56 };
57
58public:
59 Iterator begin() const;
60 Iterator end() const;
61
62private:
63 PdfArray* m_arr;
64};
65
68
75class PODOFO_API PdfArray final : public PdfDataContainer
76{
77 friend class PdfObject;
78 friend class PdfTokenizer;
79
80public:
81 using size_type = size_t;
82 using value_type = PdfObject;
83 using reference = value_type&;
84 using const_reference = const value_type&;
85 using iterator = PdfArrayList::iterator;
86 using const_iterator = PdfArrayList::const_iterator;
87 using reverse_iterator = PdfArrayList::reverse_iterator;
88 using const_reverse_iterator = PdfArrayList::const_reverse_iterator;
89
91 PdfArray();
92
96 PdfArray(const PdfArray& rhs);
97 PdfArray(PdfArray&& rhs) noexcept;
98
99 template <typename TReal, typename = std::enable_if_t<std::is_floating_point_v<TReal>>>
100 static PdfArray FromReals(cspan<TReal> reals);
101
102 template <typename TInt, typename = std::enable_if_t<std::is_integral_v<TInt>>>
103 static PdfArray FromNumbers(cspan<TInt> numbers);
104
105 static PdfArray FromBools(cspan<bool> bools);
106
110 PdfArray& operator=(const PdfArray& rhs);
111 PdfArray& operator=(PdfArray&& rhs) noexcept;
112
114 unsigned GetSize() const;
115
117 bool IsEmpty() const;
118
120 void Clear();
121
123 const PdfStatefulEncrypt* encrypt, charbuff& buffer) const override;
124
125 template <typename T>
126 const typename ObjectAdapter<T>::TRet GetAtAs(unsigned idx) const;
127
128 template <typename T>
129 typename ObjectAdapter<T>::TRet GetAtAs(unsigned idx);
130
131 template <typename T>
132 const typename ObjectAdapter<T>::TRet GetAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback = { }) const;
133
134 template <typename T>
135 typename ObjectAdapter<T>::TRet GetAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback = { });
136
137 template <typename T>
138 bool TryGetAtAs(unsigned idx, T& value) const;
139
140 template <typename T>
141 bool TryGetAtAs(unsigned idx, T& value);
142
151 const PdfObject* FindAt(unsigned idx) const;
152 PdfObject* FindAt(unsigned idx);
153
154 const PdfObject& MustFindAt(unsigned idx) const;
155 PdfObject& MustFindAt(unsigned idx);
156
157 template <typename T>
158 const typename ObjectAdapter<T>::TRet FindAtAs(unsigned idx) const;
159
160 template <typename T>
161 typename ObjectAdapter<T>::TRet FindAtAs(unsigned idx);
162
163 template <typename T>
164 const typename ObjectAdapter<T>::TRet FindAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback = { }) const;
165
166 template <typename T>
167 typename ObjectAdapter<T>::TRet FindAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback = { });
168
169 template <typename T>
170 bool TryFindAtAs(unsigned idx, T& value) const;
171
172 template <typename T>
173 bool TryFindAtAs(unsigned idx, T& value);
174
175 void RemoveAt(unsigned idx);
176
177 PdfObject& Add(const PdfObject& obj);
178
179 PdfObject& Add(PdfObject&& obj);
180
181 void AddIndirect(const PdfObject& obj);
182
183 PdfObject& AddIndirectSafe(const PdfObject& obj);
184
185 PdfObject& SetAt(unsigned idx, const PdfObject& obj);
186
187 PdfObject& SetAt(unsigned idx, PdfObject&& obj);
188
189 void SetAtIndirect(unsigned idx, const PdfObject* obj);
190
191 PdfObject& SetAtIndirectSafe(unsigned idx, const PdfObject& obj);
192
193 PdfArrayIndirectIterable GetIndirectIterator();
194
195 PdfArrayConstIndirectIterable GetIndirectIterator() const;
196
200 void Resize(unsigned count, const PdfObject& val = PdfObject());
201
202 void Reserve(unsigned n);
203
207 void SwapAt(unsigned atIndex, unsigned toIndex);
208
212 void MoveTo(unsigned atIndex, unsigned toIndex);
213
214public:
216 size_t size() const;
217
218 PdfObject& operator[](size_type idx);
219 const PdfObject& operator[](size_type idx) const;
220
224 iterator begin();
225
229 const_iterator begin() const;
230
234 iterator end();
235
239 const_iterator end() const;
240
244 reverse_iterator rbegin();
245
249 const_reverse_iterator rbegin() const;
250
254 reverse_iterator rend();
255
259 const_reverse_iterator rend() const;
260
261 void resize(size_t size);
262
263 void reserve(size_t size);
264
265 iterator insert(const iterator& pos, const PdfObject& obj);
266 iterator insert(const iterator& pos, PdfObject&& obj);
267
268 template<typename InputIterator>
269 inline void insert(const iterator& pos, const InputIterator& first, const InputIterator& last);
270
271 void erase(const iterator& pos);
272 void erase(const iterator& first, const iterator& last);
273
276 reference front();
277
280 const_reference front() const;
281
284 reference back();
285
288 const_reference back() const;
289
290public:
291 bool operator==(const PdfArray& rhs) const;
292 bool operator!=(const PdfArray& rhs) const;
293
294protected:
295 void resetDirty() override;
296 void setChildrenParent() override;
297
298private:
299 // Append a new "null" object to the back
300 PdfObject& EmplaceBackNoDirtySet();
301
302private:
303 PdfObject& add(PdfObject&& obj);
304 iterator insertAt(const iterator& pos, PdfObject&& obj);
305 PdfObject& getAt(unsigned idx) const;
306 PdfObject* findAt(unsigned idx) const;
308 const PdfStatefulEncrypt* encrypt, charbuff& buffer) const;
309
310private:
311 PdfArrayList m_Objects;
312};
313
314template<typename TReal, typename>
315PdfArray PdfArray::FromReals(cspan<TReal> reals)
316{
318 arr.reserve(reals.size());
319 for (unsigned i = 0; i < reals.size(); i++)
320 arr.Add(PdfObject(static_cast<double>(reals[i])));
321
322 return arr;
323}
324
325template<typename TInt, typename>
326PdfArray PdfArray::FromNumbers(cspan<TInt> numbers)
327{
328 PdfArray arr;
329 arr.reserve(numbers.size());
330 for (unsigned i = 0; i < numbers.size(); i++)
331 arr.Add(PdfObject(static_cast<int64_t>(numbers[i])));
332
333 return arr;
334}
335
336template<typename T>
337const typename ObjectAdapter<T>::TRet PdfArray::GetAtAs(unsigned idx) const
338{
339 return ObjectAdapter<T>::Get(const_cast<const PdfObject&>(getAt(idx)));
340}
341
342template<typename T>
343typename ObjectAdapter<T>::TRet PdfArray::GetAtAs(unsigned idx)
344{
345 return ObjectAdapter<T>::Get(getAt(idx));
346}
347
348template<typename T>
349const typename ObjectAdapter<T>::TRet PdfArray::GetAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback) const
350{
351 return ObjectAdapter<T>::Get(const_cast<const PdfObject&>(getAt(idx)), fallback);
352}
353
354template<typename T>
355typename ObjectAdapter<T>::TRet PdfArray::GetAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback)
356{
357 return ObjectAdapter<T>::Get(getAt(idx), fallback);
358}
359
360template<typename T>
361bool PdfArray::TryGetAtAs(unsigned idx, T& value) const
362{
363 if (ObjectAdapter<T>::TryGet(const_cast<const PdfObject&>(getAt(idx)), value))
364 {
365 return true;
366 }
367 else
368 {
369 value = { };
370 return false;
371 }
372}
373
374template<typename T>
375bool PdfArray::TryGetAtAs(unsigned idx, T& value)
376{
377 if (ObjectAdapter<T>::TryGet(getAt(idx), value))
378 {
379 return true;
380 }
381 else
382 {
383 value = { };
384 return false;
385 }
386}
387
388template<typename T>
389const typename ObjectAdapter<T>::TRet PdfArray::FindAtAs(unsigned idx) const
390{
391 return ObjectAdapter<T>::Get(MustFindAt(idx));
392}
393
394template<typename T>
395inline typename ObjectAdapter<T>::TRet PdfArray::FindAtAs(unsigned idx)
396{
397 return ObjectAdapter<T>::Get(MustFindAt(idx));
398}
399
400template<typename T>
401const typename ObjectAdapter<T>::TRet PdfArray::FindAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback) const
402{
403 auto obj = findAt(idx);
404 if (obj == nullptr)
405 return fallback;
406 else
407 return ObjectAdapter<T>::Get(const_cast<const PdfObject&>(*obj), fallback);
408}
409
410template<typename T>
411inline typename ObjectAdapter<T>::TRet PdfArray::FindAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback)
412{
413 auto obj = findAt(idx);
414 if (obj == nullptr)
415 return fallback;
416 else
417 return ObjectAdapter<T>::Get(*obj, fallback);
418}
419
420template<typename T>
421bool PdfArray::TryFindAtAs(unsigned idx, T& value) const
422{
423 auto obj = findAt(idx);
424 if (obj != nullptr && ObjectAdapter<T>::TryGet(const_cast<const PdfObject&>(*obj), value))
425 {
426 return true;
427 }
428 else
429 {
430 value = { };
431 return false;
432 }
433}
434
435template<typename T>
436inline bool PdfArray::TryFindAtAs(unsigned idx, T& value)
437{
438 auto obj = findAt(idx);
439 if (obj != nullptr && ObjectAdapter<T>::TryGet(*obj, value))
440 {
441 return true;
442 }
443 else
444 {
445 value = { };
446 return false;
447 }
448}
449
450template<typename InputIterator>
451void PdfArray::insert(const PdfArray::iterator& pos,
452 const InputIterator& first,
453 const InputIterator& last)
454{
455 AssertMutable();
456 auto document = GetObjectDocument();
457 InputIterator it1 = first;
458 iterator it2 = pos;
459 for (; it1 != last; it1++, it2++)
460 {
461 it2 = m_Objects.insert(it2, *it1);
462 it2->SetDocument(document);
463 }
464
465 SetDirty();
466}
467
468template<typename TObject, typename TListIterator>
469PdfArrayIndirectIterableBase<TObject, TListIterator>::PdfArrayIndirectIterableBase()
470 : m_arr(nullptr) { }
471
472template<typename TObject, typename TListIterator>
473PdfArrayIndirectIterableBase<TObject, TListIterator>::PdfArrayIndirectIterableBase(PdfArray& arr)
474 : PdfIndirectIterableBase(arr), m_arr(&arr) { }
475
476template<typename TObject, typename TListIterator>
477typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator PdfArrayIndirectIterableBase<TObject, TListIterator>::begin() const
478{
479 if (m_arr == nullptr)
480 return Iterator();
481 else
482 return Iterator(m_arr->begin(), GetObjects());
483}
484
485template<typename TObject, typename TListIterator>
486typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator PdfArrayIndirectIterableBase<TObject, TListIterator>::end() const
487{
488 if (m_arr == nullptr)
489 return Iterator();
490 else
491 return Iterator(m_arr->end(), GetObjects());
492}
493
494template<typename TObject, typename TListIterator>
495PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::Iterator() : m_objects(nullptr) { }
496
497template<typename TObject, typename TListIterator>
498PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::Iterator(TListIterator&& iterator, PdfIndirectObjectList* objects)
499 : m_iterator(std::move(iterator)), m_objects(objects) { }
500
501template<typename TObject, typename TListIterator>
502bool PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator==(const Iterator& rhs) const
503{
504 return m_iterator == rhs.m_iterator;
505}
506
507template<typename TObject, typename TListIterator>
508bool PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator!=(const Iterator& rhs) const
509{
510 return m_iterator != rhs.m_iterator;
511}
512
513template<typename TObject, typename TListIterator>
514typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator& PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator++()
515{
516 m_iterator++;
517 return *this;
518}
519
520template<typename TObject, typename TListIterator>
521typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator++(int)
522{
523 auto copy = *this;
524 m_iterator++;
525 return copy;
526}
527
528template<typename TObject, typename TListIterator>
529typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::value_type PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator*()
530{
531 return resolve();
532}
533
534template<typename TObject, typename TListIterator>
535typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::value_type PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator->()
536{
537 return resolve();
538}
539
540template<typename TObject, typename TListIterator>
541typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::value_type PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::resolve()
542{
543 TObject& robj = *m_iterator;
544 TObject* indirectobj;
545 PdfReference ref;
546 if (m_objects != nullptr
547 && robj.TryGetReference(ref)
548 && ref.IsIndirect()
549 && (indirectobj = GetObject(*m_objects, ref)) != nullptr)
550 {
551 return indirectobj;
552 }
553 else
554 {
555 return &robj;
556 }
557}
558
559};
560
561#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:19
This class represents a PdfArray Use it for all arrays that are written to a PDF file.
Definition PdfArray.h:76
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