// Copyright 2016 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_number.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_reference.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_string.h" CPDF_Array::CPDF_Array() {} CPDF_Array::~CPDF_Array() { int size = m_Objects.GetSize(); CPDF_Object** pList = m_Objects.GetData(); for (int i = 0; i < size; i++) { if (pList[i]) pList[i]->Release(); } } CPDF_Object::Type CPDF_Array::GetType() const { return ARRAY; } CPDF_Array* CPDF_Array::GetArray() const { // The method should be made non-const if we want to not be const. // See bug #234. return const_cast(this); } bool CPDF_Array::IsArray() const { return true; } CPDF_Array* CPDF_Array::AsArray() { return this; } const CPDF_Array* CPDF_Array::AsArray() const { return this; } 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) return rect; rect.left = GetNumberAt(0); rect.bottom = GetNumberAt(1); rect.right = GetNumberAt(2); rect.top = GetNumberAt(3); return rect; } CFX_Matrix CPDF_Array::GetMatrix() { CFX_Matrix matrix; if (!IsArray() || m_Objects.GetSize() != 6) return matrix; matrix.Set(GetNumberAt(0), GetNumberAt(1), GetNumberAt(2), GetNumberAt(3), 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) return NULL; if (CPDF_Dictionary* pDict = p->AsDictionary()) return pDict; if (CPDF_Stream* pStream = p->AsStream()) 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; if (nCount <= 0 || nCount > m_Objects.GetSize() - i) return; for (int j = 0; j < nCount; ++j) { if (CPDF_Object* p = m_Objects.GetAt(i + j)) p->Release(); } m_Objects.RemoveAt(i, nCount); } void CPDF_Array::SetAt(FX_DWORD i, CPDF_Object* pObj, CPDF_IndirectObjectHolder* pObjs) { ASSERT(IsArray()); ASSERT(i < (FX_DWORD)m_Objects.GetSize()); if (i >= (FX_DWORD)m_Objects.GetSize()) return; if (CPDF_Object* pOld = m_Objects.GetAt(i)) pOld->Release(); if (pObj->GetObjNum()) { ASSERT(pObjs); pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); } m_Objects.SetAt(i, pObj); } void CPDF_Array::InsertAt(FX_DWORD index, CPDF_Object* pObj, CPDF_IndirectObjectHolder* pObjs) { if (pObj->GetObjNum()) { ASSERT(pObjs); pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); } m_Objects.InsertAt(index, pObj); } void CPDF_Array::Add(CPDF_Object* pObj, CPDF_IndirectObjectHolder* pObjs) { if (pObj->GetObjNum()) { ASSERT(pObjs); pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); } 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(f); Add(pNumber); } void CPDF_Array::AddReference(CPDF_IndirectObjectHolder* pDoc, FX_DWORD objnum) { ASSERT(IsArray()); Add(new CPDF_Reference(pDoc, objnum)); }