1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkBuffer.h
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 /**
16 * @class vtkBuffer
17 * @brief internal storage class used by vtkSOADataArrayTemplate,
18 * vtkAOSDataArrayTemplate, and others.
19 *
20 * vtkBuffer makes it easier to keep data pointers in vtkDataArray subclasses.
21 * This is an internal class and not intended for direct use expect when writing
22 * new types of vtkDataArray subclasses.
23 */
24
25 #ifndef vtkBuffer_h
26 #define vtkBuffer_h
27
28 #include "vtkObject.h"
29 #include "vtkObjectFactory.h" // New() implementation
30
31 template <class ScalarTypeT>
32 class vtkBuffer : public vtkObject
33 {
34 public:
35 vtkTemplateTypeMacro(vtkBuffer<ScalarTypeT>, vtkObject)
36 typedef ScalarTypeT ScalarType;
37
38 static vtkBuffer<ScalarTypeT>* New();
39
40 /**
41 * Access the buffer as a scalar pointer.
42 */
GetBuffer()43 inline ScalarType* GetBuffer() { return this->Pointer; }
GetBuffer()44 inline const ScalarType* GetBuffer() const { return this->Pointer; }
45
46 /**
47 * Set the memory buffer that this vtkBuffer object will manage. @a array
48 * is a pointer to the buffer data and @a size is the size of the buffer (in
49 * number of elements).
50 */
51 void SetBuffer(ScalarType* array, vtkIdType size);
52
53 /**
54 * Set the free function to be used when releasing this object.
55 * If @a noFreeFunction is true, the buffer will not be freed when
56 * this vtkBuffer object is deleted or resize -- otherwise, @a deleteFunction
57 * will be called to free the buffer
58 **/
59 void SetFreeFunction(bool noFreeFunction, void(*deleteFunction)(void*)=free);
60
61 /**
62 * Return the number of elements the current buffer can hold.
63 */
GetSize()64 inline vtkIdType GetSize() const { return this->Size; }
65
66 /**
67 * Allocate a new buffer that holds @a size elements. Old data is not saved.
68 */
69 bool Allocate(vtkIdType size);
70
71 /**
72 * Allocate a new buffer that holds @a newsize elements. Old data is
73 * preserved.
74 */
75 bool Reallocate(vtkIdType newsize);
76
77 protected:
vtkBuffer()78 vtkBuffer()
79 : Pointer(nullptr),
80 Size(0),
81 DeleteFunction(free)
82 {
83 }
84
~vtkBuffer()85 ~vtkBuffer() override
86 {
87 this->SetBuffer(nullptr, 0);
88 }
89
90 ScalarType *Pointer;
91 vtkIdType Size;
92 void (*DeleteFunction)(void*);
93
94 private:
95 vtkBuffer(const vtkBuffer&) = delete;
96 void operator=(const vtkBuffer&) = delete;
97 };
98
99 template <class ScalarT>
New()100 inline vtkBuffer<ScalarT> *vtkBuffer<ScalarT>::New()
101 {
102 VTK_STANDARD_NEW_BODY(vtkBuffer<ScalarT>)
103 }
104
105 //------------------------------------------------------------------------------
106 template <typename ScalarT>
SetBuffer(typename vtkBuffer<ScalarT>::ScalarType * array,vtkIdType size)107 void vtkBuffer<ScalarT>::SetBuffer(
108 typename vtkBuffer<ScalarT>::ScalarType *array, vtkIdType size) {
109 if (this->Pointer != array)
110 {
111 if(this->DeleteFunction)
112 {
113 this->DeleteFunction(this->Pointer);
114 }
115 this->Pointer = array;
116 }
117 this->Size = size;
118 }
119 //------------------------------------------------------------------------------
120 template <typename ScalarT>
SetFreeFunction(bool noFreeFunction,void (* deleteFunction)(void *))121 void vtkBuffer<ScalarT>::SetFreeFunction(bool noFreeFunction, void(*deleteFunction)(void*))
122 {
123 if(noFreeFunction)
124 {
125 this->DeleteFunction = nullptr;
126 }
127 else
128 {
129 this->DeleteFunction = deleteFunction;
130 }
131 }
132
133 //------------------------------------------------------------------------------
134 template <typename ScalarT>
Allocate(vtkIdType size)135 bool vtkBuffer<ScalarT>::Allocate(vtkIdType size)
136 {
137 // release old memory.
138 this->SetBuffer(nullptr, 0);
139 if (size > 0)
140 {
141 ScalarType* newArray =
142 static_cast<ScalarType*>(malloc(size * sizeof(ScalarType)));
143 if (newArray)
144 {
145 this->SetBuffer(newArray, size);
146 this->DeleteFunction = free;
147 return true;
148 }
149 return false;
150 }
151 return true; // size == 0
152 }
153
154 //------------------------------------------------------------------------------
155 template <typename ScalarT>
Reallocate(vtkIdType newsize)156 bool vtkBuffer<ScalarT>::Reallocate(vtkIdType newsize)
157 {
158 if (newsize == 0) { return this->Allocate(0); }
159
160 if (this->Pointer && this->DeleteFunction != free)
161 {
162 ScalarType* newArray =
163 static_cast<ScalarType*>(malloc(newsize * sizeof(ScalarType)));
164 if (!newArray)
165 {
166 return false;
167 }
168 std::copy(this->Pointer, this->Pointer + std::min(this->Size, newsize),
169 newArray);
170 // now save the new array and release the old one too.
171 this->SetBuffer(newArray, newsize);
172 this->DeleteFunction = free;
173 }
174 else
175 {
176 // Try to reallocate with minimal memory usage and possibly avoid
177 // copying.
178 ScalarType* newArray = static_cast<ScalarType*>(
179 realloc(this->Pointer, newsize * sizeof(ScalarType)));
180 if (!newArray)
181 {
182 return false;
183 }
184 this->Pointer = newArray;
185 this->Size = newsize;
186 }
187 return true;
188 }
189
190 #endif
191 // VTK-HeaderTest-Exclude: vtkBuffer.h
192