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