| 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)
|
|
|