PoDoFo 1.2.0
Loading...
Searching...
No Matches
PdfDictionary.h
1// SPDX-FileCopyrightText: 2011 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_DICTIONARY_H
6#define PDF_DICTIONARY_H
7
8#include "PdfDeclarations.h"
9#include "PdfDataContainer.h"
10
11namespace PoDoFo {
12
13class PdfDictionary;
14
16template <typename TObject, typename TMapIterator>
17class PdfDictionaryIndirectIterableBase final : public PdfIndirectIterableBase
18{
19 friend class PdfDictionary;
20
21public:
23
24private:
26
27public:
28 class Iterator final
29 {
31 public:
32 using difference_type = void;
33 using value_type = std::pair<PdfName, TObject*>;
34 using pointer = const value_type*;
35 using reference = const value_type&;
36 using iterator_category = std::forward_iterator_tag;
37 public:
38 Iterator();
39 private:
40 Iterator(TMapIterator&& iterator, PdfIndirectObjectList* objects);
41 public:
42 Iterator(const Iterator&) = default;
43 Iterator& operator=(const Iterator&) = default;
44 bool operator==(const Iterator& rhs) const;
45 bool operator!=(const Iterator& rhs) const;
46 Iterator& operator++();
47 Iterator operator++(int);
48 reference operator*();
49 pointer operator->();
50 private:
51 void resolve();
52 private:
53 TMapIterator m_iterator;
54 PdfIndirectObjectList* m_objects;
55 value_type m_pair;
56 };
57
58public:
59 Iterator begin() const;
60 Iterator end() const;
61
62private:
63 PdfDictionary* m_dict;
64};
65
68
76class PODOFO_API PdfDictionary final : public PdfDataContainer
77{
78 friend class PdfObject;
79 friend class PdfTokenizer;
80 friend class PdfSignature;
81 friend class PdfObjectStream;
82 friend class PdfObjectOutputStream;
83
84public:
87
92
103 PdfDictionary& operator=(const PdfDictionary& rhs);
104 PdfDictionary& operator=(PdfDictionary&& rhs) noexcept;
105
109 bool operator==(const PdfDictionary& rhs) const;
110
112 bool operator!=(const PdfDictionary& rhs) const;
113
115 void Clear();
116
126 PdfObject& AddKey(const PdfName& key, const PdfObject& obj);
127 PdfObject& AddKey(const PdfName& key, PdfObject&& obj);
128
141 void AddKeyIndirect(const PdfName& key, const PdfObject& obj);
142
155 PdfObject& AddKeyIndirectSafe(const PdfName& key, const PdfObject& obj);
156
165 const PdfObject* GetKey(const std::string_view& key) const;
166
177 PdfObject* GetKey(const std::string_view& key);
178
187 const PdfObject* FindKey(const std::string_view& key) const;
188 PdfObject* FindKey(const std::string_view& key);
189 const PdfObject& MustFindKey(const std::string_view& key) const;
190 PdfObject& MustFindKey(const std::string_view& key);
191
201 const PdfObject* FindKeyParent(const std::string_view& key) const;
202 PdfObject* FindKeyParent(const std::string_view& key);
203 const PdfObject& MustFindKeyParent(const std::string_view& key) const;
204 PdfObject& MustFindKeyParent(const std::string_view& key);
205
218 const PdfObject& MustGetKey(const std::string_view& key) const;
219 PdfObject& MustGetKey(const std::string_view& key);
220
221 template <typename T>
222 const typename ObjectAdapter<T>::TRet GetKeyAs(const std::string_view& key) const;
223
224 template <typename T>
225 typename ObjectAdapter<T>::TRet GetKeyAs(const std::string_view& key);
226
227 template <typename T>
228 const typename ObjectAdapter<T>::TRet FindKeyAs(const std::string_view& key) const;
229
230 template <typename T>
231 typename ObjectAdapter<T>::TRet FindKeyAs(const std::string_view& key);
232
233 template <typename T>
234 const typename ObjectAdapter<T>::TRet FindKeyParentAs(const std::string_view& key) const;
235
236 template <typename T>
237 typename ObjectAdapter<T>::TRet FindKeyParentAs(const std::string_view& key);
238
239 template <typename T>
240 const typename ObjectAdapter<T>::TRet GetKeyAsSafe(const std::string_view& key, const std::common_type_t<T>& fallback = { }) const;
241
242 template <typename T>
243 typename ObjectAdapter<T>::TRet GetKeyAsSafe(const std::string_view& key, const std::common_type_t<T>& fallback = { });
244
245 template <typename T>
246 const typename ObjectAdapter<T>::TRet FindKeyAsSafe(const std::string_view& key, const std::common_type_t<T>& fallback = { }) const;
247
248 template <typename T>
249 typename ObjectAdapter<T>::TRet FindKeyAsSafe(const std::string_view& key, const std::common_type_t<T>& fallback = { });
250
251 template <typename T>
252 const typename ObjectAdapter<T>::TRet FindKeyParentAsSafe(const std::string_view& key, const std::common_type_t<T>& fallback = { }) const;
253
254 template <typename T>
255 typename ObjectAdapter<T>::TRet FindKeyParentAsSafe(const std::string_view& key, const std::common_type_t<T>& fallback = { });
256
257 template <typename T>
258 bool TryFindKeyAs(const std::string_view& key, T& value) const;
259
260 template <typename T>
261 bool TryFindKeyAs(const std::string_view& key, T& value);
262
263 template <typename T>
264 bool TryFindKeyParentAs(const std::string_view& key, T& value) const;
265
266 template <typename T>
267 bool TryFindKeyParentAs(const std::string_view& key, T& value);
268
273 bool HasKey(const std::string_view& key) const;
274
285 bool RemoveKey(const std::string_view& key);
286
287 void Write(OutputStream& stream, PdfWriteFlags writeMode,
288 const PdfStatefulEncrypt* encrypt, charbuff& buffer) const override;
289
291 unsigned GetSize() const;
292
293 PdfDictionaryIndirectIterable GetIndirectIterator();
294
295 PdfDictionaryConstIndirectIterable GetIndirectIterator() const;
296
297public:
298 using iterator = PdfNameMap<PdfObject>::iterator;
299 using const_iterator = PdfNameMap<PdfObject>::const_iterator;
300
301public:
302 iterator begin();
303 iterator end();
304 const_iterator begin() const;
305 const_iterator end() const;
306 size_t size() const;
307
308protected:
309 void resetDirty() override;
310 void setChildrenParent() override;
311
312private:
313 // NOTE: It also doesn't dirty set the moved "obj"
314 void AddKeyNoDirtySet(const PdfName& key, PdfObject&& obj);
315 void AddKeyNoDirtySet(const PdfName& key, PdfVariant&& var);
316 void RemoveKeyNoDirtySet(const std::string_view& key);
317 // Append a new "null" object with the given key
318 PdfObject& EmplaceNoDirtySet(const PdfName& key);
319
320private:
321 PdfObject& addKey(const PdfName& key, PdfObject&& obj);
322 PdfObject* getKey(const std::string_view& key) const;
323 PdfObject* findKey(const std::string_view& key) const;
324 PdfObject* findKeyParent(const std::string_view& key) const;
325 void write(OutputStream& stream, PdfWriteFlags writeMode, bool addDelimiters,
326 const PdfStatefulEncrypt* encrypt, charbuff& buffer) const;
327
328private:
329 PdfNameMap<PdfObject> m_Map;
330};
331
332template<typename T>
333const typename ObjectAdapter<T>::TRet PdfDictionary::GetKeyAs(const std::string_view& key) const
334{
335 return ObjectAdapter<T>::Get(MustGetKey(key));
336}
337
338template<typename T>
339typename ObjectAdapter<T>::TRet PdfDictionary::GetKeyAs(const std::string_view& key)
340{
341 return ObjectAdapter<T>::Get(MustGetKey(key));
342}
343
344template<typename T>
345const typename ObjectAdapter<T>::TRet PdfDictionary::FindKeyAs(const std::string_view& key) const
346{
347 return ObjectAdapter<T>::Get(MustFindKey(key));
348}
349
350template<typename T>
351typename ObjectAdapter<T>::TRet PdfDictionary::FindKeyAs(const std::string_view& key)
352{
353 return ObjectAdapter<T>::Get(MustFindKey(key));
354}
355
356template<typename T>
357const typename ObjectAdapter<T>::TRet PdfDictionary::FindKeyParentAs(const std::string_view& key) const
358{
359 return ObjectAdapter<T>::Get(MustFindKeyParent(key));
360}
361
362template<typename T>
363typename ObjectAdapter<T>::TRet PdfDictionary::FindKeyParentAs(const std::string_view& key)
364{
365 return ObjectAdapter<T>::Get(MustFindKeyParent(key));
366}
367
368template<typename T>
369const typename ObjectAdapter<T>::TRet PdfDictionary::GetKeyAsSafe(const std::string_view& key, const std::common_type_t<T>& fallback) const
370{
371 auto obj = getKey(key);
372 if (obj == nullptr)
373 return fallback;
374 else
375 return ObjectAdapter<T>::Get(const_cast<const PdfObject&>(*obj), fallback);
376}
377
378template<typename T>
379typename ObjectAdapter<T>::TRet PdfDictionary::GetKeyAsSafe(const std::string_view& key, const std::common_type_t<T>& fallback)
380{
381 auto obj = getKey(key);
382 if (obj == nullptr)
383 return fallback;
384 else
385 return ObjectAdapter<T>::Get(*obj, fallback);
386}
387
388template<typename T>
389const typename ObjectAdapter<T>::TRet PdfDictionary::FindKeyAsSafe(const std::string_view& key, const std::common_type_t<T>& fallback) const
390{
391 auto obj = findKey(key);
392 if (obj == nullptr)
393 return fallback;
394 else
395 return ObjectAdapter<T>::Get(const_cast<const PdfObject&>(*obj), fallback);
396}
397
398template<typename T>
399typename ObjectAdapter<T>::TRet PdfDictionary::FindKeyAsSafe(const std::string_view& key, const std::common_type_t<T>& fallback)
400{
401 auto obj = findKey(key);
402 if (obj == nullptr)
403 return fallback;
404 else
405 return ObjectAdapter<T>::Get(*obj, fallback);
406}
407
408template<typename T>
409const typename ObjectAdapter<T>::TRet PdfDictionary::FindKeyParentAsSafe(const std::string_view& key, const std::common_type_t<T>& fallback) const
410{
411 auto obj = findKeyParent(key);
412 if (obj == nullptr)
413 return fallback;
414 else
415 return ObjectAdapter<T>::Get(const_cast<const PdfObject&>(*obj), fallback);
416}
417
418template<typename T>
419typename ObjectAdapter<T>::TRet PdfDictionary::FindKeyParentAsSafe(const std::string_view& key, const std::common_type_t<T>& fallback)
420{
421 auto obj = findKeyParent(key);
422 if (obj == nullptr)
423 return fallback;
424 else
425 return ObjectAdapter<T>::Get(*obj, fallback);
426}
427
428template <typename T>
429bool PdfDictionary::TryFindKeyAs(const std::string_view& key, T& value) const
430{
431 auto obj = findKey(key);
432 if (obj != nullptr && ObjectAdapter<T>::TryGet(const_cast<const PdfObject&>(*obj), value))
433 {
434 return true;
435 }
436 else
437 {
438 value = { };
439 return false;
440 }
441}
442
443template<typename T>
444bool PdfDictionary::TryFindKeyAs(const std::string_view& key, T& value)
445{
446 auto obj = findKey(key);
447 if (obj != nullptr && ObjectAdapter<T>::TryGet(*obj, value))
448 {
449 return true;
450 }
451 else
452 {
453 value = { };
454 return false;
455 }
456}
457
458template <typename T>
459bool PdfDictionary::TryFindKeyParentAs(const std::string_view& key, T& value) const
460{
461 auto obj = findKeyParent(key);
462 if (obj != nullptr && ObjectAdapter<T>::TryGet(const_cast<const PdfObject&>(*obj), value))
463 {
464 return true;
465 }
466 else
467 {
468 value = { };
469 return false;
470 }
471}
472
473template<typename T>
474bool PdfDictionary::TryFindKeyParentAs(const std::string_view& key, T& value)
475{
476 auto obj = findKeyParent(key);
477 if (obj != nullptr && ObjectAdapter<T>::TryGet(*obj, value))
478 {
479 return true;
480 }
481 else
482 {
483 value = { };
484 return false;
485 }
486}
487
488template <typename TObject, typename TMapIterator>
489PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::PdfDictionaryIndirectIterableBase()
490 : m_dict(nullptr) { }
491
492template <typename TObject, typename TMapIterator>
493PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::PdfDictionaryIndirectIterableBase(PdfDictionary& dict)
494 : PdfIndirectIterableBase(dict), m_dict(&dict) { }
495
496template <typename TObject, typename TMapIterator>
497typename PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::begin() const
498{
499 if (m_dict == nullptr)
500 return Iterator();
501 else
502 return Iterator(m_dict->begin(), GetObjects());
503}
504
505template <typename TObject, typename TMapIterator>
506typename PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::end() const
507{
508 if (m_dict == nullptr)
509 return Iterator();
510 else
511 return Iterator(m_dict->end(), GetObjects());
512}
513
514template<typename TObject, typename TMapIterator>
515PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator::Iterator() : m_objects(nullptr) { }
516
517template<typename TObject, typename TMapIterator>
518PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator::Iterator(TMapIterator&& iterator, PdfIndirectObjectList* objects)
519 : m_iterator(std::move(iterator)), m_objects(objects) { }
520
521template<typename TObject, typename TMapIterator>
522bool PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator::operator==(const Iterator& rhs) const
523{
524 return m_iterator == rhs.m_iterator;
525}
526
527template<typename TObject, typename TMapIterator>
528bool PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator::operator!=(const Iterator& rhs) const
529{
530 return m_iterator != rhs.m_iterator;
531}
532
533template<typename TObject, typename TMapIterator>
534typename PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator& PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator::operator++()
535{
536 m_iterator++;
537 return *this;
538}
539
540template<typename TObject, typename TMapIterator>
541typename PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator::operator++(int)
542{
543 auto copy = *this;
544 m_iterator++;
545 return copy;
546}
547
548template<typename TObject, typename TMapIterator>
549typename PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator::reference PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator::operator*()
550{
551 resolve();
552 return m_pair;
553}
554
555template<typename TObject, typename TMapIterator>
556typename PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator::pointer PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator::operator->()
557{
558 resolve();
559 return &m_pair;
560}
561
562template<typename TObject, typename TMapIterator>
563void PdfDictionaryIndirectIterableBase<TObject, TMapIterator>::Iterator::resolve()
564{
565 TObject& robj = m_iterator->second;
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 m_pair = value_type(m_iterator->first, indirectobj);
574 }
575 else
576 {
577 m_pair = value_type(m_iterator->first, &robj);
578 }
579}
580
581}
582
583#endif // PDF_DICTIONARY_H
This file should be included as the FIRST file in every header of PoDoFo lib.
A PdfDataProvider object with a PdfObject owner, specialized in holding objects.
Definition PdfDataContainer.h:18
Helper class to iterate through indirect objects.
Definition PdfDictionary.h:18
The PDF dictionary data type of PoDoFo (inherits from PdfDataContainer, the base class for such repre...
Definition PdfDictionary.h:77
const PdfObject * FindKeyParent(const std::string_view &key) const
Get the keys value out of the dictionary.
const PdfObject * GetKey(const std::string_view &key) const
Get the key's value out of the dictionary.
const PdfObject * FindKey(const std::string_view &key) const
Get the keys value out of the dictionary.
PdfObject * GetKey(const std::string_view &key)
Get the key's value out of the dictionary.
const PdfObject & MustGetKey(const std::string_view &key) const
Get the key's value out of the dictionary.
A list of PdfObjects that constitutes the indirect object list of the document The PdfParser will rea...
Definition PdfIndirectObjectList.h:28
This class represents a PdfName.
Definition PdfName.h:21
A PDF stream can be appended to any PdfObject and can contain arbitrary data.
Definition PdfObjectStream.h:82
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:32
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