CMS 3D CMS Logo

Serialization.h
Go to the documentation of this file.
1 #ifndef CondCore_CondDB_Serialization_h
2 #define CondCore_CondDB_Serialization_h
3 //
4 // Package: CondDB
5 //
9 //
10 // Author: Giacomo Govi
11 // Created: October 2013
12 //
13 //
14 
18 //
19 #include <sstream>
20 #include <iostream>
21 #include <memory>
22 //
23 // temporarely
24 
26 
27 namespace cond {
28 
29  // default payload factory
30  template <typename T> T* createPayload( const std::string& payloadTypeName ){
31  std::string userTypeName = demangledName( typeid(T) );
32  if( userTypeName != payloadTypeName )
33  throwException(std::string("Type mismatch, user type: \""+userTypeName+"\", target type: \"")+payloadTypeName+"\"",
34  "createPayload" );
35  return new T;
36  }
37 
38  template <> inline std::string* createPayload<std::string>( const std::string& payloadTypeName ){
39  std::string userTypeName = demangledName( typeid(std::string) );
40  if( payloadTypeName != userTypeName && payloadTypeName != "std::string" )
41  throwException(std::string("Type mismatch, user type: \"std::string\", target type: \"")+payloadTypeName+"\"",
42  "createPayload" );
43  return new std::string;
44  }
45 
46  class StreamerInfo {
47  public:
48  static constexpr char const* TECH_LABEL = "technology";
49  static constexpr char const* TECH_VERSION_LABEL = "tech_version";
50  static constexpr char const* CMSSW_VERSION_LABEL = "CMSSW_version";
51  static constexpr char const* ARCH_LABEL = "architecture";
52  //
53  static constexpr char const* TECHNOLOGY = "boost/serialization" ;
54  static std::string techVersion();
55  static std::string jsonString();
56  };
57 
60 
61  // call for the serialization.
62  template <typename T> std::pair<Binary,Binary> serialize( const T& payload ){
63  std::pair<Binary,Binary> ret;
64  std::string streamerInfo( StreamerInfo::jsonString() );
65  try{
66  // save data to buffers
67  std::ostringstream dataBuffer;
68  CondOutputArchive oa( dataBuffer );
69  oa << payload;
70  //TODO: avoid (2!!) copies
71  ret.first.copy( dataBuffer.str() );
72  ret.second.copy( streamerInfo );
73  } catch ( const std::exception& e ){
74  std::string em( e.what() );
75  throwException("Serialization failed: "+em+". Serialization info:"+streamerInfo,"serialize");
76  }
77  return ret;
78  }
79 
80  // generates an instance of T from the binary serialized data.
81  template <typename T> std::shared_ptr<T> default_deserialize( const std::string& payloadType,
82  const Binary& payloadData,
83  const Binary& streamerInfoData ){
84  std::shared_ptr<T> payload;
85  std::stringbuf sstreamerInfoBuf;
86  sstreamerInfoBuf.pubsetbuf( static_cast<char*>(const_cast<void*>(streamerInfoData.data())), streamerInfoData.size() );
87  std::string streamerInfo = sstreamerInfoBuf.str();
88  try{
89  std::stringbuf sdataBuf;
90  sdataBuf.pubsetbuf( static_cast<char*>(const_cast<void*>(payloadData.data())), payloadData.size() );
91  std::istream dataBuffer( &sdataBuf );
92  CondInputArchive ia( dataBuffer );
93  payload.reset( createPayload<T>(payloadType) );
94  ia >> (*payload);
95  } catch ( const std::exception& e ){
96  std::string errorMsg("De-serialization failed: ");
97  std::string em( e.what() );
98  if( em == "unsupported version" ) {
99  errorMsg += "the current boost version ("+StreamerInfo::techVersion()+
100  ") is unable to read the payload. Data might have been serialized with an incompatible version.";
101  } else if( em == "input stream error" ) {
102  errorMsg +="data size does not fit with the current class layout. The Class "+payloadType+" might have been changed with respect to the layout used in the upload.";
103  } else {
104  errorMsg += em;
105  }
106  if( !streamerInfo.empty() ) errorMsg += " Payload serialization info: "+streamerInfo;
107  throwException( errorMsg, "default_deserialize" );
108  }
109  return payload;
110  }
111 
112  // default specialization
113  template <typename T> std::shared_ptr<T> deserialize( const std::string& payloadType,
114  const Binary& payloadData,
115  const Binary& streamerInfoData ){
116  return default_deserialize<T>( payloadType, payloadData, streamerInfoData );
117  }
118 
119 }
120 
121 #define DESERIALIZE_BASE_CASE( BASETYPENAME ) \
122  if( payloadType == #BASETYPENAME ){ \
123  return default_deserialize<BASETYPENAME>( payloadType, payloadData, streamerInfoData ); \
124  }
125 
126 #define DESERIALIZE_POLIMORPHIC_CASE( BASETYPENAME, DERIVEDTYPENAME ) \
127  if( payloadType == #DERIVEDTYPENAME ){ \
128  return std::dynamic_pointer_cast<BASETYPENAME>( default_deserialize<DERIVEDTYPENAME>( payloadType, payloadData, streamerInfoData ) ); \
129  }
130 
131 #endif
eos::portable_oarchive OutputArchive
Definition: Archive.h:17
static char const * CMSSW_VERSION_LABEL
Definition: Serialization.h:50
static std::string techVersion()
Definition: Serialization.cc:6
std::pair< Binary, Binary > serialize(const T &payload)
Definition: Serialization.h:62
static char const * TECH_LABEL
Definition: Serialization.h:48
cond::serialization::InputArchive CondInputArchive
Definition: Serialization.h:58
eos::portable_iarchive InputArchive
Definition: Archive.h:16
void throwException(const std::string &message, const std::string &methodName)
Definition: Exception.cc:21
#define constexpr
size_t size() const
Definition: Binary.cc:54
T * createPayload(const std::string &payloadTypeName)
Definition: Serialization.h:30
payload
payload postfix for testing
std::shared_ptr< T > default_deserialize(const std::string &payloadType, const Binary &payloadData, const Binary &streamerInfoData)
Definition: Serialization.h:81
static char const * TECHNOLOGY
Definition: Serialization.h:53
static char const * TECH_VERSION_LABEL
Definition: Serialization.h:49
const void * data() const
Definition: Binary.cc:45
static std::string jsonString()
cond::serialization::OutputArchive CondOutputArchive
Definition: Serialization.h:59
std::shared_ptr< T > deserialize(const std::string &payloadType, const Binary &payloadData, const Binary &streamerInfoData)
Definition: plugin.cc:24
static char const * ARCH_LABEL
Definition: Serialization.h:51
long double T