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