1 // Copyright 2016 The PDFium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef CORE_FPDFAPI_PARSER_CPDF_OBJECT_H_ 8 #define CORE_FPDFAPI_PARSER_CPDF_OBJECT_H_ 9 10 #include <stdint.h> 11 12 #include <set> 13 #include <type_traits> 14 15 #include "core/fxcrt/fx_string.h" 16 #include "core/fxcrt/retain_ptr.h" 17 18 class CPDF_Array; 19 class CPDF_Boolean; 20 class CPDF_Dictionary; 21 class CPDF_Encryptor; 22 class CPDF_IndirectObjectHolder; 23 class CPDF_Name; 24 class CPDF_Null; 25 class CPDF_Number; 26 class CPDF_Reference; 27 class CPDF_Stream; 28 class CPDF_String; 29 class IFX_ArchiveStream; 30 31 // ISO 32000-1:2008 defines PDF objects. When CPDF_Parser parses a PDF object, 32 // it represents the PDF object using CPDF_Objects. Take this PDF object for 33 // example: 34 // 35 // 4 0 obj << 36 // /Type /Pages 37 // /Count 1 38 // /Kids [9 0 R] 39 // >> 40 // 41 // Multiple CPDF_Objects instances are necessary to represent this PDF object: 42 // 1) A CPDF_Dictionary with object number 4 that contains 3 elements. 43 // 2) A CPDF_Name for /Pages. 44 // 3) A CPDF_Number for the count of 1. 45 // 4) A CPDF_Array for [9 0 R], which contains 1 element. 46 // 5) A CPDF_Reference that references object 9 0. 47 // 48 // CPDF_Object (1) has an object number of 4. All the other CPDF_Objects are 49 // inline objects. CPDF_Object represent that by using an object number of 0. 50 class CPDF_Object : public Retainable { 51 public: 52 static constexpr uint32_t kInvalidObjNum = static_cast<uint32_t>(-1); 53 enum Type { 54 kBoolean = 1, 55 kNumber, 56 kString, 57 kName, 58 kArray, 59 kDictionary, 60 kStream, 61 kNullobj, 62 kReference 63 }; 64 GetObjNum()65 uint32_t GetObjNum() const { return m_ObjNum; } SetObjNum(uint32_t objnum)66 void SetObjNum(uint32_t objnum) { m_ObjNum = objnum; } GetGenNum()67 uint32_t GetGenNum() const { return m_GenNum; } SetGenNum(uint32_t gennum)68 void SetGenNum(uint32_t gennum) { m_GenNum = gennum; } IsInline()69 bool IsInline() const { return m_ObjNum == 0; } 70 uint64_t KeyForCache() const; 71 72 virtual Type GetType() const = 0; 73 74 // Create a deep copy of the object. 75 virtual RetainPtr<CPDF_Object> Clone() const = 0; 76 77 // Create a deep copy of the object except any reference object be 78 // copied to the object it points to directly. 79 RetainPtr<CPDF_Object> CloneDirectObject() const; 80 81 virtual ByteString GetString() const; 82 virtual WideString GetUnicodeText() const; 83 virtual float GetNumber() const; 84 virtual int GetInteger() const; 85 86 virtual void SetString(const ByteString& str); 87 88 virtual CPDF_Array* AsMutableArray(); 89 virtual CPDF_Boolean* AsMutableBoolean(); 90 virtual CPDF_Dictionary* AsMutableDictionary(); 91 virtual CPDF_Name* AsMutableName(); 92 virtual CPDF_Null* AsMutableNull(); 93 virtual CPDF_Number* AsMutableNumber(); 94 virtual CPDF_Reference* AsMutableReference(); 95 virtual CPDF_Stream* AsMutableStream(); 96 virtual CPDF_String* AsMutableString(); 97 98 virtual bool WriteTo(IFX_ArchiveStream* archive, 99 const CPDF_Encryptor* encryptor) const = 0; 100 101 // Create a deep copy of the object with the option to either 102 // copy a reference object or directly copy the object it refers to 103 // when |bDirect| is true. 104 // Also check cyclic reference against |pVisited|, no copy if it is found. 105 // Complex objects should implement their own CloneNonCyclic() 106 // function to properly check for possible loop. 107 virtual RetainPtr<CPDF_Object> CloneNonCyclic( 108 bool bDirect, 109 std::set<const CPDF_Object*>* pVisited) const; 110 111 // Return a reference to itself. 112 // The object must be direct (!IsInlined). 113 virtual RetainPtr<CPDF_Reference> MakeReference( 114 CPDF_IndirectObjectHolder* holder) const; 115 116 RetainPtr<const CPDF_Object> GetDirect() const; // Wraps virtual method. 117 RetainPtr<CPDF_Object> GetMutableDirect(); // Wraps virtual method. 118 RetainPtr<const CPDF_Dictionary> GetDict() const; // Wraps virtual method. 119 RetainPtr<CPDF_Dictionary> GetMutableDict(); // Wraps virtual method. 120 121 // Const methods wrapping non-const virtual As*() methods. 122 const CPDF_Array* AsArray() const; 123 const CPDF_Boolean* AsBoolean() const; 124 const CPDF_Dictionary* AsDictionary() const; 125 const CPDF_Name* AsName() const; 126 const CPDF_Null* AsNull() const; 127 const CPDF_Number* AsNumber() const; 128 const CPDF_Reference* AsReference() const; 129 const CPDF_Stream* AsStream() const; 130 const CPDF_String* AsString() const; 131 132 // Type-testing methods merely wrap As*() methods. IsArray()133 bool IsArray() const { return !!AsArray(); } IsBoolean()134 bool IsBoolean() const { return !!AsBoolean(); } IsDictionary()135 bool IsDictionary() const { return !!AsDictionary(); } IsName()136 bool IsName() const { return !!AsName(); } IsNull()137 bool IsNull() const { return !!AsNull(); } IsNumber()138 bool IsNumber() const { return !!AsNumber(); } IsReference()139 bool IsReference() const { return !!AsReference(); } IsStream()140 bool IsStream() const { return !!AsStream(); } IsString()141 bool IsString() const { return !!AsString(); } 142 143 protected: 144 friend class CPDF_Dictionary; 145 friend class CPDF_Reference; 146 147 CPDF_Object() = default; 148 CPDF_Object(const CPDF_Object& src) = delete; 149 ~CPDF_Object() override; 150 151 virtual const CPDF_Object* GetDirectInternal() const; 152 virtual const CPDF_Dictionary* GetDictInternal() const; 153 RetainPtr<CPDF_Object> CloneObjectNonCyclic(bool bDirect) const; 154 155 uint32_t m_ObjNum = 0; 156 uint32_t m_GenNum = 0; 157 }; 158 159 template <typename T> 160 struct CanInternStrings { 161 static constexpr bool value = std::is_same<T, CPDF_Array>::value || 162 std::is_same<T, CPDF_Dictionary>::value || 163 std::is_same<T, CPDF_Name>::value || 164 std::is_same<T, CPDF_String>::value; 165 }; 166 167 #endif // CORE_FPDFAPI_PARSER_CPDF_OBJECT_H_ 168