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 "core/include/fpdfapi/fpdf_parser.h" | 9 #include "core/include/fpdfapi/fpdf_parser.h" |
10 #include "core/include/fxcrt/fx_string.h" | 10 #include "core/include/fxcrt/fx_string.h" |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 int n = pThis->GetCount(); | 260 int n = pThis->GetCount(); |
261 for (int i = 0; i < n; i++) { | 261 for (int i = 0; i < n; i++) { |
262 CPDF_Object* value = pThis->m_Objects.GetAt(i); | 262 CPDF_Object* value = pThis->m_Objects.GetAt(i); |
263 pCopy->m_Objects.Add(value->CloneInternal(bDirect, visited)); | 263 pCopy->m_Objects.Add(value->CloneInternal(bDirect, visited)); |
264 } | 264 } |
265 return pCopy; | 265 return pCopy; |
266 } | 266 } |
267 case PDFOBJ_DICTIONARY: { | 267 case PDFOBJ_DICTIONARY: { |
268 CPDF_Dictionary* pCopy = new CPDF_Dictionary(); | 268 CPDF_Dictionary* pCopy = new CPDF_Dictionary(); |
269 const CPDF_Dictionary* pThis = AsDictionary(); | 269 const CPDF_Dictionary* pThis = AsDictionary(); |
270 FX_POSITION pos = pThis->m_Map.GetStartPosition(); | 270 for (const auto& it : *pThis) { |
271 while (pos) { | 271 pCopy->m_Map.insert(std::make_pair( |
272 CFX_ByteString key; | 272 it.first, it.second->CloneInternal(bDirect, visited))); |
273 CPDF_Object* value; | |
274 pThis->m_Map.GetNextAssoc(pos, key, (void*&)value); | |
275 pCopy->m_Map.SetAt(key, value->CloneInternal(bDirect, visited)); | |
276 } | 273 } |
277 return pCopy; | 274 return pCopy; |
278 } | 275 } |
279 case PDFOBJ_NULL: { | 276 case PDFOBJ_NULL: { |
280 return new CPDF_Null; | 277 return new CPDF_Null; |
281 } | 278 } |
282 case PDFOBJ_STREAM: { | 279 case PDFOBJ_STREAM: { |
283 const CPDF_Stream* pThis = AsStream(); | 280 const CPDF_Stream* pThis = AsStream(); |
284 CPDF_StreamAcc acc; | 281 CPDF_StreamAcc acc; |
285 acc.LoadAllData(pThis, TRUE); | 282 acc.LoadAllData(pThis, TRUE); |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 if (m_Objects.GetSize() != pOther->m_Objects.GetSize()) { | 568 if (m_Objects.GetSize() != pOther->m_Objects.GetSize()) { |
572 return FALSE; | 569 return FALSE; |
573 } | 570 } |
574 for (int i = 0; i < m_Objects.GetSize(); i++) { | 571 for (int i = 0; i < m_Objects.GetSize(); i++) { |
575 if (!m_Objects[i]->IsIdentical(pOther->m_Objects[i])) | 572 if (!m_Objects[i]->IsIdentical(pOther->m_Objects[i])) |
576 return FALSE; | 573 return FALSE; |
577 } | 574 } |
578 return TRUE; | 575 return TRUE; |
579 } | 576 } |
580 CPDF_Dictionary::~CPDF_Dictionary() { | 577 CPDF_Dictionary::~CPDF_Dictionary() { |
581 FX_POSITION pos = m_Map.GetStartPosition(); | 578 for (const auto& it : m_Map) { |
582 while (pos) { | 579 it.second->Release(); |
583 if (CPDF_Object* value = static_cast<CPDF_Object*>(m_Map.GetNextValue(pos))) | |
584 value->Release(); | |
585 } | 580 } |
586 } | 581 } |
587 FX_POSITION CPDF_Dictionary::GetStartPos() const { | |
588 return m_Map.GetStartPosition(); | |
589 } | |
590 CPDF_Object* CPDF_Dictionary::GetNextElement(FX_POSITION& pos, | |
591 CFX_ByteString& key) const { | |
592 if (!pos) { | |
593 return NULL; | |
594 } | |
595 CPDF_Object* p; | |
596 m_Map.GetNextAssoc(pos, key, (void*&)p); | |
597 return p; | |
598 } | |
599 CPDF_Object* CPDF_Dictionary::GetElement(const CFX_ByteStringC& key) const { | 582 CPDF_Object* CPDF_Dictionary::GetElement(const CFX_ByteStringC& key) const { |
600 CPDF_Object* p = NULL; | 583 auto it = m_Map.find(key); |
601 m_Map.Lookup(key, (void*&)p); | 584 if (it == m_Map.end()) |
602 return p; | 585 return nullptr; |
| 586 return it->second; |
603 } | 587 } |
604 CPDF_Object* CPDF_Dictionary::GetElementValue( | 588 CPDF_Object* CPDF_Dictionary::GetElementValue( |
605 const CFX_ByteStringC& key) const { | 589 const CFX_ByteStringC& key) const { |
606 CPDF_Object* p = NULL; | 590 CPDF_Object* p = GetElement(key); |
607 m_Map.Lookup(key, (void*&)p); | 591 return p ? p->GetDirect() : nullptr; |
608 return p ? p->GetDirect() : NULL; | |
609 } | 592 } |
610 CFX_ByteString CPDF_Dictionary::GetString(const CFX_ByteStringC& key) const { | 593 CFX_ByteString CPDF_Dictionary::GetString(const CFX_ByteStringC& key) const { |
611 CPDF_Object* p = NULL; | 594 CPDF_Object* p = GetElement(key); |
612 m_Map.Lookup(key, (void*&)p); | |
613 if (p) { | 595 if (p) { |
614 return p->GetString(); | 596 return p->GetString(); |
615 } | 597 } |
616 return CFX_ByteString(); | 598 return CFX_ByteString(); |
617 } | 599 } |
618 CFX_ByteStringC CPDF_Dictionary::GetConstString( | 600 CFX_ByteStringC CPDF_Dictionary::GetConstString( |
619 const CFX_ByteStringC& key) const { | 601 const CFX_ByteStringC& key) const { |
620 CPDF_Object* p = NULL; | 602 CPDF_Object* p = GetElement(key); |
621 m_Map.Lookup(key, (void*&)p); | |
622 if (p) { | 603 if (p) { |
623 return p->GetConstString(); | 604 return p->GetConstString(); |
624 } | 605 } |
625 return CFX_ByteStringC(); | 606 return CFX_ByteStringC(); |
626 } | 607 } |
627 CFX_WideString CPDF_Dictionary::GetUnicodeText(const CFX_ByteStringC& key, | 608 CFX_WideString CPDF_Dictionary::GetUnicodeText(const CFX_ByteStringC& key, |
628 CFX_CharMap* pCharMap) const { | 609 CFX_CharMap* pCharMap) const { |
629 CPDF_Object* p = NULL; | 610 CPDF_Object* p = GetElement(key); |
630 m_Map.Lookup(key, (void*&)p); | |
631 if (CPDF_Reference* pRef = ToReference(p)) | 611 if (CPDF_Reference* pRef = ToReference(p)) |
632 p = pRef->GetDirect(); | 612 p = pRef->GetDirect(); |
633 return p ? p->GetUnicodeText(pCharMap) : CFX_WideString(); | 613 return p ? p->GetUnicodeText(pCharMap) : CFX_WideString(); |
634 } | 614 } |
635 CFX_ByteString CPDF_Dictionary::GetString(const CFX_ByteStringC& key, | 615 CFX_ByteString CPDF_Dictionary::GetString(const CFX_ByteStringC& key, |
636 const CFX_ByteStringC& def) const { | 616 const CFX_ByteStringC& def) const { |
637 CPDF_Object* p = NULL; | 617 CPDF_Object* p = GetElement(key); |
638 m_Map.Lookup(key, (void*&)p); | |
639 if (p) { | 618 if (p) { |
640 return p->GetString(); | 619 return p->GetString(); |
641 } | 620 } |
642 return CFX_ByteString(def); | 621 return CFX_ByteString(def); |
643 } | 622 } |
644 CFX_ByteStringC CPDF_Dictionary::GetConstString( | 623 CFX_ByteStringC CPDF_Dictionary::GetConstString( |
645 const CFX_ByteStringC& key, | 624 const CFX_ByteStringC& key, |
646 const CFX_ByteStringC& def) const { | 625 const CFX_ByteStringC& def) const { |
647 CPDF_Object* p = NULL; | 626 CPDF_Object* p = GetElement(key); |
648 m_Map.Lookup(key, (void*&)p); | |
649 if (p) { | 627 if (p) { |
650 return p->GetConstString(); | 628 return p->GetConstString(); |
651 } | 629 } |
652 return CFX_ByteStringC(def); | 630 return CFX_ByteStringC(def); |
653 } | 631 } |
654 int CPDF_Dictionary::GetInteger(const CFX_ByteStringC& key) const { | 632 int CPDF_Dictionary::GetInteger(const CFX_ByteStringC& key) const { |
655 CPDF_Object* p = NULL; | 633 CPDF_Object* p = GetElement(key); |
656 m_Map.Lookup(key, (void*&)p); | |
657 if (p) { | 634 if (p) { |
658 return p->GetInteger(); | 635 return p->GetInteger(); |
659 } | 636 } |
660 return 0; | 637 return 0; |
661 } | 638 } |
662 int CPDF_Dictionary::GetInteger(const CFX_ByteStringC& key, int def) const { | 639 int CPDF_Dictionary::GetInteger(const CFX_ByteStringC& key, int def) const { |
663 CPDF_Object* p = NULL; | 640 CPDF_Object* p = GetElement(key); |
664 m_Map.Lookup(key, (void*&)p); | |
665 if (p) { | 641 if (p) { |
666 return p->GetInteger(); | 642 return p->GetInteger(); |
667 } | 643 } |
668 return def; | 644 return def; |
669 } | 645 } |
670 FX_FLOAT CPDF_Dictionary::GetNumber(const CFX_ByteStringC& key) const { | 646 FX_FLOAT CPDF_Dictionary::GetNumber(const CFX_ByteStringC& key) const { |
671 CPDF_Object* p = NULL; | 647 CPDF_Object* p = GetElement(key); |
672 m_Map.Lookup(key, (void*&)p); | |
673 if (p) { | 648 if (p) { |
674 return p->GetNumber(); | 649 return p->GetNumber(); |
675 } | 650 } |
676 return 0; | 651 return 0; |
677 } | 652 } |
678 FX_BOOL CPDF_Dictionary::GetBoolean(const CFX_ByteStringC& key, | 653 FX_BOOL CPDF_Dictionary::GetBoolean(const CFX_ByteStringC& key, |
679 FX_BOOL bDefault) const { | 654 FX_BOOL bDefault) const { |
680 CPDF_Object* p = NULL; | 655 CPDF_Object* p = GetElement(key); |
681 m_Map.Lookup(key, (void*&)p); | |
682 if (ToBoolean(p)) | 656 if (ToBoolean(p)) |
683 return p->GetInteger(); | 657 return p->GetInteger(); |
684 return bDefault; | 658 return bDefault; |
685 } | 659 } |
686 CPDF_Dictionary* CPDF_Dictionary::GetDict(const CFX_ByteStringC& key) const { | 660 CPDF_Dictionary* CPDF_Dictionary::GetDict(const CFX_ByteStringC& key) const { |
687 CPDF_Object* p = GetElementValue(key); | 661 CPDF_Object* p = GetElementValue(key); |
688 if (!p) | 662 if (!p) |
689 return nullptr; | 663 return nullptr; |
690 if (CPDF_Dictionary* pDict = p->AsDictionary()) | 664 if (CPDF_Dictionary* pDict = p->AsDictionary()) |
691 return pDict; | 665 return pDict; |
(...skipping 15 matching lines...) Expand all Loading... |
707 return rect; | 681 return rect; |
708 } | 682 } |
709 CFX_Matrix CPDF_Dictionary::GetMatrix(const CFX_ByteStringC& key) const { | 683 CFX_Matrix CPDF_Dictionary::GetMatrix(const CFX_ByteStringC& key) const { |
710 CFX_Matrix matrix; | 684 CFX_Matrix matrix; |
711 CPDF_Array* pArray = GetArray(key); | 685 CPDF_Array* pArray = GetArray(key); |
712 if (pArray) | 686 if (pArray) |
713 matrix = pArray->GetMatrix(); | 687 matrix = pArray->GetMatrix(); |
714 return matrix; | 688 return matrix; |
715 } | 689 } |
716 FX_BOOL CPDF_Dictionary::KeyExist(const CFX_ByteStringC& key) const { | 690 FX_BOOL CPDF_Dictionary::KeyExist(const CFX_ByteStringC& key) const { |
717 void* value; | 691 return pdfium::ContainsKey(m_Map, key); |
718 return m_Map.Lookup(key, value); | |
719 } | 692 } |
720 | 693 |
721 void CPDF_Dictionary::SetAt(const CFX_ByteStringC& key, CPDF_Object* pObj) { | 694 void CPDF_Dictionary::SetAt(const CFX_ByteStringC& key, CPDF_Object* pObj) { |
722 ASSERT(IsDictionary()); | 695 ASSERT(IsDictionary()); |
723 void* pValue = nullptr; | 696 // Avoid 2 constructions of CFX_ByteString. |
724 m_Map.Lookup(key, pValue); | 697 CFX_ByteString key_bytestring = key; |
725 CPDF_Object* pExisting = static_cast<CPDF_Object*>(pValue); | 698 auto it = m_Map.find(key_bytestring); |
726 if (pExisting == pObj) | 699 if (it == m_Map.end()) { |
| 700 if (pObj) { |
| 701 m_Map.insert(std::make_pair(key_bytestring, pObj)); |
| 702 } |
727 return; | 703 return; |
| 704 } |
728 | 705 |
729 if (pExisting) | 706 if (it->second == pObj) |
730 pExisting->Release(); | 707 return; |
| 708 it->second->Release(); |
731 | 709 |
732 if (pObj) | 710 if (pObj) |
733 m_Map.SetAt(key, pObj); | 711 it->second = pObj; |
734 else | 712 else |
735 m_Map.RemoveKey(key); | 713 m_Map.erase(it); |
736 } | |
737 | |
738 void CPDF_Dictionary::AddValue(const CFX_ByteStringC& key, CPDF_Object* pObj) { | |
739 ASSERT(m_Type == PDFOBJ_DICTIONARY); | |
740 m_Map.AddValue(key, pObj); | |
741 } | 714 } |
742 void CPDF_Dictionary::RemoveAt(const CFX_ByteStringC& key) { | 715 void CPDF_Dictionary::RemoveAt(const CFX_ByteStringC& key) { |
743 ASSERT(m_Type == PDFOBJ_DICTIONARY); | 716 ASSERT(m_Type == PDFOBJ_DICTIONARY); |
744 CPDF_Object* p = NULL; | 717 auto it = m_Map.find(key); |
745 m_Map.Lookup(key, (void*&)p); | 718 if (it == m_Map.end()) |
746 if (!p) { | |
747 return; | 719 return; |
748 } | 720 |
749 p->Release(); | 721 it->second->Release(); |
750 m_Map.RemoveKey(key); | 722 m_Map.erase(it); |
751 } | 723 } |
752 void CPDF_Dictionary::ReplaceKey(const CFX_ByteStringC& oldkey, | 724 void CPDF_Dictionary::ReplaceKey(const CFX_ByteStringC& oldkey, |
753 const CFX_ByteStringC& newkey) { | 725 const CFX_ByteStringC& newkey) { |
754 ASSERT(m_Type == PDFOBJ_DICTIONARY); | 726 ASSERT(m_Type == PDFOBJ_DICTIONARY); |
755 CPDF_Object* p = NULL; | 727 auto old_it = m_Map.find(oldkey); |
756 m_Map.Lookup(oldkey, (void*&)p); | 728 if (old_it == m_Map.end()) |
757 if (!p) { | |
758 return; | 729 return; |
| 730 |
| 731 // Avoid 2 constructions of CFX_ByteString. |
| 732 CFX_ByteString newkey_bytestring = newkey; |
| 733 auto new_it = m_Map.find(newkey_bytestring); |
| 734 if (new_it != m_Map.end()) { |
| 735 new_it->second->Release(); |
| 736 new_it->second = old_it->second; |
| 737 } else { |
| 738 m_Map.insert(std::make_pair(newkey_bytestring, old_it->second)); |
759 } | 739 } |
760 m_Map.RemoveKey(oldkey); | 740 m_Map.erase(old_it); |
761 m_Map.SetAt(newkey, p); | |
762 } | 741 } |
763 FX_BOOL CPDF_Dictionary::Identical(CPDF_Dictionary* pOther) const { | 742 FX_BOOL CPDF_Dictionary::Identical(CPDF_Dictionary* pOther) const { |
764 if (!pOther) { | 743 if (!pOther) { |
765 return FALSE; | 744 return FALSE; |
766 } | 745 } |
767 if (m_Map.GetCount() != pOther->m_Map.GetCount()) { | 746 if (m_Map.size() != pOther->m_Map.size()) { |
768 return FALSE; | 747 return FALSE; |
769 } | 748 } |
770 FX_POSITION pos = m_Map.GetStartPosition(); | 749 for (const auto& it : m_Map) { |
771 while (pos) { | 750 const CFX_ByteString& key = it.first; |
772 CFX_ByteString key; | 751 if (!it.second->IsIdentical(pOther->GetElement(key))) |
773 void* value; | |
774 m_Map.GetNextAssoc(pos, key, value); | |
775 if (!value) | |
776 return FALSE; | |
777 if (!static_cast<CPDF_Object*>(value)->IsIdentical(pOther->GetElement(key))) | |
778 return FALSE; | 752 return FALSE; |
779 } | 753 } |
780 return TRUE; | 754 return TRUE; |
781 } | 755 } |
782 void CPDF_Dictionary::SetAtInteger(const CFX_ByteStringC& key, int i) { | 756 void CPDF_Dictionary::SetAtInteger(const CFX_ByteStringC& key, int i) { |
783 SetAt(key, new CPDF_Number(i)); | 757 SetAt(key, new CPDF_Number(i)); |
784 } | 758 } |
785 void CPDF_Dictionary::SetAtName(const CFX_ByteStringC& key, | 759 void CPDF_Dictionary::SetAtName(const CFX_ByteStringC& key, |
786 const CFX_ByteString& name) { | 760 const CFX_ByteString& name) { |
787 SetAt(key, new CPDF_Name(name)); | 761 SetAt(key, new CPDF_Name(name)); |
788 } | 762 } |
789 void CPDF_Dictionary::SetAtString(const CFX_ByteStringC& key, | 763 void CPDF_Dictionary::SetAtString(const CFX_ByteStringC& key, |
790 const CFX_ByteString& str) { | 764 const CFX_ByteString& str) { |
791 SetAt(key, new CPDF_String(str, FALSE)); | 765 SetAt(key, new CPDF_String(str, FALSE)); |
792 } | 766 } |
793 void CPDF_Dictionary::SetAtReference(const CFX_ByteStringC& key, | 767 void CPDF_Dictionary::SetAtReference(const CFX_ByteStringC& key, |
794 CPDF_IndirectObjects* pDoc, | 768 CPDF_IndirectObjects* pDoc, |
795 FX_DWORD objnum) { | 769 FX_DWORD objnum) { |
796 SetAt(key, new CPDF_Reference(pDoc, objnum)); | 770 SetAt(key, new CPDF_Reference(pDoc, objnum)); |
797 } | 771 } |
798 void CPDF_Dictionary::AddReference(const CFX_ByteStringC& key, | 772 void CPDF_Dictionary::AddReference(const CFX_ByteStringC& key, |
799 CPDF_IndirectObjects* pDoc, | 773 CPDF_IndirectObjects* pDoc, |
800 FX_DWORD objnum) { | 774 FX_DWORD objnum) { |
801 AddValue(key, new CPDF_Reference(pDoc, objnum)); | 775 SetAt(key, new CPDF_Reference(pDoc, objnum)); |
802 } | 776 } |
803 void CPDF_Dictionary::SetAtNumber(const CFX_ByteStringC& key, FX_FLOAT f) { | 777 void CPDF_Dictionary::SetAtNumber(const CFX_ByteStringC& key, FX_FLOAT f) { |
804 CPDF_Number* pNumber = new CPDF_Number; | 778 CPDF_Number* pNumber = new CPDF_Number; |
805 pNumber->SetNumber(f); | 779 pNumber->SetNumber(f); |
806 SetAt(key, pNumber); | 780 SetAt(key, pNumber); |
807 } | 781 } |
808 void CPDF_Dictionary::SetAtBoolean(const CFX_ByteStringC& key, FX_BOOL bValue) { | 782 void CPDF_Dictionary::SetAtBoolean(const CFX_ByteStringC& key, FX_BOOL bValue) { |
809 SetAt(key, new CPDF_Boolean(bValue)); | 783 SetAt(key, new CPDF_Boolean(bValue)); |
810 } | 784 } |
811 void CPDF_Dictionary::SetAtRect(const CFX_ByteStringC& key, | 785 void CPDF_Dictionary::SetAtRect(const CFX_ByteStringC& key, |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1176 } | 1150 } |
1177 pObj->m_ObjNum = objnum; | 1151 pObj->m_ObjNum = objnum; |
1178 m_IndirectObjs.SetAt((void*)(uintptr_t)objnum, pObj); | 1152 m_IndirectObjs.SetAt((void*)(uintptr_t)objnum, pObj); |
1179 if (m_LastObjNum < objnum) | 1153 if (m_LastObjNum < objnum) |
1180 m_LastObjNum = objnum; | 1154 m_LastObjNum = objnum; |
1181 return TRUE; | 1155 return TRUE; |
1182 } | 1156 } |
1183 FX_DWORD CPDF_IndirectObjects::GetLastObjNum() const { | 1157 FX_DWORD CPDF_IndirectObjects::GetLastObjNum() const { |
1184 return m_LastObjNum; | 1158 return m_LastObjNum; |
1185 } | 1159 } |
OLD | NEW |