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 // Can only be called for objects of types: `kBoolean`, `kNumber`, `kName`, 87 // and `kString`. 88 virtual void SetString(const ByteString& str); 89 90 virtual CPDF_Array* AsMutableArray(); 91 virtual CPDF_Boolean* AsMutableBoolean(); 92 virtual CPDF_Dictionary* AsMutableDictionary(); 93 virtual CPDF_Name* AsMutableName(); 94 virtual CPDF_Null* AsMutableNull(); 95 virtual CPDF_Number* AsMutableNumber(); 96 virtual CPDF_Reference* AsMutableReference(); 97 virtual CPDF_Stream* AsMutableStream(); 98 virtual CPDF_String* AsMutableString(); 99 100 virtual bool WriteTo(IFX_ArchiveStream* archive, 101 const CPDF_Encryptor* encryptor) const = 0; 102 103 // Create a deep copy of the object with the option to either 104 // copy a reference object or directly copy the object it refers to 105 // when |bDirect| is true. 106 // Also check cyclic reference against |pVisited|, no copy if it is found. 107 // Complex objects should implement their own CloneNonCyclic() 108 // function to properly check for possible loop. 109 virtual RetainPtr<CPDF_Object> CloneNonCyclic( 110 bool bDirect, 111 std::set<const CPDF_Object*>* pVisited) const; 112 113 // Return a reference to itself. 114 // The object must be direct (!IsInlined). 115 virtual RetainPtr<CPDF_Reference> MakeReference( 116 CPDF_IndirectObjectHolder* holder) const; 117 118 RetainPtr<const CPDF_Object> GetDirect() const; // Wraps virtual method. 119 RetainPtr<CPDF_Object> GetMutableDirect(); // Wraps virtual method. 120 RetainPtr<const CPDF_Dictionary> GetDict() const; // Wraps virtual method. 121 RetainPtr<CPDF_Dictionary> GetMutableDict(); // Wraps virtual method. 122 123 // Const methods wrapping non-const virtual As*() methods. 124 const CPDF_Array* AsArray() const; 125 const CPDF_Boolean* AsBoolean() const; 126 const CPDF_Dictionary* AsDictionary() const; 127 const CPDF_Name* AsName() const; 128 const CPDF_Null* AsNull() const; 129 const CPDF_Number* AsNumber() const; 130 const CPDF_Reference* AsReference() const; 131 const CPDF_Stream* AsStream() const; 132 const CPDF_String* AsString() const; 133 134 // Type-testing methods merely wrap As*() methods. IsArray()135 bool IsArray() const { return !!AsArray(); } IsBoolean()136 bool IsBoolean() const { return !!AsBoolean(); } IsDictionary()137 bool IsDictionary() const { return !!AsDictionary(); } IsName()138 bool IsName() const { return !!AsName(); } IsNull()139 bool IsNull() const { return !!AsNull(); } IsNumber()140 bool IsNumber() const { return !!AsNumber(); } IsReference()141 bool IsReference() const { return !!AsReference(); } IsStream()142 bool IsStream() const { return !!AsStream(); } IsString()143 bool IsString() const { return !!AsString(); } 144 145 protected: 146 friend class CPDF_Dictionary; 147 friend class CPDF_Reference; 148 149 CPDF_Object() = default; 150 CPDF_Object(const CPDF_Object& src) = delete; 151 ~CPDF_Object() override; 152 153 virtual const CPDF_Object* GetDirectInternal() const; 154 virtual const CPDF_Dictionary* GetDictInternal() const; 155 RetainPtr<CPDF_Object> CloneObjectNonCyclic(bool bDirect) const; 156 157 uint32_t m_ObjNum = 0; 158 uint32_t m_GenNum = 0; 159 }; 160 161 template <typename T> 162 struct CanInternStrings { 163 static constexpr bool value = std::is_same<T, CPDF_Array>::value || 164 std::is_same<T, CPDF_Dictionary>::value || 165 std::is_same<T, CPDF_Name>::value || 166 std::is_same<T, CPDF_String>::value; 167 }; 168 169 #endif // CORE_FPDFAPI_PARSER_CPDF_OBJECT_H_ 170