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