PoDoFo  1.0.0-dev
PdfObject.h
1 
7 #ifndef PDF_OBJECT_H
8 #define PDF_OBJECT_H
9 
10 #include "PdfVariant.h"
11 #include "PdfObjectStream.h"
12 
13 namespace PoDoFo {
14 
15 class PdfEncrypt;
16 class PdfIndirectObjectList;
17 class PdfDictionary;
18 class PdfArray;
19 class PdfDocument;
20 class PdfDataContainer;
21 
34 class 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 
55 public:
56  static const PdfObject Null;
57 
58 public:
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 
87  PdfObject(int64_t l);
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 
124  PdfObject(const PdfDictionary& dict);
125  PdfObject(PdfDictionary&& dict) noexcept;
126 
131  PdfObject(const PdfObject& rhs);
132  PdfObject(PdfObject&& rhs) noexcept;
133 
134 public:
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 
265  const PdfDictionary& GetDictionary() const;
266  PdfDictionary& GetDictionary();
267  bool TryGetDictionary(const PdfDictionary*& dict) const;
268  bool TryGetDictionary(PdfDictionary*& dict);
269 
276  void SetBool(bool b);
277 
284  void SetNumber(int64_t l);
285 
292  void SetReal(double d);
293 
300  void SetName(const PdfName& name);
301 
308  void SetString(const PdfString& str);
309 
310  void SetReference(const PdfReference& ref);
311 
312  void ForceCreateStream();
313 
322  void Write(OutputStream& stream, PdfWriteFlags writeMode,
323  const PdfStatefulEncrypt* encrypt, charbuff& buffer) const;
324 
330  PdfObjectStream& GetOrCreateStream();
331 
332  /* Remove the object stream, if it has one
333  */
334  void RemoveStream();
335 
339  const PdfObjectStream& MustGetStream() const;
340 
344  PdfObjectStream& MustGetStream();
345 
353  virtual bool TryUnload();
354 
360  bool HasStream() const;
361 
362  bool IsIndirect() const;
363 
364  const PdfVariant& GetVariant() const;
365 
366 public:
371  bool operator<(const PdfObject& rhs) const;
372 
376  bool operator==(const PdfObject& rhs) const;
377 
381  bool operator!=(const PdfObject& rhs) const;
382 
385  bool operator==(const PdfVariant& rhs) const;
386 
389  bool operator!=(const PdfVariant& rhs) const;
390 
396  PdfObject& operator=(const PdfObject& rhs);
397  PdfObject& operator=(PdfObject&& rhs) noexcept;
398 
399  operator const PdfVariant& () const;
400 
401 public:
414  inline bool IsDirty() const { return m_IsDirty; }
415 
419  inline PdfDocument* GetDocument() const { return m_Document; }
420 
424  PdfDocument& MustGetDocument() const;
425 
429  inline const PdfReference& GetIndirectReference() const { return m_IndirectReference; }
430 
431  inline const PdfDataContainer* GetParent() const { return m_Parent; }
432 
438  inline bool IsDelayedLoadDone() const { return m_IsDelayedLoadDone; }
439 
440  inline bool IsDelayedLoadStreamDone() const { return m_IsDelayedLoadStreamDone; }
441 
442  const PdfObjectStream* GetStream() const;
443  PdfObjectStream* GetStream();
444 
445 private:
446  PdfObject(PdfVariant&& var, const PdfReference& indirectReference, bool isDirty);
447 
448 protected:
457  void DelayedLoad() const;
458 
473  virtual void delayedLoad();
474 
475  virtual void delayedLoadStream();
476 
480  virtual bool removeStream();
481 
482  virtual bool HasStreamToParse() const;
483 
488  void SetDirty();
489 
490  void resetDirty();
491 
497  void SetDocument(PdfDocument* document);
498 
499  void SetVariantOwner();
500 
501  void FreeStream();
502 
503  PdfObjectStream& getOrCreateStream();
504 
505  void forceCreateStream();
506 
507  PdfObjectStream* getStream();
508 
509  void DelayedLoadStream() const;
510 
511  void delayedLoadStream() const;
512 
513  void EnableDelayedLoadingStream();
514 
515  inline void SetIndirectReference(const PdfReference& reference) { m_IndirectReference = reference; }
516 
525  void EnableDelayedLoading();
526 
530  virtual void SetRevised();
531 
532 private:
533  // To be called privately by various classes
534  PdfVariant& GetVariantUnsafe() { return m_Variant; }
535  PdfReference GetReferenceUnsafe() const { return m_Variant.GetReferenceUnsafe(); }
536  const PdfDictionary& GetDictionaryUnsafe() const { return m_Variant.GetDictionaryUnsafe(); }
537  const PdfArray& GetArrayUnsafe() const { return m_Variant.GetArrayUnsafe(); }
538  PdfDictionary& GetDictionaryUnsafe() { return m_Variant.GetDictionaryUnsafe(); }
539  PdfArray& GetArrayUnsafe() { return m_Variant.GetArrayUnsafe(); }
540  void WriteFinal(OutputStream& stream, PdfWriteFlags writeMode,
541  const PdfStatefulEncrypt* encrypt, charbuff& buffer);
542 
543  // To be called by PdfStreamedObjectStream
544  void SetNumberNoDirtySet(int64_t l);
545 
546  // To be called by PdfImmediateWriter
547  void SetImmutable();
548  void WriteHeader(OutputStream& stream, PdfWriteFlags writeMode, charbuff& buffer) const;
549 
550  // To be called by PdfDataContainer
551  bool IsImmutable() const { return m_IsImmutable; }
552 
553  // NOTE: It also doesn't dirty set the moved "obj"
554  void AssignNoDirtySet(PdfObject&& rhs);
555  void AssignNoDirtySet(PdfVariant&& rhs);
556  void AssignNoDirtySet(const PdfObject& rhs);
557 
558  void SetParent(PdfDataContainer& parent);
559 
560 private:
561  void write(OutputStream& stream, bool skipLengthFix,
562  PdfWriteFlags writeMode, const PdfStatefulEncrypt* encrypt, charbuff& buffer) const;
563 
564  void assertMutable() const;
565 
566  void assign(const PdfObject& rhs);
567 
568  void moveFrom(PdfObject&& rhs);
569 
570  void ResetDirty();
571 
572  void setDirty();
573 
574  // See PdfVariant.h for a detailed explanation of this member, which is
575  // here to prevent accidental construction of a PdfObject of integer type
576  // when passing a pointer. */
577  template<typename T>
578  PdfObject(T*) = delete;
579 
580  void copyStreamFrom(const PdfObject& obj);
581 
582  void moveStreamFrom(PdfObject& obj);
583 
584  // Shared initialization between all the ctors
585  void initObject();
586 
587 protected:
588  PdfVariant m_Variant;
589 
590 private:
591  PdfReference m_IndirectReference;
592  PdfDocument* m_Document;
593  PdfDataContainer* m_Parent;
594  std::unique_ptr<PdfObjectStream> m_Stream;
595  bool m_IsDirty; // Indicates if this object was modified after construction
596  bool m_IsImmutable;
597  mutable bool m_IsDelayedLoadDone;
598  mutable bool m_IsDelayedLoadStreamDone;
599  // Tracks whether deferred loading is still pending (in which case it'll be
600  // false). If true, deferred loading is not required or has been completed.
601 };
602 
605  template <typename T>
606  struct Object
607  {
608  static T Get(const PdfObject& obj)
609  {
610  (void)obj;
611  static_assert(always_false<T>, "Unsupported type");
612  return T{ };
613  }
614 
615  static bool TryGet(const PdfObject& obj, T& value)
616  {
617  (void)obj;
618  (void)value;
619  static_assert(always_false<T>, "Unsupported type");
620  return false;
621  }
622  };
623 
624  template <>
625  struct Object<bool>
626  {
627  static bool Get(const PdfObject& obj)
628  {
629  return obj.GetBool();
630  }
631 
632  static bool TryGet(const PdfObject& obj, bool& value)
633  {
634  return obj.TryGetBool(value);
635  }
636  };
637 
638  template <>
639  struct Object<int64_t>
640  {
641  static int64_t Get(const PdfObject& obj)
642  {
643  return obj.GetNumber();
644  }
645 
646  static bool TryGet(const PdfObject& obj, int64_t& value)
647  {
648  return obj.TryGetNumber(value);
649  }
650  };
651 
652  template <>
653  struct Object<double>
654  {
655  static double Get(const PdfObject& obj)
656  {
657  return obj.GetReal();
658  }
659 
660  static bool TryGet(const PdfObject& obj, double& value)
661  {
662  return obj.TryGetReal(value);
663  }
664  };
665 
666  template <>
667  struct Object<PdfReference>
668  {
669  static PdfReference Get(const PdfObject& obj)
670  {
671  return obj.GetReference();
672  }
673 
674  static bool TryGet(const PdfObject& obj, PdfReference& value)
675  {
676  return obj.TryGetReference(value);
677  }
678  };
679 
680  template <>
681  struct Object<PdfName>
682  {
683  static PdfName Get(const PdfObject& obj)
684  {
685  return obj.GetName();
686  }
687 
688  static bool TryGet(const PdfObject& obj, PdfName& value)
689  {
690  return obj.TryGetName(value);
691  }
692  };
693 
694  template <>
695  struct Object<const PdfName*>
696  {
697  static const PdfName* Get(const PdfObject& obj)
698  {
699  return &obj.GetName();
700  }
701 
702  static bool TryGet(const PdfObject& obj, const PdfName*& value)
703  {
704  return obj.TryGetName(value);
705  }
706  };
707 
708  template <>
709  struct Object<PdfString>
710  {
711  static PdfString Get(const PdfObject& obj)
712  {
713  return obj.GetString();
714  }
715 
716  static bool TryGet(const PdfObject& obj, PdfString& value)
717  {
718  return obj.TryGetString(value);
719  }
720  };
721 
722  template <>
723  struct Object<const PdfString*>
724  {
725  static const PdfString* Get(const PdfObject& obj)
726  {
727  return &obj.GetString();
728  }
729 
730  static bool TryGet(const PdfObject& obj, const PdfString*& value)
731  {
732  return obj.TryGetString(value);
733  }
734  };
735 
736  template <>
737  struct Object<const PdfDictionary*>
738  {
739  static const PdfDictionary* Get(const PdfObject& obj)
740  {
741  return &obj.GetDictionary();
742  }
743 
744  static bool TryGet(const PdfObject& obj, const PdfDictionary*& value)
745  {
746  return obj.TryGetDictionary(value);
747  }
748  };
749 
750  template <>
751  struct Object<PdfDictionary*>
752  {
753  static PdfDictionary* Get(PdfObject& obj)
754  {
755  return &obj.GetDictionary();
756  }
757 
758  static bool TryGet(PdfObject& obj, PdfDictionary*& value)
759  {
760  return obj.TryGetDictionary(value);
761  }
762  };
763 
764  template <>
765  struct Object<const PdfArray*>
766  {
767  static const PdfArray* Get(const PdfObject& obj)
768  {
769  return &obj.GetArray();
770  }
771 
772  static bool TryGet(const PdfObject& obj, const PdfArray*& value)
773  {
774  return obj.TryGetArray(value);
775  }
776  };
777 
778  template <>
779  struct Object<PdfArray*>
780  {
781  static PdfArray* Get(PdfObject& obj)
782  {
783  return &obj.GetArray();
784  }
785 
786  static bool TryGet(PdfObject& obj, PdfArray*& value)
787  {
788  return obj.TryGetArray(value);
789  }
790  };
791 
792  // Comparator to enable heterogeneous lookup with
793  // both objects and references
794  // See https://stackoverflow.com/a/31924435/213871
795  struct PODOFO_API PdfObjectInequality final
796  {
797  using is_transparent = std::true_type;
798 
799  bool operator()(const PdfObject* lhs, const PdfObject* rhs) const
800  {
801  return lhs->GetIndirectReference() < rhs->GetIndirectReference();
802  }
803  bool operator()(const PdfObject* lhs, const PdfReference& rhs) const
804  {
805  return lhs->GetIndirectReference() < rhs;
806  }
807  bool operator()(const PdfReference& lhs, const PdfObject* rhs) const
808  {
809  return lhs < rhs->GetIndirectReference();
810  }
811  bool operator()(const PdfObject& lhs, const PdfObject& rhs) const
812  {
813  return lhs.GetIndirectReference() < rhs.GetIndirectReference();
814  }
815  bool operator()(const PdfObject& lhs, const PdfReference& rhs) const
816  {
817  return lhs.GetIndirectReference() < rhs;
818  }
819  bool operator()(const PdfReference& lhs, const PdfObject& rhs) const
820  {
821  return lhs < rhs.GetIndirectReference();
822  }
823  };
824 }
825 
826 #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:108
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
const PdfReference & GetIndirectReference() const
Get an indirect reference to this object.
Definition: PdfObject.h:429
PdfDocument * GetDocument() const
Get the document of this object.
Definition: PdfObject.h:419
bool IsDelayedLoadDone() const
Returns true if delayed loading is disabled, or if it is enabled and loading has completed.
Definition: PdfObject.h:438
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:414
bool GetBool() const
Get the value if this object is a bool.
Definition: PdfObject.cpp:641
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:53
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:155
@ Null
The null datatype is always null.
PdfWriteFlags
Specify additional options for writing the PDF.
Definition: PdfDeclarations.h:137
Templatized object type getter helper.
Definition: PdfObject.h:607