PoDoFo 1.2.0
Loading...
Searching...
No Matches
PdfObject.h
1// SPDX-FileCopyrightText: 2005 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_OBJECT_H
6#define PDF_OBJECT_H
7
8#include "PdfVariant.h"
9#include "PdfObjectStream.h"
10
11namespace PoDoFo {
12
13class PdfEncrypt;
14class PdfIndirectObjectList;
15class PdfDictionary;
16class PdfArray;
17class PdfDocument;
18class PdfDataContainer;
19
30class PODOFO_API PdfObject
31{
32 friend class PdfIndirectObjectList;
33 friend class PdfArray;
34 friend class PdfDictionary;
35 friend class PdfDocument;
36 friend class PdfObjectStream;
37 friend class PdfObjectOutputStream;
38 friend class PdfDataContainer;
39 friend class PdfDictionaryElement;
40 friend class PdfArrayElement;
41 friend class PdfTokenizer;
42 PODOFO_PRIVATE_FRIEND(class PdfStreamedObjectStream);
43 PODOFO_PRIVATE_FRIEND(class PdfObjectStreamParser);
44 PODOFO_PRIVATE_FRIEND(class PdfParser);
45 PODOFO_PRIVATE_FRIEND(class PdfParserObject);
46 PODOFO_PRIVATE_FRIEND(class PdfWriter);
47 PODOFO_PRIVATE_FRIEND(class PdfImmediateWriter);
48 PODOFO_PRIVATE_FRIEND(class PdfXRef);
49 PODOFO_PRIVATE_FRIEND(class PdfXRefStream);
50
51public:
52 static const PdfObject Null;
53
54public:
55
57 PdfObject();
58
60 PdfObject(std::nullptr_t);
61
62 virtual ~PdfObject();
63
67 PdfObject(const PdfVariant& var);
68 PdfObject(PdfVariant&& var) noexcept;
69
73 PdfObject(bool b);
74
79
83 PdfObject(double d);
84
88 PdfObject(const PdfString& str);
89
93 PdfObject(const PdfName& name);
94
99
103 PdfObject(const PdfArray& arr);
104 PdfObject(PdfArray&& arr) noexcept;
105
110 PdfObject(PdfDictionary&& dict) noexcept;
111
115 PdfObject(const PdfObject& rhs);
116 PdfObject(PdfObject&& rhs) noexcept;
117
118public:
121 PdfDataType GetDataType() const;
122
125 std::string_view GetDataTypeString() const;
126
128 bool IsBool() const;
129
131 bool IsNumber() const;
132
136 bool IsRealStrict() const;
137
139 bool IsNumberOrReal() const;
140
142 bool IsString() const;
143
145 bool IsName() const;
146
148 bool IsArray() const;
149
151 bool IsDictionary() const;
152
154 bool IsRawData() const;
155
157 bool IsNull() const;
158
160 bool IsReference() const;
161
165 std::string ToString(PdfWriteFlags writeFlags = PdfWriteFlags::None) const;
166 void ToString(std::string& str, PdfWriteFlags writeFlags = PdfWriteFlags::None) const;
167
170 bool GetBool() const;
171 bool TryGetBool(bool& value) const;
172
177 int64_t GetNumberLenient() const;
178 bool TryGetNumberLenient(int64_t& value) const;
179
184 int64_t GetNumber() const;
185 bool TryGetNumber(int64_t& value) const;
186
191 double GetReal() const;
192 bool TryGetReal(double& value) const;
193
198 double GetRealStrict() const;
199 bool TryGetRealStrict(double& value) const;
200
202 const PdfString& GetString() const;
203 bool TryGetString(PdfString& str) const;
204 bool TryGetString(const PdfString*& str) const;
205
207 const PdfName& GetName() const;
208 bool TryGetName(PdfName& name) const;
209 bool TryGetName(const PdfName*& name) const;
210
213 PdfReference GetReference() const;
214 bool TryGetReference(PdfReference& ref) const;
215
218 const PdfArray& GetArray() const;
219 PdfArray& GetArray();
220 bool TryGetArray(const PdfArray*& arr) const;
221 bool TryGetArray(PdfArray*& arr);
222 bool TryGetArray(PdfArray& arr) const;
223
226 const PdfDictionary& GetDictionary() const;
227 PdfDictionary& GetDictionary();
228 bool TryGetDictionary(const PdfDictionary*& dict) const;
229 bool TryGetDictionary(PdfDictionary*& dict);
230 bool TryGetDictionary(PdfDictionary& dict) const;
231
237 void SetBool(bool b);
238
244 void SetNumber(int64_t l);
245
251 void SetReal(double d);
252
258 void SetName(const PdfName& name);
259
265 void SetString(const PdfString& str);
266
267 void SetReference(const PdfReference& ref);
268
269 void ForceCreateStream();
270
278 const PdfStatefulEncrypt* encrypt, charbuff& buffer) const;
279
284 PdfObjectStream& GetOrCreateStream();
285
286 /* Remove the object stream, if it has one
287 */
288 void RemoveStream();
289
292 const PdfObjectStream& MustGetStream() const;
293
296 PdfObjectStream& MustGetStream();
297
304 virtual bool TryUnload();
305
310 bool HasStream() const;
311
312 bool IsIndirect() const;
313
314 const PdfVariant& GetVariant() const;
315
316public:
320 bool operator<(const PdfObject& rhs) const;
321
324 bool operator==(const PdfObject& rhs) const;
325
328 bool operator!=(const PdfObject& rhs) const;
329
331 bool operator==(const PdfVariant& rhs) const;
332
334 bool operator!=(const PdfVariant& rhs) const;
335
340 PdfObject& operator=(const PdfObject& rhs);
341 PdfObject& operator=(PdfObject&& rhs) noexcept;
342
343 operator const PdfVariant& () const;
344
345public:
357 inline bool IsDirty() const { return m_IsDirty; }
358
361 inline PdfDocument* GetDocument() const { return m_Document; }
362
365 PdfDocument& MustGetDocument() const;
366
369 inline const PdfReference& GetIndirectReference() const { return m_IndirectReference; }
370
371 inline const PdfDataContainer* GetParent() const { return m_Parent; }
372
376 inline bool IsDelayedLoadDone() const { return m_IsDelayedLoadDone; }
377
378 inline bool IsDelayedLoadStreamDone() const { return m_IsDelayedLoadStreamDone; }
379
380 const PdfObjectStream* GetStream() const;
381 PdfObjectStream* GetStream();
382
383private:
384 PdfObject(PdfVariant&& var, const PdfReference& indirectReference, bool isDirty);
385
386 PdfObject(PdfArray* arr);
387
388protected:
395 void DelayedLoad() const;
396
410 virtual void delayedLoad();
411
412 virtual void delayedLoadStream();
413
415 virtual bool removeStream();
416
417 virtual bool HasStreamToParse() const;
418
422 void SetDirty();
423
424 void resetDirty();
425
430 void SetDocument(PdfDocument* document);
431
432 void SetVariantOwner();
433
434 void FreeStream();
435
436 PdfObjectStream& getOrCreateStream();
437
438 void forceCreateStream();
439
440 PdfObjectStream* getStream();
441
442 void DelayedLoadStream() const;
443
444 void EnableDelayedLoadingStream();
445
446 void MakeDelayedLoadingStreamDone();
447
448 inline void SetIndirectReference(const PdfReference& reference) { m_IndirectReference = reference; }
449
457 void EnableDelayedLoading();
458
461 virtual void SetRevised();
462
463private:
464 // To be called privately by various classes
465 PdfVariant& GetVariantUnsafe() { return m_Variant; }
466 PdfReference GetReferenceUnsafe() const { return m_Variant.GetReferenceUnsafe(); }
467 const PdfDictionary& GetDictionaryUnsafe() const { return m_Variant.GetDictionaryUnsafe(); }
468 const PdfArray& GetArrayUnsafe() const { return m_Variant.GetArrayUnsafe(); }
469 PdfDictionary& GetDictionaryUnsafe() { return m_Variant.GetDictionaryUnsafe(); }
470 PdfArray& GetArrayUnsafe() { return m_Variant.GetArrayUnsafe(); }
471 void WriteFinal(OutputStream& stream, PdfWriteFlags writeMode,
472 const PdfStatefulEncrypt* encrypt, charbuff& buffer);
473
474 // To be called by PdfStreamedObjectStream
475 void SetNumberNoDirtySet(int64_t l);
476
477 // To be called by PdfImmediateWriter
478 void SetImmutable();
479 void WriteHeader(OutputStream& stream, PdfWriteFlags writeMode, charbuff& buffer) const;
480
481 // To be called by PdfDataContainer
482 bool IsImmutable() const { return m_IsImmutable; }
483
484 // NOTE: It also doesn't dirty set the moved "obj"
485 void AssignNoDirtySet(PdfObject&& rhs);
486 void AssignNoDirtySet(PdfVariant&& rhs);
487 void AssignNoDirtySet(const PdfObject& rhs);
488
489 void SetParent(PdfDataContainer& parent);
490
491private:
492 void write(OutputStream& stream, bool skipLengthFix,
493 PdfWriteFlags writeMode, const PdfStatefulEncrypt* encrypt, charbuff& buffer) const;
494
495 void assertMutable() const;
496
497 void assign(const PdfObject& rhs);
498
499 void moveFrom(PdfObject&& rhs) noexcept;
500
501 void ResetDirty();
502
503 void setDirty();
504
505 // See PdfVariant.h for a detailed explanation of this member, which is
506 // here to prevent accidental construction of a PdfObject of integer type
507 // when passing a pointer. */
508 template<typename T>
509 PdfObject(T*) = delete;
510
511 void copyStreamFrom(const PdfObject& obj);
512
513 // Shared initialization between all the ctors
514 void initObject();
515
516protected:
517 PdfVariant m_Variant;
518
519private:
520 PdfReference m_IndirectReference;
521 PdfDocument* m_Document;
522 PdfDataContainer* m_Parent;
523 std::unique_ptr<PdfObjectStream> m_Stream;
524 bool m_IsDirty; // Indicates if this object was modified after construction
525 bool m_IsImmutable;
526 mutable bool m_IsDelayedLoadDone;
527 mutable bool m_IsDelayedLoadStreamDone;
528 // Tracks whether deferred loading is still pending (in which case it'll be
529 // false). If true, deferred loading is not required or has been completed.
530};
531
533 template <typename T>
535 {
536 using TRet = T;
537
538 static TRet Get(const PdfObject& obj)
539 {
540 (void)obj;
541 static_assert(always_false<T>, "Unsupported type");
542 return TRet{ };
543 }
544
545 static TRet Get(const PdfObject& obj, const T& defVal)
546 {
547 (void)obj;
548 (void)defVal;
549 static_assert(always_false<T>, "Unsupported type");
550 return TRet{ };
551 }
552
553 static bool TryGet(const PdfObject& obj, T& value)
554 {
555 (void)obj;
556 (void)value;
557 static_assert(always_false<T>, "Unsupported type");
558 return false;
559 }
560 };
561
562 template <>
563 struct ObjectAdapter<bool>
564 {
565 using TRet = bool;
566
567 static bool Get(const PdfObject& obj)
568 {
569 return obj.GetBool();
570 }
571
572 static bool Get(const PdfObject& obj, bool fallback)
573 {
574 bool ret;
575 if (obj.TryGetBool(ret))
576 return ret;
577 else
578 return fallback;
579 }
580
581 static bool TryGet(const PdfObject& obj, bool& value)
582 {
583 return obj.TryGetBool(value);
584 }
585 };
586
587 template <>
588 struct ObjectAdapter<int64_t>
589 {
590 using TRet = int64_t;
591
592 static int64_t Get(const PdfObject& obj)
593 {
594 return obj.GetNumber();
595 }
596
597 static int64_t Get(const PdfObject& obj, int64_t fallback)
598 {
599 int64_t ret;
600 if (obj.TryGetNumber(ret))
601 return ret;
602 else
603 return fallback;
604 }
605
606 static bool TryGet(const PdfObject& obj, int64_t& value)
607 {
608 return obj.TryGetNumber(value);
609 }
610 };
611
612 template <>
613 struct ObjectAdapter<double>
614 {
615 using TRet = double;
616
617 static double Get(const PdfObject& obj)
618 {
619 return obj.GetReal();
620 }
621
622 static double Get(const PdfObject& obj, double fallback)
623 {
624 double ret;
625 if (obj.TryGetReal(ret))
626 return ret;
627 else
628 return fallback;
629 }
630
631 static bool TryGet(const PdfObject& obj, double& value)
632 {
633 return obj.TryGetReal(value);
634 }
635 };
636
637 template <>
638 struct ObjectAdapter<PdfReference>
639 {
640 using TRet = PdfReference;
641
642 static PdfReference Get(const PdfObject& obj)
643 {
644 return obj.GetReference();
645 }
646
647 static PdfReference Get(const PdfObject& obj, const PdfReference& fallback)
648 {
649 PdfReference ret;
650 if (obj.TryGetReference(ret))
651 return ret;
652 else
653 return fallback;
654 }
655
656 static bool TryGet(const PdfObject& obj, PdfReference& value)
657 {
658 return obj.TryGetReference(value);
659 }
660 };
661
662 template <>
663 struct ObjectAdapter<PdfName>
664 {
665 using TRet = const PdfName&;
666
667 static const PdfName& Get(const PdfObject& obj)
668 {
669 return obj.GetName();
670 }
671
672 static const PdfName& Get(const PdfObject& obj, const PdfName& fallback)
673 {
674 const PdfName* ret;
675 if (obj.TryGetName(ret))
676 return *ret;
677 else
678 return fallback;
679 }
680
681 static bool TryGet(const PdfObject& obj, PdfName& value)
682 {
683 return obj.TryGetName(value);
684 }
685 };
686
687 template <>
688 struct ObjectAdapter<const PdfName*>
689 {
690 using TRet = const PdfName*;
691
692 static const PdfName* Get(const PdfObject& obj)
693 {
694 const PdfName* ret;
695 (void)obj.TryGetName(ret);
696 return ret;
697 }
698
699 static const PdfName* Get(const PdfObject& obj, const PdfName* fallback)
700 {
701 const PdfName* ret;
702 if (obj.TryGetName(ret))
703 return ret;
704 else
705 return fallback;
706 }
707
708 static bool TryGet(const PdfObject& obj, const PdfName*& value)
709 {
710 return obj.TryGetName(value);
711 }
712 };
713
714 template <>
715 struct ObjectAdapter<PdfString>
716 {
717 using TRet = const PdfString&;
718
719 static const PdfString& Get(const PdfObject& obj)
720 {
721 return obj.GetString();
722 }
723
724 static const PdfString& Get(const PdfObject& obj, const PdfString& fallback)
725 {
726 const PdfString* ret;
727 if (obj.TryGetString(ret))
728 return *ret;
729 else
730 return fallback;
731 }
732
733 static bool TryGet(const PdfObject& obj, PdfString& value)
734 {
735 return obj.TryGetString(value);
736 }
737 };
738
739 template <>
740 struct ObjectAdapter<const PdfString*>
741 {
742 using TRet = const PdfString*;
743
744 static const PdfString* Get(PdfObject& obj)
745 {
746 const PdfString* ret;
747 (void)obj.TryGetString(ret);
748 return ret;
749 }
750
751 static const PdfString* Get(const PdfObject& obj, const PdfString* fallback)
752 {
753 const PdfString* ret;
754 if (obj.TryGetString(ret))
755 return ret;
756 else
757 return fallback;
758 }
759
760 static bool TryGet(const PdfObject& obj, const PdfString*& value)
761 {
762 return obj.TryGetString(value);
763 }
764 };
765
766 template <>
767 struct ObjectAdapter<PdfDictionary*>
768 {
769 using TRet = PdfDictionary*;
770
771 static PdfDictionary* Get(PdfObject& obj)
772 {
773 PdfDictionary* ret;
774 (void)obj.TryGetDictionary(ret);
775 return ret;
776 }
777
778 static PdfDictionary* Get(PdfObject& obj, PdfDictionary* fallback)
779 {
780 PdfDictionary* ret;
781 if (obj.TryGetDictionary(ret))
782 return ret;
783 else
784 return fallback;
785 }
786
787 static bool TryGet(PdfObject& obj, PdfDictionary*& value)
788 {
789 return obj.TryGetDictionary(value);
790 }
791 };
792
793 template <>
794 struct ObjectAdapter<const PdfDictionary*>
795 {
796 using TRet = const PdfDictionary*;
797
798 static const PdfDictionary* Get(const PdfObject& obj)
799 {
800 const PdfDictionary* ret;
801 (void)obj.TryGetDictionary(ret);
802 return ret;
803 }
804
805 static const PdfDictionary* Get(const PdfObject& obj, const PdfDictionary* fallback)
806 {
807 const PdfDictionary* ret;
808 if (obj.TryGetDictionary(ret))
809 return ret;
810 else
811 return fallback;
812 }
813
814 static bool TryGet(const PdfObject& obj, const PdfDictionary*& value)
815 {
816 return obj.TryGetDictionary(value);
817 }
818 };
819
820 template <>
821 struct ObjectAdapter<PdfDictionary>
822 {
823 using TRet = PdfDictionary&;
824
825 static PdfDictionary& Get(PdfObject& obj)
826 {
827 return obj.GetDictionary();
828 }
829
830 static PdfDictionary& Get(PdfObject& obj, PdfDictionary& fallback)
831 {
832 PdfDictionary* ret;
833 if (obj.TryGetDictionary(ret))
834 return *ret;
835 else
836 return fallback;
837 }
838
839 static bool TryGet(const PdfObject& obj, PdfDictionary& value)
840 {
841 return obj.TryGetDictionary(value);
842 }
843 };
844
845 template <>
846 struct ObjectAdapter<PdfArray*>
847 {
848 using TRet = PdfArray*;
849
850 static PdfArray* Get(PdfObject& obj)
851 {
852 PdfArray* ret;
853 (void)obj.TryGetArray(ret);
854 return ret;
855 }
856
857 static PdfArray* Get(PdfObject& obj, PdfArray* fallback)
858 {
859 PdfArray* ret;
860 if (obj.TryGetArray(ret))
861 return ret;
862 else
863 return fallback;
864 }
865
866 static bool TryGet(PdfObject& obj, PdfArray*& value)
867 {
868 return obj.TryGetArray(value);
869 }
870 };
871
872 template <>
873 struct ObjectAdapter<const PdfArray*>
874 {
875 using TRet = const PdfArray*;
876
877 static const PdfArray* Get(const PdfObject& obj)
878 {
879 const PdfArray* ret;
880 (void)obj.TryGetArray(ret);
881 return ret;
882 }
883
884 static const PdfArray* Get(PdfObject& obj, const PdfArray* fallback)
885 {
886 const PdfArray* ret;
887 if (obj.TryGetArray(ret))
888 return ret;
889 else
890 return fallback;
891 }
892
893 static bool TryGet(const PdfObject& obj, const PdfArray*& value)
894 {
895 return obj.TryGetArray(value);
896 }
897 };
898
899 template <>
900 struct ObjectAdapter<PdfArray>
901 {
902 using TRet = PdfArray&;
903
904 static PdfArray& Get(PdfObject& obj)
905 {
906 return obj.GetArray();
907 }
908
909 static PdfArray& Get(PdfObject& obj, PdfArray& fallback)
910 {
911 PdfArray* ret;
912 if (obj.TryGetArray(ret))
913 return *ret;
914 else
915 return fallback;
916 }
917
918 static bool TryGet(const PdfObject& obj, PdfArray& value)
919 {
920 return obj.TryGetArray(value);
921 }
922 };
923
924 // Comparator to enable heterogeneous lookup with
925 // both objects and references
926 // See https://stackoverflow.com/a/31924435/213871
927 struct PODOFO_API PdfObjectInequality final
928 {
929 using is_transparent = std::true_type;
930
931 bool operator()(const PdfObject* lhs, const PdfObject* rhs) const
932 {
933 return lhs->GetIndirectReference() < rhs->GetIndirectReference();
934 }
935 bool operator()(const PdfObject* lhs, const PdfReference& rhs) const
936 {
937 return lhs->GetIndirectReference() < rhs;
938 }
939 bool operator()(const PdfReference& lhs, const PdfObject* rhs) const
940 {
941 return lhs < rhs->GetIndirectReference();
942 }
943 bool operator()(const PdfObject& lhs, const PdfObject& rhs) const
944 {
945 return lhs.GetIndirectReference() < rhs.GetIndirectReference();
946 }
947 bool operator()(const PdfObject& lhs, const PdfReference& rhs) const
948 {
949 return lhs.GetIndirectReference() < rhs;
950 }
951 bool operator()(const PdfReference& lhs, const PdfObject& rhs) const
952 {
953 return lhs < rhs.GetIndirectReference();
954 }
955 };
956}
957
958#endif // PDF_OBJECT_H
An interface for writing blocks of data to a data source.
Definition OutputStream.h:15
This class represents a PdfArray Use it for all arrays that are written to a PDF file.
Definition PdfArray.h:76
A PdfDataProvider object with a PdfObject owner, specialized in holding objects.
Definition PdfDataContainer.h:18
The PDF dictionary data type of PoDoFo (inherits from PdfDataContainer, the base class for such repre...
Definition PdfDictionary.h:77
PdfDocument is the core interface for working with PDF documents.
Definition PdfDocument.h:108
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
bool IsDelayedLoadDone() const
Returns true if delayed loading is disabled, or if it is enabled and loading has completed.
Definition PdfObject.h:376
PdfDocument * GetDocument() const
Get the document of this object.
Definition PdfObject.h:361
PdfObject(std::nullptr_t)
Create a "null" PDF object.
bool IsDirty() const
The dirty flag is set if this variant has been modified after construction.
Definition PdfObject.h:357
const PdfReference & GetIndirectReference() const
Get an indirect reference to this object.
Definition PdfObject.h:369
A reference is a pointer to a object in the PDF file of the form "4 0 R", where 4 is the object numbe...
Definition PdfReference.h:20
A string that can be written to a PDF document.
Definition PdfString.h:21
A simple tokenizer for PDF files and PDF content streams.
Definition PdfTokenizer.h:32
A variant data type which supports all data types supported by the PDF standard.
Definition PdfVariant.h:29
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
PdfDataType
Every PDF datatype that can occur in a PDF file is referenced by an own enum (e.g.
Definition PdfDeclarations.h:152
@ Null
The null datatype is always null.
PdfWriteFlags
Specify additional options for writing the PDF.
Definition PdfDeclarations.h:136
Templatized object type getter helper.
Definition PdfObject.h:535