1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkVoidArray.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkVoidArray.h"
16 #include "vtkObjectFactory.h"
17 
18 vtkStandardNewMacro(vtkVoidArray);
19 vtkStandardExtendedNewMacro(vtkVoidArray);
20 
21 typedef void* voidPtr;
22 
23 // Instantiate object.
vtkVoidArray()24 vtkVoidArray::vtkVoidArray()
25   : NumberOfPointers(0)
26   , Size(0)
27   , Array(nullptr)
28 {
29 }
30 
~vtkVoidArray()31 vtkVoidArray::~vtkVoidArray()
32 {
33   delete[] this->Array;
34 }
35 
36 // Allocate memory for this array. Delete old storage only if necessary.
Allocate(vtkIdType sz,vtkIdType vtkNotUsed (ext))37 vtkTypeBool vtkVoidArray::Allocate(vtkIdType sz, vtkIdType vtkNotUsed(ext))
38 {
39   if (sz > this->Size || this->Array != nullptr)
40   {
41     delete[] this->Array;
42 
43     this->Size = (sz > 0 ? sz : 1);
44     if ((this->Array = new voidPtr[this->Size]) == nullptr)
45     {
46       return 0;
47     }
48   }
49 
50   this->NumberOfPointers = 0;
51 
52   return 1;
53 }
54 
55 // Release storage and reset array to initial state.
Initialize()56 void vtkVoidArray::Initialize()
57 {
58   delete[] this->Array;
59   this->Array = nullptr;
60   this->Size = 0;
61   this->NumberOfPointers = 0;
62 }
63 
64 // Deep copy of another void array.
DeepCopy(vtkVoidArray * va)65 void vtkVoidArray::DeepCopy(vtkVoidArray* va)
66 {
67   // Do nothing on a nullptr input.
68   if (va == nullptr)
69   {
70     return;
71   }
72 
73   if (this != va)
74   {
75     delete[] this->Array;
76 
77     this->NumberOfPointers = va->NumberOfPointers;
78     this->Size = va->Size;
79 
80     this->Array = new voidPtr[this->Size];
81     memcpy(this->Array, va->GetVoidPointer(0), this->Size * sizeof(void*));
82   }
83 }
84 
WritePointer(vtkIdType id,vtkIdType number)85 void** vtkVoidArray::WritePointer(vtkIdType id, vtkIdType number)
86 {
87   vtkIdType newSize = id + number;
88   if (newSize > this->Size)
89   {
90     this->ResizeAndExtend(newSize);
91   }
92   if (newSize > this->NumberOfPointers)
93   {
94     this->NumberOfPointers = newSize;
95   }
96   return this->Array + id;
97 }
98 
InsertVoidPointer(vtkIdType id,void * p)99 void vtkVoidArray::InsertVoidPointer(vtkIdType id, void* p)
100 {
101   if (id >= this->Size)
102   {
103     if (!this->ResizeAndExtend(id + 1))
104     {
105       return;
106     }
107   }
108   this->Array[id] = p;
109   if (id >= this->NumberOfPointers)
110   {
111     this->NumberOfPointers = id + 1;
112   }
113 }
114 
InsertNextVoidPointer(void * p)115 vtkIdType vtkVoidArray::InsertNextVoidPointer(void* p)
116 {
117   this->InsertVoidPointer(this->NumberOfPointers, p);
118   return this->NumberOfPointers - 1;
119 }
120 
121 // Protected function does "reallocate"
122 //
ResizeAndExtend(vtkIdType sz)123 void** vtkVoidArray::ResizeAndExtend(vtkIdType sz)
124 {
125   void** newArray;
126   vtkIdType newSize;
127 
128   if (sz > this->Size)
129   {
130     newSize = this->Size + sz;
131   }
132   else if (sz == this->Size)
133   {
134     return this->Array;
135   }
136   else
137   {
138     newSize = sz;
139   }
140 
141   if (newSize <= 0)
142   {
143     this->Initialize();
144     return nullptr;
145   }
146 
147   if ((newArray = new voidPtr[newSize]) == nullptr)
148   {
149     vtkErrorMacro(<< "Cannot allocate memory\n");
150     return nullptr;
151   }
152 
153   memcpy(newArray, this->Array, (sz < this->Size ? sz : this->Size) * sizeof(voidPtr));
154 
155   if (newSize < this->Size)
156   {
157     this->NumberOfPointers = newSize;
158   }
159   this->Size = newSize;
160   delete[] this->Array;
161   this->Array = newArray;
162 
163   return this->Array;
164 }
165 
PrintSelf(ostream & os,vtkIndent indent)166 void vtkVoidArray::PrintSelf(ostream& os, vtkIndent indent)
167 {
168   this->Superclass::PrintSelf(os, indent);
169 
170   if (this->Array)
171   {
172     os << indent << "Array: " << this->Array << "\n";
173   }
174   else
175   {
176     os << indent << "Array: (null)\n";
177   }
178 }
179