xref: /aosp_15_r20/external/pdfium/core/fpdfapi/parser/cpdf_cross_ref_table.h (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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