PoDoFo  1.0.0-dev
PdfArray.h
1 
7 #ifndef PDF_ARRAY_H
8 #define PDF_ARRAY_H
9 
10 #include "PdfDeclarations.h"
11 #include "PdfDataContainer.h"
12 
13 namespace PoDoFo {
14 
15 class PdfArray;
16 using PdfArrayList = std::vector<PdfObject>;
17 
21 template <typename TObject, typename TListIterator>
22 class PdfArrayIndirectIterableBase final : public PdfIndirectIterableBase
23 {
24  friend class PdfArray;
25 
26 public:
28 
29 private:
31 
32 public:
33  class Iterator final
34  {
35  friend class PdfArrayIndirectIterableBase;
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 
62 public:
63  Iterator begin() const;
64  Iterator end() const;
65 
66 private:
67  PdfArray* m_arr;
68 };
69 
72 
80 class PODOFO_API PdfArray final : public PdfDataContainer
81 {
82  friend class PdfObject;
83  friend class PdfTokenizer;
84 
85 public:
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 
110  PdfArray& operator=(const PdfArray& rhs);
111  PdfArray& operator=(PdfArray&& rhs) noexcept;
112 
116  unsigned GetSize() const;
117 
121  bool IsEmpty() const;
122 
125  void Clear();
126 
127  void Write(OutputStream& stream, PdfWriteFlags writeMode,
128  const PdfStatefulEncrypt* encrypt, charbuff& buffer) const override;
129 
130  template <typename T>
131  T GetAtAs(unsigned idx) const;
132 
133  template <typename T>
134  T GetAtAsSafe(unsigned idx, const std::common_type_t<T>& defvalue = { }) const;
135 
136  template <typename T>
137  bool TryGetAtAs(unsigned idx, T& value) const;
138 
148  const PdfObject* FindAt(unsigned idx) const;
149  PdfObject* FindAt(unsigned idx);
150 
151  const PdfObject& MustFindAt(unsigned idx) const;
152  PdfObject& MustFindAt(unsigned idx);
153 
154  template <typename T>
155  T FindAtAs(unsigned idx, const std::common_type_t<T>& defvalue = { }) const;
156 
157  template <typename T>
158  T FindAtAsSafe(unsigned idx, const std::common_type_t<T>& defvalue = { }) const;
159 
160  template <typename T>
161  bool TryFindAtAs(unsigned idx, T& value) const;
162 
163  void RemoveAt(unsigned idx);
164 
165  PdfObject& Add(const PdfObject& obj);
166 
167  PdfObject& Add(PdfObject&& obj);
168 
169  void AddIndirect(const PdfObject& obj);
170 
171  PdfObject& AddIndirectSafe(const PdfObject& obj);
172 
173  PdfObject& SetAt(unsigned idx, const PdfObject& obj);
174 
175  PdfObject& SetAt(unsigned idx, PdfObject&& obj);
176 
177  void SetAtIndirect(unsigned idx, const PdfObject* obj);
178 
179  PdfObject& SetAtIndirectSafe(unsigned idx, const PdfObject& obj);
180 
181  PdfArrayIndirectIterable GetIndirectIterator();
182 
183  PdfArrayConstIndirectIterable GetIndirectIterator() const;
184 
190  void Resize(unsigned count, const PdfObject& val = PdfObject());
191 
192  void Reserve(unsigned n);
193 
194  void SwapAt(unsigned atIndex, unsigned toIndex);
195 
196  void MoveTo(unsigned atIndex, unsigned toIndex);
197 
198 public:
202  size_t size() const;
203 
204  PdfObject& operator[](size_type idx);
205  const PdfObject& operator[](size_type idx) const;
206 
212  iterator begin();
213 
219  const_iterator begin() const;
220 
226  iterator end();
227 
233  const_iterator end() const;
234 
240  reverse_iterator rbegin();
241 
247  const_reverse_iterator rbegin() const;
248 
254  reverse_iterator rend();
255 
261  const_reverse_iterator rend() const;
262 
263  void resize(size_t size);
264 
265  void reserve(size_t size);
266 
267  iterator insert(const iterator& pos, const PdfObject& obj);
268  iterator insert(const iterator& pos, PdfObject&& obj);
269 
270  template<typename InputIterator>
271  inline void insert(const iterator& pos, const InputIterator& first, const InputIterator& last);
272 
273  void erase(const iterator& pos);
274  void erase(const iterator& first, const iterator& last);
275 
280  reference front();
281 
286  const_reference front() const;
287 
292  reference back();
293 
298  const_reference back() const;
299 
300 public:
301  bool operator==(const PdfArray& rhs) const;
302  bool operator!=(const PdfArray& rhs) const;
303 
304 protected:
305  void resetDirty() override;
306  void setChildrenParent() override;
307 
308 private:
309  // Append a new "null" object to the back
310  PdfObject& EmplaceBackNoDirtySet();
311 
312 private:
313  PdfObject& add(PdfObject&& obj);
314  iterator insertAt(const iterator& pos, PdfObject&& obj);
315  PdfObject& getAt(unsigned idx) const;
316  PdfObject* findAt(unsigned idx) const;
317  void write(OutputStream& stream, PdfWriteFlags writeMode, bool addDelimiters,
318  const PdfStatefulEncrypt* encrypt, charbuff& buffer) const;
319 
320 private:
321  PdfArrayList m_Objects;
322 };
323 
324 template<typename T>
325 T PdfArray::GetAtAs(unsigned idx) const
326 {
327  return Object<T>::Get(getAt(idx));
328 }
329 
330 template<typename T>
331 T PdfArray::GetAtAsSafe(unsigned idx, const std::common_type_t<T>& defvalue) const
332 {
333  T value;
334  if (Object<T>::TryGet(getAt(idx), value))
335  return value;
336  else
337  return defvalue;
338 }
339 
340 template<typename T>
341 bool PdfArray::TryGetAtAs(unsigned idx, T& value) const
342 {
343  if (Object<T>::TryGet(getAt(idx), value))
344  {
345  return true;
346  }
347  else
348  {
349  value = { };
350  return false;
351  }
352 }
353 
354 template<typename T>
355 T PdfArray::FindAtAs(unsigned idx, const std::common_type_t<T>& defvalue) const
356 {
357  auto obj = findAt(idx);
358  if (obj == nullptr)
359  return defvalue;
360 
361  return Object<T>::Get(*obj);
362 }
363 
364 template<typename T>
365 T PdfArray::FindAtAsSafe(unsigned idx, const std::common_type_t<T>& defvalue) const
366 {
367  T value;
368  auto obj = findAt(idx);
369  if (obj != nullptr && Object<T>::TryGet(*obj, value))
370  return value;
371  else
372  return defvalue;
373 }
374 
375 template<typename T>
376 bool PdfArray::TryFindAtAs(unsigned idx, T& value) const
377 {
378  auto obj = findAt(idx);
379  if (obj != nullptr && Object<T>::TryGet(*obj, value))
380  {
381  return true;
382  }
383  else
384  {
385  value = { };
386  return false;
387  }
388 }
389 
390 template<typename InputIterator>
391 void PdfArray::insert(const PdfArray::iterator& pos,
392  const InputIterator& first,
393  const InputIterator& last)
394 {
395  AssertMutable();
396  auto document = GetObjectDocument();
397  InputIterator it1 = first;
398  iterator it2 = pos;
399  for (; it1 != last; it1++, it2++)
400  {
401  it2 = m_Objects.insert(it2, *it1);
402  it2->SetDocument(document);
403  }
404 
405  SetDirty();
406 }
407 
408 template<typename TObject, typename TListIterator>
409 PdfArrayIndirectIterableBase<TObject, TListIterator>::PdfArrayIndirectIterableBase()
410  : m_arr(nullptr) { }
411 
412 template<typename TObject, typename TListIterator>
413 PdfArrayIndirectIterableBase<TObject, TListIterator>::PdfArrayIndirectIterableBase(PdfArray& arr)
414  : PdfIndirectIterableBase(arr), m_arr(&arr) { }
415 
416 template<typename TObject, typename TListIterator>
417 typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator PdfArrayIndirectIterableBase<TObject, TListIterator>::begin() const
418 {
419  if (m_arr == nullptr)
420  return Iterator();
421  else
422  return Iterator(m_arr->begin(), GetObjects());
423 }
424 
425 template<typename TObject, typename TListIterator>
426 typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator PdfArrayIndirectIterableBase<TObject, TListIterator>::end() const
427 {
428  if (m_arr == nullptr)
429  return Iterator();
430  else
431  return Iterator(m_arr->end(), GetObjects());
432 }
433 
434 template<typename TObject, typename TListIterator>
435 PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::Iterator() : m_objects(nullptr) { }
436 
437 template<typename TObject, typename TListIterator>
438 PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::Iterator(TListIterator&& iterator, PdfIndirectObjectList* objects)
439  : m_iterator(std::move(iterator)), m_objects(objects) { }
440 
441 template<typename TObject, typename TListIterator>
442 bool PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator==(const Iterator& rhs) const
443 {
444  return m_iterator == rhs.m_iterator;
445 }
446 
447 template<typename TObject, typename TListIterator>
448 bool PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator!=(const Iterator& rhs) const
449 {
450  return m_iterator != rhs.m_iterator;
451 }
452 
453 template<typename TObject, typename TListIterator>
454 typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator& PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator++()
455 {
456  m_iterator++;
457  return *this;
458 }
459 
460 template<typename TObject, typename TListIterator>
461 typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator++(int)
462 {
463  auto copy = *this;
464  m_iterator++;
465  return copy;
466 }
467 
468 template<typename TObject, typename TListIterator>
469 typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::value_type PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator*()
470 {
471  return resolve();
472 }
473 
474 template<typename TObject, typename TListIterator>
475 typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::value_type PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::operator->()
476 {
477  return resolve();
478 }
479 
480 template<typename TObject, typename TListIterator>
481 typename PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::value_type PdfArrayIndirectIterableBase<TObject, TListIterator>::Iterator::resolve()
482 {
483  TObject& robj = *m_iterator;
484  TObject* indirectobj;
485  PdfReference ref;
486  if (m_objects != nullptr
487  && robj.TryGetReference(ref)
488  && ref.IsIndirect()
489  && (indirectobj = GetObject(*m_objects, ref)) != nullptr)
490  {
491  return indirectobj;
492  }
493  else
494  {
495  return &robj;
496  }
497 }
498 
499 };
500 
501 #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
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:53
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:137
Templatized object type getter helper.
Definition: PdfObject.h:607