PoDoFo 1.0.0-dev
Loading...
Searching...
No Matches
PdfObject.h
1
7#ifndef PDF_OBJECT_H
8#define PDF_OBJECT_H
9
10#include "PdfVariant.h"
11#include "PdfObjectStream.h"
12
13namespace PoDoFo {
14
15class PdfEncrypt;
16class PdfIndirectObjectList;
17class PdfDictionary;
18class PdfArray;
19class PdfDocument;
20class PdfDataContainer;
21
34class PODOFO_API PdfObject
35{
36 friend class PdfIndirectObjectList;
37 friend class PdfArray;
38 friend class PdfDictionary;
39 friend class PdfDocument;
40 friend class PdfObjectStream;
41 friend class PdfObjectOutputStream;
42 friend class PdfDataContainer;
43 friend class PdfDictionaryElement;
44 friend class PdfArrayElement;
45 friend class PdfTokenizer;
46 PODOFO_PRIVATE_FRIEND(class PdfStreamedObjectStream);
47 PODOFO_PRIVATE_FRIEND(class PdfObjectStreamParser);
48 PODOFO_PRIVATE_FRIEND(class PdfParser);
49 PODOFO_PRIVATE_FRIEND(class PdfParserObject);
50 PODOFO_PRIVATE_FRIEND(class PdfWriter);
51 PODOFO_PRIVATE_FRIEND(class PdfImmediateWriter);
52 PODOFO_PRIVATE_FRIEND(class PdfXRef);
53 PODOFO_PRIVATE_FRIEND(class PdfXRefStream);
54
55public:
56 static const PdfObject Null;
57
58public:
59
62 PdfObject();
63
66 PdfObject(std::nullptr_t);
67
68 virtual ~PdfObject();
69
74 PdfObject(const PdfVariant& var);
75 PdfObject(PdfVariant&& var) noexcept;
76
81 PdfObject(bool b);
82
88
93 PdfObject(double d);
94
99 PdfObject(const PdfString& str);
100
105 PdfObject(const PdfName& name);
106
111 PdfObject(const PdfReference& ref);
112
117 PdfObject(const PdfArray& arr);
118 PdfObject(PdfArray&& arr) noexcept;
119
125 PdfObject(PdfDictionary&& dict) noexcept;
126
131 PdfObject(const PdfObject& rhs);
132 PdfObject(PdfObject&& rhs) noexcept;
133
134public:
138 PdfDataType GetDataType() const;
139
143 std::string_view GetDataTypeString() const;
144
147 bool IsBool() const;
148
151 bool IsNumber() const;
152
157 bool IsRealStrict() const;
158
161 bool IsNumberOrReal() const;
162
165 bool IsString() const;
166
169 bool IsName() const;
170
173 bool IsArray() const;
174
177 bool IsDictionary() const;
178
181 bool IsRawData() const;
182
185 bool IsNull() const;
186
189 bool IsReference() const;
190
195 std::string ToString(PdfWriteFlags writeFlags = PdfWriteFlags::None) const;
196 void ToString(std::string& str, PdfWriteFlags writeFlags = PdfWriteFlags::None) const;
197
201 bool GetBool() const;
202 bool TryGetBool(bool& value) const;
203
209 int64_t GetNumberLenient() const;
210 bool TryGetNumberLenient(int64_t& value) const;
211
217 int64_t GetNumber() const;
218 bool TryGetNumber(int64_t& value) const;
219
225 double GetReal() const;
226 bool TryGetReal(double& value) const;
227
233 double GetRealStrict() const;
234 bool TryGetRealStrict(double& value) const;
235
238 const PdfString& GetString() const;
239 bool TryGetString(PdfString& str) const;
240 bool TryGetString(const PdfString*& str) const;
241
244 const PdfName& GetName() const;
245 bool TryGetName(PdfName& name) const;
246 bool TryGetName(const PdfName*& name) const;
247
251 PdfReference GetReference() const;
252 bool TryGetReference(PdfReference& ref) const;
253
257 const PdfArray& GetArray() const;
258 PdfArray& GetArray();
259 bool TryGetArray(const PdfArray*& arr) const;
260 bool TryGetArray(PdfArray*& arr);
261 bool TryGetArray(PdfArray& arr) const;
262
266 const PdfDictionary& GetDictionary() const;
267 PdfDictionary& GetDictionary();
268 bool TryGetDictionary(const PdfDictionary*& dict) const;
269 bool TryGetDictionary(PdfDictionary*& dict);
270 bool TryGetDictionary(PdfDictionary& dict) const;
271
278 void SetBool(bool b);
279
286 void SetNumber(int64_t l);
287
294 void SetReal(double d);
295
302 void SetName(const PdfName& name);
303
310 void SetString(const PdfString& str);
311
312 void SetReference(const PdfReference& ref);
313
314 void ForceCreateStream();
315
325 const PdfStatefulEncrypt* encrypt, charbuff& buffer) const;
326
332 PdfObjectStream& GetOrCreateStream();
333
334 /* Remove the object stream, if it has one
335 */
336 void RemoveStream();
337
341 const PdfObjectStream& MustGetStream() const;
342
346 PdfObjectStream& MustGetStream();
347
355 virtual bool TryUnload();
356
362 bool HasStream() const;
363
364 bool IsIndirect() const;
365
366 const PdfVariant& GetVariant() const;
367
368public:
373 bool operator<(const PdfObject& rhs) const;
374
378 bool operator==(const PdfObject& rhs) const;
379
383 bool operator!=(const PdfObject& rhs) const;
384
387 bool operator==(const PdfVariant& rhs) const;
388
391 bool operator!=(const PdfVariant& rhs) const;
392
398 PdfObject& operator=(const PdfObject& rhs);
399 PdfObject& operator=(PdfObject&& rhs) noexcept;
400
401 operator const PdfVariant& () const;
402
403public:
416 inline bool IsDirty() const { return m_IsDirty; }
417
421 inline PdfDocument* GetDocument() const { return m_Document; }
422
426 PdfDocument& MustGetDocument() const;
427
431 inline const PdfReference& GetIndirectReference() const { return m_IndirectReference; }
432
433 inline const PdfDataContainer* GetParent() const { return m_Parent; }
434
440 inline bool IsDelayedLoadDone() const { return m_IsDelayedLoadDone; }
441
442 inline bool IsDelayedLoadStreamDone() const { return m_IsDelayedLoadStreamDone; }
443
444 const PdfObjectStream* GetStream() const;
445 PdfObjectStream* GetStream();
446
447private:
448 PdfObject(PdfVariant&& var, const PdfReference& indirectReference, bool isDirty);
449
450 PdfObject(PdfArray* arr);
451
452protected:
461 void DelayedLoad() const;
462
477 virtual void delayedLoad();
478
479 virtual void delayedLoadStream();
480
484 virtual bool removeStream();
485
486 virtual bool HasStreamToParse() const;
487
492 void SetDirty();
493
494 void resetDirty();
495
501 void SetDocument(PdfDocument* document);
502
503 void SetVariantOwner();
504
505 void FreeStream();
506
507 PdfObjectStream& getOrCreateStream();
508
509 void forceCreateStream();
510
511 PdfObjectStream* getStream();
512
513 void DelayedLoadStream() const;
514
515 void delayedLoadStream() const;
516
517 void EnableDelayedLoadingStream();
518
519 inline void SetIndirectReference(const PdfReference& reference) { m_IndirectReference = reference; }
520
529 void EnableDelayedLoading();
530
534 virtual void SetRevised();
535
536private:
537 // To be called privately by various classes
538 PdfVariant& GetVariantUnsafe() { return m_Variant; }
539 PdfReference GetReferenceUnsafe() const { return m_Variant.GetReferenceUnsafe(); }
540 const PdfDictionary& GetDictionaryUnsafe() const { return m_Variant.GetDictionaryUnsafe(); }
541 const PdfArray& GetArrayUnsafe() const { return m_Variant.GetArrayUnsafe(); }
542 PdfDictionary& GetDictionaryUnsafe() { return m_Variant.GetDictionaryUnsafe(); }
543 PdfArray& GetArrayUnsafe() { return m_Variant.GetArrayUnsafe(); }
544 void WriteFinal(OutputStream& stream, PdfWriteFlags writeMode,
545 const PdfStatefulEncrypt* encrypt, charbuff& buffer);
546
547 // To be called by PdfStreamedObjectStream
548 void SetNumberNoDirtySet(int64_t l);
549
550 // To be called by PdfImmediateWriter
551 void SetImmutable();
552 void WriteHeader(OutputStream& stream, PdfWriteFlags writeMode, charbuff& buffer) const;
553
554 // To be called by PdfDataContainer
555 bool IsImmutable() const { return m_IsImmutable; }
556
557 // NOTE: It also doesn't dirty set the moved "obj"
558 void AssignNoDirtySet(PdfObject&& rhs);
559 void AssignNoDirtySet(PdfVariant&& rhs);
560 void AssignNoDirtySet(const PdfObject& rhs);
561
562 void SetParent(PdfDataContainer& parent);
563
564private:
565 void write(OutputStream& stream, bool skipLengthFix,
566 PdfWriteFlags writeMode, const PdfStatefulEncrypt* encrypt, charbuff& buffer) const;
567
568 void assertMutable() const;
569
570 void assign(const PdfObject& rhs);
571
572 void moveFrom(PdfObject&& rhs);
573
574 void ResetDirty();
575
576 void setDirty();
577
578 // See PdfVariant.h for a detailed explanation of this member, which is
579 // here to prevent accidental construction of a PdfObject of integer type
580 // when passing a pointer. */
581 template<typename T>
582 PdfObject(T*) = delete;
583
584 void copyStreamFrom(const PdfObject& obj);
585
586 void moveStreamFrom(PdfObject& obj);
587
588 // Shared initialization between all the ctors
589 void initObject();
590
591protected:
592 PdfVariant m_Variant;
593
594private:
595 PdfReference m_IndirectReference;
596 PdfDocument* m_Document;
597 PdfDataContainer* m_Parent;
598 std::unique_ptr<PdfObjectStream> m_Stream;
599 bool m_IsDirty; // Indicates if this object was modified after construction
600 bool m_IsImmutable;
601 mutable bool m_IsDelayedLoadDone;
602 mutable bool m_IsDelayedLoadStreamDone;
603 // Tracks whether deferred loading is still pending (in which case it'll be
604 // false). If true, deferred loading is not required or has been completed.
605};
606
609 template <typename T>
611 {
612 using TRet = T;
613
614 static TRet Get(const PdfObject& obj)
615 {
616 (void)obj;
617 static_assert(always_false<T>, "Unsupported type");
618 return TRet{ };
619 }
620
621 static TRet Get(const PdfObject& obj, const T& defVal)
622 {
623 (void)obj;
624 (void)defVal;
625 static_assert(always_false<T>, "Unsupported type");
626 return TRet{ };
627 }
628
629 static bool TryGet(const PdfObject& obj, T& value)
630 {
631 (void)obj;
632 (void)value;
633 static_assert(always_false<T>, "Unsupported type");
634 return false;
635 }
636 };
637
638 template <>
639 struct ObjectAdapter<bool>
640 {
641 using TRet = bool;
642
643 static bool Get(const PdfObject& obj)
644 {
645 return obj.GetBool();
646 }
647
648 static bool Get(const PdfObject& obj, bool fallback)
649 {
650 bool ret;
651 if (obj.TryGetBool(ret))
652 return ret;
653 else
654 return fallback;
655 }
656
657 static bool TryGet(const PdfObject& obj, bool& value)
658 {
659 return obj.TryGetBool(value);
660 }
661 };
662
663 template <>
664 struct ObjectAdapter<int64_t>
665 {
666 using TRet = int64_t;
667
668 static int64_t Get(const PdfObject& obj)
669 {
670 return obj.GetNumber();
671 }
672
673 static int64_t Get(const PdfObject& obj, int64_t fallback)
674 {
675 int64_t ret;
676 if (obj.TryGetNumber(ret))
677 return ret;
678 else
679 return fallback;
680 }
681
682 static bool TryGet(const PdfObject& obj, int64_t& value)
683 {
684 return obj.TryGetNumber(value);
685 }
686 };
687
688 template <>
689 struct ObjectAdapter<double>
690 {
691 using TRet = double;
692
693 static double Get(const PdfObject& obj)
694 {
695 return obj.GetReal();
696 }
697
698 static double Get(const PdfObject& obj, double fallback)
699 {
700 double ret;
701 if (obj.TryGetReal(ret))
702 return ret;
703 else
704 return fallback;
705 }
706
707 static bool TryGet(const PdfObject& obj, double& value)
708 {
709 return obj.TryGetReal(value);
710 }
711 };
712
713 template <>
714 struct ObjectAdapter<PdfReference>
715 {
716 using TRet = PdfReference;
717
718 static PdfReference Get(const PdfObject& obj)
719 {
720 return obj.GetReference();
721 }
722
723 static PdfReference Get(const PdfObject& obj, const PdfReference& fallback)
724 {
725 PdfReference ret;
726 if (obj.TryGetReference(ret))
727 return ret;
728 else
729 return fallback;
730 }
731
732 static bool TryGet(const PdfObject& obj, PdfReference& value)
733 {
734 return obj.TryGetReference(value);
735 }
736 };
737
738 template <>
739 struct ObjectAdapter<PdfName>
740 {
741 using TRet = const PdfName&;
742
743 static const PdfName& Get(const PdfObject& obj)
744 {
745 return obj.GetName();
746 }
747
748 static const PdfName& Get(const PdfObject& obj, const PdfName& fallback)
749 {
750 const PdfName* ret;
751 if (obj.TryGetName(ret))
752 return *ret;
753 else
754 return fallback;
755 }
756
757 static bool TryGet(const PdfObject& obj, PdfName& value)
758 {
759 return obj.TryGetName(value);
760 }
761 };
762
763 template <>
764 struct ObjectAdapter<const PdfName*>
765 {
766 using TRet = const PdfName*;
767
768 static const PdfName* Get(const PdfObject& obj)
769 {
770 const PdfName* ret;
771 (void)obj.TryGetName(ret);
772 return ret;
773 }
774
775 static const PdfName* Get(const PdfObject& obj, const PdfName* fallback)
776 {
777 const PdfName* ret;
778 if (obj.TryGetName(ret))
779 return ret;
780 else
781 return fallback;
782 }
783
784 static bool TryGet(const PdfObject& obj, const PdfName*& value)
785 {
786 return obj.TryGetName(value);
787 }
788 };
789
790 template <>
791 struct ObjectAdapter<PdfString>
792 {
793 using TRet = const PdfString&;
794
795 static const PdfString& Get(const PdfObject& obj)
796 {
797 return obj.GetString();
798 }
799
800 static const PdfString& Get(const PdfObject& obj, const PdfString& fallback)
801 {
802 const PdfString* ret;
803 if (obj.TryGetString(ret))
804 return *ret;
805 else
806 return fallback;
807 }
808
809 static bool TryGet(const PdfObject& obj, PdfString& value)
810 {
811 return obj.TryGetString(value);
812 }
813 };
814
815 template <>
816 struct ObjectAdapter<const PdfString*>
817 {
818 using TRet = const PdfString*;
819
820 static const PdfString* Get(PdfObject& obj)
821 {
822 const PdfString* ret;
823 (void)obj.TryGetString(ret);
824 return ret;
825 }
826
827 static const PdfString* Get(const PdfObject& obj, const PdfString* fallback)
828 {
829 const PdfString* ret;
830 if (obj.TryGetString(ret))
831 return ret;
832 else
833 return fallback;
834 }
835
836 static bool TryGet(const PdfObject& obj, const PdfString*& value)
837 {
838 return obj.TryGetString(value);
839 }
840 };
841
842 template <>
843 struct ObjectAdapter<PdfDictionary*>
844 {
845 using TRet = PdfDictionary*;
846
847 static PdfDictionary* Get(PdfObject& obj)
848 {
849 PdfDictionary* ret;
850 (void)obj.TryGetDictionary(ret);
851 return ret;
852 }
853
854 static PdfDictionary* Get(PdfObject& obj, PdfDictionary* fallback)
855 {
856 PdfDictionary* ret;
857 if (obj.TryGetDictionary(ret))
858 return ret;
859 else
860 return fallback;
861 }
862
863 static bool TryGet(PdfObject& obj, PdfDictionary*& value)
864 {
865 return obj.TryGetDictionary(value);
866 }
867 };
868
869 template <>
870 struct ObjectAdapter<const PdfDictionary*>
871 {
872 using TRet = const PdfDictionary*;
873
874 static const PdfDictionary* Get(const PdfObject& obj)
875 {
876 const PdfDictionary* ret;
877 (void)obj.TryGetDictionary(ret);
878 return ret;
879 }
880
881 static const PdfDictionary* Get(const PdfObject& obj, const PdfDictionary* fallback)
882 {
883 const PdfDictionary* ret;
884 if (obj.TryGetDictionary(ret))
885 return ret;
886 else
887 return fallback;
888 }
889
890 static bool TryGet(const PdfObject& obj, const PdfDictionary*& value)
891 {
892 return obj.TryGetDictionary(value);
893 }
894 };
895
896 template <>
897 struct ObjectAdapter<PdfDictionary>
898 {
899 using TRet = PdfDictionary&;
900
901 static PdfDictionary& Get(PdfObject& obj)
902 {
903 return obj.GetDictionary();
904 }
905
906 static PdfDictionary& Get(PdfObject& obj, PdfDictionary& fallback)
907 {
908 PdfDictionary* ret;
909 if (obj.TryGetDictionary(ret))
910 return *ret;
911 else
912 return fallback;
913 }
914
915 static bool TryGet(const PdfObject& obj, PdfDictionary& value)
916 {
917 return obj.TryGetDictionary(value);
918 }
919 };
920
921 template <>
922 struct ObjectAdapter<PdfArray*>
923 {
924 using TRet = PdfArray*;
925
926 static PdfArray* Get(PdfObject& obj)
927 {
928 PdfArray* ret;
929 (void)obj.TryGetArray(ret);
930 return ret;
931 }
932
933 static PdfArray* Get(PdfObject& obj, PdfArray* fallback)
934 {
935 PdfArray* ret;
936 if (obj.TryGetArray(ret))
937 return ret;
938 else
939 return fallback;
940 }
941
942 static bool TryGet(PdfObject& obj, PdfArray*& value)
943 {
944 return obj.TryGetArray(value);
945 }
946 };
947
948 template <>
949 struct ObjectAdapter<const PdfArray*>
950 {
951 using TRet = const PdfArray*;
952
953 static const PdfArray* Get(const PdfObject& obj)
954 {
955 const PdfArray* ret;
956 (void)obj.TryGetArray(ret);
957 return ret;
958 }
959
960 static const PdfArray* Get(PdfObject& obj, const PdfArray* fallback)
961 {
962 const PdfArray* ret;
963 if (obj.TryGetArray(ret))
964 return ret;
965 else
966 return fallback;
967 }
968
969 static bool TryGet(const PdfObject& obj, const PdfArray*& value)
970 {
971 return obj.TryGetArray(value);
972 }
973 };
974
975 template <>
976 struct ObjectAdapter<PdfArray>
977 {
978 using TRet = PdfArray&;
979
980 static PdfArray& Get(PdfObject& obj)
981 {
982 return obj.GetArray();
983 }
984
985 static PdfArray& Get(PdfObject& obj, PdfArray& fallback)
986 {
987 PdfArray* ret;
988 if (obj.TryGetArray(ret))
989 return *ret;
990 else
991 return fallback;
992 }
993
994 static bool TryGet(const PdfObject& obj, PdfArray& value)
995 {
996 return obj.TryGetArray(value);
997 }
998 };
999
1000 // Comparator to enable heterogeneous lookup with
1001 // both objects and references
1002 // See https://stackoverflow.com/a/31924435/213871
1003 struct PODOFO_API PdfObjectInequality final
1004 {
1005 using is_transparent = std::true_type;
1006
1007 bool operator()(const PdfObject* lhs, const PdfObject* rhs) const
1008 {
1009 return lhs->GetIndirectReference() < rhs->GetIndirectReference();
1010 }
1011 bool operator()(const PdfObject* lhs, const PdfReference& rhs) const
1012 {
1013 return lhs->GetIndirectReference() < rhs;
1014 }
1015 bool operator()(const PdfReference& lhs, const PdfObject* rhs) const
1016 {
1017 return lhs < rhs->GetIndirectReference();
1018 }
1019 bool operator()(const PdfObject& lhs, const PdfObject& rhs) const
1020 {
1021 return lhs.GetIndirectReference() < rhs.GetIndirectReference();
1022 }
1023 bool operator()(const PdfObject& lhs, const PdfReference& rhs) const
1024 {
1025 return lhs.GetIndirectReference() < rhs;
1026 }
1027 bool operator()(const PdfReference& lhs, const PdfObject& rhs) const
1028 {
1029 return lhs < rhs.GetIndirectReference();
1030 }
1031 };
1032}
1033
1034#endif // PDF_OBJECT_H
An interface for writing blocks of data to a data source.
Definition OutputStream.h:18
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
The PDF dictionary data type of PoDoFo (inherits from PdfDataContainer, the base class for such repre...
Definition PdfDictionary.h:82
PdfDocument is the core interface for working with PDF documents.
Definition PdfDocument.h:111
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 PdfName.
Definition PdfName.h:24
A PDF stream can be appended to any PdfObject and can contain arbitrary data.
Definition PdfObjectStream.h:87
This class represents a PDF indirect Object in memory.
Definition PdfObject.h:35
bool IsDelayedLoadDone() const
Returns true if delayed loading is disabled, or if it is enabled and loading has completed.
Definition PdfObject.h:440
PdfDocument * GetDocument() const
Get the document of this object.
Definition PdfObject.h:421
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:416
const PdfReference & GetIndirectReference() const
Get an indirect reference to this object.
Definition PdfObject.h:431
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:24
A string that can be written to a PDF document.
Definition PdfString.h:24
A simple tokenizer for PDF files and PDF content streams.
Definition PdfTokenizer.h:36
A variant data type which supports all data types supported by the PDF standard.
Definition PdfVariant.h:33
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
PdfDataType
Every PDF datatype that can occur in a PDF file is referenced by an own enum (e.g.
Definition PdfDeclarations.h:167
@ Null
The null datatype is always null.
PdfWriteFlags
Specify additional options for writing the PDF.
Definition PdfDeclarations.h:149
Templatized object type getter helper.
Definition PdfObject.h:611