1
//========================================================================
5
// Copyright 1996-2003 Glyph & Cog, LLC
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 <ubanus@users.sf.net>
21
// To see a description of the changes please see the Changelog file that
22
// came with your tarball or type make ChangeLog if you are building from git
24
//========================================================================
29
#ifdef USE_GCC_PRAGMAS
36
#include "goo/gtypes.h"
38
#include "goo/GooString.h"
39
#include "goo/GooLikely.h"
42
#define OBJECT_TYPE_CHECK(wanted_type) \
43
if (unlikely(type != wanted_type)) { \
44
error(0, (char *) "Call to Object where the object was type %d, " \
45
"not the expected type %d", type, wanted_type); \
49
#define OBJECT_2TYPES_CHECK(wanted_type1, wanted_type2) \
50
if (unlikely(type != wanted_type1) && unlikely(type != wanted_type2)) { \
51
error(0, (char *) "Call to Object where the object was type %d, " \
52
"not the expected type %d or %d", type, wanted_type1, wanted_type2); \
61
//------------------------------------------------------------------------
63
//------------------------------------------------------------------------
66
int num; // object number
67
int gen; // generation number
70
//------------------------------------------------------------------------
72
//------------------------------------------------------------------------
85
objDict, // dictionary
87
objRef, // indirect reference
90
objCmd, // command name
91
objError, // error return from Lexer
92
objEOF, // end of file return from Lexer
93
objNone, // uninitialized object
95
// poppler-only objects
96
objUint // overflown integer that still fits in a unsigned integer
99
#define numObjTypes 15 // total number of object types
101
//------------------------------------------------------------------------
103
//------------------------------------------------------------------------
106
#define initObj(t) zeroUnion(); ++numAlloc[type = t]
108
#define initObj(t) zeroUnion(); type = t
113
// clear the anonymous union as best we can -- clear at least a pointer
114
// XXX Emscripten: Also null out ref.gen
115
void zeroUnion() { this->name = NULL; this->ref.gen = 0; }
117
// Default constructor.
119
type(objNone) { zeroUnion(); }
121
// Initialize an object.
122
Object *initBool(GBool boolnA)
123
{ initObj(objBool); booln = boolnA; return this; }
124
Object *initInt(int intgA)
125
{ initObj(objInt); intg = intgA; return this; }
126
Object *initReal(double realA)
127
{ initObj(objReal); real = realA; return this; }
128
Object *initString(GooString *stringA)
129
{ initObj(objString); string = stringA; return this; }
130
Object *initName(char *nameA)
131
{ initObj(objName); name = copyString(nameA); return this; }
133
{ initObj(objNull); return this; }
134
Object *initArray(XRef *xref);
135
Object *initDict(XRef *xref);
136
Object *initDict(Dict *dictA);
137
Object *initStream(Stream *streamA);
138
Object *initRef(int numA, int genA)
139
{ initObj(objRef); ref.num = numA; ref.gen = genA; return this; }
140
Object *initCmd(char *cmdA)
141
{ initObj(objCmd); cmd = copyString(cmdA); return this; }
143
{ initObj(objError); return this; }
145
{ initObj(objEOF); return this; }
146
Object *initUint(unsigned int uintgA)
147
{ initObj(objUint); uintg = uintgA; return this; }
150
Object *copy(Object *obj);
151
Object *shallowCopy(Object *obj) {
156
// If object is a Ref, fetch and return the referenced object.
157
// Otherwise, return a copy of the object.
158
Object *fetch(XRef *xref, Object *obj, std::set<int> *fetchOriginatorNums = NULL);
160
// Free object contents.
164
ObjType getType() { return type; }
165
GBool isBool() { return type == objBool; }
166
GBool isInt() { return type == objInt; }
167
GBool isReal() { return type == objReal; }
168
GBool isNum() { return type == objInt || type == objReal; }
169
GBool isString() { return type == objString; }
170
GBool isName() { return type == objName; }
171
GBool isNull() { return type == objNull; }
172
GBool isArray() { return type == objArray; }
173
GBool isDict() { return type == objDict; }
174
GBool isStream() { return type == objStream; }
175
GBool isRef() { return type == objRef; }
176
GBool isCmd() { return type == objCmd; }
177
GBool isError() { return type == objError; }
178
GBool isEOF() { return type == objEOF; }
179
GBool isNone() { return type == objNone; }
180
GBool isUint() { return type == objUint; }
182
// Special type checking.
183
GBool isName(char *nameA)
184
{ return type == objName && !strcmp(name, nameA); }
185
GBool isDict(char *dictType);
186
GBool isStream(char *dictType);
187
GBool isCmd(char *cmdA)
188
{ return type == objCmd && !strcmp(cmd, cmdA); }
191
GBool getBool() { OBJECT_TYPE_CHECK(objBool); return booln; }
192
int getInt() { OBJECT_TYPE_CHECK(objInt); return intg; }
193
double getReal() { OBJECT_TYPE_CHECK(objReal); return real; }
194
double getNum() { OBJECT_2TYPES_CHECK(objInt, objReal); return type == objInt ? (double)intg : real; }
195
GooString *getString() { OBJECT_TYPE_CHECK(objString); return string; }
196
char *getName() { OBJECT_TYPE_CHECK(objName); return name; }
197
Array *getArray() { OBJECT_TYPE_CHECK(objArray); return array; }
198
Dict *getDict() { OBJECT_TYPE_CHECK(objDict); return dict; }
199
Stream *getStream() { OBJECT_TYPE_CHECK(objStream); return stream; }
200
Ref getRef() { OBJECT_TYPE_CHECK(objRef); return ref; }
201
int getRefNum() { OBJECT_TYPE_CHECK(objRef); return ref.num; }
202
int getRefGen() { OBJECT_TYPE_CHECK(objRef); return ref.gen; }
203
char *getCmd() { OBJECT_TYPE_CHECK(objCmd); return cmd; }
204
unsigned int getUint() { OBJECT_TYPE_CHECK(objUint); return uintg; }
207
int arrayGetLength();
208
void arrayAdd(Object *elem);
209
Object *arrayGet(int i, Object *obj);
210
Object *arrayGetNF(int i, Object *obj);
214
void dictAdd(char *key, Object *val);
215
void dictSet(char *key, Object *val);
216
GBool dictIs(char *dictType);
217
Object *dictLookup(char *key, Object *obj, std::set<int> *fetchOriginatorNums = NULL);
218
Object *dictLookupNF(char *key, Object *obj);
219
char *dictGetKey(int i);
220
Object *dictGetVal(int i, Object *obj);
221
Object *dictGetValNF(int i, Object *obj);
224
GBool streamIs(char *dictType);
228
int streamGetChars(int nChars, Guchar *buffer);
229
int streamLookChar();
230
char *streamGetLine(char *buf, int size);
231
Guint streamGetPos();
232
void streamSetPos(Guint pos, int dir = 0);
233
Dict *streamGetDict();
237
void print(FILE *f = stdout);
240
static void memCheck(FILE *f);
244
ObjType type; // object type
245
union { // value for each type:
246
GBool booln; // boolean
248
unsigned int uintg; // unsigned integer
250
GooString *string; // string
252
Array *array; // array
253
Dict *dict; // dictionary
254
Stream *stream; // stream
255
Ref ref; // indirect reference
256
char *cmd; // command
260
static int // number of each type of object
261
numAlloc[numObjTypes]; // currently allocated
265
//------------------------------------------------------------------------
267
//------------------------------------------------------------------------
271
inline int Object::arrayGetLength()
272
{ OBJECT_TYPE_CHECK(objArray); return array->getLength(); }
274
inline void Object::arrayAdd(Object *elem)
275
{ OBJECT_TYPE_CHECK(objArray); array->add(elem); }
277
inline Object *Object::arrayGet(int i, Object *obj)
278
{ OBJECT_TYPE_CHECK(objArray); return array->get(i, obj); }
280
inline Object *Object::arrayGetNF(int i, Object *obj)
281
{ OBJECT_TYPE_CHECK(objArray); return array->getNF(i, obj); }
283
//------------------------------------------------------------------------
285
//------------------------------------------------------------------------
289
inline int Object::dictGetLength()
290
{ OBJECT_TYPE_CHECK(objDict); return dict->getLength(); }
292
inline void Object::dictAdd(char *key, Object *val)
293
{ OBJECT_TYPE_CHECK(objDict); dict->add(key, val); }
295
inline void Object::dictSet(char *key, Object *val)
296
{ OBJECT_TYPE_CHECK(objDict); dict->set(key, val); }
298
inline GBool Object::dictIs(char *dictType)
299
{ OBJECT_TYPE_CHECK(objDict); return dict->is(dictType); }
301
inline GBool Object::isDict(char *dictType)
302
{ return type == objDict && dictIs(dictType); }
304
inline Object *Object::dictLookup(char *key, Object *obj, std::set<int> *fetchOriginatorNums)
305
{ OBJECT_TYPE_CHECK(objDict); return dict->lookup(key, obj, fetchOriginatorNums); }
307
inline Object *Object::dictLookupNF(char *key, Object *obj)
308
{ OBJECT_TYPE_CHECK(objDict); return dict->lookupNF(key, obj); }
310
inline char *Object::dictGetKey(int i)
311
{ OBJECT_TYPE_CHECK(objDict); return dict->getKey(i); }
313
inline Object *Object::dictGetVal(int i, Object *obj)
314
{ OBJECT_TYPE_CHECK(objDict); return dict->getVal(i, obj); }
316
inline Object *Object::dictGetValNF(int i, Object *obj)
317
{ OBJECT_TYPE_CHECK(objDict); return dict->getValNF(i, obj); }
319
//------------------------------------------------------------------------
321
//------------------------------------------------------------------------
325
inline GBool Object::streamIs(char *dictType)
326
{ OBJECT_TYPE_CHECK(objStream); return stream->getDict()->is(dictType); }
328
inline GBool Object::isStream(char *dictType)
329
{ return type == objStream && streamIs(dictType); }
331
inline void Object::streamReset()
332
{ OBJECT_TYPE_CHECK(objStream); stream->reset(); }
334
inline void Object::streamClose()
335
{ OBJECT_TYPE_CHECK(objStream); stream->close(); }
337
inline int Object::streamGetChar()
338
{ OBJECT_TYPE_CHECK(objStream); return stream->getChar(); }
340
inline int Object::streamGetChars(int nChars, Guchar *buffer)
341
{ OBJECT_TYPE_CHECK(objStream); return stream->doGetChars(nChars, buffer); }
343
inline int Object::streamLookChar()
344
{ OBJECT_TYPE_CHECK(objStream); return stream->lookChar(); }
346
inline char *Object::streamGetLine(char *buf, int size)
347
{ OBJECT_TYPE_CHECK(objStream); return stream->getLine(buf, size); }
349
inline Guint Object::streamGetPos()
350
{ OBJECT_TYPE_CHECK(objStream); return stream->getPos(); }
352
inline void Object::streamSetPos(Guint pos, int dir)
353
{ OBJECT_TYPE_CHECK(objStream); stream->setPos(pos, dir); }
355
inline Dict *Object::streamGetDict()
356
{ OBJECT_TYPE_CHECK(objStream); return stream->getDict(); }