• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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