Simpatico  v1.10
MemoryIArchive.h
1 #ifndef UTIL_MEMORY_I_ARCHIVE_H
2 #define UTIL_MEMORY_I_ARCHIVE_H
3 
4 /*
5 * Util Package - C++ Utilities for Scientific Computation
6 *
7 * Copyright 2010 - 2017, The Regents of the University of Minnesota
8 * Distributed under the terms of the GNU General Public License.
9 */
10 
11 #include "Byte.h"
12 #include "serialize.h"
13 
14 #include <util/space/Vector.h>
15 #include <util/space/IntVector.h>
16 
17 #include <complex>
18 #include <string>
19 #include <vector>
20 
21 namespace Util
22 {
23 
24  class MemoryOArchive;
25 
32  {
33 
34  public:
35 
37  static bool is_saving();
38 
40  static bool is_loading();
41 
46 
51 
57  void allocate(size_t capacity);
58 
63 
67  void reset();
68 
74  void clear();
75 
79  void release();
80 
86  template <typename T>
87  MemoryIArchive& operator & (T& data);
88 
94  template <typename T>
95  MemoryIArchive& operator >> (T& data);
96 
102  template <typename T>
103  void unpack(T& data);
104 
111  template <typename T>
112  void unpack(T* array, int n);
113 
125  template <typename T>
126  void unpack(T* array, int m, int n, int np);
127 
128  #ifdef UTIL_MPI
129 
135  void recv(MPI::Intracomm& comm, int source);
136  #endif
137 
141  Byte* begin() const;
142 
146  Byte* cursor() const;
147 
151  Byte* end() const;
152 
156  size_t capacity() const;
157 
161  bool isAllocated() const;
162 
163  private:
164 
166  Byte* buffer_;
167 
169  Byte* begin_;
170 
172  Byte* cursor_;
173 
175  Byte* end_;
176 
178  Byte* endAllocated_;
179 
181  MemoryOArchive* oArchivePtr_;
182 
184  size_t capacity_;
185 
187  unsigned int version_;
188 
190  bool ownsData_;
191 
192  };
193 
194  // Inline static methods
195 
197  { return false; }
198 
200  { return true; }
201 
202  // Inline non-static methods
203 
204  /*
205  * Return pointer to beginning of block.
206  */
207  inline Byte* MemoryIArchive::begin() const
208  { return begin_; }
209 
210  /*
211  * Return pointer to cursor position.
212  */
213  inline Byte* MemoryIArchive::cursor() const
214  { return cursor_; }
215 
216  /*
217  * Return end of packed block (one Byte past the last).
218  */
219  inline Byte* MemoryIArchive::end() const
220  { return end_; }
221 
222  /*
223  * Return capacity in Bytes.
224  */
225  inline size_t MemoryIArchive::capacity() const
226  { return capacity_; }
227 
228  /*
229  * Has a memory block been allocated?
230  */
231  inline bool MemoryIArchive::isAllocated() const
232  { return (bool) begin_; }
233 
234  // Template methods
235 
236  /*
237  * Load one T object from a MemoryIArchive.
238  */
239  template <typename T>
241  {
242  serialize(*this, data, version_);
243  return *this;
244  }
245 
246  /*
247  * Load one T object from this MemoryIArchive.
248  */
249  template <typename T>
251  {
252  serialize(*this, data, version_);
253  return *this;
254  }
255 
256  /*
257  * Load one T object from this MemoryIArchive.
258  */
259  template <typename T>
261  {
262  if (cursor_ + sizeof(data) > end_) {
263  UTIL_THROW("Attempted read past end of packed block");
264  }
265  T* ptr = (T *)cursor_;
266  data = *ptr;
267  ++ptr;
268  cursor_ = (Byte *)ptr;
269  }
270 
271  /*
272  * Load a C-array of objects of type T.
273  */
274  template <typename T>
275  void MemoryIArchive::unpack(T* array, int n)
276  {
277  if (cursor_ + n*sizeof(T) > end_) {
278  UTIL_THROW("Attempted read past end of data");
279  }
280  T* ptr = (T *)cursor_;
281  for (int i=0; i < n; ++i) {
282  array[i] = *ptr;
283  ++ptr;
284  }
285  cursor_ = (Byte *)ptr;
286  }
287 
288  /*
289  * Bitwise pack a 2D C-array of objects of type T.
290  */
291  template <typename T>
292  void MemoryIArchive::unpack(T* array, int m, int n, int np)
293  {
294  if (cursor_ + m*n*sizeof(T) > end_) {
295  UTIL_THROW("Attempted read past end of data");
296  }
297  int i, j;
298  T* ptr = (T *)cursor_;
299  for (i = 0; i < m; ++i) {
300  for (j = 0; j < n; ++j) {
301  array[i*np + j] = *ptr;
302  ++ptr;
303  }
304  }
305  cursor_ = (Byte *)ptr;
306  }
307 
308  // Explicit specializations of serialize function
309 
310  /*
311  * Load a char from a MemoryIArchive.
312  */
313  template <>
314  inline void serialize(MemoryIArchive& ar, char& data,
315  const unsigned int version)
316  { ar.unpack(data); }
317 
318  /*
319  * Load a bool from a MemoryIArchive.
320  */
321  template <>
322  inline void serialize(MemoryIArchive& ar, bool& data,
323  const unsigned int version)
324  { ar.unpack(data); }
325 
326  /*
327  * Load an unsigned int from a MemoryIArchive.
328  */
329  template <>
330  inline void serialize(MemoryIArchive& ar, unsigned int& data,
331  const unsigned int version)
332  { ar.unpack(data); }
333 
334  /*
335  * Load an int from a MemoryIArchive.
336  */
337  template <>
338  inline void serialize(MemoryIArchive& ar, int& data,
339  const unsigned int version)
340  { ar.unpack(data); }
341 
342  /*
343  * Load an unsigned long int from a MemoryIArchive.
344  */
345  template <>
346  inline void serialize(MemoryIArchive& ar, unsigned long& data,
347  const unsigned int version)
348  { ar.unpack(data); }
349 
350  /*
351  * Load a long int from a MemoryIArchive.
352  */
353  template <>
354  inline void serialize(MemoryIArchive& ar, long& data,
355  const unsigned int version)
356  { ar.unpack(data); }
357 
358  /*
359  * Load a float from a MemoryIArchive.
360  */
361  template <>
362  inline void serialize(MemoryIArchive& ar, float& data,
363  const unsigned int version)
364  { ar.unpack(data); }
365 
366  /*
367  * Load a double from a MemoryIArchive.
368  */
369  template <>
370  inline void serialize(MemoryIArchive& ar, double& data,
371  const unsigned int version)
372  { ar.unpack(data); }
373 
374  /*
375  * Load a std::vector from a MemoryIArchive.
376  */
377  template <typename T>
378  void serialize(MemoryIArchive& ar, std::vector<T>& data,
379  const unsigned int version)
380  {
381  T element;
382  std::size_t size;
383  ar.unpack(size);
384  data.reserve(size);
385  data.clear();
386  for (size_t i = 0; i < size; ++i) {
387  ar & element;
388  data.push_back(element);
389  }
390  }
391 
392  // Explicit serialize methods for std library types.
393 
394  /*
395  * Load a std::complex<float> from a MemoryIArchive.
396  */
397  template <>
398  inline void serialize(MemoryIArchive& ar, std::complex<float>& data,
399  const unsigned int version)
400  { ar.unpack(data); }
401 
402  /*
403  * Load a std::complex<double> from a MemoryIArchive.
404  */
405  template <>
406  inline void serialize(MemoryIArchive& ar, std::complex<double>& data,
407  const unsigned int version)
408  { ar.unpack(data); }
409 
410  /*
411  * Load a std::string from MemoryIArchive.
412  */
413  template <>
414  void serialize(MemoryIArchive& ar, std::string& data,
415  const unsigned int version);
416 
417  // Explicit serialize methods for Util namespace types.
418 
419  /*
420  * Load a Util::Vector from a MemoryIArchive.
421  */
422  template <>
423  inline void serialize(MemoryIArchive& ar, Vector& data,
424  const unsigned int version)
425  { ar.unpack(data); }
426 
427  /*
428  * Load a Util::IntVector from a MemoryIArchive.
429  */
430  template <>
431  inline void serialize(MemoryIArchive& ar, IntVector& data,
432  const unsigned int version)
433  { ar.unpack(data); }
434 
435 }
436 #endif
A Vector is a Cartesian vector.
Definition: Vector.h:75
Byte * end() const
Return pointer to end of packed block (one Byte past the last).
size_t capacity() const
Return capacity in Bytes.
MemoryIArchive & operator=(MemoryOArchive &other)
Assignment from MemoryOArchive.
MemoryIArchive & operator&(T &data)
Load one object.
void reset()
Reset the cursor to the beginning (for rereading).
void release()
Release memory obtained by assignment.
MemoryIArchive()
Constructor.
unsigned char Byte
Define a "Byte" type.
Definition: Byte.h:19
void allocate(size_t capacity)
Allocate memory block.
void unpack(T &data)
Unpack one object of type T.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
Save archive for packed heterogeneous binary data.
Utility classes for scientific computation.
Definition: accumulators.mod:1
Byte * cursor() const
Return pointer to current position (cursor).
void clear()
Reset to empty state.
MemoryIArchive & operator>>(T &data)
Load one object.
static bool is_loading()
Returns false;.
Byte * begin() const
Return pointer to beginning of block.
bool isAllocated() const
Has memory been allocated?
void recv(MPI::Intracomm &comm, int source)
Receive packed data via MPI.
An IntVector is an integer Cartesian vector.
Definition: IntVector.h:73
~MemoryIArchive()
Destructor.
static bool is_saving()
Returns true;.
Input archive for packed heterogeneous binary data.