1 // Copyright 2018 PDFium Authors. All rights reserved.
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 <map>
9 #include <memory>
10 
11 #include "core/fxcrt/fx_system.h"
12 #include "core/fxcrt/retain_ptr.h"
13 
14 class CPDF_Dictionary;
15 
16 class CPDF_CrossRefTable {
17  public:
18   enum class ObjectType : uint8_t {
19     kFree = 0x00,
20     kNormal = 0x01,
21     kNotCompressed = kNormal,
22     kCompressed = 0x02,
23     kObjStream = 0xFF,
24     kNull = kObjStream,
25   };
26 
27   struct ObjectInfo {
ObjectInfoObjectInfo28     ObjectInfo() : pos(0), type(ObjectType::kFree), gennum(0) {}
29     // if type is ObjectType::kCompressed the archive_obj_num should be used.
30     // if type is ObjectType::kNotCompressed the pos should be used.
31     // In other cases its are unused.
32     union {
33       FX_FILESIZE pos;
34       uint32_t archive_obj_num;
35     };
36     ObjectType type;
37     uint16_t gennum;
38   };
39 
40   // Merge cross reference tables.  Apply top on current.
41   static std::unique_ptr<CPDF_CrossRefTable> MergeUp(
42       std::unique_ptr<CPDF_CrossRefTable> current,
43       std::unique_ptr<CPDF_CrossRefTable> top);
44 
45   CPDF_CrossRefTable();
46   explicit CPDF_CrossRefTable(RetainPtr<CPDF_Dictionary> trailer);
47   ~CPDF_CrossRefTable();
48 
49   void AddCompressed(uint32_t obj_num, uint32_t archive_obj_num);
50   void AddNormal(uint32_t obj_num, uint16_t gen_num, FX_FILESIZE pos);
51   void SetFree(uint32_t obj_num);
52 
53   void SetTrailer(RetainPtr<CPDF_Dictionary> trailer);
trailer()54   const CPDF_Dictionary* trailer() const { return trailer_.Get(); }
GetMutableTrailerForTesting()55   CPDF_Dictionary* GetMutableTrailerForTesting() { return trailer_.Get(); }
56 
57   const ObjectInfo* GetObjectInfo(uint32_t obj_num) const;
58 
objects_info()59   const std::map<uint32_t, ObjectInfo>& objects_info() const {
60     return objects_info_;
61   }
62 
63   void Update(std::unique_ptr<CPDF_CrossRefTable> new_cross_ref);
64 
65   void ShrinkObjectMap(uint32_t objnum);
66 
67  private:
68   void UpdateInfo(std::map<uint32_t, ObjectInfo>&& new_objects_info);
69   void UpdateTrailer(RetainPtr<CPDF_Dictionary> new_trailer);
70 
71   RetainPtr<CPDF_Dictionary> trailer_;
72   std::map<uint32_t, ObjectInfo> objects_info_;
73 };
74 
75 #endif  // CORE_FPDFAPI_PARSER_CPDF_CROSS_REF_TABLE_H_
76