OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/include/fpdfapi/fpdf_objects.h" | 7 #include "core/include/fpdfapi/fpdf_objects.h" |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
11 #include "core/include/fpdfapi/fpdf_parser.h" | 11 #include "core/include/fpdfapi/fpdf_parser.h" |
12 #include "core/include/fxcrt/fx_string.h" | 12 #include "core/include/fxcrt/fx_string.h" |
13 #include "third_party/base/stl_util.h" | 13 #include "third_party/base/stl_util.h" |
14 | 14 |
15 namespace { | |
16 | |
17 const FX_DWORD kBlockSize = 1024; | |
18 | |
19 } // namespace | |
20 | |
21 void CPDF_Object::Release() { | 15 void CPDF_Object::Release() { |
22 if (m_ObjNum) { | 16 if (m_ObjNum) { |
23 return; | 17 return; |
24 } | 18 } |
25 Destroy(); | 19 Destroy(); |
26 } | 20 } |
27 void CPDF_Object::Destroy() { | |
28 switch (m_Type) { | |
29 case STRING: | |
30 delete AsString(); | |
31 break; | |
32 case NAME: | |
33 delete AsName(); | |
34 break; | |
35 case ARRAY: | |
36 delete AsArray(); | |
37 break; | |
38 case DICTIONARY: | |
39 delete AsDictionary(); | |
40 break; | |
41 case STREAM: | |
42 delete AsStream(); | |
43 break; | |
44 default: | |
45 delete this; | |
46 } | |
47 } | |
48 | 21 |
49 const CPDF_Object* CPDF_Object::GetBasicObject() const { | 22 CPDF_Number::CPDF_Number(const CFX_ByteStringC& str) { |
50 const CPDF_Reference* pRef = AsReference(); | |
51 if (!pRef) { | |
52 // This is not an indirect reference. | |
53 return this; | |
54 } | |
55 if (!pRef->m_pObjList) | |
56 return nullptr; | |
57 return pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum()); | |
58 } | |
59 | |
60 CFX_ByteString CPDF_Object::GetString() const { | |
61 const CPDF_Object* obj = GetBasicObject(); | |
62 if (obj) { | |
63 switch (obj->GetType()) { | |
64 case BOOLEAN: | |
65 return obj->AsBoolean()->GetString(); | |
66 case NUMBER: | |
67 return obj->AsNumber()->GetString(); | |
68 case STRING: | |
69 return obj->AsString()->GetString(); | |
70 case NAME: | |
71 return obj->AsName()->GetString(); | |
72 default: | |
73 break; | |
74 } | |
75 } | |
76 return CFX_ByteString(); | |
77 } | |
78 | |
79 CFX_ByteStringC CPDF_Object::GetConstString() const { | |
80 const CPDF_Object* obj = GetBasicObject(); | |
81 if (obj) { | |
82 FX_DWORD type = obj->GetType(); | |
83 if (type == STRING) { | |
84 CFX_ByteString str = obj->AsString()->GetString(); | |
85 return CFX_ByteStringC(str); | |
86 } | |
87 if (type == NAME) { | |
88 CFX_ByteString name = obj->AsName()->GetString(); | |
89 return CFX_ByteStringC(name); | |
90 } | |
91 } | |
92 return CFX_ByteStringC(); | |
93 } | |
94 | |
95 FX_FLOAT CPDF_Object::GetNumber() const { | |
96 const CPDF_Object* obj = GetBasicObject(); | |
97 if (obj && obj->GetType() == NUMBER) | |
98 return obj->AsNumber()->GetNumber(); | |
99 return 0; | |
100 } | |
101 | |
102 FX_FLOAT CPDF_Object::GetNumber16() const { | |
103 return GetNumber(); | |
104 } | |
105 | |
106 int CPDF_Object::GetInteger() const { | |
107 const CPDF_Object* obj = GetBasicObject(); | |
108 if (obj) { | |
109 FX_DWORD type = obj->GetType(); | |
110 if (type == BOOLEAN) | |
111 return obj->AsBoolean()->GetValue(); | |
112 if (type == NUMBER) | |
113 return obj->AsNumber()->GetInteger(); | |
114 } | |
115 return 0; | |
116 } | |
117 | |
118 CPDF_Dictionary* CPDF_Object::GetDict() const { | |
119 const CPDF_Object* obj = GetBasicObject(); | |
120 if (obj) { | |
121 FX_DWORD type = obj->GetType(); | |
122 if (type == DICTIONARY) { | |
123 // The method should be made non-const if we want to not be const. | |
124 // See bug #234. | |
125 return const_cast<CPDF_Dictionary*>(obj->AsDictionary()); | |
126 } | |
127 if (type == STREAM) | |
128 return obj->AsStream()->GetDict(); | |
129 } | |
130 return nullptr; | |
131 } | |
132 | |
133 CPDF_Array* CPDF_Object::GetArray() const { | |
134 // The method should be made non-const if we want to not be const. | |
135 // See bug #234. | |
136 return const_cast<CPDF_Array*>(AsArray()); | |
137 } | |
138 | |
139 void CPDF_Object::SetString(const CFX_ByteString& str) { | |
140 switch (m_Type) { | |
141 case BOOLEAN: | |
142 AsBoolean()->m_bValue = (str == "true"); | |
143 return; | |
144 case NUMBER: | |
145 AsNumber()->SetString(str); | |
146 return; | |
147 case STRING: | |
148 AsString()->m_String = str; | |
149 return; | |
150 case NAME: | |
151 AsName()->m_Name = str; | |
152 return; | |
153 default: | |
154 break; | |
155 } | |
156 ASSERT(FALSE); | |
157 } | |
158 FX_BOOL CPDF_Object::IsIdentical(CPDF_Object* pOther) const { | |
159 if (this == pOther) | |
160 return TRUE; | |
161 if (!pOther) | |
162 return FALSE; | |
163 if (pOther->m_Type != m_Type) { | |
164 if (IsReference() && GetDirect()) | |
165 return GetDirect()->IsIdentical(pOther); | |
166 if (pOther->IsReference()) | |
167 return IsIdentical(pOther->GetDirect()); | |
168 return FALSE; | |
169 } | |
170 switch (m_Type) { | |
171 case BOOLEAN: | |
172 return AsBoolean()->Identical(pOther->AsBoolean()); | |
173 case NUMBER: | |
174 return AsNumber()->Identical(pOther->AsNumber()); | |
175 case STRING: | |
176 return AsString()->Identical(pOther->AsString()); | |
177 case NAME: | |
178 return AsName()->Identical(pOther->AsName()); | |
179 case ARRAY: | |
180 return AsArray()->Identical(pOther->AsArray()); | |
181 case DICTIONARY: | |
182 return AsDictionary()->Identical(pOther->AsDictionary()); | |
183 case NULLOBJ: | |
184 return TRUE; | |
185 case STREAM: | |
186 return AsStream()->Identical(pOther->AsStream()); | |
187 case REFERENCE: | |
188 return AsReference()->Identical(pOther->AsReference()); | |
189 } | |
190 return FALSE; | |
191 } | |
192 | |
193 CPDF_Object* CPDF_Object::GetDirect() const { | |
194 const CPDF_Reference* pRef = AsReference(); | |
195 if (!pRef) | |
196 return const_cast<CPDF_Object*>(this); | |
197 if (!pRef->m_pObjList) | |
198 return nullptr; | |
199 return pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum()); | |
200 } | |
201 | |
202 CPDF_Object* CPDF_Object::Clone(FX_BOOL bDirect) const { | |
203 std::set<FX_DWORD> visited; | |
204 return CloneInternal(bDirect, &visited); | |
205 } | |
206 CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, | |
207 std::set<FX_DWORD>* visited) const { | |
208 switch (m_Type) { | |
209 case BOOLEAN: | |
210 return new CPDF_Boolean(AsBoolean()->m_bValue); | |
211 case NUMBER: { | |
212 const CPDF_Number* pThis = AsNumber(); | |
213 return new CPDF_Number(pThis->m_bInteger ? pThis->m_Integer | |
214 : pThis->m_Float); | |
215 } | |
216 case STRING: { | |
217 const CPDF_String* pString = AsString(); | |
218 return new CPDF_String(pString->m_String, pString->IsHex()); | |
219 } | |
220 case NAME: | |
221 return new CPDF_Name(AsName()->m_Name); | |
222 case ARRAY: { | |
223 CPDF_Array* pCopy = new CPDF_Array(); | |
224 const CPDF_Array* pThis = AsArray(); | |
225 int n = pThis->GetCount(); | |
226 for (int i = 0; i < n; i++) { | |
227 CPDF_Object* value = pThis->m_Objects.GetAt(i); | |
228 pCopy->m_Objects.Add(value->CloneInternal(bDirect, visited)); | |
229 } | |
230 return pCopy; | |
231 } | |
232 case DICTIONARY: { | |
233 CPDF_Dictionary* pCopy = new CPDF_Dictionary(); | |
234 const CPDF_Dictionary* pThis = AsDictionary(); | |
235 for (const auto& it : *pThis) { | |
236 pCopy->m_Map.insert(std::make_pair( | |
237 it.first, it.second->CloneInternal(bDirect, visited))); | |
238 } | |
239 return pCopy; | |
240 } | |
241 case NULLOBJ: { | |
242 return new CPDF_Null; | |
243 } | |
244 case STREAM: { | |
245 const CPDF_Stream* pThis = AsStream(); | |
246 CPDF_StreamAcc acc; | |
247 acc.LoadAllData(pThis, TRUE); | |
248 FX_DWORD streamSize = acc.GetSize(); | |
249 CPDF_Dictionary* pDict = pThis->GetDict(); | |
250 if (pDict) { | |
251 pDict = ToDictionary(pDict->CloneInternal(bDirect, visited)); | |
252 } | |
253 return new CPDF_Stream(acc.DetachData(), streamSize, pDict); | |
254 } | |
255 case REFERENCE: { | |
256 const CPDF_Reference* pRef = AsReference(); | |
257 FX_DWORD obj_num = pRef->GetRefObjNum(); | |
258 if (bDirect && !pdfium::ContainsKey(*visited, obj_num)) { | |
259 visited->insert(obj_num); | |
260 auto* pDirect = pRef->GetDirect(); | |
261 return pDirect ? pDirect->CloneInternal(TRUE, visited) : nullptr; | |
262 } | |
263 return new CPDF_Reference(pRef->m_pObjList, obj_num); | |
264 } | |
265 } | |
266 return NULL; | |
267 } | |
268 CPDF_Object* CPDF_Object::CloneRef(CPDF_IndirectObjectHolder* pDoc) const { | |
269 if (m_ObjNum) { | |
270 return new CPDF_Reference(pDoc, m_ObjNum); | |
271 } | |
272 return Clone(); | |
273 } | |
274 CFX_WideString CPDF_Object::GetUnicodeText(CFX_CharMap* pCharMap) const { | |
275 if (const CPDF_String* pString = AsString()) | |
276 return PDF_DecodeText(pString->m_String, pCharMap); | |
277 | |
278 if (const CPDF_Stream* pStream = AsStream()) { | |
279 CPDF_StreamAcc stream; | |
280 stream.LoadAllData(pStream, FALSE); | |
281 CFX_WideString result = | |
282 PDF_DecodeText(stream.GetData(), stream.GetSize(), pCharMap); | |
283 return result; | |
284 } | |
285 if (const CPDF_Name* pName = AsName()) | |
286 return PDF_DecodeText(pName->m_Name, pCharMap); | |
287 return CFX_WideString(); | |
288 } | |
289 void CPDF_Object::SetUnicodeText(const FX_WCHAR* pUnicodes, int len) { | |
290 if (CPDF_String* pString = AsString()) { | |
291 pString->m_String = PDF_EncodeText(pUnicodes, len); | |
292 } else if (CPDF_Stream* pStream = AsStream()) { | |
293 CFX_ByteString result = PDF_EncodeText(pUnicodes, len); | |
294 pStream->SetData((uint8_t*)result.c_str(), result.GetLength(), FALSE, | |
295 FALSE); | |
296 } | |
297 } | |
298 | |
299 CPDF_Array* CPDF_Object::AsArray() { | |
300 return IsArray() ? static_cast<CPDF_Array*>(this) : nullptr; | |
301 } | |
302 | |
303 const CPDF_Array* CPDF_Object::AsArray() const { | |
304 return IsArray() ? static_cast<const CPDF_Array*>(this) : nullptr; | |
305 } | |
306 | |
307 CPDF_Boolean* CPDF_Object::AsBoolean() { | |
308 return IsBoolean() ? static_cast<CPDF_Boolean*>(this) : nullptr; | |
309 } | |
310 | |
311 const CPDF_Boolean* CPDF_Object::AsBoolean() const { | |
312 return IsBoolean() ? static_cast<const CPDF_Boolean*>(this) : nullptr; | |
313 } | |
314 | |
315 CPDF_Dictionary* CPDF_Object::AsDictionary() { | |
316 return IsDictionary() ? static_cast<CPDF_Dictionary*>(this) : nullptr; | |
317 } | |
318 | |
319 const CPDF_Dictionary* CPDF_Object::AsDictionary() const { | |
320 return IsDictionary() ? static_cast<const CPDF_Dictionary*>(this) : nullptr; | |
321 } | |
322 | |
323 CPDF_Name* CPDF_Object::AsName() { | |
324 return IsName() ? static_cast<CPDF_Name*>(this) : nullptr; | |
325 } | |
326 | |
327 const CPDF_Name* CPDF_Object::AsName() const { | |
328 return IsName() ? static_cast<const CPDF_Name*>(this) : nullptr; | |
329 } | |
330 | |
331 CPDF_Number* CPDF_Object::AsNumber() { | |
332 return IsNumber() ? static_cast<CPDF_Number*>(this) : nullptr; | |
333 } | |
334 | |
335 const CPDF_Number* CPDF_Object::AsNumber() const { | |
336 return IsNumber() ? static_cast<const CPDF_Number*>(this) : nullptr; | |
337 } | |
338 | |
339 CPDF_Reference* CPDF_Object::AsReference() { | |
340 return IsReference() ? static_cast<CPDF_Reference*>(this) : nullptr; | |
341 } | |
342 | |
343 const CPDF_Reference* CPDF_Object::AsReference() const { | |
344 return IsReference() ? static_cast<const CPDF_Reference*>(this) : nullptr; | |
345 } | |
346 | |
347 CPDF_Stream* CPDF_Object::AsStream() { | |
348 return IsStream() ? static_cast<CPDF_Stream*>(this) : nullptr; | |
349 } | |
350 | |
351 const CPDF_Stream* CPDF_Object::AsStream() const { | |
352 return IsStream() ? static_cast<const CPDF_Stream*>(this) : nullptr; | |
353 } | |
354 | |
355 CPDF_String* CPDF_Object::AsString() { | |
356 return IsString() ? static_cast<CPDF_String*>(this) : nullptr; | |
357 } | |
358 | |
359 const CPDF_String* CPDF_Object::AsString() const { | |
360 return IsString() ? static_cast<const CPDF_String*>(this) : nullptr; | |
361 } | |
362 | |
363 CPDF_Number::CPDF_Number(int value) | |
364 : CPDF_Object(NUMBER), m_bInteger(TRUE), m_Integer(value) {} | |
365 | |
366 CPDF_Number::CPDF_Number(FX_FLOAT value) | |
367 : CPDF_Object(NUMBER), m_bInteger(FALSE), m_Float(value) {} | |
368 | |
369 CPDF_Number::CPDF_Number(const CFX_ByteStringC& str) : CPDF_Object(NUMBER) { | |
370 FX_atonum(str, m_bInteger, &m_Integer); | 23 FX_atonum(str, m_bInteger, &m_Integer); |
371 } | 24 } |
372 | 25 |
373 void CPDF_Number::SetString(const CFX_ByteStringC& str) { | 26 void CPDF_Number::SetString(const CFX_ByteString& str) { |
374 FX_atonum(str, m_bInteger, &m_Integer); | 27 FX_atonum(str, m_bInteger, &m_Integer); |
375 } | 28 } |
376 FX_BOOL CPDF_Number::Identical(CPDF_Number* pOther) const { | 29 |
377 return m_bInteger == pOther->m_bInteger && m_Integer == pOther->m_Integer; | |
378 } | |
379 CFX_ByteString CPDF_Number::GetString() const { | 30 CFX_ByteString CPDF_Number::GetString() const { |
380 return m_bInteger ? CFX_ByteString::FormatInteger(m_Integer, FXFORMAT_SIGNED) | 31 return m_bInteger ? CFX_ByteString::FormatInteger(m_Integer, FXFORMAT_SIGNED) |
381 : CFX_ByteString::FormatFloat(m_Float); | 32 : CFX_ByteString::FormatFloat(m_Float); |
382 } | 33 } |
383 void CPDF_Number::SetNumber(FX_FLOAT value) { | 34 |
384 m_bInteger = FALSE; | 35 CPDF_String::CPDF_String(const CFX_WideString& str) : m_bHex(FALSE) { |
385 m_Float = value; | |
386 } | |
387 CPDF_String::CPDF_String(const CFX_WideString& str) | |
388 : CPDF_Object(STRING), m_bHex(FALSE) { | |
389 m_String = PDF_EncodeText(str); | 36 m_String = PDF_EncodeText(str); |
390 } | 37 } |
| 38 |
| 39 CFX_WideString CPDF_String::GetUnicodeText(CFX_CharMap* pCharMap) const { |
| 40 return PDF_DecodeText(m_String, pCharMap); |
| 41 } |
| 42 |
| 43 CFX_WideString CPDF_Name::GetUnicodeText(CFX_CharMap* pCharMap) const { |
| 44 return PDF_DecodeText(m_Name, pCharMap); |
| 45 } |
| 46 |
391 CPDF_Array::~CPDF_Array() { | 47 CPDF_Array::~CPDF_Array() { |
392 int size = m_Objects.GetSize(); | 48 int size = m_Objects.GetSize(); |
393 CPDF_Object** pList = m_Objects.GetData(); | 49 CPDF_Object** pList = m_Objects.GetData(); |
394 for (int i = 0; i < size; i++) { | 50 for (int i = 0; i < size; i++) { |
395 if (pList[i]) | 51 if (pList[i]) |
396 pList[i]->Release(); | 52 pList[i]->Release(); |
397 } | 53 } |
398 } | 54 } |
| 55 |
| 56 CPDF_Object* CPDF_Array::Clone(FX_BOOL bDirect) const { |
| 57 CPDF_Array* pCopy = new CPDF_Array(); |
| 58 for (int i = 0; i < GetCount(); i++) { |
| 59 CPDF_Object* value = m_Objects.GetAt(i); |
| 60 pCopy->m_Objects.Add(value->Clone(bDirect)); |
| 61 } |
| 62 return pCopy; |
| 63 } |
| 64 |
399 CFX_FloatRect CPDF_Array::GetRect() { | 65 CFX_FloatRect CPDF_Array::GetRect() { |
400 CFX_FloatRect rect; | 66 CFX_FloatRect rect; |
401 if (!IsArray() || m_Objects.GetSize() != 4) | 67 if (!IsArray() || m_Objects.GetSize() != 4) |
402 return rect; | 68 return rect; |
403 | 69 |
404 rect.left = GetNumberAt(0); | 70 rect.left = GetNumberAt(0); |
405 rect.bottom = GetNumberAt(1); | 71 rect.bottom = GetNumberAt(1); |
406 rect.right = GetNumberAt(2); | 72 rect.right = GetNumberAt(2); |
407 rect.top = GetNumberAt(3); | 73 rect.top = GetNumberAt(3); |
408 return rect; | 74 return rect; |
409 } | 75 } |
| 76 |
410 CFX_Matrix CPDF_Array::GetMatrix() { | 77 CFX_Matrix CPDF_Array::GetMatrix() { |
411 CFX_Matrix matrix; | 78 CFX_Matrix matrix; |
412 if (!IsArray() || m_Objects.GetSize() != 6) | 79 if (!IsArray() || m_Objects.GetSize() != 6) |
413 return matrix; | 80 return matrix; |
414 | 81 |
415 matrix.Set(GetNumberAt(0), GetNumberAt(1), GetNumberAt(2), GetNumberAt(3), | 82 matrix.Set(GetNumberAt(0), GetNumberAt(1), GetNumberAt(2), GetNumberAt(3), |
416 GetNumberAt(4), GetNumberAt(5)); | 83 GetNumberAt(4), GetNumberAt(5)); |
417 return matrix; | 84 return matrix; |
418 } | 85 } |
| 86 |
419 CPDF_Object* CPDF_Array::GetElement(FX_DWORD i) const { | 87 CPDF_Object* CPDF_Array::GetElement(FX_DWORD i) const { |
420 if (i >= (FX_DWORD)m_Objects.GetSize()) | 88 if (i >= (FX_DWORD)m_Objects.GetSize()) |
421 return nullptr; | 89 return nullptr; |
422 return m_Objects.GetAt(i); | 90 return m_Objects.GetAt(i); |
423 } | 91 } |
| 92 |
424 CPDF_Object* CPDF_Array::GetElementValue(FX_DWORD i) const { | 93 CPDF_Object* CPDF_Array::GetElementValue(FX_DWORD i) const { |
425 if (i >= (FX_DWORD)m_Objects.GetSize()) | 94 if (i >= (FX_DWORD)m_Objects.GetSize()) |
426 return nullptr; | 95 return nullptr; |
427 return m_Objects.GetAt(i)->GetDirect(); | 96 return m_Objects.GetAt(i)->GetDirect(); |
428 } | 97 } |
| 98 |
429 CFX_ByteString CPDF_Array::GetStringAt(FX_DWORD i) const { | 99 CFX_ByteString CPDF_Array::GetStringAt(FX_DWORD i) const { |
430 if (i >= (FX_DWORD)m_Objects.GetSize()) | 100 if (i >= (FX_DWORD)m_Objects.GetSize()) |
431 return CFX_ByteString(); | 101 return CFX_ByteString(); |
432 return m_Objects.GetAt(i)->GetString(); | 102 return m_Objects.GetAt(i)->GetString(); |
433 } | 103 } |
| 104 |
434 CFX_ByteStringC CPDF_Array::GetConstStringAt(FX_DWORD i) const { | 105 CFX_ByteStringC CPDF_Array::GetConstStringAt(FX_DWORD i) const { |
435 if (i >= (FX_DWORD)m_Objects.GetSize()) | 106 if (i >= (FX_DWORD)m_Objects.GetSize()) |
436 return CFX_ByteStringC(); | 107 return CFX_ByteStringC(); |
437 return m_Objects.GetAt(i)->GetConstString(); | 108 return m_Objects.GetAt(i)->GetConstString(); |
438 } | 109 } |
| 110 |
439 int CPDF_Array::GetIntegerAt(FX_DWORD i) const { | 111 int CPDF_Array::GetIntegerAt(FX_DWORD i) const { |
440 if (i >= (FX_DWORD)m_Objects.GetSize()) | 112 if (i >= (FX_DWORD)m_Objects.GetSize()) |
441 return 0; | 113 return 0; |
442 return m_Objects.GetAt(i)->GetInteger(); | 114 return m_Objects.GetAt(i)->GetInteger(); |
443 } | 115 } |
| 116 |
444 FX_FLOAT CPDF_Array::GetNumberAt(FX_DWORD i) const { | 117 FX_FLOAT CPDF_Array::GetNumberAt(FX_DWORD i) const { |
445 if (i >= (FX_DWORD)m_Objects.GetSize()) | 118 if (i >= (FX_DWORD)m_Objects.GetSize()) |
446 return 0; | 119 return 0; |
447 return m_Objects.GetAt(i)->GetNumber(); | 120 return m_Objects.GetAt(i)->GetNumber(); |
448 } | 121 } |
| 122 |
449 CPDF_Dictionary* CPDF_Array::GetDictAt(FX_DWORD i) const { | 123 CPDF_Dictionary* CPDF_Array::GetDictAt(FX_DWORD i) const { |
450 CPDF_Object* p = GetElementValue(i); | 124 CPDF_Object* p = GetElementValue(i); |
451 if (!p) | 125 if (!p) |
452 return NULL; | 126 return NULL; |
453 if (CPDF_Dictionary* pDict = p->AsDictionary()) | 127 if (CPDF_Dictionary* pDict = p->AsDictionary()) |
454 return pDict; | 128 return pDict; |
455 if (CPDF_Stream* pStream = p->AsStream()) | 129 if (CPDF_Stream* pStream = p->AsStream()) |
456 return pStream->GetDict(); | 130 return pStream->GetDict(); |
457 return NULL; | 131 return NULL; |
458 } | 132 } |
| 133 |
459 CPDF_Stream* CPDF_Array::GetStreamAt(FX_DWORD i) const { | 134 CPDF_Stream* CPDF_Array::GetStreamAt(FX_DWORD i) const { |
460 return ToStream(GetElementValue(i)); | 135 return ToStream(GetElementValue(i)); |
461 } | 136 } |
| 137 |
462 CPDF_Array* CPDF_Array::GetArrayAt(FX_DWORD i) const { | 138 CPDF_Array* CPDF_Array::GetArrayAt(FX_DWORD i) const { |
463 return ToArray(GetElementValue(i)); | 139 return ToArray(GetElementValue(i)); |
464 } | 140 } |
| 141 |
465 void CPDF_Array::RemoveAt(FX_DWORD i, int nCount) { | 142 void CPDF_Array::RemoveAt(FX_DWORD i, int nCount) { |
466 if (i >= (FX_DWORD)m_Objects.GetSize()) | 143 if (i >= (FX_DWORD)m_Objects.GetSize()) |
467 return; | 144 return; |
468 | 145 |
469 if (nCount <= 0 || nCount > m_Objects.GetSize() - i) | 146 if (nCount <= 0 || nCount > m_Objects.GetSize() - i) |
470 return; | 147 return; |
471 | 148 |
472 for (int j = 0; j < nCount; ++j) { | 149 for (int j = 0; j < nCount; ++j) { |
473 if (CPDF_Object* p = m_Objects.GetAt(i + j)) | 150 if (CPDF_Object* p = m_Objects.GetAt(i + j)) |
474 p->Release(); | 151 p->Release(); |
475 } | 152 } |
476 m_Objects.RemoveAt(i, nCount); | 153 m_Objects.RemoveAt(i, nCount); |
477 } | 154 } |
| 155 |
478 void CPDF_Array::SetAt(FX_DWORD i, | 156 void CPDF_Array::SetAt(FX_DWORD i, |
479 CPDF_Object* pObj, | 157 CPDF_Object* pObj, |
480 CPDF_IndirectObjectHolder* pObjs) { | 158 CPDF_IndirectObjectHolder* pObjs) { |
481 ASSERT(IsArray()); | 159 ASSERT(IsArray()); |
482 ASSERT(i < (FX_DWORD)m_Objects.GetSize()); | 160 ASSERT(i < (FX_DWORD)m_Objects.GetSize()); |
483 if (i >= (FX_DWORD)m_Objects.GetSize()) | 161 if (i >= (FX_DWORD)m_Objects.GetSize()) |
484 return; | 162 return; |
485 if (CPDF_Object* pOld = m_Objects.GetAt(i)) | 163 if (CPDF_Object* pOld = m_Objects.GetAt(i)) |
486 pOld->Release(); | 164 pOld->Release(); |
487 if (pObj->GetObjNum()) { | 165 if (pObj->GetObjNum()) { |
488 ASSERT(pObjs); | 166 ASSERT(pObjs); |
489 pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); | 167 pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); |
490 } | 168 } |
491 m_Objects.SetAt(i, pObj); | 169 m_Objects.SetAt(i, pObj); |
492 } | 170 } |
| 171 |
493 void CPDF_Array::InsertAt(FX_DWORD index, | 172 void CPDF_Array::InsertAt(FX_DWORD index, |
494 CPDF_Object* pObj, | 173 CPDF_Object* pObj, |
495 CPDF_IndirectObjectHolder* pObjs) { | 174 CPDF_IndirectObjectHolder* pObjs) { |
496 if (pObj->GetObjNum()) { | 175 if (pObj->GetObjNum()) { |
497 ASSERT(pObjs); | 176 ASSERT(pObjs); |
498 pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); | 177 pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); |
499 } | 178 } |
500 m_Objects.InsertAt(index, pObj); | 179 m_Objects.InsertAt(index, pObj); |
501 } | 180 } |
| 181 |
502 void CPDF_Array::Add(CPDF_Object* pObj, CPDF_IndirectObjectHolder* pObjs) { | 182 void CPDF_Array::Add(CPDF_Object* pObj, CPDF_IndirectObjectHolder* pObjs) { |
503 if (pObj->GetObjNum()) { | 183 if (pObj->GetObjNum()) { |
504 ASSERT(pObjs); | 184 ASSERT(pObjs); |
505 pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); | 185 pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); |
506 } | 186 } |
507 m_Objects.Add(pObj); | 187 m_Objects.Add(pObj); |
508 } | 188 } |
| 189 |
509 void CPDF_Array::AddName(const CFX_ByteString& str) { | 190 void CPDF_Array::AddName(const CFX_ByteString& str) { |
510 ASSERT(IsArray()); | 191 ASSERT(IsArray()); |
511 Add(new CPDF_Name(str)); | 192 Add(new CPDF_Name(str)); |
512 } | 193 } |
| 194 |
513 void CPDF_Array::AddString(const CFX_ByteString& str) { | 195 void CPDF_Array::AddString(const CFX_ByteString& str) { |
514 ASSERT(IsArray()); | 196 ASSERT(IsArray()); |
515 Add(new CPDF_String(str, FALSE)); | 197 Add(new CPDF_String(str, FALSE)); |
516 } | 198 } |
| 199 |
517 void CPDF_Array::AddInteger(int i) { | 200 void CPDF_Array::AddInteger(int i) { |
518 ASSERT(IsArray()); | 201 ASSERT(IsArray()); |
519 Add(new CPDF_Number(i)); | 202 Add(new CPDF_Number(i)); |
520 } | 203 } |
| 204 |
521 void CPDF_Array::AddNumber(FX_FLOAT f) { | 205 void CPDF_Array::AddNumber(FX_FLOAT f) { |
522 ASSERT(IsArray()); | 206 ASSERT(IsArray()); |
523 CPDF_Number* pNumber = new CPDF_Number; | 207 CPDF_Number* pNumber = new CPDF_Number(f); |
524 pNumber->SetNumber(f); | |
525 Add(pNumber); | 208 Add(pNumber); |
526 } | 209 } |
| 210 |
527 void CPDF_Array::AddReference(CPDF_IndirectObjectHolder* pDoc, | 211 void CPDF_Array::AddReference(CPDF_IndirectObjectHolder* pDoc, |
528 FX_DWORD objnum) { | 212 FX_DWORD objnum) { |
529 ASSERT(IsArray()); | 213 ASSERT(IsArray()); |
530 Add(new CPDF_Reference(pDoc, objnum)); | 214 Add(new CPDF_Reference(pDoc, objnum)); |
531 } | 215 } |
532 FX_BOOL CPDF_Array::Identical(CPDF_Array* pOther) const { | 216 |
533 if (m_Objects.GetSize() != pOther->m_Objects.GetSize()) { | |
534 return FALSE; | |
535 } | |
536 for (int i = 0; i < m_Objects.GetSize(); i++) { | |
537 if (!m_Objects[i]->IsIdentical(pOther->m_Objects[i])) | |
538 return FALSE; | |
539 } | |
540 return TRUE; | |
541 } | |
542 CPDF_Dictionary::~CPDF_Dictionary() { | 217 CPDF_Dictionary::~CPDF_Dictionary() { |
543 for (const auto& it : m_Map) { | 218 for (const auto& it : m_Map) { |
544 it.second->Release(); | 219 it.second->Release(); |
545 } | 220 } |
546 } | 221 } |
| 222 |
| 223 CPDF_Object* CPDF_Dictionary::Clone(FX_BOOL bDirect) const { |
| 224 CPDF_Dictionary* pCopy = new CPDF_Dictionary(); |
| 225 for (const auto& it : *this) |
| 226 pCopy->m_Map.insert(std::make_pair(it.first, it.second->Clone(bDirect))); |
| 227 return pCopy; |
| 228 } |
| 229 |
547 CPDF_Object* CPDF_Dictionary::GetElement(const CFX_ByteStringC& key) const { | 230 CPDF_Object* CPDF_Dictionary::GetElement(const CFX_ByteStringC& key) const { |
548 auto it = m_Map.find(key); | 231 auto it = m_Map.find(key); |
549 if (it == m_Map.end()) | 232 if (it == m_Map.end()) |
550 return nullptr; | 233 return nullptr; |
551 return it->second; | 234 return it->second; |
552 } | 235 } |
553 CPDF_Object* CPDF_Dictionary::GetElementValue( | 236 CPDF_Object* CPDF_Dictionary::GetElementValue( |
554 const CFX_ByteStringC& key) const { | 237 const CFX_ByteStringC& key) const { |
555 CPDF_Object* p = GetElement(key); | 238 CPDF_Object* p = GetElement(key); |
556 return p ? p->GetDirect() : nullptr; | 239 return p ? p->GetDirect() : nullptr; |
557 } | 240 } |
| 241 |
558 CFX_ByteString CPDF_Dictionary::GetStringBy(const CFX_ByteStringC& key) const { | 242 CFX_ByteString CPDF_Dictionary::GetStringBy(const CFX_ByteStringC& key) const { |
559 CPDF_Object* p = GetElement(key); | 243 CPDF_Object* p = GetElement(key); |
560 if (p) { | 244 if (p) { |
561 return p->GetString(); | 245 return p->GetString(); |
562 } | 246 } |
563 return CFX_ByteString(); | 247 return CFX_ByteString(); |
564 } | 248 } |
| 249 |
565 CFX_ByteStringC CPDF_Dictionary::GetConstStringBy( | 250 CFX_ByteStringC CPDF_Dictionary::GetConstStringBy( |
566 const CFX_ByteStringC& key) const { | 251 const CFX_ByteStringC& key) const { |
567 CPDF_Object* p = GetElement(key); | 252 CPDF_Object* p = GetElement(key); |
568 if (p) { | 253 if (p) { |
569 return p->GetConstString(); | 254 return p->GetConstString(); |
570 } | 255 } |
571 return CFX_ByteStringC(); | 256 return CFX_ByteStringC(); |
572 } | 257 } |
| 258 |
573 CFX_WideString CPDF_Dictionary::GetUnicodeTextBy(const CFX_ByteStringC& key, | 259 CFX_WideString CPDF_Dictionary::GetUnicodeTextBy(const CFX_ByteStringC& key, |
574 CFX_CharMap* pCharMap) const { | 260 CFX_CharMap* pCharMap) const { |
575 CPDF_Object* p = GetElement(key); | 261 CPDF_Object* p = GetElement(key); |
576 if (CPDF_Reference* pRef = ToReference(p)) | 262 if (CPDF_Reference* pRef = ToReference(p)) |
577 p = pRef->GetDirect(); | 263 p = pRef->GetDirect(); |
578 return p ? p->GetUnicodeText(pCharMap) : CFX_WideString(); | 264 return p ? p->GetUnicodeText(pCharMap) : CFX_WideString(); |
579 } | 265 } |
| 266 |
580 CFX_ByteString CPDF_Dictionary::GetStringBy(const CFX_ByteStringC& key, | 267 CFX_ByteString CPDF_Dictionary::GetStringBy(const CFX_ByteStringC& key, |
581 const CFX_ByteStringC& def) const { | 268 const CFX_ByteStringC& def) const { |
582 CPDF_Object* p = GetElement(key); | 269 CPDF_Object* p = GetElement(key); |
583 if (p) { | 270 if (p) { |
584 return p->GetString(); | 271 return p->GetString(); |
585 } | 272 } |
586 return CFX_ByteString(def); | 273 return CFX_ByteString(def); |
587 } | 274 } |
| 275 |
588 CFX_ByteStringC CPDF_Dictionary::GetConstStringBy( | 276 CFX_ByteStringC CPDF_Dictionary::GetConstStringBy( |
589 const CFX_ByteStringC& key, | 277 const CFX_ByteStringC& key, |
590 const CFX_ByteStringC& def) const { | 278 const CFX_ByteStringC& def) const { |
591 CPDF_Object* p = GetElement(key); | 279 CPDF_Object* p = GetElement(key); |
592 if (p) { | 280 if (p) { |
593 return p->GetConstString(); | 281 return p->GetConstString(); |
594 } | 282 } |
595 return CFX_ByteStringC(def); | 283 return CFX_ByteStringC(def); |
596 } | 284 } |
| 285 |
597 int CPDF_Dictionary::GetIntegerBy(const CFX_ByteStringC& key) const { | 286 int CPDF_Dictionary::GetIntegerBy(const CFX_ByteStringC& key) const { |
598 CPDF_Object* p = GetElement(key); | 287 CPDF_Object* p = GetElement(key); |
599 if (p) { | 288 if (p) { |
600 return p->GetInteger(); | 289 return p->GetInteger(); |
601 } | 290 } |
602 return 0; | 291 return 0; |
603 } | 292 } |
| 293 |
604 int CPDF_Dictionary::GetIntegerBy(const CFX_ByteStringC& key, int def) const { | 294 int CPDF_Dictionary::GetIntegerBy(const CFX_ByteStringC& key, int def) const { |
605 CPDF_Object* p = GetElement(key); | 295 CPDF_Object* p = GetElement(key); |
606 if (p) { | 296 if (p) { |
607 return p->GetInteger(); | 297 return p->GetInteger(); |
608 } | 298 } |
609 return def; | 299 return def; |
610 } | 300 } |
| 301 |
611 FX_FLOAT CPDF_Dictionary::GetNumberBy(const CFX_ByteStringC& key) const { | 302 FX_FLOAT CPDF_Dictionary::GetNumberBy(const CFX_ByteStringC& key) const { |
612 CPDF_Object* p = GetElement(key); | 303 CPDF_Object* p = GetElement(key); |
613 if (p) { | 304 if (p) { |
614 return p->GetNumber(); | 305 return p->GetNumber(); |
615 } | 306 } |
616 return 0; | 307 return 0; |
617 } | 308 } |
| 309 |
618 FX_BOOL CPDF_Dictionary::GetBooleanBy(const CFX_ByteStringC& key, | 310 FX_BOOL CPDF_Dictionary::GetBooleanBy(const CFX_ByteStringC& key, |
619 FX_BOOL bDefault) const { | 311 FX_BOOL bDefault) const { |
620 CPDF_Object* p = GetElement(key); | 312 CPDF_Object* p = GetElement(key); |
621 if (ToBoolean(p)) | 313 if (ToBoolean(p)) |
622 return p->GetInteger(); | 314 return p->GetInteger(); |
623 return bDefault; | 315 return bDefault; |
624 } | 316 } |
| 317 |
625 CPDF_Dictionary* CPDF_Dictionary::GetDictBy(const CFX_ByteStringC& key) const { | 318 CPDF_Dictionary* CPDF_Dictionary::GetDictBy(const CFX_ByteStringC& key) const { |
626 CPDF_Object* p = GetElementValue(key); | 319 CPDF_Object* p = GetElementValue(key); |
627 if (!p) | 320 if (!p) |
628 return nullptr; | 321 return nullptr; |
629 if (CPDF_Dictionary* pDict = p->AsDictionary()) | 322 if (CPDF_Dictionary* pDict = p->AsDictionary()) |
630 return pDict; | 323 return pDict; |
631 if (CPDF_Stream* pStream = p->AsStream()) | 324 if (CPDF_Stream* pStream = p->AsStream()) |
632 return pStream->GetDict(); | 325 return pStream->GetDict(); |
633 return nullptr; | 326 return nullptr; |
634 } | 327 } |
| 328 |
635 CPDF_Array* CPDF_Dictionary::GetArrayBy(const CFX_ByteStringC& key) const { | 329 CPDF_Array* CPDF_Dictionary::GetArrayBy(const CFX_ByteStringC& key) const { |
636 return ToArray(GetElementValue(key)); | 330 return ToArray(GetElementValue(key)); |
637 } | 331 } |
| 332 |
638 CPDF_Stream* CPDF_Dictionary::GetStreamBy(const CFX_ByteStringC& key) const { | 333 CPDF_Stream* CPDF_Dictionary::GetStreamBy(const CFX_ByteStringC& key) const { |
639 return ToStream(GetElementValue(key)); | 334 return ToStream(GetElementValue(key)); |
640 } | 335 } |
| 336 |
641 CFX_FloatRect CPDF_Dictionary::GetRectBy(const CFX_ByteStringC& key) const { | 337 CFX_FloatRect CPDF_Dictionary::GetRectBy(const CFX_ByteStringC& key) const { |
642 CFX_FloatRect rect; | 338 CFX_FloatRect rect; |
643 CPDF_Array* pArray = GetArrayBy(key); | 339 CPDF_Array* pArray = GetArrayBy(key); |
644 if (pArray) | 340 if (pArray) |
645 rect = pArray->GetRect(); | 341 rect = pArray->GetRect(); |
646 return rect; | 342 return rect; |
647 } | 343 } |
| 344 |
648 CFX_Matrix CPDF_Dictionary::GetMatrixBy(const CFX_ByteStringC& key) const { | 345 CFX_Matrix CPDF_Dictionary::GetMatrixBy(const CFX_ByteStringC& key) const { |
649 CFX_Matrix matrix; | 346 CFX_Matrix matrix; |
650 CPDF_Array* pArray = GetArrayBy(key); | 347 CPDF_Array* pArray = GetArrayBy(key); |
651 if (pArray) | 348 if (pArray) |
652 matrix = pArray->GetMatrix(); | 349 matrix = pArray->GetMatrix(); |
653 return matrix; | 350 return matrix; |
654 } | 351 } |
| 352 |
655 FX_BOOL CPDF_Dictionary::KeyExist(const CFX_ByteStringC& key) const { | 353 FX_BOOL CPDF_Dictionary::KeyExist(const CFX_ByteStringC& key) const { |
656 return pdfium::ContainsKey(m_Map, key); | 354 return pdfium::ContainsKey(m_Map, key); |
657 } | 355 } |
658 | 356 |
659 void CPDF_Dictionary::SetAt(const CFX_ByteStringC& key, CPDF_Object* pObj) { | 357 void CPDF_Dictionary::SetAt(const CFX_ByteStringC& key, CPDF_Object* pObj) { |
660 ASSERT(IsDictionary()); | 358 ASSERT(IsDictionary()); |
661 // Avoid 2 constructions of CFX_ByteString. | 359 // Avoid 2 constructions of CFX_ByteString. |
662 CFX_ByteString key_bytestring = key; | 360 CFX_ByteString key_bytestring = key; |
663 auto it = m_Map.find(key_bytestring); | 361 auto it = m_Map.find(key_bytestring); |
664 if (it == m_Map.end()) { | 362 if (it == m_Map.end()) { |
665 if (pObj) { | 363 if (pObj) { |
666 m_Map.insert(std::make_pair(key_bytestring, pObj)); | 364 m_Map.insert(std::make_pair(key_bytestring, pObj)); |
667 } | 365 } |
668 return; | 366 return; |
669 } | 367 } |
670 | 368 |
671 if (it->second == pObj) | 369 if (it->second == pObj) |
672 return; | 370 return; |
673 it->second->Release(); | 371 it->second->Release(); |
674 | 372 |
675 if (pObj) | 373 if (pObj) |
676 it->second = pObj; | 374 it->second = pObj; |
677 else | 375 else |
678 m_Map.erase(it); | 376 m_Map.erase(it); |
679 } | 377 } |
| 378 |
680 void CPDF_Dictionary::RemoveAt(const CFX_ByteStringC& key) { | 379 void CPDF_Dictionary::RemoveAt(const CFX_ByteStringC& key) { |
681 ASSERT(m_Type == DICTIONARY); | |
682 auto it = m_Map.find(key); | 380 auto it = m_Map.find(key); |
683 if (it == m_Map.end()) | 381 if (it == m_Map.end()) |
684 return; | 382 return; |
685 | 383 |
686 it->second->Release(); | 384 it->second->Release(); |
687 m_Map.erase(it); | 385 m_Map.erase(it); |
688 } | 386 } |
| 387 |
689 void CPDF_Dictionary::ReplaceKey(const CFX_ByteStringC& oldkey, | 388 void CPDF_Dictionary::ReplaceKey(const CFX_ByteStringC& oldkey, |
690 const CFX_ByteStringC& newkey) { | 389 const CFX_ByteStringC& newkey) { |
691 ASSERT(m_Type == DICTIONARY); | |
692 auto old_it = m_Map.find(oldkey); | 390 auto old_it = m_Map.find(oldkey); |
693 if (old_it == m_Map.end()) | 391 if (old_it == m_Map.end()) |
694 return; | 392 return; |
695 | 393 |
696 // Avoid 2 constructions of CFX_ByteString. | 394 // Avoid 2 constructions of CFX_ByteString. |
697 CFX_ByteString newkey_bytestring = newkey; | 395 CFX_ByteString newkey_bytestring = newkey; |
698 auto new_it = m_Map.find(newkey_bytestring); | 396 auto new_it = m_Map.find(newkey_bytestring); |
699 if (new_it == old_it) | 397 if (new_it == old_it) |
700 return; | 398 return; |
701 | 399 |
702 if (new_it != m_Map.end()) { | 400 if (new_it != m_Map.end()) { |
703 new_it->second->Release(); | 401 new_it->second->Release(); |
704 new_it->second = old_it->second; | 402 new_it->second = old_it->second; |
705 } else { | 403 } else { |
706 m_Map.insert(std::make_pair(newkey_bytestring, old_it->second)); | 404 m_Map.insert(std::make_pair(newkey_bytestring, old_it->second)); |
707 } | 405 } |
708 m_Map.erase(old_it); | 406 m_Map.erase(old_it); |
709 } | 407 } |
710 FX_BOOL CPDF_Dictionary::Identical(CPDF_Dictionary* pOther) const { | 408 |
711 if (!pOther) { | |
712 return FALSE; | |
713 } | |
714 if (m_Map.size() != pOther->m_Map.size()) { | |
715 return FALSE; | |
716 } | |
717 for (const auto& it : m_Map) { | |
718 const CFX_ByteString& key = it.first; | |
719 if (!it.second->IsIdentical(pOther->GetElement(key))) | |
720 return FALSE; | |
721 } | |
722 return TRUE; | |
723 } | |
724 void CPDF_Dictionary::SetAtInteger(const CFX_ByteStringC& key, int i) { | 409 void CPDF_Dictionary::SetAtInteger(const CFX_ByteStringC& key, int i) { |
725 SetAt(key, new CPDF_Number(i)); | 410 SetAt(key, new CPDF_Number(i)); |
726 } | 411 } |
| 412 |
727 void CPDF_Dictionary::SetAtName(const CFX_ByteStringC& key, | 413 void CPDF_Dictionary::SetAtName(const CFX_ByteStringC& key, |
728 const CFX_ByteString& name) { | 414 const CFX_ByteString& name) { |
729 SetAt(key, new CPDF_Name(name)); | 415 SetAt(key, new CPDF_Name(name)); |
730 } | 416 } |
| 417 |
731 void CPDF_Dictionary::SetAtString(const CFX_ByteStringC& key, | 418 void CPDF_Dictionary::SetAtString(const CFX_ByteStringC& key, |
732 const CFX_ByteString& str) { | 419 const CFX_ByteString& str) { |
733 SetAt(key, new CPDF_String(str, FALSE)); | 420 SetAt(key, new CPDF_String(str, FALSE)); |
734 } | 421 } |
| 422 |
735 void CPDF_Dictionary::SetAtReference(const CFX_ByteStringC& key, | 423 void CPDF_Dictionary::SetAtReference(const CFX_ByteStringC& key, |
736 CPDF_IndirectObjectHolder* pDoc, | 424 CPDF_IndirectObjectHolder* pDoc, |
737 FX_DWORD objnum) { | 425 FX_DWORD objnum) { |
738 SetAt(key, new CPDF_Reference(pDoc, objnum)); | 426 SetAt(key, new CPDF_Reference(pDoc, objnum)); |
739 } | 427 } |
| 428 |
740 void CPDF_Dictionary::AddReference(const CFX_ByteStringC& key, | 429 void CPDF_Dictionary::AddReference(const CFX_ByteStringC& key, |
741 CPDF_IndirectObjectHolder* pDoc, | 430 CPDF_IndirectObjectHolder* pDoc, |
742 FX_DWORD objnum) { | 431 FX_DWORD objnum) { |
743 SetAt(key, new CPDF_Reference(pDoc, objnum)); | 432 SetAt(key, new CPDF_Reference(pDoc, objnum)); |
744 } | 433 } |
| 434 |
745 void CPDF_Dictionary::SetAtNumber(const CFX_ByteStringC& key, FX_FLOAT f) { | 435 void CPDF_Dictionary::SetAtNumber(const CFX_ByteStringC& key, FX_FLOAT f) { |
746 CPDF_Number* pNumber = new CPDF_Number; | 436 CPDF_Number* pNumber = new CPDF_Number(f); |
747 pNumber->SetNumber(f); | |
748 SetAt(key, pNumber); | 437 SetAt(key, pNumber); |
749 } | 438 } |
| 439 |
750 void CPDF_Dictionary::SetAtBoolean(const CFX_ByteStringC& key, FX_BOOL bValue) { | 440 void CPDF_Dictionary::SetAtBoolean(const CFX_ByteStringC& key, FX_BOOL bValue) { |
751 SetAt(key, new CPDF_Boolean(bValue)); | 441 SetAt(key, new CPDF_Boolean(bValue)); |
752 } | 442 } |
| 443 |
753 void CPDF_Dictionary::SetAtRect(const CFX_ByteStringC& key, | 444 void CPDF_Dictionary::SetAtRect(const CFX_ByteStringC& key, |
754 const CFX_FloatRect& rect) { | 445 const CFX_FloatRect& rect) { |
755 CPDF_Array* pArray = new CPDF_Array; | 446 CPDF_Array* pArray = new CPDF_Array; |
756 pArray->AddNumber(rect.left); | 447 pArray->AddNumber(rect.left); |
757 pArray->AddNumber(rect.bottom); | 448 pArray->AddNumber(rect.bottom); |
758 pArray->AddNumber(rect.right); | 449 pArray->AddNumber(rect.right); |
759 pArray->AddNumber(rect.top); | 450 pArray->AddNumber(rect.top); |
760 SetAt(key, pArray); | 451 SetAt(key, pArray); |
761 } | 452 } |
| 453 |
762 void CPDF_Dictionary::SetAtMatrix(const CFX_ByteStringC& key, | 454 void CPDF_Dictionary::SetAtMatrix(const CFX_ByteStringC& key, |
763 const CFX_Matrix& matrix) { | 455 const CFX_Matrix& matrix) { |
764 CPDF_Array* pArray = new CPDF_Array; | 456 CPDF_Array* pArray = new CPDF_Array; |
765 pArray->AddNumber16(matrix.a); | 457 pArray->AddNumber16(matrix.a); |
766 pArray->AddNumber16(matrix.b); | 458 pArray->AddNumber16(matrix.b); |
767 pArray->AddNumber16(matrix.c); | 459 pArray->AddNumber16(matrix.c); |
768 pArray->AddNumber16(matrix.d); | 460 pArray->AddNumber16(matrix.d); |
769 pArray->AddNumber(matrix.e); | 461 pArray->AddNumber(matrix.e); |
770 pArray->AddNumber(matrix.f); | 462 pArray->AddNumber(matrix.f); |
771 SetAt(key, pArray); | 463 SetAt(key, pArray); |
772 } | 464 } |
| 465 |
773 CPDF_Stream::CPDF_Stream(uint8_t* pData, FX_DWORD size, CPDF_Dictionary* pDict) | 466 CPDF_Stream::CPDF_Stream(uint8_t* pData, FX_DWORD size, CPDF_Dictionary* pDict) |
774 : CPDF_Object(STREAM), | 467 : m_pDict(pDict), |
775 m_pDict(pDict), | |
776 m_dwSize(size), | 468 m_dwSize(size), |
777 m_GenNum(kMemoryBasedGenNum), | 469 m_GenNum(kMemoryBasedGenNum), |
778 m_pDataBuf(pData) {} | 470 m_pDataBuf(pData) {} |
779 | 471 |
780 CPDF_Stream::~CPDF_Stream() { | 472 CPDF_Stream::~CPDF_Stream() { |
781 if (IsMemoryBased()) | 473 if (IsMemoryBased()) |
782 FX_Free(m_pDataBuf); | 474 FX_Free(m_pDataBuf); |
783 | 475 |
784 if (m_pDict) | 476 if (m_pDict) |
785 m_pDict->Release(); | 477 m_pDict->Release(); |
(...skipping 19 matching lines...) Expand all Loading... |
805 m_GenNum = kMemoryBasedGenNum; | 497 m_GenNum = kMemoryBasedGenNum; |
806 m_pDataBuf = FX_Alloc(uint8_t, size); | 498 m_pDataBuf = FX_Alloc(uint8_t, size); |
807 if (pData) { | 499 if (pData) { |
808 FXSYS_memcpy(m_pDataBuf, pData, size); | 500 FXSYS_memcpy(m_pDataBuf, pData, size); |
809 } | 501 } |
810 m_dwSize = size; | 502 m_dwSize = size; |
811 if (m_pDict) { | 503 if (m_pDict) { |
812 m_pDict->SetAtInteger("Length", size); | 504 m_pDict->SetAtInteger("Length", size); |
813 } | 505 } |
814 } | 506 } |
| 507 |
| 508 CPDF_Object* CPDF_Stream::Clone(FX_BOOL bDirect) const { |
| 509 CPDF_StreamAcc acc; |
| 510 acc.LoadAllData(this, TRUE); |
| 511 FX_DWORD streamSize = acc.GetSize(); |
| 512 CPDF_Dictionary* pDict = GetDict(); |
| 513 if (pDict) { |
| 514 pDict = ToDictionary(pDict->Clone(bDirect)); |
| 515 } |
| 516 return new CPDF_Stream(acc.DetachData(), streamSize, pDict); |
| 517 } |
| 518 |
815 void CPDF_Stream::SetData(const uint8_t* pData, | 519 void CPDF_Stream::SetData(const uint8_t* pData, |
816 FX_DWORD size, | 520 FX_DWORD size, |
817 FX_BOOL bCompressed, | 521 FX_BOOL bCompressed, |
818 FX_BOOL bKeepBuf) { | 522 FX_BOOL bKeepBuf) { |
819 if (IsMemoryBased()) | 523 if (IsMemoryBased()) |
820 FX_Free(m_pDataBuf); | 524 FX_Free(m_pDataBuf); |
821 m_GenNum = kMemoryBasedGenNum; | 525 m_GenNum = kMemoryBasedGenNum; |
822 | 526 |
823 if (bKeepBuf) { | 527 if (bKeepBuf) { |
824 m_pDataBuf = (uint8_t*)pData; | 528 m_pDataBuf = const_cast<uint8_t*>(pData); |
825 } else { | 529 } else { |
826 m_pDataBuf = FX_Alloc(uint8_t, size); | 530 m_pDataBuf = FX_Alloc(uint8_t, size); |
827 if (pData) { | 531 if (pData) { |
828 FXSYS_memcpy(m_pDataBuf, pData, size); | 532 FXSYS_memcpy(m_pDataBuf, pData, size); |
829 } | 533 } |
830 } | 534 } |
831 m_dwSize = size; | 535 m_dwSize = size; |
832 if (!m_pDict) | 536 if (!m_pDict) |
833 m_pDict = new CPDF_Dictionary; | 537 m_pDict = new CPDF_Dictionary; |
834 m_pDict->SetAtInteger("Length", size); | 538 m_pDict->SetAtInteger("Length", size); |
835 if (!bCompressed) { | 539 if (!bCompressed) { |
836 m_pDict->RemoveAt("Filter"); | 540 m_pDict->RemoveAt("Filter"); |
837 m_pDict->RemoveAt("DecodeParms"); | 541 m_pDict->RemoveAt("DecodeParms"); |
838 } | 542 } |
839 } | 543 } |
| 544 |
840 FX_BOOL CPDF_Stream::ReadRawData(FX_FILESIZE offset, | 545 FX_BOOL CPDF_Stream::ReadRawData(FX_FILESIZE offset, |
841 uint8_t* buf, | 546 uint8_t* buf, |
842 FX_DWORD size) const { | 547 FX_DWORD size) const { |
843 if (!IsMemoryBased() && m_pFile) | 548 if (!IsMemoryBased() && m_pFile) |
844 return m_pFile->ReadBlock(buf, offset, size); | 549 return m_pFile->ReadBlock(buf, offset, size); |
845 | 550 |
846 if (m_pDataBuf) | 551 if (m_pDataBuf) |
847 FXSYS_memcpy(buf, m_pDataBuf + offset, size); | 552 FXSYS_memcpy(buf, m_pDataBuf + offset, size); |
848 return TRUE; | 553 return TRUE; |
849 } | 554 } |
850 void CPDF_Stream::InitStreamFromFile(IFX_FileRead* pFile, | 555 void CPDF_Stream::InitStreamFromFile(IFX_FileRead* pFile, |
851 CPDF_Dictionary* pDict) { | 556 CPDF_Dictionary* pDict) { |
852 InitStreamInternal(pDict); | 557 InitStreamInternal(pDict); |
853 m_pFile = pFile; | 558 m_pFile = pFile; |
854 m_dwSize = (FX_DWORD)pFile->GetSize(); | 559 m_dwSize = (FX_DWORD)pFile->GetSize(); |
855 if (m_pDict) { | 560 if (m_pDict) { |
856 m_pDict->SetAtInteger("Length", m_dwSize); | 561 m_pDict->SetAtInteger("Length", m_dwSize); |
857 } | 562 } |
858 } | 563 } |
859 | 564 |
860 FX_BOOL CPDF_Stream::Identical(CPDF_Stream* pOther) const { | 565 CFX_WideString CPDF_Stream::GetUnicodeText(CFX_CharMap* pCharMap) const { |
861 if (!m_pDict) | 566 CPDF_StreamAcc stream; |
862 return !pOther->m_pDict; | 567 stream.LoadAllData(this, FALSE); |
863 | 568 return PDF_DecodeText(stream.GetData(), stream.GetSize(), pCharMap); |
864 if (!m_pDict->Identical(pOther->m_pDict)) | |
865 return FALSE; | |
866 | |
867 if (m_dwSize != pOther->m_dwSize) | |
868 return FALSE; | |
869 | |
870 if (!IsMemoryBased() && !pOther->IsMemoryBased()) { | |
871 if (m_pFile == pOther->m_pFile && !m_pFile) | |
872 return TRUE; | |
873 | |
874 if (!m_pFile || !pOther->m_pFile) | |
875 return FALSE; | |
876 | |
877 uint8_t srcBuf[kBlockSize]; | |
878 uint8_t destBuf[kBlockSize]; | |
879 FX_DWORD size = m_dwSize; | |
880 if (m_pFile == pOther->m_pFile) | |
881 return TRUE; | |
882 | |
883 FX_DWORD offset = 0; | |
884 while (size > 0) { | |
885 FX_DWORD actualSize = std::min(size, kBlockSize); | |
886 m_pFile->ReadBlock(srcBuf, offset, actualSize); | |
887 pOther->m_pFile->ReadBlock(destBuf, offset, actualSize); | |
888 if (FXSYS_memcmp(srcBuf, destBuf, actualSize) != 0) | |
889 return FALSE; | |
890 | |
891 size -= actualSize; | |
892 offset += actualSize; | |
893 } | |
894 return TRUE; | |
895 } | |
896 | |
897 if (!IsMemoryBased() || !pOther->IsMemoryBased()) { | |
898 IFX_FileRead* pFile = nullptr; | |
899 uint8_t* pBuf = nullptr; | |
900 if (!pOther->IsMemoryBased()) { | |
901 pFile = pOther->m_pFile; | |
902 pBuf = m_pDataBuf; | |
903 } else if (!IsMemoryBased()) { | |
904 pFile = m_pFile; | |
905 pBuf = pOther->m_pDataBuf; | |
906 } | |
907 if (!pBuf) | |
908 return FALSE; | |
909 | |
910 uint8_t srcBuf[kBlockSize]; | |
911 FX_DWORD size = m_dwSize; | |
912 FX_DWORD offset = 0; | |
913 while (size > 0) { | |
914 FX_DWORD actualSize = std::min(size, kBlockSize); | |
915 pFile->ReadBlock(srcBuf, offset, actualSize); | |
916 if (FXSYS_memcmp(srcBuf, pBuf, actualSize) != 0) | |
917 return FALSE; | |
918 | |
919 pBuf += actualSize; | |
920 size -= actualSize; | |
921 offset += actualSize; | |
922 } | |
923 return TRUE; | |
924 } | |
925 return FXSYS_memcmp(m_pDataBuf, pOther->m_pDataBuf, m_dwSize) == 0; | |
926 } | 569 } |
927 | 570 |
928 CPDF_StreamAcc::CPDF_StreamAcc() { | 571 CPDF_StreamAcc::CPDF_StreamAcc() { |
929 m_bNewBuf = FALSE; | 572 m_bNewBuf = FALSE; |
930 m_pData = NULL; | 573 m_pData = NULL; |
931 m_dwSize = 0; | 574 m_dwSize = 0; |
932 m_pImageParam = NULL; | 575 m_pImageParam = NULL; |
933 m_pStream = NULL; | 576 m_pStream = NULL; |
934 m_pSrcData = NULL; | 577 m_pSrcData = NULL; |
935 } | 578 } |
936 void CPDF_StreamAcc::LoadAllData(const CPDF_Stream* pStream, | 579 void CPDF_StreamAcc::LoadAllData(const CPDF_Stream* pStream, |
937 FX_BOOL bRawAccess, | 580 FX_BOOL bRawAccess, |
938 FX_DWORD estimated_size, | 581 FX_DWORD estimated_size, |
939 FX_BOOL bImageAcc) { | 582 FX_BOOL bImageAcc) { |
940 if (!pStream) | 583 if (!pStream) |
941 return; | 584 return; |
942 | 585 |
943 m_pStream = pStream; | 586 m_pStream = pStream; |
944 if (pStream->IsMemoryBased() && | 587 if (pStream->IsMemoryBased() && |
945 (!pStream->GetDict()->KeyExist("Filter") || bRawAccess)) { | 588 (!pStream->GetDict()->KeyExist("Filter") || bRawAccess)) { |
946 m_dwSize = pStream->m_dwSize; | 589 m_dwSize = pStream->GetRawSize(); |
947 m_pData = (uint8_t*)pStream->m_pDataBuf; | 590 m_pData = pStream->GetRawData(); |
948 return; | 591 return; |
949 } | 592 } |
950 uint8_t* pSrcData; | 593 uint8_t* pSrcData; |
951 FX_DWORD dwSrcSize = pStream->m_dwSize; | 594 FX_DWORD dwSrcSize = pStream->GetRawSize(); |
952 if (dwSrcSize == 0) | 595 if (dwSrcSize == 0) |
953 return; | 596 return; |
954 | 597 |
955 if (!pStream->IsMemoryBased()) { | 598 if (!pStream->IsMemoryBased()) { |
956 pSrcData = m_pSrcData = FX_Alloc(uint8_t, dwSrcSize); | 599 pSrcData = m_pSrcData = FX_Alloc(uint8_t, dwSrcSize); |
957 if (!pStream->ReadRawData(0, pSrcData, dwSrcSize)) | 600 if (!pStream->ReadRawData(0, pSrcData, dwSrcSize)) |
958 return; | 601 return; |
959 } else { | 602 } else { |
960 pSrcData = pStream->m_pDataBuf; | 603 pSrcData = pStream->GetRawData(); |
961 } | 604 } |
962 uint8_t* pDecryptedData = pSrcData; | 605 uint8_t* pDecryptedData = pSrcData; |
963 FX_DWORD dwDecryptedSize = dwSrcSize; | 606 FX_DWORD dwDecryptedSize = dwSrcSize; |
964 if (!pStream->GetDict()->KeyExist("Filter") || bRawAccess) { | 607 if (!pStream->GetDict()->KeyExist("Filter") || bRawAccess) { |
965 m_pData = pDecryptedData; | 608 m_pData = pDecryptedData; |
966 m_dwSize = dwDecryptedSize; | 609 m_dwSize = dwDecryptedSize; |
967 } else { | 610 } else { |
968 FX_BOOL bRet = PDF_DataDecode( | 611 FX_BOOL bRet = PDF_DataDecode( |
969 pDecryptedData, dwDecryptedSize, m_pStream->GetDict(), m_pData, | 612 pDecryptedData, dwDecryptedSize, m_pStream->GetDict(), m_pData, |
970 m_dwSize, m_ImageDecoder, m_pImageParam, estimated_size, bImageAcc); | 613 m_dwSize, m_ImageDecoder, m_pImageParam, estimated_size, bImageAcc); |
971 if (!bRet) { | 614 if (!bRet) { |
972 m_pData = pDecryptedData; | 615 m_pData = pDecryptedData; |
973 m_dwSize = dwDecryptedSize; | 616 m_dwSize = dwDecryptedSize; |
974 } | 617 } |
975 } | 618 } |
976 if (pSrcData != pStream->m_pDataBuf && pSrcData != m_pData) { | 619 if (pSrcData != pStream->GetRawData() && pSrcData != m_pData) { |
977 FX_Free(pSrcData); | 620 FX_Free(pSrcData); |
978 } | 621 } |
979 if (pDecryptedData != pSrcData && pDecryptedData != m_pData) { | 622 if (pDecryptedData != pSrcData && pDecryptedData != m_pData) { |
980 FX_Free(pDecryptedData); | 623 FX_Free(pDecryptedData); |
981 } | 624 } |
982 m_pSrcData = NULL; | 625 m_pSrcData = NULL; |
983 m_bNewBuf = m_pData != pStream->m_pDataBuf; | 626 m_bNewBuf = m_pData != pStream->GetRawData(); |
984 } | 627 } |
| 628 |
985 CPDF_StreamAcc::~CPDF_StreamAcc() { | 629 CPDF_StreamAcc::~CPDF_StreamAcc() { |
986 if (m_bNewBuf) { | 630 if (m_bNewBuf) { |
987 FX_Free(m_pData); | 631 FX_Free(m_pData); |
988 } | 632 } |
989 FX_Free(m_pSrcData); | 633 FX_Free(m_pSrcData); |
990 } | 634 } |
| 635 |
991 const uint8_t* CPDF_StreamAcc::GetData() const { | 636 const uint8_t* CPDF_StreamAcc::GetData() const { |
992 if (m_bNewBuf) { | 637 if (m_bNewBuf) { |
993 return m_pData; | 638 return m_pData; |
994 } | 639 } |
995 if (!m_pStream) { | 640 if (!m_pStream) { |
996 return NULL; | 641 return NULL; |
997 } | 642 } |
998 return m_pStream->m_pDataBuf; | 643 return m_pStream->GetRawData(); |
999 } | 644 } |
| 645 |
1000 FX_DWORD CPDF_StreamAcc::GetSize() const { | 646 FX_DWORD CPDF_StreamAcc::GetSize() const { |
1001 if (m_bNewBuf) { | 647 if (m_bNewBuf) { |
1002 return m_dwSize; | 648 return m_dwSize; |
1003 } | 649 } |
1004 if (!m_pStream) { | 650 if (!m_pStream) { |
1005 return 0; | 651 return 0; |
1006 } | 652 } |
1007 return m_pStream->m_dwSize; | 653 return m_pStream->GetRawSize(); |
1008 } | 654 } |
| 655 |
1009 uint8_t* CPDF_StreamAcc::DetachData() { | 656 uint8_t* CPDF_StreamAcc::DetachData() { |
1010 if (m_bNewBuf) { | 657 if (m_bNewBuf) { |
1011 uint8_t* p = m_pData; | 658 uint8_t* p = m_pData; |
1012 m_pData = NULL; | 659 m_pData = NULL; |
1013 m_dwSize = 0; | 660 m_dwSize = 0; |
1014 return p; | 661 return p; |
1015 } | 662 } |
1016 uint8_t* p = FX_Alloc(uint8_t, m_dwSize); | 663 uint8_t* p = FX_Alloc(uint8_t, m_dwSize); |
1017 FXSYS_memcpy(p, m_pData, m_dwSize); | 664 FXSYS_memcpy(p, m_pData, m_dwSize); |
1018 return p; | 665 return p; |
1019 } | 666 } |
| 667 |
| 668 CPDF_Object* CPDF_Reference::Clone(FX_BOOL bDirect) const { |
| 669 if (bDirect) { |
| 670 auto* pDirect = GetDirect(); |
| 671 return pDirect ? pDirect->Clone(TRUE) : nullptr; |
| 672 } |
| 673 return new CPDF_Reference(m_pObjList, m_RefObjNum); |
| 674 } |
| 675 |
1020 void CPDF_Reference::SetRef(CPDF_IndirectObjectHolder* pDoc, FX_DWORD objnum) { | 676 void CPDF_Reference::SetRef(CPDF_IndirectObjectHolder* pDoc, FX_DWORD objnum) { |
1021 m_pObjList = pDoc; | 677 m_pObjList = pDoc; |
1022 m_RefObjNum = objnum; | 678 m_RefObjNum = objnum; |
1023 } | 679 } |
| 680 |
| 681 CPDF_Object* CPDF_Reference::GetDirect() const { |
| 682 return m_pObjList ? m_pObjList->GetIndirectObject(m_RefObjNum) : nullptr; |
| 683 } |
| 684 |
1024 CPDF_IndirectObjectHolder::CPDF_IndirectObjectHolder(CPDF_Parser* pParser) | 685 CPDF_IndirectObjectHolder::CPDF_IndirectObjectHolder(CPDF_Parser* pParser) |
1025 : m_pParser(pParser), m_LastObjNum(0) { | 686 : m_pParser(pParser), m_LastObjNum(0) { |
1026 if (pParser) | 687 if (pParser) |
1027 m_LastObjNum = m_pParser->GetLastObjNum(); | 688 m_LastObjNum = m_pParser->GetLastObjNum(); |
1028 } | 689 } |
| 690 |
1029 CPDF_IndirectObjectHolder::~CPDF_IndirectObjectHolder() { | 691 CPDF_IndirectObjectHolder::~CPDF_IndirectObjectHolder() { |
1030 for (const auto& pair : m_IndirectObjs) { | 692 for (const auto& pair : m_IndirectObjs) { |
1031 pair.second->Destroy(); | 693 pair.second->Destroy(); |
1032 } | 694 } |
1033 } | 695 } |
| 696 |
1034 CPDF_Object* CPDF_IndirectObjectHolder::GetIndirectObject(FX_DWORD objnum) { | 697 CPDF_Object* CPDF_IndirectObjectHolder::GetIndirectObject(FX_DWORD objnum) { |
1035 if (objnum == 0) | 698 if (objnum == 0) |
1036 return nullptr; | 699 return nullptr; |
1037 | 700 |
1038 auto it = m_IndirectObjs.find(objnum); | 701 auto it = m_IndirectObjs.find(objnum); |
1039 if (it != m_IndirectObjs.end()) | 702 if (it != m_IndirectObjs.end()) |
1040 return it->second->GetObjNum() != -1 ? it->second : nullptr; | 703 return it->second->GetObjNum() != -1 ? it->second : nullptr; |
1041 | 704 |
1042 if (!m_pParser) | 705 if (!m_pParser) |
1043 return nullptr; | 706 return nullptr; |
1044 | 707 |
1045 CPDF_Object* pObj = m_pParser->ParseIndirectObject(this, objnum); | 708 CPDF_Object* pObj = m_pParser->ParseIndirectObject(this, objnum); |
1046 if (!pObj) | 709 if (!pObj) |
1047 return nullptr; | 710 return nullptr; |
1048 | 711 |
1049 pObj->m_ObjNum = objnum; | 712 pObj->m_ObjNum = objnum; |
1050 m_LastObjNum = std::max(m_LastObjNum, objnum); | 713 m_LastObjNum = std::max(m_LastObjNum, objnum); |
1051 if (m_IndirectObjs[objnum]) | 714 if (m_IndirectObjs[objnum]) |
1052 m_IndirectObjs[objnum]->Destroy(); | 715 m_IndirectObjs[objnum]->Destroy(); |
1053 | 716 |
1054 m_IndirectObjs[objnum] = pObj; | 717 m_IndirectObjs[objnum] = pObj; |
1055 return pObj; | 718 return pObj; |
1056 } | 719 } |
| 720 |
1057 FX_DWORD CPDF_IndirectObjectHolder::AddIndirectObject(CPDF_Object* pObj) { | 721 FX_DWORD CPDF_IndirectObjectHolder::AddIndirectObject(CPDF_Object* pObj) { |
1058 if (pObj->m_ObjNum) { | 722 if (pObj->m_ObjNum) { |
1059 return pObj->m_ObjNum; | 723 return pObj->m_ObjNum; |
1060 } | 724 } |
1061 m_LastObjNum++; | 725 m_LastObjNum++; |
1062 m_IndirectObjs[m_LastObjNum] = pObj; | 726 m_IndirectObjs[m_LastObjNum] = pObj; |
1063 pObj->m_ObjNum = m_LastObjNum; | 727 pObj->m_ObjNum = m_LastObjNum; |
1064 return m_LastObjNum; | 728 return m_LastObjNum; |
1065 } | 729 } |
| 730 |
1066 void CPDF_IndirectObjectHolder::ReleaseIndirectObject(FX_DWORD objnum) { | 731 void CPDF_IndirectObjectHolder::ReleaseIndirectObject(FX_DWORD objnum) { |
1067 auto it = m_IndirectObjs.find(objnum); | 732 auto it = m_IndirectObjs.find(objnum); |
1068 if (it == m_IndirectObjs.end() || it->second->GetObjNum() == -1) | 733 if (it == m_IndirectObjs.end() || it->second->GetObjNum() == -1) |
1069 return; | 734 return; |
1070 it->second->Destroy(); | 735 it->second->Destroy(); |
1071 m_IndirectObjs.erase(it); | 736 m_IndirectObjs.erase(it); |
1072 } | 737 } |
| 738 |
1073 FX_BOOL CPDF_IndirectObjectHolder::InsertIndirectObject(FX_DWORD objnum, | 739 FX_BOOL CPDF_IndirectObjectHolder::InsertIndirectObject(FX_DWORD objnum, |
1074 CPDF_Object* pObj) { | 740 CPDF_Object* pObj) { |
1075 if (!objnum || !pObj) | 741 if (!objnum || !pObj) |
1076 return FALSE; | 742 return FALSE; |
1077 auto it = m_IndirectObjs.find(objnum); | 743 auto it = m_IndirectObjs.find(objnum); |
1078 if (it != m_IndirectObjs.end()) { | 744 if (it != m_IndirectObjs.end()) { |
1079 if (pObj->GetGenNum() <= it->second->GetGenNum()) { | 745 if (pObj->GetGenNum() <= it->second->GetGenNum()) { |
1080 pObj->Destroy(); | 746 pObj->Destroy(); |
1081 return FALSE; | 747 return FALSE; |
1082 } | 748 } |
1083 it->second->Destroy(); | 749 it->second->Destroy(); |
1084 } | 750 } |
1085 pObj->m_ObjNum = objnum; | 751 pObj->m_ObjNum = objnum; |
1086 m_IndirectObjs[objnum] = pObj; | 752 m_IndirectObjs[objnum] = pObj; |
1087 m_LastObjNum = std::max(m_LastObjNum, objnum); | 753 m_LastObjNum = std::max(m_LastObjNum, objnum); |
1088 return TRUE; | 754 return TRUE; |
1089 } | 755 } |
OLD | NEW |