Index: core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp |
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp |
index 6b512949ae0ed0ac4b8fa77e719008f7b307da3a..813c18a4c5c0b7e9b8fe53e6322e93500af6fdb1 100644 |
--- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp |
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp |
@@ -12,382 +12,38 @@ |
#include "core/include/fxcrt/fx_string.h" |
#include "third_party/base/stl_util.h" |
-namespace { |
- |
-const FX_DWORD kBlockSize = 1024; |
- |
-} // namespace |
- |
void CPDF_Object::Release() { |
if (m_ObjNum) { |
return; |
} |
Destroy(); |
} |
-void CPDF_Object::Destroy() { |
- switch (m_Type) { |
- case STRING: |
- delete AsString(); |
- break; |
- case NAME: |
- delete AsName(); |
- break; |
- case ARRAY: |
- delete AsArray(); |
- break; |
- case DICTIONARY: |
- delete AsDictionary(); |
- break; |
- case STREAM: |
- delete AsStream(); |
- break; |
- default: |
- delete this; |
- } |
-} |
- |
-const CPDF_Object* CPDF_Object::GetBasicObject() const { |
- const CPDF_Reference* pRef = AsReference(); |
- if (!pRef) { |
- // This is not an indirect reference. |
- return this; |
- } |
- if (!pRef->m_pObjList) |
- return nullptr; |
- return pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum()); |
-} |
- |
-CFX_ByteString CPDF_Object::GetString() const { |
- const CPDF_Object* obj = GetBasicObject(); |
- if (obj) { |
- switch (obj->GetType()) { |
- case BOOLEAN: |
- return obj->AsBoolean()->GetString(); |
- case NUMBER: |
- return obj->AsNumber()->GetString(); |
- case STRING: |
- return obj->AsString()->GetString(); |
- case NAME: |
- return obj->AsName()->GetString(); |
- default: |
- break; |
- } |
- } |
- return CFX_ByteString(); |
-} |
- |
-CFX_ByteStringC CPDF_Object::GetConstString() const { |
- const CPDF_Object* obj = GetBasicObject(); |
- if (obj) { |
- FX_DWORD type = obj->GetType(); |
- if (type == STRING) { |
- CFX_ByteString str = obj->AsString()->GetString(); |
- return CFX_ByteStringC(str); |
- } |
- if (type == NAME) { |
- CFX_ByteString name = obj->AsName()->GetString(); |
- return CFX_ByteStringC(name); |
- } |
- } |
- return CFX_ByteStringC(); |
-} |
- |
-FX_FLOAT CPDF_Object::GetNumber() const { |
- const CPDF_Object* obj = GetBasicObject(); |
- if (obj && obj->GetType() == NUMBER) |
- return obj->AsNumber()->GetNumber(); |
- return 0; |
-} |
- |
-FX_FLOAT CPDF_Object::GetNumber16() const { |
- return GetNumber(); |
-} |
- |
-int CPDF_Object::GetInteger() const { |
- const CPDF_Object* obj = GetBasicObject(); |
- if (obj) { |
- FX_DWORD type = obj->GetType(); |
- if (type == BOOLEAN) |
- return obj->AsBoolean()->GetValue(); |
- if (type == NUMBER) |
- return obj->AsNumber()->GetInteger(); |
- } |
- return 0; |
-} |
- |
-CPDF_Dictionary* CPDF_Object::GetDict() const { |
- const CPDF_Object* obj = GetBasicObject(); |
- if (obj) { |
- FX_DWORD type = obj->GetType(); |
- if (type == DICTIONARY) { |
- // The method should be made non-const if we want to not be const. |
- // See bug #234. |
- return const_cast<CPDF_Dictionary*>(obj->AsDictionary()); |
- } |
- if (type == STREAM) |
- return obj->AsStream()->GetDict(); |
- } |
- return nullptr; |
-} |
- |
-CPDF_Array* CPDF_Object::GetArray() const { |
- // The method should be made non-const if we want to not be const. |
- // See bug #234. |
- return const_cast<CPDF_Array*>(AsArray()); |
-} |
- |
-void CPDF_Object::SetString(const CFX_ByteString& str) { |
- switch (m_Type) { |
- case BOOLEAN: |
- AsBoolean()->m_bValue = (str == "true"); |
- return; |
- case NUMBER: |
- AsNumber()->SetString(str); |
- return; |
- case STRING: |
- AsString()->m_String = str; |
- return; |
- case NAME: |
- AsName()->m_Name = str; |
- return; |
- default: |
- break; |
- } |
- ASSERT(FALSE); |
-} |
-FX_BOOL CPDF_Object::IsIdentical(CPDF_Object* pOther) const { |
- if (this == pOther) |
- return TRUE; |
- if (!pOther) |
- return FALSE; |
- if (pOther->m_Type != m_Type) { |
- if (IsReference() && GetDirect()) |
- return GetDirect()->IsIdentical(pOther); |
- if (pOther->IsReference()) |
- return IsIdentical(pOther->GetDirect()); |
- return FALSE; |
- } |
- switch (m_Type) { |
- case BOOLEAN: |
- return AsBoolean()->Identical(pOther->AsBoolean()); |
- case NUMBER: |
- return AsNumber()->Identical(pOther->AsNumber()); |
- case STRING: |
- return AsString()->Identical(pOther->AsString()); |
- case NAME: |
- return AsName()->Identical(pOther->AsName()); |
- case ARRAY: |
- return AsArray()->Identical(pOther->AsArray()); |
- case DICTIONARY: |
- return AsDictionary()->Identical(pOther->AsDictionary()); |
- case NULLOBJ: |
- return TRUE; |
- case STREAM: |
- return AsStream()->Identical(pOther->AsStream()); |
- case REFERENCE: |
- return AsReference()->Identical(pOther->AsReference()); |
- } |
- return FALSE; |
-} |
- |
-CPDF_Object* CPDF_Object::GetDirect() const { |
- const CPDF_Reference* pRef = AsReference(); |
- if (!pRef) |
- return const_cast<CPDF_Object*>(this); |
- if (!pRef->m_pObjList) |
- return nullptr; |
- return pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum()); |
-} |
- |
-CPDF_Object* CPDF_Object::Clone(FX_BOOL bDirect) const { |
- std::set<FX_DWORD> visited; |
- return CloneInternal(bDirect, &visited); |
-} |
-CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, |
- std::set<FX_DWORD>* visited) const { |
- switch (m_Type) { |
- case BOOLEAN: |
- return new CPDF_Boolean(AsBoolean()->m_bValue); |
- case NUMBER: { |
- const CPDF_Number* pThis = AsNumber(); |
- return new CPDF_Number(pThis->m_bInteger ? pThis->m_Integer |
- : pThis->m_Float); |
- } |
- case STRING: { |
- const CPDF_String* pString = AsString(); |
- return new CPDF_String(pString->m_String, pString->IsHex()); |
- } |
- case NAME: |
- return new CPDF_Name(AsName()->m_Name); |
- case ARRAY: { |
- CPDF_Array* pCopy = new CPDF_Array(); |
- const CPDF_Array* pThis = AsArray(); |
- int n = pThis->GetCount(); |
- for (int i = 0; i < n; i++) { |
- CPDF_Object* value = pThis->m_Objects.GetAt(i); |
- pCopy->m_Objects.Add(value->CloneInternal(bDirect, visited)); |
- } |
- return pCopy; |
- } |
- case DICTIONARY: { |
- CPDF_Dictionary* pCopy = new CPDF_Dictionary(); |
- const CPDF_Dictionary* pThis = AsDictionary(); |
- for (const auto& it : *pThis) { |
- pCopy->m_Map.insert(std::make_pair( |
- it.first, it.second->CloneInternal(bDirect, visited))); |
- } |
- return pCopy; |
- } |
- case NULLOBJ: { |
- return new CPDF_Null; |
- } |
- case STREAM: { |
- const CPDF_Stream* pThis = AsStream(); |
- CPDF_StreamAcc acc; |
- acc.LoadAllData(pThis, TRUE); |
- FX_DWORD streamSize = acc.GetSize(); |
- CPDF_Dictionary* pDict = pThis->GetDict(); |
- if (pDict) { |
- pDict = ToDictionary(pDict->CloneInternal(bDirect, visited)); |
- } |
- return new CPDF_Stream(acc.DetachData(), streamSize, pDict); |
- } |
- case REFERENCE: { |
- const CPDF_Reference* pRef = AsReference(); |
- FX_DWORD obj_num = pRef->GetRefObjNum(); |
- if (bDirect && !pdfium::ContainsKey(*visited, obj_num)) { |
- visited->insert(obj_num); |
- auto* pDirect = pRef->GetDirect(); |
- return pDirect ? pDirect->CloneInternal(TRUE, visited) : nullptr; |
- } |
- return new CPDF_Reference(pRef->m_pObjList, obj_num); |
- } |
- } |
- return NULL; |
-} |
-CPDF_Object* CPDF_Object::CloneRef(CPDF_IndirectObjectHolder* pDoc) const { |
- if (m_ObjNum) { |
- return new CPDF_Reference(pDoc, m_ObjNum); |
- } |
- return Clone(); |
-} |
-CFX_WideString CPDF_Object::GetUnicodeText(CFX_CharMap* pCharMap) const { |
- if (const CPDF_String* pString = AsString()) |
- return PDF_DecodeText(pString->m_String, pCharMap); |
- |
- if (const CPDF_Stream* pStream = AsStream()) { |
- CPDF_StreamAcc stream; |
- stream.LoadAllData(pStream, FALSE); |
- CFX_WideString result = |
- PDF_DecodeText(stream.GetData(), stream.GetSize(), pCharMap); |
- return result; |
- } |
- if (const CPDF_Name* pName = AsName()) |
- return PDF_DecodeText(pName->m_Name, pCharMap); |
- return CFX_WideString(); |
-} |
-void CPDF_Object::SetUnicodeText(const FX_WCHAR* pUnicodes, int len) { |
- if (CPDF_String* pString = AsString()) { |
- pString->m_String = PDF_EncodeText(pUnicodes, len); |
- } else if (CPDF_Stream* pStream = AsStream()) { |
- CFX_ByteString result = PDF_EncodeText(pUnicodes, len); |
- pStream->SetData((uint8_t*)result.c_str(), result.GetLength(), FALSE, |
- FALSE); |
- } |
-} |
- |
-CPDF_Array* CPDF_Object::AsArray() { |
- return IsArray() ? static_cast<CPDF_Array*>(this) : nullptr; |
-} |
- |
-const CPDF_Array* CPDF_Object::AsArray() const { |
- return IsArray() ? static_cast<const CPDF_Array*>(this) : nullptr; |
-} |
-CPDF_Boolean* CPDF_Object::AsBoolean() { |
- return IsBoolean() ? static_cast<CPDF_Boolean*>(this) : nullptr; |
-} |
- |
-const CPDF_Boolean* CPDF_Object::AsBoolean() const { |
- return IsBoolean() ? static_cast<const CPDF_Boolean*>(this) : nullptr; |
-} |
- |
-CPDF_Dictionary* CPDF_Object::AsDictionary() { |
- return IsDictionary() ? static_cast<CPDF_Dictionary*>(this) : nullptr; |
-} |
- |
-const CPDF_Dictionary* CPDF_Object::AsDictionary() const { |
- return IsDictionary() ? static_cast<const CPDF_Dictionary*>(this) : nullptr; |
-} |
- |
-CPDF_Name* CPDF_Object::AsName() { |
- return IsName() ? static_cast<CPDF_Name*>(this) : nullptr; |
-} |
- |
-const CPDF_Name* CPDF_Object::AsName() const { |
- return IsName() ? static_cast<const CPDF_Name*>(this) : nullptr; |
-} |
- |
-CPDF_Number* CPDF_Object::AsNumber() { |
- return IsNumber() ? static_cast<CPDF_Number*>(this) : nullptr; |
-} |
- |
-const CPDF_Number* CPDF_Object::AsNumber() const { |
- return IsNumber() ? static_cast<const CPDF_Number*>(this) : nullptr; |
-} |
- |
-CPDF_Reference* CPDF_Object::AsReference() { |
- return IsReference() ? static_cast<CPDF_Reference*>(this) : nullptr; |
-} |
- |
-const CPDF_Reference* CPDF_Object::AsReference() const { |
- return IsReference() ? static_cast<const CPDF_Reference*>(this) : nullptr; |
+CPDF_Number::CPDF_Number(const CFX_ByteStringC& str) { |
+ FX_atonum(str, m_bInteger, &m_Integer); |
} |
-CPDF_Stream* CPDF_Object::AsStream() { |
- return IsStream() ? static_cast<CPDF_Stream*>(this) : nullptr; |
+void CPDF_Number::SetString(const CFX_ByteString& str) { |
+ FX_atonum(str, m_bInteger, &m_Integer); |
} |
-const CPDF_Stream* CPDF_Object::AsStream() const { |
- return IsStream() ? static_cast<const CPDF_Stream*>(this) : nullptr; |
+CFX_ByteString CPDF_Number::GetString() const { |
+ return m_bInteger ? CFX_ByteString::FormatInteger(m_Integer, FXFORMAT_SIGNED) |
+ : CFX_ByteString::FormatFloat(m_Float); |
} |
-CPDF_String* CPDF_Object::AsString() { |
- return IsString() ? static_cast<CPDF_String*>(this) : nullptr; |
+CPDF_String::CPDF_String(const CFX_WideString& str) : m_bHex(FALSE) { |
+ m_String = PDF_EncodeText(str); |
} |
-const CPDF_String* CPDF_Object::AsString() const { |
- return IsString() ? static_cast<const CPDF_String*>(this) : nullptr; |
+CFX_WideString CPDF_String::GetUnicodeText(CFX_CharMap* pCharMap) const { |
+ return PDF_DecodeText(m_String, pCharMap); |
} |
-CPDF_Number::CPDF_Number(int value) |
- : CPDF_Object(NUMBER), m_bInteger(TRUE), m_Integer(value) {} |
- |
-CPDF_Number::CPDF_Number(FX_FLOAT value) |
- : CPDF_Object(NUMBER), m_bInteger(FALSE), m_Float(value) {} |
- |
-CPDF_Number::CPDF_Number(const CFX_ByteStringC& str) : CPDF_Object(NUMBER) { |
- FX_atonum(str, m_bInteger, &m_Integer); |
+CFX_WideString CPDF_Name::GetUnicodeText(CFX_CharMap* pCharMap) const { |
+ return PDF_DecodeText(m_Name, pCharMap); |
} |
-void CPDF_Number::SetString(const CFX_ByteStringC& str) { |
- FX_atonum(str, m_bInteger, &m_Integer); |
-} |
-FX_BOOL CPDF_Number::Identical(CPDF_Number* pOther) const { |
- return m_bInteger == pOther->m_bInteger && m_Integer == pOther->m_Integer; |
-} |
-CFX_ByteString CPDF_Number::GetString() const { |
- return m_bInteger ? CFX_ByteString::FormatInteger(m_Integer, FXFORMAT_SIGNED) |
- : CFX_ByteString::FormatFloat(m_Float); |
-} |
-void CPDF_Number::SetNumber(FX_FLOAT value) { |
- m_bInteger = FALSE; |
- m_Float = value; |
-} |
-CPDF_String::CPDF_String(const CFX_WideString& str) |
- : CPDF_Object(STRING), m_bHex(FALSE) { |
- m_String = PDF_EncodeText(str); |
-} |
CPDF_Array::~CPDF_Array() { |
int size = m_Objects.GetSize(); |
CPDF_Object** pList = m_Objects.GetData(); |
@@ -396,6 +52,16 @@ CPDF_Array::~CPDF_Array() { |
pList[i]->Release(); |
} |
} |
+ |
+CPDF_Object* CPDF_Array::Clone(FX_BOOL bDirect) const { |
+ CPDF_Array* pCopy = new CPDF_Array(); |
+ for (int i = 0; i < GetCount(); i++) { |
+ CPDF_Object* value = m_Objects.GetAt(i); |
+ pCopy->m_Objects.Add(value->Clone(bDirect)); |
+ } |
+ return pCopy; |
+} |
+ |
CFX_FloatRect CPDF_Array::GetRect() { |
CFX_FloatRect rect; |
if (!IsArray() || m_Objects.GetSize() != 4) |
@@ -407,6 +73,7 @@ CFX_FloatRect CPDF_Array::GetRect() { |
rect.top = GetNumberAt(3); |
return rect; |
} |
+ |
CFX_Matrix CPDF_Array::GetMatrix() { |
CFX_Matrix matrix; |
if (!IsArray() || m_Objects.GetSize() != 6) |
@@ -416,36 +83,43 @@ CFX_Matrix CPDF_Array::GetMatrix() { |
GetNumberAt(4), GetNumberAt(5)); |
return matrix; |
} |
+ |
CPDF_Object* CPDF_Array::GetElement(FX_DWORD i) const { |
if (i >= (FX_DWORD)m_Objects.GetSize()) |
return nullptr; |
return m_Objects.GetAt(i); |
} |
+ |
CPDF_Object* CPDF_Array::GetElementValue(FX_DWORD i) const { |
if (i >= (FX_DWORD)m_Objects.GetSize()) |
return nullptr; |
return m_Objects.GetAt(i)->GetDirect(); |
} |
+ |
CFX_ByteString CPDF_Array::GetStringAt(FX_DWORD i) const { |
if (i >= (FX_DWORD)m_Objects.GetSize()) |
return CFX_ByteString(); |
return m_Objects.GetAt(i)->GetString(); |
} |
+ |
CFX_ByteStringC CPDF_Array::GetConstStringAt(FX_DWORD i) const { |
if (i >= (FX_DWORD)m_Objects.GetSize()) |
return CFX_ByteStringC(); |
return m_Objects.GetAt(i)->GetConstString(); |
} |
+ |
int CPDF_Array::GetIntegerAt(FX_DWORD i) const { |
if (i >= (FX_DWORD)m_Objects.GetSize()) |
return 0; |
return m_Objects.GetAt(i)->GetInteger(); |
} |
+ |
FX_FLOAT CPDF_Array::GetNumberAt(FX_DWORD i) const { |
if (i >= (FX_DWORD)m_Objects.GetSize()) |
return 0; |
return m_Objects.GetAt(i)->GetNumber(); |
} |
+ |
CPDF_Dictionary* CPDF_Array::GetDictAt(FX_DWORD i) const { |
CPDF_Object* p = GetElementValue(i); |
if (!p) |
@@ -456,12 +130,15 @@ CPDF_Dictionary* CPDF_Array::GetDictAt(FX_DWORD i) const { |
return pStream->GetDict(); |
return NULL; |
} |
+ |
CPDF_Stream* CPDF_Array::GetStreamAt(FX_DWORD i) const { |
return ToStream(GetElementValue(i)); |
} |
+ |
CPDF_Array* CPDF_Array::GetArrayAt(FX_DWORD i) const { |
return ToArray(GetElementValue(i)); |
} |
+ |
void CPDF_Array::RemoveAt(FX_DWORD i, int nCount) { |
if (i >= (FX_DWORD)m_Objects.GetSize()) |
return; |
@@ -475,6 +152,7 @@ void CPDF_Array::RemoveAt(FX_DWORD i, int nCount) { |
} |
m_Objects.RemoveAt(i, nCount); |
} |
+ |
void CPDF_Array::SetAt(FX_DWORD i, |
CPDF_Object* pObj, |
CPDF_IndirectObjectHolder* pObjs) { |
@@ -490,6 +168,7 @@ void CPDF_Array::SetAt(FX_DWORD i, |
} |
m_Objects.SetAt(i, pObj); |
} |
+ |
void CPDF_Array::InsertAt(FX_DWORD index, |
CPDF_Object* pObj, |
CPDF_IndirectObjectHolder* pObjs) { |
@@ -499,6 +178,7 @@ void CPDF_Array::InsertAt(FX_DWORD index, |
} |
m_Objects.InsertAt(index, pObj); |
} |
+ |
void CPDF_Array::Add(CPDF_Object* pObj, CPDF_IndirectObjectHolder* pObjs) { |
if (pObj->GetObjNum()) { |
ASSERT(pObjs); |
@@ -506,44 +186,47 @@ void CPDF_Array::Add(CPDF_Object* pObj, CPDF_IndirectObjectHolder* pObjs) { |
} |
m_Objects.Add(pObj); |
} |
+ |
void CPDF_Array::AddName(const CFX_ByteString& str) { |
ASSERT(IsArray()); |
Add(new CPDF_Name(str)); |
} |
+ |
void CPDF_Array::AddString(const CFX_ByteString& str) { |
ASSERT(IsArray()); |
Add(new CPDF_String(str, FALSE)); |
} |
+ |
void CPDF_Array::AddInteger(int i) { |
ASSERT(IsArray()); |
Add(new CPDF_Number(i)); |
} |
+ |
void CPDF_Array::AddNumber(FX_FLOAT f) { |
ASSERT(IsArray()); |
- CPDF_Number* pNumber = new CPDF_Number; |
- pNumber->SetNumber(f); |
+ CPDF_Number* pNumber = new CPDF_Number(f); |
Add(pNumber); |
} |
+ |
void CPDF_Array::AddReference(CPDF_IndirectObjectHolder* pDoc, |
FX_DWORD objnum) { |
ASSERT(IsArray()); |
Add(new CPDF_Reference(pDoc, objnum)); |
} |
-FX_BOOL CPDF_Array::Identical(CPDF_Array* pOther) const { |
- if (m_Objects.GetSize() != pOther->m_Objects.GetSize()) { |
- return FALSE; |
- } |
- for (int i = 0; i < m_Objects.GetSize(); i++) { |
- if (!m_Objects[i]->IsIdentical(pOther->m_Objects[i])) |
- return FALSE; |
- } |
- return TRUE; |
-} |
+ |
CPDF_Dictionary::~CPDF_Dictionary() { |
for (const auto& it : m_Map) { |
it.second->Release(); |
} |
} |
+ |
+CPDF_Object* CPDF_Dictionary::Clone(FX_BOOL bDirect) const { |
+ CPDF_Dictionary* pCopy = new CPDF_Dictionary(); |
+ for (const auto& it : *this) |
+ pCopy->m_Map.insert(std::make_pair(it.first, it.second->Clone(bDirect))); |
+ return pCopy; |
+} |
+ |
CPDF_Object* CPDF_Dictionary::GetElement(const CFX_ByteStringC& key) const { |
auto it = m_Map.find(key); |
if (it == m_Map.end()) |
@@ -555,6 +238,7 @@ CPDF_Object* CPDF_Dictionary::GetElementValue( |
CPDF_Object* p = GetElement(key); |
return p ? p->GetDirect() : nullptr; |
} |
+ |
CFX_ByteString CPDF_Dictionary::GetStringBy(const CFX_ByteStringC& key) const { |
CPDF_Object* p = GetElement(key); |
if (p) { |
@@ -562,6 +246,7 @@ CFX_ByteString CPDF_Dictionary::GetStringBy(const CFX_ByteStringC& key) const { |
} |
return CFX_ByteString(); |
} |
+ |
CFX_ByteStringC CPDF_Dictionary::GetConstStringBy( |
const CFX_ByteStringC& key) const { |
CPDF_Object* p = GetElement(key); |
@@ -570,6 +255,7 @@ CFX_ByteStringC CPDF_Dictionary::GetConstStringBy( |
} |
return CFX_ByteStringC(); |
} |
+ |
CFX_WideString CPDF_Dictionary::GetUnicodeTextBy(const CFX_ByteStringC& key, |
CFX_CharMap* pCharMap) const { |
CPDF_Object* p = GetElement(key); |
@@ -577,6 +263,7 @@ CFX_WideString CPDF_Dictionary::GetUnicodeTextBy(const CFX_ByteStringC& key, |
p = pRef->GetDirect(); |
return p ? p->GetUnicodeText(pCharMap) : CFX_WideString(); |
} |
+ |
CFX_ByteString CPDF_Dictionary::GetStringBy(const CFX_ByteStringC& key, |
const CFX_ByteStringC& def) const { |
CPDF_Object* p = GetElement(key); |
@@ -585,6 +272,7 @@ CFX_ByteString CPDF_Dictionary::GetStringBy(const CFX_ByteStringC& key, |
} |
return CFX_ByteString(def); |
} |
+ |
CFX_ByteStringC CPDF_Dictionary::GetConstStringBy( |
const CFX_ByteStringC& key, |
const CFX_ByteStringC& def) const { |
@@ -594,6 +282,7 @@ CFX_ByteStringC CPDF_Dictionary::GetConstStringBy( |
} |
return CFX_ByteStringC(def); |
} |
+ |
int CPDF_Dictionary::GetIntegerBy(const CFX_ByteStringC& key) const { |
CPDF_Object* p = GetElement(key); |
if (p) { |
@@ -601,6 +290,7 @@ int CPDF_Dictionary::GetIntegerBy(const CFX_ByteStringC& key) const { |
} |
return 0; |
} |
+ |
int CPDF_Dictionary::GetIntegerBy(const CFX_ByteStringC& key, int def) const { |
CPDF_Object* p = GetElement(key); |
if (p) { |
@@ -608,6 +298,7 @@ int CPDF_Dictionary::GetIntegerBy(const CFX_ByteStringC& key, int def) const { |
} |
return def; |
} |
+ |
FX_FLOAT CPDF_Dictionary::GetNumberBy(const CFX_ByteStringC& key) const { |
CPDF_Object* p = GetElement(key); |
if (p) { |
@@ -615,6 +306,7 @@ FX_FLOAT CPDF_Dictionary::GetNumberBy(const CFX_ByteStringC& key) const { |
} |
return 0; |
} |
+ |
FX_BOOL CPDF_Dictionary::GetBooleanBy(const CFX_ByteStringC& key, |
FX_BOOL bDefault) const { |
CPDF_Object* p = GetElement(key); |
@@ -622,6 +314,7 @@ FX_BOOL CPDF_Dictionary::GetBooleanBy(const CFX_ByteStringC& key, |
return p->GetInteger(); |
return bDefault; |
} |
+ |
CPDF_Dictionary* CPDF_Dictionary::GetDictBy(const CFX_ByteStringC& key) const { |
CPDF_Object* p = GetElementValue(key); |
if (!p) |
@@ -632,12 +325,15 @@ CPDF_Dictionary* CPDF_Dictionary::GetDictBy(const CFX_ByteStringC& key) const { |
return pStream->GetDict(); |
return nullptr; |
} |
+ |
CPDF_Array* CPDF_Dictionary::GetArrayBy(const CFX_ByteStringC& key) const { |
return ToArray(GetElementValue(key)); |
} |
+ |
CPDF_Stream* CPDF_Dictionary::GetStreamBy(const CFX_ByteStringC& key) const { |
return ToStream(GetElementValue(key)); |
} |
+ |
CFX_FloatRect CPDF_Dictionary::GetRectBy(const CFX_ByteStringC& key) const { |
CFX_FloatRect rect; |
CPDF_Array* pArray = GetArrayBy(key); |
@@ -645,6 +341,7 @@ CFX_FloatRect CPDF_Dictionary::GetRectBy(const CFX_ByteStringC& key) const { |
rect = pArray->GetRect(); |
return rect; |
} |
+ |
CFX_Matrix CPDF_Dictionary::GetMatrixBy(const CFX_ByteStringC& key) const { |
CFX_Matrix matrix; |
CPDF_Array* pArray = GetArrayBy(key); |
@@ -652,6 +349,7 @@ CFX_Matrix CPDF_Dictionary::GetMatrixBy(const CFX_ByteStringC& key) const { |
matrix = pArray->GetMatrix(); |
return matrix; |
} |
+ |
FX_BOOL CPDF_Dictionary::KeyExist(const CFX_ByteStringC& key) const { |
return pdfium::ContainsKey(m_Map, key); |
} |
@@ -677,8 +375,8 @@ void CPDF_Dictionary::SetAt(const CFX_ByteStringC& key, CPDF_Object* pObj) { |
else |
m_Map.erase(it); |
} |
+ |
void CPDF_Dictionary::RemoveAt(const CFX_ByteStringC& key) { |
- ASSERT(m_Type == DICTIONARY); |
auto it = m_Map.find(key); |
if (it == m_Map.end()) |
return; |
@@ -686,9 +384,9 @@ void CPDF_Dictionary::RemoveAt(const CFX_ByteStringC& key) { |
it->second->Release(); |
m_Map.erase(it); |
} |
+ |
void CPDF_Dictionary::ReplaceKey(const CFX_ByteStringC& oldkey, |
const CFX_ByteStringC& newkey) { |
- ASSERT(m_Type == DICTIONARY); |
auto old_it = m_Map.find(oldkey); |
if (old_it == m_Map.end()) |
return; |
@@ -707,49 +405,42 @@ void CPDF_Dictionary::ReplaceKey(const CFX_ByteStringC& oldkey, |
} |
m_Map.erase(old_it); |
} |
-FX_BOOL CPDF_Dictionary::Identical(CPDF_Dictionary* pOther) const { |
- if (!pOther) { |
- return FALSE; |
- } |
- if (m_Map.size() != pOther->m_Map.size()) { |
- return FALSE; |
- } |
- for (const auto& it : m_Map) { |
- const CFX_ByteString& key = it.first; |
- if (!it.second->IsIdentical(pOther->GetElement(key))) |
- return FALSE; |
- } |
- return TRUE; |
-} |
+ |
void CPDF_Dictionary::SetAtInteger(const CFX_ByteStringC& key, int i) { |
SetAt(key, new CPDF_Number(i)); |
} |
+ |
void CPDF_Dictionary::SetAtName(const CFX_ByteStringC& key, |
const CFX_ByteString& name) { |
SetAt(key, new CPDF_Name(name)); |
} |
+ |
void CPDF_Dictionary::SetAtString(const CFX_ByteStringC& key, |
const CFX_ByteString& str) { |
SetAt(key, new CPDF_String(str, FALSE)); |
} |
+ |
void CPDF_Dictionary::SetAtReference(const CFX_ByteStringC& key, |
CPDF_IndirectObjectHolder* pDoc, |
FX_DWORD objnum) { |
SetAt(key, new CPDF_Reference(pDoc, objnum)); |
} |
+ |
void CPDF_Dictionary::AddReference(const CFX_ByteStringC& key, |
CPDF_IndirectObjectHolder* pDoc, |
FX_DWORD objnum) { |
SetAt(key, new CPDF_Reference(pDoc, objnum)); |
} |
+ |
void CPDF_Dictionary::SetAtNumber(const CFX_ByteStringC& key, FX_FLOAT f) { |
- CPDF_Number* pNumber = new CPDF_Number; |
- pNumber->SetNumber(f); |
+ CPDF_Number* pNumber = new CPDF_Number(f); |
SetAt(key, pNumber); |
} |
+ |
void CPDF_Dictionary::SetAtBoolean(const CFX_ByteStringC& key, FX_BOOL bValue) { |
SetAt(key, new CPDF_Boolean(bValue)); |
} |
+ |
void CPDF_Dictionary::SetAtRect(const CFX_ByteStringC& key, |
const CFX_FloatRect& rect) { |
CPDF_Array* pArray = new CPDF_Array; |
@@ -759,6 +450,7 @@ void CPDF_Dictionary::SetAtRect(const CFX_ByteStringC& key, |
pArray->AddNumber(rect.top); |
SetAt(key, pArray); |
} |
+ |
void CPDF_Dictionary::SetAtMatrix(const CFX_ByteStringC& key, |
const CFX_Matrix& matrix) { |
CPDF_Array* pArray = new CPDF_Array; |
@@ -770,9 +462,9 @@ void CPDF_Dictionary::SetAtMatrix(const CFX_ByteStringC& key, |
pArray->AddNumber(matrix.f); |
SetAt(key, pArray); |
} |
+ |
CPDF_Stream::CPDF_Stream(uint8_t* pData, FX_DWORD size, CPDF_Dictionary* pDict) |
- : CPDF_Object(STREAM), |
- m_pDict(pDict), |
+ : m_pDict(pDict), |
m_dwSize(size), |
m_GenNum(kMemoryBasedGenNum), |
m_pDataBuf(pData) {} |
@@ -812,6 +504,18 @@ void CPDF_Stream::InitStream(uint8_t* pData, |
m_pDict->SetAtInteger("Length", size); |
} |
} |
+ |
+CPDF_Object* CPDF_Stream::Clone(FX_BOOL bDirect) const { |
+ CPDF_StreamAcc acc; |
+ acc.LoadAllData(this, TRUE); |
+ FX_DWORD streamSize = acc.GetSize(); |
+ CPDF_Dictionary* pDict = GetDict(); |
+ if (pDict) { |
+ pDict = ToDictionary(pDict->Clone(bDirect)); |
+ } |
+ return new CPDF_Stream(acc.DetachData(), streamSize, pDict); |
+} |
+ |
void CPDF_Stream::SetData(const uint8_t* pData, |
FX_DWORD size, |
FX_BOOL bCompressed, |
@@ -821,7 +525,7 @@ void CPDF_Stream::SetData(const uint8_t* pData, |
m_GenNum = kMemoryBasedGenNum; |
if (bKeepBuf) { |
- m_pDataBuf = (uint8_t*)pData; |
+ m_pDataBuf = const_cast<uint8_t*>(pData); |
} else { |
m_pDataBuf = FX_Alloc(uint8_t, size); |
if (pData) { |
@@ -837,6 +541,7 @@ void CPDF_Stream::SetData(const uint8_t* pData, |
m_pDict->RemoveAt("DecodeParms"); |
} |
} |
+ |
FX_BOOL CPDF_Stream::ReadRawData(FX_FILESIZE offset, |
uint8_t* buf, |
FX_DWORD size) const { |
@@ -857,72 +562,10 @@ void CPDF_Stream::InitStreamFromFile(IFX_FileRead* pFile, |
} |
} |
-FX_BOOL CPDF_Stream::Identical(CPDF_Stream* pOther) const { |
- if (!m_pDict) |
- return !pOther->m_pDict; |
- |
- if (!m_pDict->Identical(pOther->m_pDict)) |
- return FALSE; |
- |
- if (m_dwSize != pOther->m_dwSize) |
- return FALSE; |
- |
- if (!IsMemoryBased() && !pOther->IsMemoryBased()) { |
- if (m_pFile == pOther->m_pFile && !m_pFile) |
- return TRUE; |
- |
- if (!m_pFile || !pOther->m_pFile) |
- return FALSE; |
- |
- uint8_t srcBuf[kBlockSize]; |
- uint8_t destBuf[kBlockSize]; |
- FX_DWORD size = m_dwSize; |
- if (m_pFile == pOther->m_pFile) |
- return TRUE; |
- |
- FX_DWORD offset = 0; |
- while (size > 0) { |
- FX_DWORD actualSize = std::min(size, kBlockSize); |
- m_pFile->ReadBlock(srcBuf, offset, actualSize); |
- pOther->m_pFile->ReadBlock(destBuf, offset, actualSize); |
- if (FXSYS_memcmp(srcBuf, destBuf, actualSize) != 0) |
- return FALSE; |
- |
- size -= actualSize; |
- offset += actualSize; |
- } |
- return TRUE; |
- } |
- |
- if (!IsMemoryBased() || !pOther->IsMemoryBased()) { |
- IFX_FileRead* pFile = nullptr; |
- uint8_t* pBuf = nullptr; |
- if (!pOther->IsMemoryBased()) { |
- pFile = pOther->m_pFile; |
- pBuf = m_pDataBuf; |
- } else if (!IsMemoryBased()) { |
- pFile = m_pFile; |
- pBuf = pOther->m_pDataBuf; |
- } |
- if (!pBuf) |
- return FALSE; |
- |
- uint8_t srcBuf[kBlockSize]; |
- FX_DWORD size = m_dwSize; |
- FX_DWORD offset = 0; |
- while (size > 0) { |
- FX_DWORD actualSize = std::min(size, kBlockSize); |
- pFile->ReadBlock(srcBuf, offset, actualSize); |
- if (FXSYS_memcmp(srcBuf, pBuf, actualSize) != 0) |
- return FALSE; |
- |
- pBuf += actualSize; |
- size -= actualSize; |
- offset += actualSize; |
- } |
- return TRUE; |
- } |
- return FXSYS_memcmp(m_pDataBuf, pOther->m_pDataBuf, m_dwSize) == 0; |
+CFX_WideString CPDF_Stream::GetUnicodeText(CFX_CharMap* pCharMap) const { |
+ CPDF_StreamAcc stream; |
+ stream.LoadAllData(this, FALSE); |
+ return PDF_DecodeText(stream.GetData(), stream.GetSize(), pCharMap); |
} |
CPDF_StreamAcc::CPDF_StreamAcc() { |
@@ -943,12 +586,12 @@ void CPDF_StreamAcc::LoadAllData(const CPDF_Stream* pStream, |
m_pStream = pStream; |
if (pStream->IsMemoryBased() && |
(!pStream->GetDict()->KeyExist("Filter") || bRawAccess)) { |
- m_dwSize = pStream->m_dwSize; |
- m_pData = (uint8_t*)pStream->m_pDataBuf; |
+ m_dwSize = pStream->GetRawSize(); |
+ m_pData = pStream->GetRawData(); |
return; |
} |
uint8_t* pSrcData; |
- FX_DWORD dwSrcSize = pStream->m_dwSize; |
+ FX_DWORD dwSrcSize = pStream->GetRawSize(); |
if (dwSrcSize == 0) |
return; |
@@ -957,7 +600,7 @@ void CPDF_StreamAcc::LoadAllData(const CPDF_Stream* pStream, |
if (!pStream->ReadRawData(0, pSrcData, dwSrcSize)) |
return; |
} else { |
- pSrcData = pStream->m_pDataBuf; |
+ pSrcData = pStream->GetRawData(); |
} |
uint8_t* pDecryptedData = pSrcData; |
FX_DWORD dwDecryptedSize = dwSrcSize; |
@@ -973,21 +616,23 @@ void CPDF_StreamAcc::LoadAllData(const CPDF_Stream* pStream, |
m_dwSize = dwDecryptedSize; |
} |
} |
- if (pSrcData != pStream->m_pDataBuf && pSrcData != m_pData) { |
+ if (pSrcData != pStream->GetRawData() && pSrcData != m_pData) { |
FX_Free(pSrcData); |
} |
if (pDecryptedData != pSrcData && pDecryptedData != m_pData) { |
FX_Free(pDecryptedData); |
} |
m_pSrcData = NULL; |
- m_bNewBuf = m_pData != pStream->m_pDataBuf; |
+ m_bNewBuf = m_pData != pStream->GetRawData(); |
} |
+ |
CPDF_StreamAcc::~CPDF_StreamAcc() { |
if (m_bNewBuf) { |
FX_Free(m_pData); |
} |
FX_Free(m_pSrcData); |
} |
+ |
const uint8_t* CPDF_StreamAcc::GetData() const { |
if (m_bNewBuf) { |
return m_pData; |
@@ -995,8 +640,9 @@ const uint8_t* CPDF_StreamAcc::GetData() const { |
if (!m_pStream) { |
return NULL; |
} |
- return m_pStream->m_pDataBuf; |
+ return m_pStream->GetRawData(); |
} |
+ |
FX_DWORD CPDF_StreamAcc::GetSize() const { |
if (m_bNewBuf) { |
return m_dwSize; |
@@ -1004,8 +650,9 @@ FX_DWORD CPDF_StreamAcc::GetSize() const { |
if (!m_pStream) { |
return 0; |
} |
- return m_pStream->m_dwSize; |
+ return m_pStream->GetRawSize(); |
} |
+ |
uint8_t* CPDF_StreamAcc::DetachData() { |
if (m_bNewBuf) { |
uint8_t* p = m_pData; |
@@ -1017,20 +664,36 @@ uint8_t* CPDF_StreamAcc::DetachData() { |
FXSYS_memcpy(p, m_pData, m_dwSize); |
return p; |
} |
+ |
+CPDF_Object* CPDF_Reference::Clone(FX_BOOL bDirect) const { |
+ if (bDirect) { |
+ auto* pDirect = GetDirect(); |
+ return pDirect ? pDirect->Clone(TRUE) : nullptr; |
+ } |
+ return new CPDF_Reference(m_pObjList, m_RefObjNum); |
+} |
+ |
void CPDF_Reference::SetRef(CPDF_IndirectObjectHolder* pDoc, FX_DWORD objnum) { |
m_pObjList = pDoc; |
m_RefObjNum = objnum; |
} |
+ |
+CPDF_Object* CPDF_Reference::GetDirect() const { |
+ return m_pObjList ? m_pObjList->GetIndirectObject(m_RefObjNum) : nullptr; |
+} |
+ |
CPDF_IndirectObjectHolder::CPDF_IndirectObjectHolder(CPDF_Parser* pParser) |
: m_pParser(pParser), m_LastObjNum(0) { |
if (pParser) |
m_LastObjNum = m_pParser->GetLastObjNum(); |
} |
+ |
CPDF_IndirectObjectHolder::~CPDF_IndirectObjectHolder() { |
for (const auto& pair : m_IndirectObjs) { |
pair.second->Destroy(); |
} |
} |
+ |
CPDF_Object* CPDF_IndirectObjectHolder::GetIndirectObject(FX_DWORD objnum) { |
if (objnum == 0) |
return nullptr; |
@@ -1054,6 +717,7 @@ CPDF_Object* CPDF_IndirectObjectHolder::GetIndirectObject(FX_DWORD objnum) { |
m_IndirectObjs[objnum] = pObj; |
return pObj; |
} |
+ |
FX_DWORD CPDF_IndirectObjectHolder::AddIndirectObject(CPDF_Object* pObj) { |
if (pObj->m_ObjNum) { |
return pObj->m_ObjNum; |
@@ -1063,6 +727,7 @@ FX_DWORD CPDF_IndirectObjectHolder::AddIndirectObject(CPDF_Object* pObj) { |
pObj->m_ObjNum = m_LastObjNum; |
return m_LastObjNum; |
} |
+ |
void CPDF_IndirectObjectHolder::ReleaseIndirectObject(FX_DWORD objnum) { |
auto it = m_IndirectObjs.find(objnum); |
if (it == m_IndirectObjs.end() || it->second->GetObjNum() == -1) |
@@ -1070,6 +735,7 @@ void CPDF_IndirectObjectHolder::ReleaseIndirectObject(FX_DWORD objnum) { |
it->second->Destroy(); |
m_IndirectObjs.erase(it); |
} |
+ |
FX_BOOL CPDF_IndirectObjectHolder::InsertIndirectObject(FX_DWORD objnum, |
CPDF_Object* pObj) { |
if (!objnum || !pObj) |