/src/poppler/poppler/Object.cc
Line | Count | Source (jump to first uncovered line) |
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, 2024 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 | | |
40 | | static const char *objTypeNames[numObjTypes] = { "boolean", "integer", "real", "string", "name", "null", "array", "dictionary", "stream", "ref", "cmd", "error", "eof", "none", "integer64", "hexString", "dead" }; |
41 | | |
42 | | Object Object::copy() const |
43 | 388M | { |
44 | 388M | CHECK_NOT_DEAD; |
45 | | |
46 | 388M | Object obj; |
47 | 388M | std::memcpy(reinterpret_cast<void *>(&obj), this, sizeof(Object)); // NOLINT(bugprone-undefined-memory-manipulation) |
48 | | |
49 | 388M | switch (type) { |
50 | 27.5M | case objString: |
51 | 27.5M | case objHexString: |
52 | 27.5M | obj.string = new GooString(string); |
53 | 27.5M | break; |
54 | 34.6M | case objName: |
55 | 40.5M | case objCmd: |
56 | 40.5M | obj.cString = copyString(cString); |
57 | 40.5M | break; |
58 | 19.3M | case objArray: |
59 | 19.3M | array->incRef(); |
60 | 19.3M | break; |
61 | 8.66M | case objDict: |
62 | 8.66M | dict->incRef(); |
63 | 8.66M | break; |
64 | 20.5M | case objStream: |
65 | 20.5M | stream->incRef(); |
66 | 20.5M | break; |
67 | 271M | default: |
68 | 271M | break; |
69 | 388M | } |
70 | | |
71 | 388M | return obj; |
72 | 388M | } |
73 | | |
74 | | Object Object::deepCopy() const |
75 | 1.16M | { |
76 | 1.16M | CHECK_NOT_DEAD; |
77 | | |
78 | 1.16M | Object obj; |
79 | 1.16M | std::memcpy(reinterpret_cast<void *>(&obj), this, sizeof(Object)); // NOLINT(bugprone-undefined-memory-manipulation) |
80 | | |
81 | 1.16M | switch (type) { |
82 | 18.8k | case objString: |
83 | 18.8k | case objHexString: |
84 | 18.8k | obj.string = new GooString(string); |
85 | 18.8k | break; |
86 | 87.3k | case objName: |
87 | 141k | case objCmd: |
88 | 141k | obj.cString = copyString(cString); |
89 | 141k | break; |
90 | 21.4k | case objArray: |
91 | 21.4k | obj.array = array->deepCopy(); |
92 | 21.4k | break; |
93 | 90.5k | case objDict: |
94 | 90.5k | obj.dict = dict->deepCopy(); |
95 | 90.5k | break; |
96 | 4.81k | case objStream: |
97 | 4.81k | stream->incRef(); |
98 | 4.81k | break; |
99 | 883k | default: |
100 | 883k | break; |
101 | 1.16M | } |
102 | | |
103 | 1.16M | return obj; |
104 | 1.16M | } |
105 | | |
106 | | Object Object::fetch(XRef *xref, int recursion) const |
107 | 314M | { |
108 | 314M | CHECK_NOT_DEAD; |
109 | | |
110 | 314M | return (type == objRef && xref) ? xref->fetch(ref, recursion) : copy(); |
111 | 314M | } |
112 | | |
113 | | void Object::free() |
114 | 18.8G | { |
115 | 18.8G | switch (type) { |
116 | 77.1M | case objString: |
117 | 77.1M | case objHexString: |
118 | | |
119 | 77.1M | delete string; |
120 | 77.1M | break; |
121 | 350M | case objName: |
122 | 775M | case objCmd: |
123 | 775M | gfree(cString); |
124 | 775M | break; |
125 | 56.8M | case objArray: |
126 | 56.8M | if (!array->decRef()) { |
127 | 37.4M | delete array; |
128 | 37.4M | } |
129 | 56.8M | break; |
130 | 33.5M | case objDict: |
131 | 33.5M | if (!dict->decRef()) { |
132 | 24.8M | delete dict; |
133 | 24.8M | } |
134 | 33.5M | break; |
135 | 43.3M | case objStream: |
136 | 43.3M | if (!stream->decRef()) { |
137 | 22.8M | delete stream; |
138 | 22.8M | } |
139 | 43.3M | break; |
140 | 17.9G | default: |
141 | 17.9G | break; |
142 | 18.8G | } |
143 | 18.8G | type = objNone; |
144 | 18.8G | } |
145 | | |
146 | | const char *Object::getTypeName() const |
147 | 1.19M | { |
148 | 1.19M | return objTypeNames[type]; |
149 | 1.19M | } |
150 | | |
151 | | void Object::print(FILE *f) const |
152 | 0 | { |
153 | 0 | int i; |
154 | |
|
155 | 0 | switch (type) { |
156 | 0 | case objBool: |
157 | 0 | fprintf(f, "%s", booln ? "true" : "false"); |
158 | 0 | break; |
159 | 0 | case objInt: |
160 | 0 | fprintf(f, "%d", intg); |
161 | 0 | break; |
162 | 0 | case objReal: |
163 | 0 | fprintf(f, "%g", real); |
164 | 0 | break; |
165 | 0 | case objString: |
166 | 0 | fprintf(f, "("); |
167 | 0 | fwrite(string->c_str(), 1, string->getLength(), f); |
168 | 0 | fprintf(f, ")"); |
169 | 0 | break; |
170 | 0 | case objHexString: |
171 | 0 | fprintf(f, "<"); |
172 | 0 | for (i = 0; i < string->getLength(); i++) { |
173 | 0 | fprintf(f, "%02x", string->getChar(i) & 0xff); |
174 | 0 | } |
175 | 0 | fprintf(f, ">"); |
176 | 0 | break; |
177 | 0 | case objName: |
178 | 0 | fprintf(f, "/%s", cString); |
179 | 0 | break; |
180 | 0 | case objNull: |
181 | 0 | fprintf(f, "null"); |
182 | 0 | break; |
183 | 0 | case objArray: |
184 | 0 | fprintf(f, "["); |
185 | 0 | for (i = 0; i < arrayGetLength(); ++i) { |
186 | 0 | if (i > 0) { |
187 | 0 | fprintf(f, " "); |
188 | 0 | } |
189 | 0 | const Object &obj = arrayGetNF(i); |
190 | 0 | obj.print(f); |
191 | 0 | } |
192 | 0 | fprintf(f, "]"); |
193 | 0 | break; |
194 | 0 | case objDict: |
195 | 0 | fprintf(f, "<<"); |
196 | 0 | for (i = 0; i < dictGetLength(); ++i) { |
197 | 0 | fprintf(f, " /%s ", dictGetKey(i)); |
198 | 0 | const Object &obj = dictGetValNF(i); |
199 | 0 | obj.print(f); |
200 | 0 | } |
201 | 0 | fprintf(f, " >>"); |
202 | 0 | break; |
203 | 0 | case objStream: |
204 | 0 | fprintf(f, "<stream>"); |
205 | 0 | break; |
206 | 0 | case objRef: |
207 | 0 | fprintf(f, "%d %d R", ref.num, ref.gen); |
208 | 0 | break; |
209 | 0 | case objCmd: |
210 | 0 | fprintf(f, "%s", cString); |
211 | 0 | break; |
212 | 0 | case objError: |
213 | 0 | fprintf(f, "<error>"); |
214 | 0 | break; |
215 | 0 | case objEOF: |
216 | 0 | fprintf(f, "<EOF>"); |
217 | 0 | break; |
218 | 0 | case objNone: |
219 | 0 | fprintf(f, "<none>"); |
220 | 0 | break; |
221 | 0 | case objDead: |
222 | 0 | fprintf(f, "<dead>"); |
223 | 0 | break; |
224 | 0 | case objInt64: |
225 | 0 | fprintf(f, "%lld", int64g); |
226 | 0 | break; |
227 | 0 | } |
228 | 0 | } |