1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
//========================================================================
//
// XRef.h
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef XREF_H
#define XREF_H
#include <aconf.h>
#include "gtypes.h"
#include "gfile.h"
#include "Object.h"
#if MULTITHREADED
#include "GMutex.h"
#endif
class Dict;
class Stream;
class Parser;
class ObjectStream;
class XRefPosSet;
//------------------------------------------------------------------------
// XRef
//------------------------------------------------------------------------
enum XRefEntryType {
xrefEntryFree,
xrefEntryUncompressed,
xrefEntryCompressed
};
struct XRefEntry {
GFileOffset offset;
int gen;
XRefEntryType type;
};
struct XRefCacheEntry {
int num;
int gen;
Object obj;
};
#define xrefCacheSize 16
#define objStrCacheSize 128
#define objStrCacheTimeout 1000
class XRef {
public:
// Constructor. Read xref table from stream.
XRef(BaseStream *strA, GBool repair);
// Destructor.
~XRef();
// Is xref table valid?
GBool isOk() { return ok; }
// Get the error code (if isOk() returns false).
int getErrorCode() { return errCode; }
// Was the xref constructed by the repair code?
GBool isRepaired() { return repaired; }
// Set the encryption parameters.
void setEncryption(int permFlagsA, GBool ownerPasswordOkA,
Guchar *fileKeyA, int keyLengthA, int encVersionA,
CryptAlgorithm encAlgorithmA);
// Is the file encrypted?
GBool isEncrypted() { return encrypted; }
GBool getEncryption(int *permFlagsA, GBool *ownerPasswordOkA,
int *keyLengthA, int *encVersionA,
CryptAlgorithm *encAlgorithmA);
// Check various permissions.
GBool okToPrint(GBool ignoreOwnerPW = gFalse);
GBool okToChange(GBool ignoreOwnerPW = gFalse);
GBool okToCopy(GBool ignoreOwnerPW = gFalse);
GBool okToAddNotes(GBool ignoreOwnerPW = gFalse);
int getPermFlags() { return permFlags; }
// Get catalog object.
Object *getCatalog(Object *obj) { return fetch(rootNum, rootGen, obj); }
// Fetch an indirect reference.
Object *fetch(int num, int gen, Object *obj, int recursion = 0);
// Return the document's Info dictionary (if any).
Object *getDocInfo(Object *obj);
Object *getDocInfoNF(Object *obj);
// Return the number of objects in the xref table.
int getNumObjects() { return last + 1; }
// Return the offset of the last xref table.
GFileOffset getLastXRefPos() { return lastXRefPos; }
// Return the offset of the 'startxref' at the end of the file.
GFileOffset getLastStartxrefPos() { return lastStartxrefPos; }
// Return the catalog object reference.
int getRootNum() { return rootNum; }
int getRootGen() { return rootGen; }
// Get the xref table positions.
int getNumXRefTables() { return xrefTablePosLen; }
GFileOffset getXRefTablePos(int idx) { return xrefTablePos[idx]; }
// Get end position for a stream in a damaged file.
// Returns false if unknown or file is not damaged.
GBool getStreamEnd(GFileOffset streamStart, GFileOffset *streamEnd);
// Direct access.
int getSize() { return size; }
XRefEntry *getEntry(int i) { return &entries[i]; }
Object *getTrailerDict() { return &trailerDict; }
private:
BaseStream *str; // input stream
GFileOffset start; // offset in file (to allow for garbage
// at beginning of file)
XRefEntry *entries; // xref entries
int size; // size of <entries> array
int last; // last used index in <entries>
int rootNum, rootGen; // catalog dict
GBool ok; // true if xref table is valid
int errCode; // error code (if <ok> is false)
GBool repaired; // set if the xref table was constructed by
// the repair code
Object trailerDict; // trailer dictionary
GFileOffset lastXRefPos; // offset of last xref table
GFileOffset lastStartxrefPos; // offset of 'startxref' at end of file
GFileOffset *xrefTablePos; // positions of all xref tables
int xrefTablePosLen; // number of xref table positions
GFileOffset *streamEnds; // 'endstream' positions - only used in
// damaged files
int streamEndsLen; // number of valid entries in streamEnds
ObjectStream * // cached object streams
objStrs[objStrCacheSize];
int objStrCacheLength; // number of valid entries in objStrs[]
Guint // time of last use for each obj stream
objStrLastUse[objStrCacheSize];
Guint objStrTime; // current time for the obj stream cache
#if MULTITHREADED
GMutex objStrsMutex;
#endif
GBool encrypted; // true if file is encrypted
int permFlags; // permission bits
GBool ownerPasswordOk; // true if owner password is correct
Guchar fileKey[32]; // file decryption key
int keyLength; // length of key, in bytes
int encVersion; // encryption version
CryptAlgorithm encAlgorithm; // encryption algorithm
XRefCacheEntry // cache of recently accessed objects
cache[xrefCacheSize];
#if MULTITHREADED
GMutex cacheMutex;
#endif
GFileOffset getStartXref();
GBool readXRef(GFileOffset *pos, XRefPosSet *posSet, GBool hybrid);
GBool readXRefTable(GFileOffset *pos, int offset, XRefPosSet *posSet);
GBool readXRefStream(Stream *xrefStr, GFileOffset *pos, GBool hybrid);
GBool readXRefStreamSection(Stream *xrefStr, int *w, int first, int n);
GBool constructXRef();
void constructTrailerDict(GFileOffset pos);
void saveTrailerDict(Dict *dict, GBool isXRefStream);
char *constructObjectEntry(char *p, GFileOffset pos, int *objNum);
void constructObjectStreamEntries(Object *objStr, int objStrObjNum);
GBool constructXRefEntry(int num, int gen, GFileOffset pos,
XRefEntryType type);
GBool getObjectStreamObject(int objStrNum, int objIdx,
int objNum, Object *obj, int recursion);
ObjectStream *getObjectStreamFromCache(int objStrNum);
void addObjectStreamToCache(ObjectStream *objStr);
void cleanObjectStreamCache();
GFileOffset strToFileOffset(char *s);
};
#endif
|