File indexing completed on 2025-12-10 10:23:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #ifndef XREF_H
0037 #define XREF_H
0038
0039 #include <functional>
0040
0041 #include "poppler-config.h"
0042 #include "poppler_private_export.h"
0043 #include "Object.h"
0044 #include "Stream.h"
0045 #include "PopplerCache.h"
0046
0047 class Dict;
0048 class Stream;
0049 class Parser;
0050 class ObjectStream;
0051
0052
0053
0054
0055
0056 enum XRefEntryType
0057 {
0058 xrefEntryFree,
0059 xrefEntryUncompressed,
0060 xrefEntryCompressed,
0061 xrefEntryNone
0062 };
0063
0064 struct XRefEntry
0065 {
0066 Goffset offset;
0067 int gen;
0068 XRefEntryType type;
0069 int flags;
0070 Object obj;
0071
0072 enum Flag
0073 {
0074
0075 Updated,
0076 Parsing,
0077
0078
0079 Unencrypted,
0080 DontRewrite
0081 };
0082
0083 inline bool getFlag(Flag flag) const
0084 {
0085 const int mask = (1 << (int)flag);
0086 return (flags & mask) != 0;
0087 }
0088
0089 inline void setFlag(Flag flag, bool value)
0090 {
0091 const int mask = (1 << (int)flag);
0092 if (value) {
0093 flags |= mask;
0094 } else {
0095 flags &= ~mask;
0096 }
0097 }
0098 };
0099
0100 class POPPLER_PRIVATE_EXPORT XRef
0101 {
0102 public:
0103
0104 XRef();
0105
0106 explicit XRef(const Object *trailerDictA);
0107
0108 XRef(BaseStream *strA, Goffset pos, Goffset mainXRefEntriesOffsetA = 0, bool *wasReconstructed = nullptr, bool reconstruct = false, const std::function<void()> &xrefReconstructedCallback = {});
0109
0110
0111 ~XRef();
0112
0113 XRef(const XRef &) = delete;
0114 XRef &operator=(const XRef &) = delete;
0115
0116
0117 XRef *copy() const;
0118
0119
0120 bool isOk() const { return ok; }
0121
0122
0123 bool isXRefStream() const { return xRefStream; }
0124
0125
0126 int getErrorCode() const { return errCode; }
0127
0128
0129 void setEncryption(int permFlagsA, bool ownerPasswordOkA, const unsigned char *fileKeyA, int keyLengthA, int encVersionA, int encRevisionA, CryptAlgorithm encAlgorithmA);
0130
0131 void markUnencrypted();
0132
0133 void getEncryptionParameters(unsigned char **fileKeyA, CryptAlgorithm *encAlgorithmA, int *keyLengthA);
0134
0135
0136 bool isEncrypted() const { return encrypted; }
0137
0138
0139 bool isRefEncrypted(Ref r);
0140
0141
0142 bool okToPrint(bool ignoreOwnerPW = false) const;
0143 bool okToPrintHighRes(bool ignoreOwnerPW = false) const;
0144 bool okToChange(bool ignoreOwnerPW = false) const;
0145 bool okToCopy(bool ignoreOwnerPW = false) const;
0146 bool okToAddNotes(bool ignoreOwnerPW = false) const;
0147 bool okToFillForm(bool ignoreOwnerPW = false) const;
0148 bool okToAccessibility(bool ignoreOwnerPW = false) const;
0149 bool okToAssemble(bool ignoreOwnerPW = false) const;
0150 int getPermFlags() const { return permFlags; }
0151
0152
0153 Object getCatalog();
0154
0155
0156 Object fetch(const Ref ref, int recursion = 0);
0157
0158
0159
0160 Object fetch(int num, int gen, int recursion = 0, Goffset *endPos = nullptr);
0161
0162
0163 Object getDocInfo();
0164 Object getDocInfoNF();
0165
0166
0167
0168
0169 Object createDocInfoIfNeeded(Ref *ref);
0170
0171
0172 void removeDocInfo();
0173
0174
0175 int getNumObjects() const { return size; }
0176
0177
0178 int getRootNum() const { return rootNum; }
0179 int getRootGen() const { return rootGen; }
0180 Ref getRoot() const { return { rootNum, rootGen }; }
0181
0182
0183
0184 bool getStreamEnd(Goffset streamStart, Goffset *streamEnd);
0185
0186
0187 int getNumEntry(Goffset offset);
0188
0189
0190
0191
0192
0193
0194
0195 void scanSpecialFlags();
0196
0197
0198 XRefEntry *getEntry(int i, bool complainIfMissing = true);
0199 Object *getTrailerDict() { return &trailerDict; }
0200
0201
0202 bool isModified() const { return modified; }
0203
0204 void setModified() { modified = true; }
0205
0206
0207 void setModifiedObject(const Object *o, Ref r);
0208 Ref addIndirectObject(const Object &o);
0209 void removeIndirectObject(Ref r);
0210 bool add(int num, int gen, Goffset offs, bool used);
0211 void add(Ref ref, Goffset offs, bool used);
0212
0213
0214
0215
0216 Ref addStreamObject(Dict *dict, char *buffer, const Goffset bufferSize);
0217 Ref addStreamObject(Dict *dict, uint8_t *buffer, const Goffset bufferSize);
0218
0219
0220 void writeTableToFile(OutStream *outStr, bool writeAllEntries);
0221
0222 void writeStreamToBuffer(GooString *stmBuf, Dict *xrefDict, XRef *xref);
0223
0224
0225 void lock();
0226 void unlock();
0227
0228 private:
0229 BaseStream *str;
0230 Goffset start;
0231
0232 XRefEntry *entries;
0233 int capacity;
0234 int size;
0235 int rootNum, rootGen;
0236 bool ok;
0237 int errCode;
0238 bool xrefReconstructed;
0239 Object trailerDict;
0240 bool modified;
0241 Goffset *streamEnds;
0242
0243 int streamEndsLen;
0244 PopplerCache<Goffset, ObjectStream> objStrs;
0245 bool encrypted;
0246 int encRevision;
0247 int encVersion;
0248 CryptAlgorithm encAlgorithm;
0249 int keyLength;
0250 int permFlags;
0251 unsigned char fileKey[32];
0252 bool ownerPasswordOk;
0253 Goffset prevXRefOffset;
0254 Goffset mainXRefEntriesOffset;
0255 bool xRefStream;
0256 Goffset mainXRefOffset;
0257 bool scannedSpecialFlags;
0258 bool strOwner;
0259 mutable std::recursive_mutex mutex;
0260 std::function<void()> xrefReconstructedCb;
0261
0262 int reserve(int newSize);
0263 int resize(int newSize);
0264 bool readXRef(Goffset *pos, std::vector<Goffset> *followedXRefStm, std::vector<int> *xrefStreamObjsNum);
0265 bool readXRefTable(Parser *parser, Goffset *pos, std::vector<Goffset> *followedXRefStm, std::vector<int> *xrefStreamObjsNum);
0266 bool readXRefStreamSection(Stream *xrefStr, const int *w, int first, int n);
0267 bool readXRefStream(Stream *xrefStr, Goffset *pos);
0268 bool constructXRef(bool *wasReconstructed, bool needCatalogDict = false);
0269 bool parseEntry(Goffset offset, XRefEntry *entry);
0270 void readXRefUntil(int untilEntryNum, std::vector<int> *xrefStreamObjsNum = nullptr);
0271 void markUnencrypted(Object *obj);
0272
0273 class XRefWriter
0274 {
0275 public:
0276 XRefWriter() = default;
0277 virtual void startSection(int first, int count) = 0;
0278 virtual void writeEntry(Goffset offset, int gen, XRefEntryType type) = 0;
0279 virtual ~XRefWriter();
0280
0281 XRefWriter(const XRefWriter &) = delete;
0282 XRefWriter &operator=(const XRefWriter &other) = delete;
0283 };
0284
0285
0286 class XRefTableWriter : public XRefWriter
0287 {
0288 public:
0289 explicit XRefTableWriter(OutStream *outStrA);
0290 void startSection(int first, int count) override;
0291 void writeEntry(Goffset offset, int gen, XRefEntryType type) override;
0292
0293 private:
0294 OutStream *outStr;
0295 };
0296
0297
0298 class XRefStreamWriter : public XRefWriter
0299 {
0300 public:
0301 XRefStreamWriter(Array *index, GooString *stmBuf, int offsetSize);
0302 void startSection(int first, int count) override;
0303 void writeEntry(Goffset offset, int gen, XRefEntryType type) override;
0304
0305 private:
0306 Array *index;
0307 GooString *stmBuf;
0308 int offsetSize;
0309 };
0310
0311
0312 class XRefPreScanWriter : public XRefWriter
0313 {
0314 public:
0315 XRefPreScanWriter();
0316 void startSection(int first, int count) override;
0317 void writeEntry(Goffset offset, int gen, XRefEntryType type) override;
0318
0319 bool hasOffsetsBeyond4GB;
0320 };
0321
0322 void writeXRef(XRefWriter *writer, bool writeAllEntries);
0323 };
0324
0325 #endif