fw4spl
src/fwData/Array.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2015.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 
8 #include "fwData/registry/macros.hpp"
9 #include "fwData/Exception.hpp"
10 #include "fwData/Array.hpp"
11 
12 #include <algorithm>
13 #include <cstdlib>
14 #include <functional>
15 #include <numeric>
16 
17 namespace fwData
18 {
19 
20 fwDataRegisterMacro( ::fwData::Array );
21 
22 inline size_t computeSize(
23  size_t elementSize,
24  const ::fwData::Array::SizeType &size,
25  size_t nbOfComponents )
26 {
27  size_t total = 0;
28  if (!size.empty())
29  {
30  total = elementSize;
31  total *=
32  std::accumulate (size.begin(),
33  size.end(), nbOfComponents, std::multiplies< ::fwData::Array::SizeType::value_type >() );
34  }
35  return total;
36 }
37 
38 ::fwData::Array::OffsetType Array::computeStrides( SizeType size, size_t nbOfComponents, size_t sizeOfType )
39 {
41  strides.reserve(size.size());
42 
43  size_t currentStride = sizeOfType*nbOfComponents;
44  for(const SizeType::value_type& s : size)
45  {
46  strides.push_back(currentStride);
47  currentStride *= s;
48  }
49  return strides;
50 }
51 
52 //------------------------------------------------------------------------------
53 
55  m_strides(0),
56  m_type(),
57  m_bufferObject(::fwMemory::BufferObject::New()),
58  m_size(0),
59  m_nbOfComponents(0),
60  m_isBufferOwner(true)
61 {
62 }
63 
64 //------------------------------------------------------------------------------
65 
66 Array::~Array()
67 {
68  this->clear();
69 }
70 
71 //------------------------------------------------------------------------------
72 
73 void Array::swap( Array::sptr _source )
74 {
75  m_fields.swap(_source->m_fields);
76  m_strides.swap(_source->m_strides);
77  m_size.swap(_source->m_size);
78  m_bufferObject->swap(_source->m_bufferObject);
79 
80  std::swap(m_type, _source->m_type);
81  std::swap(m_nbOfComponents, _source->m_nbOfComponents);
82  std::swap(m_isBufferOwner, _source->m_isBufferOwner);
83 }
84 
85 //------------------------------------------------------------------------------
86 
87 void Array::cachedDeepCopy(const Object::csptr &_source, DeepCopyCacheType &cache)
88 {
89  Array::csptr other = Array::dynamicConstCast(_source);
90  FW_RAISE_EXCEPTION_IF( ::fwData::Exception(
91  "Unable to copy" + (_source ? _source->getClassname() : std::string("<NULL>"))
92  + " to " + this->getClassname()), !bool(other) );
93  this->fieldDeepCopy( _source, cache );
94 
95  this->clear();
96 
97  if( !other->m_bufferObject->isEmpty() )
98  {
99  ::fwMemory::BufferObject::Lock lockerDest(m_bufferObject);
100  this->resize(other->m_type, other->m_size, other->m_nbOfComponents, true);
101  char * buffDest = static_cast< char * >( lockerDest.getBuffer() );
102  ::fwMemory::BufferObject::Lock lockerSource(other->m_bufferObject);
103  char * buffSrc = static_cast< char * >( lockerSource.getBuffer() );
104  std::copy(buffSrc, buffSrc+other->getSizeInBytes(), buffDest );
105  }
106  else
107  {
108  m_strides = other->m_strides;
109  m_type = other->m_type;
110  m_size = other->m_size;
111  m_nbOfComponents = other->m_nbOfComponents;
112  }
113 }
114 
115 //------------------------------------------------------------------------------
116 
118  const ::fwTools::Type &type,
119  const SizeType &size,
120  size_t nbOfComponents,
121  bool reallocate
122  )
123 {
124  nbOfComponents = (nbOfComponents == 0) ? 1 : nbOfComponents;
125  size_t bufSize = computeSize(type.sizeOf(), size, nbOfComponents);
126 
127  if(reallocate && (m_isBufferOwner || m_bufferObject->isEmpty()))
128  {
129  if(m_bufferObject->isEmpty())
130  {
131  m_bufferObject->allocate(bufSize);
132  }
133  else
134  {
135  m_bufferObject->reallocate(bufSize);
136  }
137  m_isBufferOwner = true;
138  }
139  else if(reallocate && !m_isBufferOwner)
140  {
141  FW_RAISE_EXCEPTION_MSG( ::fwData::Exception,
142  "Tried to reallocate a not-owned Buffer.");
143  }
144 
145  m_strides = computeStrides(size, nbOfComponents, type.sizeOf());
146  m_type = type;
147  m_size = size;
148  m_nbOfComponents = nbOfComponents;
149 
150  return bufSize;
151 }
152 
153 //------------------------------------------------------------------------------
154 
155 size_t Array::resize(const SizeType &size, size_t nbOfComponents, bool reallocate)
156 {
157  return this->resize(m_type, size, nbOfComponents, reallocate);
158 }
159 
160 //------------------------------------------------------------------------------
161 
162 size_t Array::resize(const SizeType &size, bool reallocate)
163 {
164  return this->resize(m_type, size, m_nbOfComponents, reallocate);
165 }
166 //------------------------------------------------------------------------------
167 
168 size_t Array::resize(const std::string &type, const SizeType &size, size_t nbOfComponents,
169  bool reallocate)
170 {
171  ::fwTools::Type fwType = ::fwTools::Type::create(type);
172  return this->resize( fwType, size, nbOfComponents, reallocate);
173 }
174 
175 //------------------------------------------------------------------------------
176 
178 {
179  if ( !this->m_bufferObject->isEmpty() )
180  {
181  if(m_isBufferOwner)
182  {
183  this->m_bufferObject->destroy();
184  }
185  m_strides.clear();
186  m_type = ::fwTools::Type();
187  m_size.clear();
188  m_nbOfComponents = 0;
189  }
190 }
191 
192 //------------------------------------------------------------------------------
193 
194 bool Array::empty() const
195 {
196  return m_size.empty();
197 }
198 
199 //------------------------------------------------------------------------------
200 
202 {
203  return m_type.sizeOf() * m_nbOfComponents;
204 }
205 
206 //------------------------------------------------------------------------------
207 
209 {
210  return computeSize(1, m_size, m_nbOfComponents);
211 }
212 
213 //------------------------------------------------------------------------------
214 
215 size_t Array::getSizeInBytes() const
216 {
217  return computeSize(m_type.sizeOf(), m_size, m_nbOfComponents);
218 }
219 
220 //------------------------------------------------------------------------------
221 
222 
223 const ::fwData::Array::SizeType &Array::getSize() const
224 {
225  return m_size;
226 }
227 
228 //------------------------------------------------------------------------------
229 
230 const ::fwData::Array::OffsetType &Array::getStrides() const
231 {
232  return m_strides;
233 }
234 
235 //------------------------------------------------------------------------------
236 
238 {
239  m_nbOfComponents = (nb == 0) ? 1 : nb;
240  this->resize(
241  m_type,
242  m_size,
243  m_nbOfComponents,
244  (m_isBufferOwner && !m_bufferObject->isEmpty())
245  );
246 }
247 
248 //------------------------------------------------------------------------------
249 
251 {
252  return m_nbOfComponents;
253 }
254 
255 //------------------------------------------------------------------------------
256 
258 {
259  return m_size.size();
260 }
261 
262 //------------------------------------------------------------------------------
263 
264 void Array::setIsBufferOwner(const bool own)
265 {
266  m_isBufferOwner = own;
267 }
268 
269 //------------------------------------------------------------------------------
270 
272 {
273  return m_isBufferOwner;
274 }
275 
276 //------------------------------------------------------------------------------
277 
278 void Array::setType(const std::string &type)
279 {
280  ::fwTools::Type fwType = ::fwTools::Type::create(type);
281  this->setType(fwType);
282 }
283 
284 void Array::setType(const ::fwTools::Type &type)
285 {
286  m_type = type;
287  this->resize(
288  m_type,
289  m_size,
290  m_nbOfComponents,
291  (m_isBufferOwner && !m_bufferObject->isEmpty())
292  );
293 }
294 
295 
296 //------------------------------------------------------------------------------
297 
299 {
300  return m_type;
301 }
302 
303 //------------------------------------------------------------------------------
304 
305 size_t Array::getBufferOffset( const ::fwData::Array::IndexType &id, size_t component, size_t sizeOfType ) const
306 {
307  OSLM_ASSERT(
308  "Given index has " << id.size() << " dimensions, but Array has " << m_size.size() << "dimensions.",
309  id.size() == m_size.size()
310  );
311 
312  OffsetType offsets(id.size());
313 
314  std::transform(id.begin(), id.end(), m_strides.begin(), offsets.begin(),
315  std::multiplies<OffsetType::value_type>() );
316 
317  size_t offset;
318  offset = std::accumulate(offsets.begin(), offsets.end(), size_t(0));
319 
320  offset += component*sizeOfType;
321 
322  return offset;
323 }
324 
325 //------------------------------------------------------------------------------
326 
327 } //namespace fwData
static FWDATA_API OffsetType computeStrides(SizeType size, size_t nbOfComponents, size_t sizeOfType)
Compute strides for given parameters.
virtual FWDATA_API size_t resize(const ::fwTools::Type &type, const SizeType &size, size_t nbOfComponents, bool reallocate=false)
Resizes and allocate (if needed) the array.
virtual FWDATA_API bool getIsBufferOwner() const
Getter for array&#39;s buffer ownership.
std::vector< size_t > SizeType
Array size type.
virtual FWDATA_API void setType(const std::string &type)
Setter for array&#39;s type.
#define OSLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:310
virtual FWDATA_API size_t getNumberOfElements() const
Get the number of elements of type <getType()> in the array.
The namespace fwMemory contains tools to manage memory. Use for dump.
Definition: SReader.hpp:20
Key class used to restrict access to Object construction. See http://www.drdobbs.com/184402053.
Implements data exception class.
virtual FWDATA_API size_t getSizeInBytes() const
Getter for the array view size.
virtual FWDATA_API size_t getElementSizeInBytes() const
Get the size of one element of the array, ie. sizeof type * nbOfComponents.
FWDATA_API size_t getBufferOffset(const ::fwData::Array::IndexType &id, size_t component, size_t sizeOfType) const
Compute offset in buffer for given parameters of type.
virtual FWDATA_API const OffsetType & getStrides() const
Getter for the array strides.
base class for BufferObject Lock
virtual FWDATA_API::fwTools::Type getType() const
Getter for array&#39;s type.
std::vector< size_t > OffsetType
Offset type.
FWDATA_API void swap(Array::sptr _source)
Exchanges the content of the Array with the content of _source.
virtual FWDATA_API void clear()
Clear this array. Size, type, nbOfComponents are reset, buffer is released.
virtual FWDATA_API size_t getNumberOfComponents() const
Getter for number of components.
Provides a way to manage a view on a multidimentionnal array.
virtual FWDATA_API bool empty() const
Test whether array is empty.
virtual FWDATA_API size_t getNumberOfDimensions() const
Getter for number of dimensions, ie. getSize().size()
FWDATA_API void fieldDeepCopy(const ::fwData::Object::csptr &source)
A deep copy of fields (objects in m_children)
LockBase< T >::BufferType getBuffer() const
Returns BufferObject&#39;s buffer pointer.
Class describing an elementary C++ type aka unsigned char, signed char, .... int, float...
Definition: Type.hpp:32
FWDATA_API Array(::fwData::Object::Key key)
Constructor.
virtual FWDATA_API const SizeType & getSize() const
Getter for the array size.
FWDATA_API void cachedDeepCopy(const Object::csptr &_source, DeepCopyCacheType &cache) override
Defines deep copy.
Contains the representation of the data objects used in the framework.
virtual const std::string & getClassname() const override
return full object&#39;s classname with its namespace, i.e. fwCore::BaseObject
virtual FWDATA_API void setIsBufferOwner(const bool own)
Set array&#39;s buffer ownership.
virtual FWDATA_API void setNumberOfComponents(size_t nb)
Setter for array&#39;s number of components If the array has a buffer and owns it, the buffer will be rea...
FWTOOLS_API unsigned char sizeOf() const
Return the sizeof of the type.
Definition: Type.cpp:168