/src/xpdf-4.05/xpdf/Object.h
Line | Count | Source (jump to first uncovered line) |
1 | | //======================================================================== |
2 | | // |
3 | | // Object.h |
4 | | // |
5 | | // Copyright 1996-2003 Glyph & Cog, LLC |
6 | | // |
7 | | //======================================================================== |
8 | | |
9 | | #ifndef OBJECT_H |
10 | | #define OBJECT_H |
11 | | |
12 | | #include <aconf.h> |
13 | | |
14 | | #include <stdio.h> |
15 | | #include <string.h> |
16 | | #include "gtypes.h" |
17 | | #include "gmem.h" |
18 | | #include "gfile.h" |
19 | | #include "GString.h" |
20 | | #if MULTITHREADED |
21 | | #include "GMutex.h" |
22 | | #endif |
23 | | |
24 | | class XRef; |
25 | | class Array; |
26 | | class Dict; |
27 | | class Stream; |
28 | | |
29 | | //------------------------------------------------------------------------ |
30 | | // Ref |
31 | | //------------------------------------------------------------------------ |
32 | | |
33 | | struct Ref { |
34 | | int num; // object number |
35 | | int gen; // generation number |
36 | | }; |
37 | | |
38 | | //------------------------------------------------------------------------ |
39 | | // object types |
40 | | //------------------------------------------------------------------------ |
41 | | |
42 | | enum ObjType { |
43 | | // simple objects |
44 | | objBool, // boolean |
45 | | objInt, // integer |
46 | | objReal, // real |
47 | | objString, // string |
48 | | objName, // name |
49 | | objNull, // null |
50 | | |
51 | | // complex objects |
52 | | objArray, // array |
53 | | objDict, // dictionary |
54 | | objStream, // stream |
55 | | objRef, // indirect reference |
56 | | |
57 | | // special objects |
58 | | objCmd, // command name |
59 | | objError, // error return from Lexer |
60 | | objEOF, // end of file return from Lexer |
61 | | objNone // uninitialized object |
62 | | }; |
63 | | |
64 | | #define numObjTypes 14 // total number of object types |
65 | | |
66 | | //------------------------------------------------------------------------ |
67 | | // Object |
68 | | //------------------------------------------------------------------------ |
69 | | |
70 | | #ifdef DEBUG_OBJECT_MEM |
71 | | # if MULTITHREADED |
72 | | # define initObj(t) gAtomicIncrement(&numAlloc[type = t]) |
73 | | # else |
74 | | # define initObj(t) ++numAlloc[type = t] |
75 | | # endif |
76 | | #else |
77 | 269M | #define initObj(t) type = t |
78 | | #endif |
79 | | |
80 | | class Object { |
81 | | public: |
82 | | |
83 | | // Default constructor. |
84 | | Object(): |
85 | 399M | type(objNone) {} |
86 | | |
87 | | // Initialize an object. |
88 | | Object *initBool(GBool boolnA) |
89 | 73.3k | { initObj(objBool); booln = boolnA; return this; } |
90 | | Object *initInt(int intgA) |
91 | 14.1M | { initObj(objInt); intg = intgA; return this; } |
92 | | Object *initReal(double realA) |
93 | 899k | { initObj(objReal); real = realA; return this; } |
94 | | Object *initString(GString *stringA) |
95 | 1.09M | { initObj(objString); string = stringA; return this; } |
96 | | Object *initName(const char *nameA) |
97 | 8.69M | { initObj(objName); name = copyString(nameA); return this; } |
98 | | Object *initNull() |
99 | 51.9M | { initObj(objNull); return this; } |
100 | | Object *initArray(XRef *xref); |
101 | | Object *initDict(XRef *xref); |
102 | | Object *initDict(Dict *dictA); |
103 | | Object *initStream(Stream *streamA); |
104 | | Object *initRef(int numA, int genA) |
105 | 1.01M | { initObj(objRef); ref.num = numA; ref.gen = genA; return this; } |
106 | | Object *initCmd(char *cmdA) |
107 | 30.4M | { initObj(objCmd); cmd = copyString(cmdA); return this; } |
108 | | Object *initError() |
109 | 2.42M | { initObj(objError); return this; } |
110 | | Object *initEOF() |
111 | 156M | { initObj(objEOF); return this; } |
112 | | |
113 | | // Copy an object. |
114 | | Object *copy(Object *obj); |
115 | | |
116 | | // If object is a Ref, fetch and return the referenced object. |
117 | | // Otherwise, return a copy of the object. |
118 | | Object *fetch(XRef *xref, Object *obj, int recursion = 0); |
119 | | |
120 | | // Free object contents. |
121 | | void free(); |
122 | | |
123 | | // Type checking. |
124 | 0 | ObjType getType() { return type; } |
125 | 4.87k | GBool isBool() { return type == objBool; } |
126 | 273M | GBool isInt() { return type == objInt; } |
127 | 0 | GBool isReal() { return type == objReal; } |
128 | 119k | GBool isNum() { return type == objInt || type == objReal; } |
129 | 180M | GBool isString() { return type == objString; } |
130 | 17.6M | GBool isName() { return type == objName; } |
131 | 502k | GBool isNull() { return type == objNull; } |
132 | 3.50M | GBool isArray() { return type == objArray; } |
133 | 2.15M | GBool isDict() { return type == objDict; } |
134 | 46.8M | GBool isStream() { return type == objStream; } |
135 | 10.2M | GBool isRef() { return type == objRef; } |
136 | 0 | GBool isCmd() { return type == objCmd; } |
137 | 3.55M | GBool isError() { return type == objError; } |
138 | 46.6M | GBool isEOF() { return type == objEOF; } |
139 | 1.39G | GBool isNone() { return type == objNone; } |
140 | | |
141 | | // Special type checking. |
142 | | GBool isName(const char *nameA) |
143 | 604k | { return type == objName && !strcmp(name, nameA); } |
144 | | GBool isDict(const char *dictType); |
145 | | GBool isStream(char *dictType); |
146 | | GBool isCmd(const char *cmdA) |
147 | 284M | { return type == objCmd && !strcmp(cmd, cmdA); } |
148 | | |
149 | | // Accessors. NB: these assume object is of correct type. |
150 | 359 | GBool getBool() { return booln; } |
151 | 8.54M | int getInt() { return intg; } |
152 | 0 | double getReal() { return real; } |
153 | 9.11k | double getNum() { return type == objInt ? (double)intg : real; } |
154 | 57.3k | GString *getString() { return string; } |
155 | 4.01M | char *getName() { return name; } |
156 | 79 | Array *getArray() { return array; } |
157 | 644k | Dict *getDict() { return dict; } |
158 | 839k | Stream *getStream() { return stream; } |
159 | 218k | Ref getRef() { return ref; } |
160 | 5.02M | int getRefNum() { return ref.num; } |
161 | 2.44M | int getRefGen() { return ref.gen; } |
162 | 0 | char *getCmd() { return cmd; } |
163 | | |
164 | | // Array accessors. |
165 | | int arrayGetLength(); |
166 | | void arrayAdd(Object *elem); |
167 | | Object *arrayGet(int i, Object *obj, int recursion = 0); |
168 | | Object *arrayGetNF(int i, Object *obj); |
169 | | |
170 | | // Dict accessors. |
171 | | int dictGetLength(); |
172 | | void dictAdd(char *key, Object *val); |
173 | | GBool dictIs(const char *dictType); |
174 | | Object *dictLookup(const char *key, Object *obj, int recursion = 0); |
175 | | Object *dictLookupNF(const char *key, Object *obj); |
176 | | char *dictGetKey(int i); |
177 | | Object *dictGetVal(int i, Object *obj); |
178 | | Object *dictGetValNF(int i, Object *obj); |
179 | | |
180 | | // Stream accessors. |
181 | | GBool streamIs(char *dictType); |
182 | | void streamReset(); |
183 | | void streamClose(); |
184 | | int streamGetChar(); |
185 | | int streamLookChar(); |
186 | | int streamGetBlock(char *blk, int size); |
187 | | char *streamGetLine(char *buf, int size); |
188 | | GFileOffset streamGetPos(); |
189 | | void streamSetPos(GFileOffset pos, int dir = 0); |
190 | | Dict *streamGetDict(); |
191 | | |
192 | | // Output. |
193 | | const char *getTypeName(); |
194 | | void print(FILE *f = stdout); |
195 | | |
196 | | // Memory testing. |
197 | | static void memCheck(FILE *f); |
198 | | |
199 | | private: |
200 | | |
201 | | ObjType type; // object type |
202 | | union { // value for each type: |
203 | | GBool booln; // boolean |
204 | | int intg; // integer |
205 | | double real; // real |
206 | | GString *string; // string |
207 | | char *name; // name |
208 | | Array *array; // array |
209 | | Dict *dict; // dictionary |
210 | | Stream *stream; // stream |
211 | | Ref ref; // indirect reference |
212 | | char *cmd; // command |
213 | | }; |
214 | | |
215 | | #ifdef DEBUG_OBJECT_MEM |
216 | | #if MULTITHREADED |
217 | | static GAtomicCounter // number of each type of object |
218 | | numAlloc[numObjTypes]; // currently allocated |
219 | | #else |
220 | | static int // number of each type of object |
221 | | numAlloc[numObjTypes]; // currently allocated |
222 | | #endif |
223 | | #endif |
224 | | }; |
225 | | |
226 | | //------------------------------------------------------------------------ |
227 | | // Array accessors. |
228 | | //------------------------------------------------------------------------ |
229 | | |
230 | | #include "Array.h" |
231 | | |
232 | | inline int Object::arrayGetLength() |
233 | 9.26M | { return array->getLength(); } |
234 | | |
235 | | inline void Object::arrayAdd(Object *elem) |
236 | 23.8M | { array->add(elem); } |
237 | | |
238 | | inline Object *Object::arrayGet(int i, Object *obj, int recursion) |
239 | 719k | { return array->get(i, obj, recursion); } |
240 | | |
241 | | inline Object *Object::arrayGetNF(int i, Object *obj) |
242 | 8.21M | { return array->getNF(i, obj); } |
243 | | |
244 | | //------------------------------------------------------------------------ |
245 | | // Dict accessors. |
246 | | //------------------------------------------------------------------------ |
247 | | |
248 | | #include "Dict.h" |
249 | | |
250 | | inline int Object::dictGetLength() |
251 | 0 | { return dict->getLength(); } |
252 | | |
253 | | inline void Object::dictAdd(char *key, Object *val) |
254 | 3.51M | { dict->add(key, val); } |
255 | | |
256 | | inline GBool Object::dictIs(const char *dictType) |
257 | 0 | { return dict->is(dictType); } |
258 | | |
259 | | inline GBool Object::isDict(const char *dictType) |
260 | 0 | { return type == objDict && dictIs(dictType); } |
261 | | |
262 | | inline Object *Object::dictLookup(const char *key, Object *obj, int recursion) |
263 | 915k | { return dict->lookup(key, obj, recursion); } |
264 | | |
265 | | inline Object *Object::dictLookupNF(const char *key, Object *obj) |
266 | 5.48k | { return dict->lookupNF(key, obj); } |
267 | | |
268 | | inline char *Object::dictGetKey(int i) |
269 | 0 | { return dict->getKey(i); } |
270 | | |
271 | | inline Object *Object::dictGetVal(int i, Object *obj) |
272 | 0 | { return dict->getVal(i, obj); } |
273 | | |
274 | | inline Object *Object::dictGetValNF(int i, Object *obj) |
275 | 0 | { return dict->getValNF(i, obj); } |
276 | | |
277 | | //------------------------------------------------------------------------ |
278 | | // Stream accessors. |
279 | | //------------------------------------------------------------------------ |
280 | | |
281 | | #include "Stream.h" |
282 | | |
283 | | inline GBool Object::streamIs(char *dictType) |
284 | 0 | { return stream->getDict()->is(dictType); } |
285 | | |
286 | | inline GBool Object::isStream(char *dictType) |
287 | 0 | { return type == objStream && streamIs(dictType); } |
288 | | |
289 | | inline void Object::streamReset() |
290 | 378k | { stream->reset(); } |
291 | | |
292 | | inline void Object::streamClose() |
293 | 374k | { stream->close(); } |
294 | | |
295 | | inline int Object::streamGetChar() |
296 | 879M | { return stream->getChar(); } |
297 | | |
298 | | inline int Object::streamLookChar() |
299 | 303M | { return stream->lookChar(); } |
300 | | |
301 | | inline int Object::streamGetBlock(char *blk, int size) |
302 | 0 | { return stream->getBlock(blk, size); } |
303 | | |
304 | | inline char *Object::streamGetLine(char *buf, int size) |
305 | 0 | { return stream->getLine(buf, size); } |
306 | | |
307 | | inline GFileOffset Object::streamGetPos() |
308 | 49.7M | { return stream->getPos(); } |
309 | | |
310 | | inline void Object::streamSetPos(GFileOffset pos, int dir) |
311 | 123k | { stream->setPos(pos, dir); } |
312 | | |
313 | | inline Dict *Object::streamGetDict() |
314 | 397k | { return stream->getDict(); } |
315 | | |
316 | | #endif |