1 //========================================================================
2 //
3 // Object.cc
4 //
5 // Copyright 1996-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8 
9 //========================================================================
10 //
11 // Modified under the Poppler project - http://poppler.freedesktop.org
12 //
13 // All changes made under the Poppler project to this file are licensed
14 // under GPL version 2 or later
15 //
16 // Copyright (C) 2008, 2010, 2012 Albert Astals Cid <aacid@kde.org>
17 // Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
18 //
19 // To see a description of the changes please see the Changelog file that
20 // came with your tarball or type make ChangeLog if you are building from git
21 //
22 //========================================================================
23 
24 #include <config.h>
25 
26 #ifdef USE_GCC_PRAGMAS
27 #pragma implementation
28 #endif
29 
30 #include <stddef.h>
31 #include "Object.h"
32 #include "Array.h"
33 #include "Dict.h"
34 #include "Error.h"
35 #include "Stream.h"
36 #include "XRef.h"
37 
38 //------------------------------------------------------------------------
39 // Object
40 //------------------------------------------------------------------------
41 
42 static const char *objTypeNames[numObjTypes] = {
43   "boolean",
44   "integer",
45   "real",
46   "string",
47   "name",
48   "null",
49   "array",
50   "dictionary",
51   "stream",
52   "ref",
53   "cmd",
54   "error",
55   "eof",
56   "none",
57   "integer64"
58 };
59 
60 #ifdef DEBUG_MEM
61 int Object::numAlloc[numObjTypes] =
62   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
63 #endif
64 
initArray(XRef * xref)65 Object *Object::initArray(XRef *xref) {
66   initObj(objArray);
67   array = new Array(xref);
68   return this;
69 }
70 
initDict(XRef * xref)71 Object *Object::initDict(XRef *xref) {
72   initObj(objDict);
73   dict = new Dict(xref);
74   return this;
75 }
76 
initDict(Dict * dictA)77 Object *Object::initDict(Dict *dictA) {
78   initObj(objDict);
79   dict = dictA;
80   dict->incRef();
81   return this;
82 }
83 
initStream(Stream * streamA)84 Object *Object::initStream(Stream *streamA) {
85   initObj(objStream);
86   stream = streamA;
87   return this;
88 }
89 
copy(Object * obj)90 Object *Object::copy(Object *obj) {
91   *obj = *this;
92   switch (type) {
93   case objString:
94     obj->string = string->copy();
95     break;
96   case objName:
97     obj->name = copyString(name);
98     break;
99   case objArray:
100     array->incRef();
101     break;
102   case objDict:
103     dict->incRef();
104     break;
105   case objStream:
106     stream->incRef();
107     break;
108   case objCmd:
109     obj->cmd = copyString(cmd);
110     break;
111   default:
112     break;
113   }
114 #ifdef DEBUG_MEM
115   ++numAlloc[type];
116 #endif
117   return obj;
118 }
119 
fetch(XRef * xref,Object * obj,int recursion)120 Object *Object::fetch(XRef *xref, Object *obj, int recursion) {
121   return (type == objRef && xref) ?
122          xref->fetch(ref.num, ref.gen, obj, recursion) : copy(obj);
123 }
124 
free()125 void Object::free() {
126   switch (type) {
127   case objString:
128     delete string;
129     break;
130   case objName:
131     gfree(name);
132     break;
133   case objArray:
134     if (!array->decRef()) {
135       delete array;
136     }
137     break;
138   case objDict:
139     if (!dict->decRef()) {
140       delete dict;
141     }
142     break;
143   case objStream:
144     if (!stream->decRef()) {
145       delete stream;
146     }
147     break;
148   case objCmd:
149     gfree(cmd);
150     break;
151   default:
152     break;
153   }
154 #ifdef DEBUG_MEM
155   --numAlloc[type];
156 #endif
157   type = objNone;
158 }
159 
getTypeName()160 const char *Object::getTypeName() {
161   return objTypeNames[type];
162 }
163 
print(FILE * f)164 void Object::print(FILE *f) {
165   Object obj;
166   int i;
167 
168   switch (type) {
169   case objBool:
170     fprintf(f, "%s", booln ? "true" : "false");
171     break;
172   case objInt:
173     fprintf(f, "%d", intg);
174     break;
175   case objReal:
176     fprintf(f, "%g", real);
177     break;
178   case objString:
179     fprintf(f, "(");
180     fwrite(string->getCString(), 1, string->getLength(), f);
181     fprintf(f, ")");
182     break;
183   case objName:
184     fprintf(f, "/%s", name);
185     break;
186   case objNull:
187     fprintf(f, "null");
188     break;
189   case objArray:
190     fprintf(f, "[");
191     for (i = 0; i < arrayGetLength(); ++i) {
192       if (i > 0)
193 	fprintf(f, " ");
194       arrayGetNF(i, &obj);
195       obj.print(f);
196       obj.free();
197     }
198     fprintf(f, "]");
199     break;
200   case objDict:
201     fprintf(f, "<<");
202     for (i = 0; i < dictGetLength(); ++i) {
203       fprintf(f, " /%s ", dictGetKey(i));
204       dictGetValNF(i, &obj);
205       obj.print(f);
206       obj.free();
207     }
208     fprintf(f, " >>");
209     break;
210   case objStream:
211     fprintf(f, "<stream>");
212     break;
213   case objRef:
214     fprintf(f, "%d %d R", ref.num, ref.gen);
215     break;
216   case objCmd:
217     fprintf(f, "%s", cmd);
218     break;
219   case objError:
220     fprintf(f, "<error>");
221     break;
222   case objEOF:
223     fprintf(f, "<EOF>");
224     break;
225   case objNone:
226     fprintf(f, "<none>");
227     break;
228   case objInt64:
229     fprintf(f, "%lld", int64g);
230     break;
231   }
232 }
233 
memCheck(FILE * f)234 void Object::memCheck(FILE *f) {
235 #ifdef DEBUG_MEM
236   int i;
237   int t;
238 
239   t = 0;
240   for (i = 0; i < numObjTypes; ++i)
241     t += numAlloc[i];
242   if (t > 0) {
243     fprintf(f, "Allocated objects:\n");
244     for (i = 0; i < numObjTypes; ++i) {
245       if (numAlloc[i] > 0)
246 	fprintf(f, "  %-20s: %6d\n", objTypeNames[i], numAlloc[i]);
247     }
248   }
249 #else
250   (void)f;
251 #endif
252 }
253