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
19template <typename TObject, typename TListIterator>
20class PdfArrayIndirectIterableBase final : public PdfIndirectIterableBase
21{
22 friend class PdfArray;
23
24public:
26
27private:
29
30public:
31 class Iterator final
32 {
34 public:
35 using difference_type = void;
36 using value_type = TObject*;
37 using pointer = void;
38 using reference = void;
39 using iterator_category = std::forward_iterator_tag;
40 public:
41 Iterator();
42 private:
43 Iterator(TListIterator&& iterator, PdfIndirectObjectList* objects);
44 public:
45 Iterator(const Iterator&) = default;
46 Iterator& operator=(const Iterator&) = default;
47 bool operator==(const Iterator& rhs) const;
48 bool operator!=(const Iterator& rhs) const;
49 Iterator& operator++();
50 Iterator operator++(int);
51 value_type operator*();
52 value_type operator->();
53 private:
54 value_type resolve();
55 private:
56 TListIterator m_iterator;
57 PdfIndirectObjectList* m_objects;
58 };
59
60public:
61 Iterator begin() const;
62 Iterator end() const;
63
64private:
65 PdfArray* m_arr;
66};
67
70
78class PODOFO_API PdfArray final : public PdfDataContainer
79{
80 friend class PdfObject;
81 friend class PdfTokenizer;
82
83public:
84 using size_type = size_t;
85 using value_type = PdfObject;
86 using reference = value_type&;
87 using const_reference = const value_type&;
88 using iterator = PdfArrayList::iterator;
89 using const_iterator = PdfArrayList::const_iterator;
90 using reverse_iterator = PdfArrayList::reverse_iterator;
91 using const_reverse_iterator = PdfArrayList::const_reverse_iterator;
92
95 PdfArray();
96
101 PdfArray(const PdfArray& rhs);
102 PdfArray(PdfArray&& rhs) noexcept;
103
104 template <typename TReal, typename = std::enable_if_t<std::is_floating_point_v<TReal>>>
105 static PdfArray FromReals(cspan<TReal> reals);
106
107 template <typename TInt, typename = std::enable_if_t<std::is_integral_v<TInt>>>
108 static PdfArray FromNumbers(cspan<TInt> numbers);
109
110 static PdfArray FromBools(cspan<bool> bools);
111
116 PdfArray& operator=(const PdfArray& rhs);
117 PdfArray& operator=(PdfArray&& rhs) noexcept;
118
122 unsigned GetSize() const;
123
127 bool IsEmpty() const;
128
131 void Clear();
132
134 const PdfStatefulEncrypt* encrypt, charbuff& buffer) const override;
135
136 template <typename T>
137 const typename ObjectAdapter<T>::TRet GetAtAs(unsigned idx) const;
138
139 template <typename T>
140 typename ObjectAdapter<T>::TRet GetAtAs(unsigned idx);
141
142 template <typename T>
143 const typename ObjectAdapter<T>::TRet GetAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback = { }) const;
144
145 template <typename T>
146 typename ObjectAdapter<T>::TRet GetAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback = { });
147
148 template <typename T>
149 bool TryGetAtAs(unsigned idx, T& value) const;
150
151 template <typename T>
152 bool TryGetAtAs(unsigned idx, T& value);
153
163 const PdfObject* FindAt(unsigned idx) const;
164 PdfObject* FindAt(unsigned idx);
165
166 const PdfObject& MustFindAt(unsigned idx) const;
167 PdfObject& MustFindAt(unsigned idx);
168
169 template <typename T>
170 const typename ObjectAdapter<T>::TRet FindAtAs(unsigned idx) const;
171
172 template <typename T>
173 typename ObjectAdapter<T>::TRet FindAtAs(unsigned idx);
174
175 template <typename T>
176 const typename ObjectAdapter<T>::TRet FindAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback = { }) const;
177
178 template <typename T>
179 typename ObjectAdapter<T>::TRet FindAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback = { });
180
181 template <typename T>
182 bool TryFindAtAs(unsigned idx, T& value) const;
183
184 template <typename T>
185 bool TryFindAtAs(unsigned idx, T& value);
186
187 void RemoveAt(unsigned idx);
188
189 PdfObject& Add(const PdfObject& obj);
190
191 PdfObject& Add(PdfObject&& obj);
192
193 void AddIndirect(const PdfObject& obj);
194
195 PdfObject& AddIndirectSafe(const PdfObject& obj);
196
197 PdfObject& SetAt(unsigned idx, const PdfObject& obj);
198
199 PdfObject& SetAt(unsigned idx, PdfObject&& obj);
200
201 void SetAtIndirect(unsigned idx, const PdfObject* obj);
202
203 PdfObject& SetAtIndirectSafe(unsigned idx, const PdfObject& obj);
204
205 PdfArrayIndirectIterable GetIndirectIterator();
206
207 PdfArrayConstIndirectIterable GetIndirectIterator() const;
208
214 void Resize(unsigned count, const PdfObject& val = PdfObject());
215
216 void Reserve(unsigned n);
217
218 void SwapAt(unsigned atIndex, unsigned toIndex);
219
220 void MoveTo(unsigned atIndex, unsigned toIndex);
221
222public:
226 size_t size() const;
227
228 PdfObject& operator[](size_type idx);
229 const PdfObject& operator[](size_type idx) const;
230
236 iterator begin();
237
243 const_iterator begin() const;
244
250 iterator end();
251
257 const_iterator end() const;
258
264 reverse_iterator rbegin();
265
271 const_reverse_iterator rbegin() const;
272
278 reverse_iterator rend();
279
285 const_reverse_iterator rend() const;
286
287 void resize(size_t size);
288
289 void reserve(size_t size);
290
291 iterator insert(const iterator& pos, const PdfObject& obj);
292 iterator insert(const iterator& pos, PdfObject&& obj);
293
294 template<typename InputIterator>
295 inline void insert(const iterator& pos, const InputIterator& first, const InputIterator& last);
296
297 void erase(const iterator& pos);
298 void erase(const iterator& first, const iterator& last);
299
304 reference front();
305
310 const_reference front() const;
311
316 reference back();
317
322 const_reference back() const;
323
324public:
325 bool operator==(const PdfArray& rhs) const;
326 bool operator!=(const PdfArray& rhs) const;
327
328protected:
329 void resetDirty() override;
330 void setChildrenParent() override;
331
332private:
333 // Append a new "null" object to the back
334 PdfObject& EmplaceBackNoDirtySet();
335
336private:
337 PdfObject& add(PdfObject&& obj);
338 iterator insertAt(const iterator& pos, PdfObject&& obj);
339 PdfObject& getAt(unsigned idx) const;
340 PdfObject* findAt(unsigned idx) const;
342 const PdfStatefulEncrypt* encrypt, charbuff& buffer) const;
343
344private:
345 PdfArrayList m_Objects;
346};
347
348template<typename TReal, typename>
349PdfArray PdfArray::FromReals(cspan<TReal> reals)
350{
352 arr.reserve(reals.size());
353 for (unsigned i = 0; i < reals.size(); i++)
354 arr.Add(PdfObject(static_cast<double>(reals[i])));
355
356 return arr;
357}
358
359template<typename TInt, typename>
360PdfArray PdfArray::FromNumbers(cspan<TInt> numbers)
361{
362 PdfArray arr;
363 arr.reserve(numbers.size());
364 for (unsigned i = 0; i < numbers.size(); i++)
365 arr.Add(PdfObject(static_cast<int64_t>(numbers[i])));
366
367 return arr;
368}
369
370template<typename T>
371const typename ObjectAdapter<T>::TRet PdfArray::GetAtAs(unsigned idx) const
372{
373 return ObjectAdapter<T>::Get(const_cast<const PdfObject&>(getAt(idx)));
374}
375
376template<typename T>
377typename ObjectAdapter<T>::TRet PdfArray::GetAtAs(unsigned idx)
378{
379 return ObjectAdapter<T>::Get(getAt(idx));
380}
381
382template<typename T>
383const typename ObjectAdapter<T>::TRet PdfArray::GetAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback) const
384{
385 return ObjectAdapter<T>::Get(const_cast<const PdfObject&>(getAt(idx)), fallback);
386}
387
388template<typename T>
389typename ObjectAdapter<T>::TRet PdfArray::GetAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback)
390{
391 return ObjectAdapter<T>::Get(getAt(idx), fallback);
392}
393
394template<typename T>
395bool PdfArray::TryGetAtAs(unsigned idx, T& value) const
396{
397 if (ObjectAdapter<T>::TryGet(const_cast<const PdfObject&>(getAt(idx)), value))
398 {
399 return true;
400 }
401 else
402 {
403 value = { };
404 return false;
405 }
406}
407
408template<typename T>
409bool PdfArray::TryGetAtAs(unsigned idx, T& value)
410{
411 if (ObjectAdapter<T>::TryGet(getAt(idx), value))
412 {
413 return true;
414 }
415 else
416 {
417 value = { };
418 return false;
419 }
420}
421
422template<typename T>
423const typename ObjectAdapter<T>::TRet PdfArray::FindAtAs(unsigned idx) const
424{
425 return ObjectAdapter<T>::Get(MustFindAt(idx));
426}
427
428template<typename T>
429inline typename ObjectAdapter<T>::TRet PdfArray::FindAtAs(unsigned idx)
430{
431 return ObjectAdapter<T>::Get(MustFindAt(idx));
432}
433
434template<typename T>
435const typename ObjectAdapter<T>::TRet PdfArray::FindAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback) const
436{
437 auto obj = findAt(idx);
438 if (obj == nullptr)
439 return fallback;
440 else
441 return ObjectAdapter<T>::Get(const_cast<const PdfObject&>(*obj), fallback);
442}
443
444template<typename T>
445inline typename ObjectAdapter<T>::TRet PdfArray::FindAtAsSafe(unsigned idx, const std::common_type_t<T>& fallback)
446{
447 auto obj = findAt(idx);
448 if (obj == nullptr)
449 return fallback;
450 else
451 return ObjectAdapter<T>::Get(*obj, fallback);
452}
453
454template<typename T>
455bool PdfArray::TryFindAtAs(unsigned idx, T& value) const
456{
457 auto obj = findAt(idx);
458 if (obj != nullptr && ObjectAdapter<T>::TryGet(const_cast<const PdfObject&>(*obj), value))
459 {
460 return true;
461 }
462 else
463 {
464 value = { };
465 return false;
466 }
467}
468
469template<typename T>
470inline bool PdfArray::TryFindAtAs(unsigned idx, T& value)
471{
472 auto obj = findAt(idx);
473 if (obj != nullptr && ObjectAdapter<T>::TryGet(*obj, value))
474 {
475 return true;
476 }
477 else
478 {
479 value = { };
480 return false;
481 }
482}
483
484template<typename InputIterator>
485void PdfArray::insert(const PdfArray::iterator& pos,
486 const InputIterator& first,
487 const InputIterator& last)
488{
489 AssertMutable();
490 auto document = GetObjectDocument();
491 InputIterator it1 = first;
492 iterator it2 = pos;
493 for (; it1 != last; it1++, it2++)
494 {
495 it2 = m_Objects.insert(it2, *it1);
496 it2->SetDocument(document);
497 }
498
499 SetDirty();
500}
501
502template<typename TObject, typename TListIterator>
503PdfArrayIndirectIterableBase<TObject, TListIterator>::PdfArrayIndirectIterableBase()
504 : m_arr(nullptr) { }
505
506template<typename TObject, typename TListIterator>
507PdfArrayIndirectIterableBase<TObject, TListIterator>::PdfArrayIndirectIterableBase(PdfArray& arr)
508 : PdfIndirectIterableBase(arr), m_arr(&arr) { }
509
510template<typename TObject, typename TListIterator>
511typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator PdfArrayIndirectIterableBase<TObject, TListIterator>::begin() const
512{
513 if (m_arr == nullptr)
514 return Iterator();
515 else
516 return Iterator(m_arr->begin(), GetObjects());
517}
518
519template<typename TObject, typename TListIterator>
520typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator PdfArrayIndirectIterableBase<TObject, TListIterator>::end() const
521{
522 if (m_arr == nullptr)
523 return Iterator();
524 else
525 return Iterator(m_arr->end(), GetObjects());
526}
527
528template<typename TObject, typename TListIterator>
529PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::Iterator() : m_objects(nullptr) { }
530
531template<typename TObject, typename TListIterator>
532PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::Iterator(TListIterator&& iterator, PdfIndirectObjectList* objects)
533 : m_iterator(std::move(iterator)), m_objects(objects) { }
534
535template<typename TObject, typename TListIterator>
536bool PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator==(const Iterator& rhs) const
537{
538 return m_iterator == rhs.m_iterator;
539}
540
541template<typename TObject, typename TListIterator>
542bool PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator!=(const Iterator& rhs) const
543{
544 return m_iterator != rhs.m_iterator;
545}
546
547template<typename TObject, typename TListIterator>
548typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator& PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator++()
549{
550 m_iterator++;
551 return *this;
552}
553
554template<typename TObject, typename TListIterator>
555typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator++(int)
556{
557 auto copy = *this;
558 m_iterator++;
559 return copy;
560}
561
562template<typename TObject, typename TListIterator>
563typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::value_type PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator*()
564{
565 return resolve();
566}
567
568template<typename TObject, typename TListIterator>
569typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::value_type PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator->()
570{
571 return resolve();
572}
573
574template<typename TObject, typename TListIterator>
575typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::value_type PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::resolve()
576{
577 TObject& robj = *m_iterator;
578 TObject* indirectobj;
579 PdfReference ref;
580 if (m_objects != nullptr
581 && robj.TryGetReference(ref)
582 && ref.IsIndirect()
583 && (indirectobj = GetObject(*m_objects, ref)) != nullptr)
584 {
585 return indirectobj;
586 }
587 else
588 {
589 return &robj;
590 }
591}
592
593};
594
595#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:16
Helper class to iterate through array indirect objects.
Definition PdfArray.h:21
This class represents a PdfArray Use it for all arrays that are written to a PDF file.
Definition PdfArray.h:79
PdfArray()
Create an empty array.
Definition PdfArray.cpp:13
A PdfDataProvider object with a PdfObject owner, specialized in holding objects.
Definition PdfDataContainer.h:20
A list of PdfObjects that constitutes the indirect object list of the document The PdfParser will rea...
Definition PdfIndirectObjectList.h:29
This class represents a PDF indirect Object in memory.
Definition PdfObject.h:33
A simple tokenizer for PDF files and PDF content streams.
Definition PdfTokenizer.h:34
Convenient type for char array storage and/or buffer with std::string compatibility.
Definition basetypes.h:35
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:147