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