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 void DelayedLoadStream() const;
413
414 virtual void delayedLoadStream();
415
417 virtual bool removeStream();
418
419 virtual bool HasStreamToParse() const;
420
424 void SetDirty();
425
426 void resetDirty();
427
432 void SetDocument(PdfDocument* document);
433
434 void SetVariantOwner();
435
436 void FreeStream();
437
438 PdfObjectStream& getOrCreateStream();
439
440 void forceCreateStream();
441
442 PdfObjectStream* getStream();
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 void DelayedLoad(bool throwOnError) const;
465 void DelayedLoadStream(bool throwOnError) const;
466
467 // To be called privately by various classes
468 PdfVariant& GetVariantUnsafe() { return m_Variant; }
469 const PdfReference& GetReferenceUnsafe() const { return m_Variant.GetReferenceUnsafe(); }
470 const PdfDictionary& GetDictionaryUnsafe() const { return m_Variant.GetDictionaryUnsafe(); }
471 const PdfArray& GetArrayUnsafe() const { return m_Variant.GetArrayUnsafe(); }
472 PdfDictionary& GetDictionaryUnsafe() { return m_Variant.GetDictionaryUnsafe(); }
473 PdfArray& GetArrayUnsafe() { return m_Variant.GetArrayUnsafe(); }
474 void WriteFinal(OutputStream& stream, PdfWriteFlags writeMode,
475 const PdfStatefulEncrypt* encrypt, charbuff& buffer);
476
477 // To be called by PdfStreamedObjectStream
478 void SetNumberNoDirtySet(int64_t l);
479
480 // To be called by PdfImmediateWriter
481 void SetImmutable();
482 void WriteHeader(OutputStream& stream, PdfWriteFlags writeMode, charbuff& buffer) const;
483
484 // To be called by PdfDataContainer
485 bool IsImmutable() const { return m_IsImmutable; }
486
487 // NOTE: It also doesn't dirty set the moved "obj"
488 void AssignNoDirtySet(PdfObject&& rhs);
489 void AssignNoDirtySet(PdfVariant&& rhs);
490 void AssignNoDirtySet(const PdfObject& rhs);
491
492 void SetParent(PdfDataContainer& parent);
493
494private:
495 void write(OutputStream& stream, bool skipLengthFix,
496 PdfWriteFlags writeMode, const PdfStatefulEncrypt* encrypt, charbuff& buffer) const;
497
498 void assertMutable() const;
499
500 void assign(const PdfObject& rhs);
501
502 void moveFrom(PdfObject&& rhs) noexcept;
503
504 void ResetDirty();
505
506 void setDirty();
507
508 // See PdfVariant.h for a detailed explanation of this member, which is
509 // here to prevent accidental construction of a PdfObject of integer type
510 // when passing a pointer. */
511 template<typename T>
512 PdfObject(T*) = delete;
513
514 void copyStreamFrom(const PdfObject& obj);
515
516 // Shared initialization between all the ctors
517 void initObject();
518
519protected:
520 PdfVariant m_Variant;
521
522private:
523 PdfReference m_IndirectReference;
524 PdfDocument* m_Document;
525 PdfDataContainer* m_Parent;
526 std::unique_ptr<PdfObjectStream> m_Stream;
527 bool m_IsDirty; // Indicates if this object was modified after construction
528 bool m_IsImmutable;
529 mutable bool m_IsDelayedLoadDone;
530 mutable bool m_IsDelayedLoadStreamDone;
531 // Tracks whether deferred loading is still pending (in which case it'll be
532 // false). If true, deferred loading is not required or has been completed.
533};
534
536 template <typename T>
538 {
539 using TRet = T;
540
541 static TRet Get(const PdfObject& obj)
542 {
543 (void)obj;
544 static_assert(always_false<T>, "Unsupported type");
545 return TRet{ };
546 }
547
548 static TRet Get(const PdfObject& obj, const T& defVal)
549 {
550 (void)obj;
551 (void)defVal;
552 static_assert(always_false<T>, "Unsupported type");
553 return TRet{ };
554 }
555
556 static bool TryGet(const PdfObject& obj, T& value)
557 {
558 (void)obj;
559 (void)value;
560 static_assert(always_false<T>, "Unsupported type");
561 return false;
562 }
563 };
564
565 template <>
566 struct ObjectAdapter<bool>
567 {
568 using TRet = bool;
569
570 static bool Get(const PdfObject& obj)
571 {
572 return obj.GetBool();
573 }
574
575 static bool Get(const PdfObject& obj, bool fallback)
576 {
577 bool ret;
578 if (obj.TryGetBool(ret))
579 return ret;
580 else
581 return fallback;
582 }
583
584 static bool TryGet(const PdfObject& obj, bool& value)
585 {
586 return obj.TryGetBool(value);
587 }
588 };
589
590 template <>
591 struct ObjectAdapter<int64_t>
592 {
593 using TRet = int64_t;
594
595 static int64_t Get(const PdfObject& obj)
596 {
597 return obj.GetNumber();
598 }
599
600 static int64_t Get(const PdfObject& obj, int64_t fallback)
601 {
602 int64_t ret;
603 if (obj.TryGetNumber(ret))
604 return ret;
605 else
606 return fallback;
607 }
608
609 static bool TryGet(const PdfObject& obj, int64_t& value)
610 {
611 return obj.TryGetNumber(value);
612 }
613 };
614
615 template <>
616 struct ObjectAdapter<double>
617 {
618 using TRet = double;
619
620 static double Get(const PdfObject& obj)
621 {
622 return obj.GetReal();
623 }
624
625 static double Get(const PdfObject& obj, double fallback)
626 {
627 double ret;
628 if (obj.TryGetReal(ret))
629 return ret;
630 else
631 return fallback;
632 }
633
634 static bool TryGet(const PdfObject& obj, double& value)
635 {
636 return obj.TryGetReal(value);
637 }
638 };
639
640 template <>
641 struct ObjectAdapter<PdfReference>
642 {
643 using TRet = PdfReference;
644
645 static PdfReference Get(const PdfObject& obj)
646 {
647 return obj.GetReference();
648 }
649
650 static PdfReference Get(const PdfObject& obj, const PdfReference& fallback)
651 {
652 PdfReference ret;
653 if (obj.TryGetReference(ret))
654 return ret;
655 else
656 return fallback;
657 }
658
659 static bool TryGet(const PdfObject& obj, PdfReference& value)
660 {
661 return obj.TryGetReference(value);
662 }
663 };
664
665 template <>
666 struct ObjectAdapter<PdfName>
667 {
668 using TRet = const PdfName&;
669
670 static const PdfName& Get(const PdfObject& obj)
671 {
672 return obj.GetName();
673 }
674
675 static const PdfName& Get(const PdfObject& obj, const PdfName& fallback)
676 {
677 const PdfName* ret;
678 if (obj.TryGetName(ret))
679 return *ret;
680 else
681 return fallback;
682 }
683
684 static bool TryGet(const PdfObject& obj, PdfName& value)
685 {
686 return obj.TryGetName(value);
687 }
688 };
689
690 template <>
691 struct ObjectAdapter<const PdfName*>
692 {
693 using TRet = const PdfName*;
694
695 static const PdfName* Get(const PdfObject& obj)
696 {
697 const PdfName* ret;
698 (void)obj.TryGetName(ret);
699 return ret;
700 }
701
702 static const PdfName* Get(const PdfObject& obj, const PdfName* fallback)
703 {
704 const PdfName* ret;
705 if (obj.TryGetName(ret))
706 return ret;
707 else
708 return fallback;
709 }
710
711 static bool TryGet(const PdfObject& obj, const PdfName*& value)
712 {
713 return obj.TryGetName(value);
714 }
715 };
716
717 template <>
718 struct ObjectAdapter<PdfString>
719 {
720 using TRet = const PdfString&;
721
722 static const PdfString& Get(const PdfObject& obj)
723 {
724 return obj.GetString();
725 }
726
727 static const PdfString& Get(const PdfObject& obj, const PdfString& fallback)
728 {
729 const PdfString* ret;
730 if (obj.TryGetString(ret))
731 return *ret;
732 else
733 return fallback;
734 }
735
736 static bool TryGet(const PdfObject& obj, PdfString& value)
737 {
738 return obj.TryGetString(value);
739 }
740 };
741
742 template <>
743 struct ObjectAdapter<const PdfString*>
744 {
745 using TRet = const PdfString*;
746
747 static const PdfString* Get(PdfObject& obj)
748 {
749 const PdfString* ret;
750 (void)obj.TryGetString(ret);
751 return ret;
752 }
753
754 static const PdfString* Get(const PdfObject& obj, const PdfString* fallback)
755 {
756 const PdfString* ret;
757 if (obj.TryGetString(ret))
758 return ret;
759 else
760 return fallback;
761 }
762
763 static bool TryGet(const PdfObject& obj, const PdfString*& value)
764 {
765 return obj.TryGetString(value);
766 }
767 };
768
769 template <>
770 struct ObjectAdapter<PdfDictionary*>
771 {
772 using TRet = PdfDictionary*;
773
774 static PdfDictionary* Get(PdfObject& obj)
775 {
776 PdfDictionary* ret;
777 (void)obj.TryGetDictionary(ret);
778 return ret;
779 }
780
781 static PdfDictionary* Get(PdfObject& obj, PdfDictionary* fallback)
782 {
783 PdfDictionary* ret;
784 if (obj.TryGetDictionary(ret))
785 return ret;
786 else
787 return fallback;
788 }
789
790 static bool TryGet(PdfObject& obj, PdfDictionary*& value)
791 {
792 return obj.TryGetDictionary(value);
793 }
794 };
795
796 template <>
797 struct ObjectAdapter<const PdfDictionary*>
798 {
799 using TRet = const PdfDictionary*;
800
801 static const PdfDictionary* Get(const PdfObject& obj)
802 {
803 const PdfDictionary* ret;
804 (void)obj.TryGetDictionary(ret);
805 return ret;
806 }
807
808 static const PdfDictionary* Get(const PdfObject& obj, const PdfDictionary* fallback)
809 {
810 const PdfDictionary* ret;
811 if (obj.TryGetDictionary(ret))
812 return ret;
813 else
814 return fallback;
815 }
816
817 static bool TryGet(const PdfObject& obj, const PdfDictionary*& value)
818 {
819 return obj.TryGetDictionary(value);
820 }
821 };
822
823 template <>
824 struct ObjectAdapter<PdfDictionary>
825 {
826 using TRet = PdfDictionary&;
827
828 static PdfDictionary& Get(PdfObject& obj)
829 {
830 return obj.GetDictionary();
831 }
832
833 static PdfDictionary& Get(PdfObject& obj, PdfDictionary& fallback)
834 {
835 PdfDictionary* ret;
836 if (obj.TryGetDictionary(ret))
837 return *ret;
838 else
839 return fallback;
840 }
841
842 static bool TryGet(const PdfObject& obj, PdfDictionary& value)
843 {
844 return obj.TryGetDictionary(value);
845 }
846 };
847
848 template <>
849 struct ObjectAdapter<PdfArray*>
850 {
851 using TRet = PdfArray*;
852
853 static PdfArray* Get(PdfObject& obj)
854 {
855 PdfArray* ret;
856 (void)obj.TryGetArray(ret);
857 return ret;
858 }
859
860 static PdfArray* Get(PdfObject& obj, PdfArray* fallback)
861 {
862 PdfArray* ret;
863 if (obj.TryGetArray(ret))
864 return ret;
865 else
866 return fallback;
867 }
868
869 static bool TryGet(PdfObject& obj, PdfArray*& value)
870 {
871 return obj.TryGetArray(value);
872 }
873 };
874
875 template <>
876 struct ObjectAdapter<const PdfArray*>
877 {
878 using TRet = const PdfArray*;
879
880 static const PdfArray* Get(const PdfObject& obj)
881 {
882 const PdfArray* ret;
883 (void)obj.TryGetArray(ret);
884 return ret;
885 }
886
887 static const PdfArray* Get(PdfObject& obj, const PdfArray* fallback)
888 {
889 const PdfArray* ret;
890 if (obj.TryGetArray(ret))
891 return ret;
892 else
893 return fallback;
894 }
895
896 static bool TryGet(const PdfObject& obj, const PdfArray*& value)
897 {
898 return obj.TryGetArray(value);
899 }
900 };
901
902 template <>
903 struct ObjectAdapter<PdfArray>
904 {
905 using TRet = PdfArray&;
906
907 static PdfArray& Get(PdfObject& obj)
908 {
909 return obj.GetArray();
910 }
911
912 static PdfArray& Get(PdfObject& obj, PdfArray& fallback)
913 {
914 PdfArray* ret;
915 if (obj.TryGetArray(ret))
916 return *ret;
917 else
918 return fallback;
919 }
920
921 static bool TryGet(const PdfObject& obj, PdfArray& value)
922 {
923 return obj.TryGetArray(value);
924 }
925 };
926
927 // Comparator to enable heterogeneous lookup with
928 // both objects and references
929 // See https://stackoverflow.com/a/31924435/213871
930 struct PODOFO_API PdfObjectInequality final
931 {
932 using is_transparent = std::true_type;
933
934 bool operator()(const PdfObject* lhs, const PdfObject* rhs) const
935 {
936 return lhs->GetIndirectReference() < rhs->GetIndirectReference();
937 }
938 bool operator()(const PdfObject* lhs, const PdfReference& rhs) const
939 {
940 return lhs->GetIndirectReference() < rhs;
941 }
942 bool operator()(const PdfReference& lhs, const PdfObject* rhs) const
943 {
944 return lhs < rhs->GetIndirectReference();
945 }
946 bool operator()(const PdfObject& lhs, const PdfObject& rhs) const
947 {
948 return lhs.GetIndirectReference() < rhs.GetIndirectReference();
949 }
950 bool operator()(const PdfObject& lhs, const PdfReference& rhs) const
951 {
952 return lhs.GetIndirectReference() < rhs;
953 }
954 bool operator()(const PdfReference& lhs, const PdfObject& rhs) const
955 {
956 return lhs < rhs.GetIndirectReference();
957 }
958 };
959}
960
961#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:34
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:47
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:538