beta-0.89.2
[luatex.git] / source / libs / poppler / poppler-src / poppler / Object.h
blob2a3766288a677458cfa751f46d1a151e1b620300
1 //========================================================================
2 //
3 // Object.h
4 //
5 // Copyright 1996-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
9 //========================================================================
11 // Modified under the Poppler project - http://poppler.freedesktop.org
13 // All changes made under the Poppler project to this file are licensed
14 // under GPL version 2 or later
16 // Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
17 // Copyright (C) 2008 Kees Cook <kees@outflux.net>
18 // Copyright (C) 2008, 2010 Albert Astals Cid <aacid@kde.org>
19 // Copyright (C) 2009 Jakub Wilk <jwilk@jwilk.net>
20 // Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
21 // Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
22 // Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
23 // Copyright (C) 2013 Adrian Perez de Castro <aperez@igalia.com>
25 // To see a description of the changes please see the Changelog file that
26 // came with your tarball or type make ChangeLog if you are building from git
28 //========================================================================
30 #ifndef OBJECT_H
31 #define OBJECT_H
33 #ifdef USE_GCC_PRAGMAS
34 #pragma interface
35 #endif
37 #include <set>
38 #include <stdio.h>
39 #include <string.h>
40 #include "goo/gtypes.h"
41 #include "goo/gmem.h"
42 #include "goo/GooString.h"
43 #include "goo/GooLikely.h"
44 #include "Error.h"
46 #define OBJECT_TYPE_CHECK(wanted_type) \
47 if (unlikely(type != wanted_type)) { \
48 error(errInternal, 0, "Call to Object where the object was type {0:d}, " \
49 "not the expected type {1:d}", type, wanted_type); \
50 abort(); \
53 #define OBJECT_3TYPES_CHECK(wanted_type1, wanted_type2, wanted_type3) \
54 if (unlikely(type != wanted_type1) && unlikely(type != wanted_type2) && unlikely(type != wanted_type3)) { \
55 error(errInternal, 0, "Call to Object where the object was type {0:d}, " \
56 "not the expected type {1:d}, {2:d} or {3:d}", type, wanted_type1, wanted_type2, wanted_type3); \
57 abort(); \
60 class XRef;
61 class Array;
62 class Dict;
63 class Stream;
65 //------------------------------------------------------------------------
66 // Ref
67 //------------------------------------------------------------------------
69 struct Ref {
70 int num; // object number
71 int gen; // generation number
74 //------------------------------------------------------------------------
75 // object types
76 //------------------------------------------------------------------------
78 enum ObjType {
79 // simple objects
80 objBool, // boolean
81 objInt, // integer
82 objReal, // real
83 objString, // string
84 objName, // name
85 objNull, // null
87 // complex objects
88 objArray, // array
89 objDict, // dictionary
90 objStream, // stream
91 objRef, // indirect reference
93 // special objects
94 objCmd, // command name
95 objError, // error return from Lexer
96 objEOF, // end of file return from Lexer
97 objNone, // uninitialized object
99 // poppler-only objects
100 objInt64 // integer with at least 64-bits
103 #define numObjTypes 15 // total number of object types
105 //------------------------------------------------------------------------
106 // Object
107 //------------------------------------------------------------------------
109 #ifdef DEBUG_MEM
110 #define initObj(t) zeroUnion(); ++numAlloc[type = t]
111 #else
112 #define initObj(t) zeroUnion(); type = t
113 #endif
115 class Object {
116 public:
117 // clear the anonymous union as best we can -- clear at least a pointer
118 void zeroUnion() { this->name = NULL; }
120 // Default constructor.
121 Object():
122 type(objNone) { zeroUnion(); }
124 // Initialize an object.
125 Object *initBool(GBool boolnA)
126 { initObj(objBool); booln = boolnA; return this; }
127 Object *initInt(int intgA)
128 { initObj(objInt); intg = intgA; return this; }
129 Object *initReal(double realA)
130 { initObj(objReal); real = realA; return this; }
131 Object *initString(GooString *stringA)
132 { initObj(objString); string = stringA; return this; }
133 Object *initName(const char *nameA)
134 { initObj(objName); name = copyString(nameA); return this; }
135 Object *initNull()
136 { initObj(objNull); return this; }
137 Object *initArray(XRef *xref);
138 Object *initDict(XRef *xref);
139 Object *initDict(Dict *dictA);
140 Object *initStream(Stream *streamA);
141 Object *initRef(int numA, int genA)
142 { initObj(objRef); ref.num = numA; ref.gen = genA; return this; }
143 Object *initCmd(const char *cmdA)
144 { initObj(objCmd); cmd = copyString(cmdA); return this; }
145 Object *initError()
146 { initObj(objError); return this; }
147 Object *initEOF()
148 { initObj(objEOF); return this; }
149 Object *initInt64(long long int64gA)
150 { initObj(objInt64); int64g = int64gA; return this; }
152 // Copy an object.
153 Object *copy(Object *obj);
154 Object *shallowCopy(Object *obj) {
155 *obj = *this;
156 return obj;
159 // If object is a Ref, fetch and return the referenced object.
160 // Otherwise, return a copy of the object.
161 Object *fetch(XRef *xref, Object *obj, int recursion = 0);
163 // Free object contents.
164 void free();
166 // Type checking.
167 ObjType getType() { return type; }
168 GBool isBool() { return type == objBool; }
169 GBool isInt() { return type == objInt; }
170 GBool isReal() { return type == objReal; }
171 GBool isNum() { return type == objInt || type == objReal || type == objInt64; }
172 GBool isString() { return type == objString; }
173 GBool isName() { return type == objName; }
174 GBool isNull() { return type == objNull; }
175 GBool isArray() { return type == objArray; }
176 GBool isDict() { return type == objDict; }
177 GBool isStream() { return type == objStream; }
178 GBool isRef() { return type == objRef; }
179 GBool isCmd() { return type == objCmd; }
180 GBool isError() { return type == objError; }
181 GBool isEOF() { return type == objEOF; }
182 GBool isNone() { return type == objNone; }
183 GBool isInt64() { return type == objInt64; }
185 // Special type checking.
186 GBool isName(const char *nameA)
187 { return type == objName && !strcmp(name, nameA); }
188 GBool isDict(const char *dictType);
189 GBool isStream(const char *dictType);
190 GBool isCmd(const char *cmdA)
191 { return type == objCmd && !strcmp(cmd, cmdA); }
193 // Accessors.
194 GBool getBool() { OBJECT_TYPE_CHECK(objBool); return booln; }
195 int getInt() { OBJECT_TYPE_CHECK(objInt); return intg; }
196 double getReal() { OBJECT_TYPE_CHECK(objReal); return real; }
198 // Note: integers larger than 2^53 can not be exactly represented by a double.
199 // Where the exact value of integers up to 2^63 is required, use isInt64()/getInt64().
200 double getNum() { OBJECT_3TYPES_CHECK(objInt, objInt64, objReal);
201 return type == objInt ? (double)intg : type == objInt64 ? (double)int64g : real; }
202 GooString *getString() { OBJECT_TYPE_CHECK(objString); return string; }
203 // After takeString() the only method that should be called for the object is free()
204 // because the object it's not expected to have a NULL string.
205 GooString *takeString() {
206 OBJECT_TYPE_CHECK(objString); GooString *s = string; string = NULL; return s; }
207 char *getName() { OBJECT_TYPE_CHECK(objName); return name; }
208 Array *getArray() { OBJECT_TYPE_CHECK(objArray); return array; }
209 Dict *getDict() { OBJECT_TYPE_CHECK(objDict); return dict; }
210 Stream *getStream() { OBJECT_TYPE_CHECK(objStream); return stream; }
211 Ref getRef() { OBJECT_TYPE_CHECK(objRef); return ref; }
212 int getRefNum() { OBJECT_TYPE_CHECK(objRef); return ref.num; }
213 int getRefGen() { OBJECT_TYPE_CHECK(objRef); return ref.gen; }
214 char *getCmd() { OBJECT_TYPE_CHECK(objCmd); return cmd; }
215 long long getInt64() { OBJECT_TYPE_CHECK(objInt64); return int64g; }
217 // Array accessors.
218 int arrayGetLength();
219 void arrayAdd(Object *elem);
220 void arrayRemove(int i);
221 Object *arrayGet(int i, Object *obj, int recursion);
222 Object *arrayGetNF(int i, Object *obj);
224 // Dict accessors.
225 int dictGetLength();
226 void dictAdd(char *key, Object *val);
227 void dictSet(const char *key, Object *val);
228 GBool dictIs(const char *dictType);
229 Object *dictLookup(const char *key, Object *obj, int recursion = 0);
230 Object *dictLookupNF(const char *key, Object *obj);
231 char *dictGetKey(int i);
232 Object *dictGetVal(int i, Object *obj);
233 Object *dictGetValNF(int i, Object *obj);
235 // Stream accessors.
236 GBool streamIs(const char *dictType);
237 void streamReset();
238 void streamClose();
239 int streamGetChar();
240 int streamGetChars(int nChars, Guchar *buffer);
241 int streamLookChar();
242 char *streamGetLine(char *buf, int size);
243 Goffset streamGetPos();
244 void streamSetPos(Goffset pos, int dir = 0);
245 Dict *streamGetDict();
247 // Output.
248 const char *getTypeName();
249 void print(FILE *f = stdout);
251 // Memory testing.
252 static void memCheck(FILE *f);
254 private:
256 ObjType type; // object type
257 union { // value for each type:
258 GBool booln; // boolean
259 int intg; // integer
260 long long int64g; // 64-bit integer
261 double real; // real
262 GooString *string; // string
263 char *name; // name
264 Array *array; // array
265 Dict *dict; // dictionary
266 Stream *stream; // stream
267 Ref ref; // indirect reference
268 char *cmd; // command
271 #ifdef DEBUG_MEM
272 static int // number of each type of object
273 numAlloc[numObjTypes]; // currently allocated
274 #endif
277 //------------------------------------------------------------------------
278 // Array accessors.
279 //------------------------------------------------------------------------
281 #include "Array.h"
283 inline int Object::arrayGetLength()
284 { OBJECT_TYPE_CHECK(objArray); return array->getLength(); }
286 inline void Object::arrayAdd(Object *elem)
287 { OBJECT_TYPE_CHECK(objArray); array->add(elem); }
289 inline void Object::arrayRemove(int i)
290 { OBJECT_TYPE_CHECK(objArray); array->remove(i); }
292 inline Object *Object::arrayGet(int i, Object *obj, int recursion = 0)
293 { OBJECT_TYPE_CHECK(objArray); return array->get(i, obj, recursion); }
295 inline Object *Object::arrayGetNF(int i, Object *obj)
296 { OBJECT_TYPE_CHECK(objArray); return array->getNF(i, obj); }
298 //------------------------------------------------------------------------
299 // Dict accessors.
300 //------------------------------------------------------------------------
302 #include "Dict.h"
304 inline int Object::dictGetLength()
305 { OBJECT_TYPE_CHECK(objDict); return dict->getLength(); }
307 inline void Object::dictAdd(char *key, Object *val)
308 { OBJECT_TYPE_CHECK(objDict); dict->add(key, val); }
310 inline void Object::dictSet(const char *key, Object *val)
311 { OBJECT_TYPE_CHECK(objDict); dict->set(key, val); }
313 inline GBool Object::dictIs(const char *dictType)
314 { OBJECT_TYPE_CHECK(objDict); return dict->is(dictType); }
316 inline GBool Object::isDict(const char *dictType)
317 { return type == objDict && dictIs(dictType); }
319 inline Object *Object::dictLookup(const char *key, Object *obj, int recursion)
320 { OBJECT_TYPE_CHECK(objDict); return dict->lookup(key, obj, recursion); }
322 inline Object *Object::dictLookupNF(const char *key, Object *obj)
323 { OBJECT_TYPE_CHECK(objDict); return dict->lookupNF(key, obj); }
325 inline char *Object::dictGetKey(int i)
326 { OBJECT_TYPE_CHECK(objDict); return dict->getKey(i); }
328 inline Object *Object::dictGetVal(int i, Object *obj)
329 { OBJECT_TYPE_CHECK(objDict); return dict->getVal(i, obj); }
331 inline Object *Object::dictGetValNF(int i, Object *obj)
332 { OBJECT_TYPE_CHECK(objDict); return dict->getValNF(i, obj); }
334 //------------------------------------------------------------------------
335 // Stream accessors.
336 //------------------------------------------------------------------------
338 #include "Stream.h"
340 inline GBool Object::streamIs(const char *dictType)
341 { OBJECT_TYPE_CHECK(objStream); return stream->getDict()->is(dictType); }
343 inline GBool Object::isStream(const char *dictType)
344 { return type == objStream && streamIs(dictType); }
346 inline void Object::streamReset()
347 { OBJECT_TYPE_CHECK(objStream); stream->reset(); }
349 inline void Object::streamClose()
350 { OBJECT_TYPE_CHECK(objStream); stream->close(); }
352 inline int Object::streamGetChar()
353 { OBJECT_TYPE_CHECK(objStream); return stream->getChar(); }
355 inline int Object::streamGetChars(int nChars, Guchar *buffer)
356 { OBJECT_TYPE_CHECK(objStream); return stream->doGetChars(nChars, buffer); }
358 inline int Object::streamLookChar()
359 { OBJECT_TYPE_CHECK(objStream); return stream->lookChar(); }
361 inline char *Object::streamGetLine(char *buf, int size)
362 { OBJECT_TYPE_CHECK(objStream); return stream->getLine(buf, size); }
364 inline Goffset Object::streamGetPos()
365 { OBJECT_TYPE_CHECK(objStream); return stream->getPos(); }
367 inline void Object::streamSetPos(Goffset pos, int dir)
368 { OBJECT_TYPE_CHECK(objStream); stream->setPos(pos, dir); }
370 inline Dict *Object::streamGetDict()
371 { OBJECT_TYPE_CHECK(objStream); return stream->getDict(); }
373 #endif