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 // See ISO 32000-1:2008 table 18. 21 enum class ObjectType : uint8_t { 22 kFree = 0, 23 kNormal = 1, 24 kCompressed = 2, 25 }; 26 27 struct ObjectInfo { 28 ObjectType type = ObjectType::kFree; 29 bool is_object_stream_flag = false; 30 uint16_t gennum = 0; 31 // If `type` is `ObjectType::kCompressed`, `archive` should be used. 32 // If `type` is `ObjectType::kNormal`, `pos` should be used. 33 // In other cases, it is unused. 34 union { 35 FX_FILESIZE pos = 0; 36 struct { 37 uint32_t obj_num; 38 uint32_t obj_index; 39 } archive; 40 }; 41 }; 42 43 // Merge cross reference tables. Apply top on current. 44 static std::unique_ptr<CPDF_CrossRefTable> MergeUp( 45 std::unique_ptr<CPDF_CrossRefTable> current, 46 std::unique_ptr<CPDF_CrossRefTable> top); 47 48 CPDF_CrossRefTable(); 49 CPDF_CrossRefTable(RetainPtr<CPDF_Dictionary> trailer, 50 uint32_t trailer_object_number); 51 ~CPDF_CrossRefTable(); 52 53 void AddCompressed(uint32_t obj_num, 54 uint32_t archive_obj_num, 55 uint32_t archive_obj_index); 56 void AddNormal(uint32_t obj_num, 57 uint16_t gen_num, 58 bool is_object_stream, 59 FX_FILESIZE pos); 60 void SetFree(uint32_t obj_num, uint16_t gen_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