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