// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkInformationVector.h" #include "vtkGarbageCollector.h" #include "vtkInformation.h" #include "vtkObjectFactory.h" #include VTK_ABI_NAMESPACE_BEGIN vtkStandardNewMacro(vtkInformationVector); class vtkInformationVectorInternals { public: std::vector Vector; ~vtkInformationVectorInternals(); }; //------------------------------------------------------------------------------ vtkInformationVectorInternals::~vtkInformationVectorInternals() { // Delete all the information objects. for (std::vector::iterator i = this->Vector.begin(); i != this->Vector.end(); ++i) { if (vtkInformation* info = *i) { info->Delete(); } } } //------------------------------------------------------------------------------ vtkInformationVector::vtkInformationVector() { this->Internal = new vtkInformationVectorInternals; this->NumberOfInformationObjects = 0; } //------------------------------------------------------------------------------ vtkInformationVector::~vtkInformationVector() { delete this->Internal; } //------------------------------------------------------------------------------ void vtkInformationVector::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "Number of Information Objects: " << this->NumberOfInformationObjects << "\n"; os << indent << "Information Objects:\n"; for (int i = 0; i < this->NumberOfInformationObjects; ++i) { vtkInformation* info = this->GetInformationObject(i); vtkIndent nextIndent = indent.GetNextIndent(); os << nextIndent << info->GetClassName() << "(" << info << "):\n"; info->PrintSelf(os, nextIndent.GetNextIndent()); } } //------------------------------------------------------------------------------ void vtkInformationVector::SetNumberOfInformationObjects(int newNumber) { // Adjust the number of objects. int oldNumber = this->NumberOfInformationObjects; if (newNumber > oldNumber) { // Create new information objects. this->Internal->Vector.resize(newNumber, nullptr); for (int i = oldNumber; i < newNumber; ++i) { this->Internal->Vector[i] = vtkInformation::New(); } this->NumberOfInformationObjects = newNumber; } else if (newNumber < oldNumber) { // Delete old information objects. for (int i = newNumber; i < oldNumber; ++i) { if (vtkInformation* info = this->Internal->Vector[i]) { // Set the pointer to nullptr first to avoid reporting of the // entry if deleting the information object causes a garbage // collection reference walk. this->Internal->Vector[i] = nullptr; info->Delete(); } } this->Internal->Vector.resize(newNumber); this->NumberOfInformationObjects = newNumber; } } //------------------------------------------------------------------------------ void vtkInformationVector::SetInformationObject(int index, vtkInformation* newInfo) { if (newInfo && index >= 0 && index < this->NumberOfInformationObjects) { // Replace an existing information object. vtkInformation* oldInfo = this->Internal->Vector[index]; if (oldInfo != newInfo) { newInfo->Register(this); this->Internal->Vector[index] = newInfo; oldInfo->UnRegister(this); } } else if (newInfo && index >= this->NumberOfInformationObjects) { // If a hole will be created fill it with empty objects. if (index > this->NumberOfInformationObjects) { this->SetNumberOfInformationObjects(index); } // Store the information object in a new entry. newInfo->Register(this); this->Internal->Vector.push_back(newInfo); this->NumberOfInformationObjects++; } else if (!newInfo && index >= 0 && index < this->NumberOfInformationObjects - 1) { // We do not allow nullptr information objects. Create an empty one // to fill in the hole. vtkInformation* oldInfo = this->Internal->Vector[index]; this->Internal->Vector[index] = vtkInformation::New(); oldInfo->UnRegister(this); } else if (!newInfo && index >= 0 && index == this->NumberOfInformationObjects - 1) { // Remove the last information object. this->SetNumberOfInformationObjects(index); } } //------------------------------------------------------------------------------ vtkInformation* vtkInformationVector::GetInformationObject(int index) { if (index >= 0 && index < this->NumberOfInformationObjects) { return this->Internal->Vector[index]; } return nullptr; } //------------------------------------------------------------------------------ void vtkInformationVector::Append(vtkInformation* info) { // Setting an entry beyond the end will automatically append. this->SetInformationObject(this->NumberOfInformationObjects, info); } //------------------------------------------------------------------------------ void vtkInformationVector::Remove(vtkInformation* info) { // Search for the information object and remove it. for (int i = 0; i < this->NumberOfInformationObjects; ++i) { if (this->Internal->Vector[i] == info) { this->Internal->Vector.erase(this->Internal->Vector.begin() + i); info->UnRegister(this); this->NumberOfInformationObjects--; } } } //------------------------------------------------------------------------------ void vtkInformationVector::Remove(int i) { if (i < this->NumberOfInformationObjects) { if (this->Internal->Vector[i]) { this->Internal->Vector[i]->UnRegister(this); } this->Internal->Vector.erase(this->Internal->Vector.begin() + i); this->NumberOfInformationObjects--; } } //------------------------------------------------------------------------------ void vtkInformationVector::Copy(vtkInformationVector* from, vtkTypeBool deep) { // if deep we can reuse existing info objects if (deep) { this->SetNumberOfInformationObjects(from->GetNumberOfInformationObjects()); for (int i = 0; i < from->GetNumberOfInformationObjects(); ++i) { this->Internal->Vector[i]->Copy(from->GetInformationObject(i), deep); } return; } // otherwise it is a shallow copy and we must copy pointers this->SetNumberOfInformationObjects(0); // copy the data for (int i = 0; i < from->GetNumberOfInformationObjects(); ++i) { vtkInformation* fromI = from->GetInformationObject(i); this->SetInformationObject(i, fromI); } } //------------------------------------------------------------------------------ void vtkInformationVector::ReportReferences(vtkGarbageCollector* collector) { this->Superclass::ReportReferences(collector); for (int i = 0; i < this->NumberOfInformationObjects; ++i) { vtkGarbageCollectorReport(collector, this->Internal->Vector[i], "Entry"); } } VTK_ABI_NAMESPACE_END