1 // Copyright 2018 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 #ifndef CORE_FPDFAPI_PARSER_CPDF_CROSS_REF_TABLE_H_ 6 #define CORE_FPDFAPI_PARSER_CPDF_CROSS_REF_TABLE_H_ 7 8 #include <stdint.h> 9 10 #include <map> 11 #include <memory> 12 13 #include "core/fxcrt/fx_types.h" 14 #include "core/fxcrt/retain_ptr.h" 15 16 class CPDF_Dictionary; 17 18 class CPDF_CrossRefTable { 19 public: 20 enum class ObjectType : uint8_t { 21 kFree = 0x00, 22 kNormal = 0x01, 23 kNotCompressed = kNormal, 24 kCompressed = 0x02, 25 kObjStream = 0xFF, 26 kNull = kObjStream, 27 }; 28 29 struct ObjectInfo { 30 ObjectInfo() = default; 31 32 // If `type` is `ObjectType::kCompressed`, `archive` should be used. 33 // If `type` is `ObjectType::kNotCompressed`, `pos` should be used. 34 // In other cases, it is unused. 35 union { 36 FX_FILESIZE pos = 0; 37 struct { 38 uint32_t obj_num; 39 uint32_t obj_index; 40 } archive; 41 }; 42 ObjectType type = ObjectType::kFree; 43 uint16_t gennum = 0; 44 }; 45 46 // Merge cross reference tables. Apply top on current. 47 static std::unique_ptr<CPDF_CrossRefTable> MergeUp( 48 std::unique_ptr<CPDF_CrossRefTable> current, 49 std::unique_ptr<CPDF_CrossRefTable> top); 50 51 CPDF_CrossRefTable(); 52 CPDF_CrossRefTable(RetainPtr<CPDF_Dictionary> trailer, 53 uint32_t trailer_object_number); 54 ~CPDF_CrossRefTable(); 55 56 void AddCompressed(uint32_t obj_num, 57 uint32_t archive_obj_num, 58 uint32_t archive_obj_index); 59 void AddNormal(uint32_t obj_num, uint16_t gen_num, FX_FILESIZE pos); 60 void SetFree(uint32_t obj_num); 61 62 void SetTrailer(RetainPtr<CPDF_Dictionary> trailer, 63 uint32_t trailer_object_number); trailer_object_number()64 uint32_t trailer_object_number() const { return trailer_object_number_; } trailer()65 const CPDF_Dictionary* trailer() const { return trailer_.Get(); } GetMutableTrailerForTesting()66 CPDF_Dictionary* GetMutableTrailerForTesting() { return trailer_.Get(); } 67 68 const ObjectInfo* GetObjectInfo(uint32_t obj_num) const; 69 objects_info()70 const std::map<uint32_t, ObjectInfo>& objects_info() const { 71 return objects_info_; 72 } 73 74 void Update(std::unique_ptr<CPDF_CrossRefTable> new_cross_ref); 75 76 // Objects with object number >= `size` will be removed. 77 void SetObjectMapSize(uint32_t size); 78 79 private: 80 void UpdateInfo(std::map<uint32_t, ObjectInfo> new_objects_info); 81 void UpdateTrailer(RetainPtr<CPDF_Dictionary> new_trailer); 82 83 RetainPtr<CPDF_Dictionary> trailer_; 84 // `trailer_` can be the dictionary part of a XRef stream object. Since it is 85 // inline, it has no object number. Store the stream's object number, or 0 if 86 // there is none. 87 uint32_t trailer_object_number_ = 0; 88 std::map<uint32_t, ObjectInfo> objects_info_; 89 }; 90 91 #endif // CORE_FPDFAPI_PARSER_CPDF_CROSS_REF_TABLE_H_ 92