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