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, 2017, 2019 Albert Astals Cid <aacid@kde.org>
17// Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
18// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
19// Copyright (C) 2020 Jakub Alba <jakubalba@gmail.com>
20//
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
23//
24//========================================================================
25
26#include <config.h>
27
28#include <cstddef>
29#include "Object.h"
30#include "Array.h"
31#include "Dict.h"
32#include "Error.h"
33#include "Stream.h"
34#include "XRef.h"
35
36//------------------------------------------------------------------------
37// Object
38//------------------------------------------------------------------------
39
40static const char *objTypeNames[numObjTypes] = { "boolean", "integer", "real", "string", "name", "null", "array", "dictionary", "stream", "ref", "cmd", "error", "eof", "none", "integer64", "hexString", "dead" };
41
42Object Object::copy() const
43{
44 CHECK_NOT_DEAD;
45
46 Object obj;
47 std::memcpy(dest: reinterpret_cast<void *>(&obj), src: this, n: sizeof(Object));
48
49 switch (type) {
50 case objString:
51 case objHexString:
52 obj.string = string->copy();
53 break;
54 case objName:
55 case objCmd:
56 obj.cString = copyString(s: cString);
57 break;
58 case objArray:
59 array->incRef();
60 break;
61 case objDict:
62 dict->incRef();
63 break;
64 case objStream:
65 stream->incRef();
66 break;
67 default:
68 break;
69 }
70
71 return obj;
72}
73
74Object Object::deepCopy() const
75{
76 CHECK_NOT_DEAD;
77
78 Object obj;
79 std::memcpy(dest: reinterpret_cast<void *>(&obj), src: this, n: sizeof(Object));
80
81 switch (type) {
82 case objString:
83 case objHexString:
84 obj.string = string->copy();
85 break;
86 case objName:
87 case objCmd:
88 obj.cString = copyString(s: cString);
89 break;
90 case objArray:
91 obj.array = array->deepCopy();
92 break;
93 case objDict:
94 obj.dict = dict->deepCopy();
95 break;
96 case objStream:
97 stream->incRef();
98 break;
99 default:
100 break;
101 }
102
103 return obj;
104}
105
106Object Object::fetch(XRef *xref, int recursion) const
107{
108 CHECK_NOT_DEAD;
109
110 return (type == objRef && xref) ? xref->fetch(ref: ref, recursion) : copy();
111}
112
113void Object::free()
114{
115 switch (type) {
116 case objString:
117 case objHexString:
118
119 delete string;
120 break;
121 case objName:
122 case objCmd:
123 gfree(p: cString);
124 break;
125 case objArray:
126 if (!array->decRef()) {
127 delete array;
128 }
129 break;
130 case objDict:
131 if (!dict->decRef()) {
132 delete dict;
133 }
134 break;
135 case objStream:
136 if (!stream->decRef()) {
137 delete stream;
138 }
139 break;
140 default:
141 break;
142 }
143 type = objNone;
144}
145
146const char *Object::getTypeName() const
147{
148 return objTypeNames[type];
149}
150
151void Object::print(FILE *f) const
152{
153 int i;
154
155 switch (type) {
156 case objBool:
157 fprintf(stream: f, format: "%s", booln ? "true" : "false");
158 break;
159 case objInt:
160 fprintf(stream: f, format: "%d", intg);
161 break;
162 case objReal:
163 fprintf(stream: f, format: "%g", real);
164 break;
165 case objString:
166 fprintf(stream: f, format: "(");
167 fwrite(ptr: string->c_str(), size: 1, n: string->getLength(), s: f);
168 fprintf(stream: f, format: ")");
169 break;
170 case objHexString:
171 fprintf(stream: f, format: "<");
172 for (i = 0; i < string->getLength(); i++) {
173 fprintf(stream: f, format: "%02x", string->getChar(i) & 0xff);
174 }
175 fprintf(stream: f, format: ">");
176 break;
177 case objName:
178 fprintf(stream: f, format: "/%s", cString);
179 break;
180 case objNull:
181 fprintf(stream: f, format: "null");
182 break;
183 case objArray:
184 fprintf(stream: f, format: "[");
185 for (i = 0; i < arrayGetLength(); ++i) {
186 if (i > 0) {
187 fprintf(stream: f, format: " ");
188 }
189 const Object &obj = arrayGetNF(i);
190 obj.print(f);
191 }
192 fprintf(stream: f, format: "]");
193 break;
194 case objDict:
195 fprintf(stream: f, format: "<<");
196 for (i = 0; i < dictGetLength(); ++i) {
197 fprintf(stream: f, format: " /%s ", dictGetKey(i));
198 const Object &obj = dictGetValNF(i);
199 obj.print(f);
200 }
201 fprintf(stream: f, format: " >>");
202 break;
203 case objStream:
204 fprintf(stream: f, format: "<stream>");
205 break;
206 case objRef:
207 fprintf(stream: f, format: "%d %d R", ref.num, ref.gen);
208 break;
209 case objCmd:
210 fprintf(stream: f, format: "%s", cString);
211 break;
212 case objError:
213 fprintf(stream: f, format: "<error>");
214 break;
215 case objEOF:
216 fprintf(stream: f, format: "<EOF>");
217 break;
218 case objNone:
219 fprintf(stream: f, format: "<none>");
220 break;
221 case objDead:
222 fprintf(stream: f, format: "<dead>");
223 break;
224 case objInt64:
225 fprintf(stream: f, format: "%lld", int64g);
226 break;
227 }
228}
229

source code of poppler/poppler/Object.cc