cisst-saw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cmnDeSerializer.h
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3 
4 /*
5 
6  Author(s): Anton Deguet, Min Yang Jung
7  Created on: 2007-04-08
8 
9  (C) Copyright 2007-2013 Johns Hopkins University (JHU), All Rights Reserved.
10 
11 --- begin cisst license - do not edit ---
12 
13 This software is provided "as is" under an open source license, with
14 no warranty. The complete license can be found in license.txt and
15 http://www.cisst.org/cisst/license.txt.
16 
17 --- end cisst license ---
18 
19 */
20 
21 
26 #pragma once
27 
28 #ifndef _cmnDeSerializer_h
29 #define _cmnDeSerializer_h
30 
35 #include <cisstCommon/cmnThrow.h>
36 #include <cisstCommon/cmnAssert.h>
37 
38 #include <string>
39 #include <fstream>
40 #include <map>
41 #include <cstddef>
42 
43 #include <cisstCommon/cmnExport.h>
44 
45 
46 // Implementation class to provide deserialization when _elementType is not derived from cmnGenericObject
47 template <class _elementType, bool>
49 {
50 public:
51  static void DeSerializeRaw(std::istream & inputStream, _elementType & data) throw (std::runtime_error)
52  {
53  inputStream.read(reinterpret_cast<char *>(&data), sizeof(_elementType));
54  if (inputStream.fail()) {
55  std::string message("cmnDeSerializeRaw(_elementType): Error occured with std::istream::read, _elementType = ");
56  message += typeid(_elementType).name();
57  cmnThrow(message);
58  }
59  }
60 };
61 
62 // Implementation class to provide deserialization when _elementType is derived from cmnGenericObject
63 template <class _elementType>
64 class cmnDeSerializeRawImpl<_elementType, true>
65 {
66 public:
67  static void DeSerializeRaw(std::istream & inputStream, _elementType & data) throw (std::runtime_error)
68  {
69  data.DeSerializeRaw(inputStream);
70  }
71 };
72 
81 template <class _elementType>
82 inline void cmnDeSerializeRaw(std::istream & inputStream, _elementType & data)
83  throw (std::runtime_error)
84 {
86  impl::DeSerializeRaw(inputStream, data);
87 }
88 
96 inline void cmnDeSerializeSizeRaw(std::istream & inputStream, size_t & data)
97  throw (std::runtime_error)
98 {
99  unsigned long long int dataToRead;
100  cmnDeSerializeRaw(inputStream, dataToRead);
101  if (dataToRead <= cmnTypeTraits<size_t>::MaxPositiveValue()) {
102  data = static_cast<size_t>(dataToRead);
103  } else {
104  cmnThrow("cmnDeSerializeSizeRaw: received size greater than maximum supported on this configuration");
105  }
106 }
107 
108 
114 inline void cmnDeSerializeRaw(std::istream & inputStream, std::string & data)
115  throw (std::runtime_error)
116 {
117  std::string::size_type size = 0;
118  cmnDeSerializeSizeRaw(inputStream, size);
119  data.resize(size);
120  // The following seems to work fine, but may not be valid for all implementations of std::string
121  // because it is not guaranteed that c_str(), or data(), returns a pointer to the internal buffer;
122  // it could create a copy and then return a pointer to the copy.
123  //
124  // inputStream.read(const_cast<char *>(data.c_str()), size * sizeof(std::string::value_type));
125  //
126  // So, even though it is less efficient, the data is first deserialized to a buffer and then
127  // assigned to the string.
128  std::string::value_type *buffer = new std::string::value_type[size];
129  inputStream.read(static_cast<char *>(buffer), size * sizeof(std::string::value_type));
130  data.assign(buffer, size);
131  delete [] buffer;
132  if (inputStream.fail()) {
133  cmnThrow("cmnDeSerializeRaw(std::string): Error occured with std::istream::read");
134  }
135 }
136 
137 
144 template <class _elementType>
145 inline void cmnDeSerializeRaw(std::istream & inputStream, std::vector<_elementType> & data)
146  throw (std::runtime_error)
147 {
148  typename std::vector<_elementType>::size_type size = 0;
149  cmnDeSerializeSizeRaw(inputStream, size);
150  data.resize(size);
151  for (size_t i = 0; i < size; i++) {
152  cmnDeSerializeRaw(inputStream, data[i]);
153  if (inputStream.fail()) {
154  cmnThrow("cmnDeSerializeRaw(std::vector<_elementType>): Error occured with std::istream::read");
155  }
156  }
157 }
158 
159 
179 
180 public:
184  typedef long long int TypeId;
185 
192  cmnDeSerializer(std::istream & inputStream);
193 
195  ~cmnDeSerializer();
196 
198  void Reset(void);
199 
218  cmnGenericObject * DeSerialize(const bool serializeObject = true);
219 
220 
232  template <class _elementType>
233  inline void DeSerialize(_elementType & object, const bool serializeObject = true) {
234  // get object services
235  TypeId typeId;
236  cmnDeSerializeRaw(this->InputStream, typeId);
237  if (typeId == 0) {
238  this->DeSerializeServices();
239  // read again to deserialize coming object
240  if (serializeObject) {
241  this->DeSerialize(object);
242  }
243  } else {
244  const const_iterator end = ServicesContainer.end();
245  const const_iterator iterator = ServicesContainer.find(typeId);
246  if (iterator == end) {
247  cmnThrow("DeSerialize: Can't find corresponding class information");
248  } else {
249  cmnClassServicesBase * servicesPointerLocal = iterator->second;
250  if (servicesPointerLocal != object.Services()) {
251  CMN_LOG_CLASS_RUN_ERROR << "DeSerialize: Object types don't match, local class = "
252  << servicesPointerLocal->GetName() << ", object class = " << object.Services()->GetName()
253  << std::endl;
254  cmnThrow("DeSerialize: Object types don't match");
255  } else {
256  if (serializeObject) {
257  object.DeSerializeRaw(this->InputStream);
258  }
259  }
260  }
261  }
262  }
263 
264 
265  private:
279  void DeSerializeServices(void) throw(std::runtime_error);
280 
281  std::istream & InputStream;
282 
283  typedef std::map<TypeId, cmnClassServicesBase *> ServicesContainerType;
284  typedef ServicesContainerType::value_type EntryType;
285 
286  typedef ServicesContainerType::const_iterator const_iterator;
287  typedef ServicesContainerType::iterator iterator;
288 
289  ServicesContainerType ServicesContainer;
290 };
291 
292 
293 // Add services instantiation
295 
296 
297 #endif // _cmnDeSerialize_h
298 
#define CISST_EXPORT
Definition: cmnExportMacros.h:50
Assert macros definitions.
Portability across compilers and operating systems tools.
static void DeSerializeRaw(std::istream &inputStream, _elementType &data)
Definition: cmnDeSerializer.h:51
void cmnDeSerializeSizeRaw(std::istream &inputStream, size_t &data)
Definition: cmnDeSerializer.h:96
Definition: cmnDeSerializer.h:48
const std::string & GetName(void) const
size_t size_type
Definition: vctContainerTraits.h:35
Base class for high level objects.
Definition: cmnGenericObject.h:51
Class register definitions and log macros.
virtual const cmnClassServicesBase * Services(void) const =0
Macros to export the symbols of cisstCommon (in a Dll).
Declaration of the class cmnTypeTraits.
void cmnDeSerializeRaw(std::istream &inputStream, _elementType &data)
Definition: cmnDeSerializer.h:82
Defines cmnGenericObject.
De-serialization utility class.This class allows to deserialize objects previously serialized using c...
Definition: cmnDeSerializer.h:177
void DeSerialize(_elementType &object, const bool serializeObject=true)
Definition: cmnDeSerializer.h:233
#define CMN_DECLARE_SERVICES(hasDynamicCreation, lod)
Definition: cmnClassRegisterMacros.h:116
#define cmnThrow(a)
Definition: MinimalCmn.h:4
long long int TypeId
Definition: cmnDeSerializer.h:184
#define CMN_LOG_CLASS_RUN_ERROR
Definition: cmnLogger.h:117
Base class for class services.
Definition: cmnClassServicesBase.h:45
Declaration of the template function cmnThrow.
A collection of useful information about the C++ basic types, represented in a generic programming wa...
Definition: cmnTypeTraits.h:155
const int CMN_NO_DYNAMIC_CREATION
Definition: cmnClassRegisterMacros.h:328
#define CMN_DECLARE_SERVICES_INSTANTIATION(className)
Definition: cmnClassRegisterMacros.h:202
#define CMN_LOG_ALLOW_DEFAULT
Definition: cmnLogLoD.h:76
static void DeSerializeRaw(std::istream &inputStream, _elementType &data)
Definition: cmnDeSerializer.h:67