PSCF v1.1
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
21namespace 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>
88
94 template <typename T>
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
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 */
208 { return begin_; }
209
210 /*
211 * Return pointer to cursor position.
212 */
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
Input archive for packed heterogeneous binary data.
void recv(MPI::Intracomm &comm, int source)
Receive packed data via MPI.
Byte * begin() const
Return pointer to beginning of block.
static bool is_saving()
Returns true;.
MemoryIArchive & operator&(T &data)
Load one object.
static bool is_loading()
Returns false;.
MemoryIArchive & operator=(MemoryOArchive &other)
Assignment from MemoryOArchive.
void allocate(size_t capacity)
Allocate memory block.
void reset()
Reset the cursor to the beginning (for rereading).
size_t capacity() const
Return capacity in Bytes.
void clear()
Reset to empty state.
~MemoryIArchive()
Destructor.
void unpack(T &data)
Unpack one object of type T.
Byte * cursor() const
Return pointer to current position (cursor).
MemoryIArchive & operator>>(T &data)
Load one object.
void release()
Release memory obtained by assignment.
MemoryIArchive()
Constructor.
Byte * end() const
Return pointer to end of packed block (one Byte past the last).
bool isAllocated() const
Has memory been allocated?
Save archive for packed heterogeneous binary data.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
Utility classes for scientific computation.
Definition: accumulators.mod:1
unsigned char Byte
Define a "Byte" type.
Definition: Byte.h:19