CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 //
22 // temporarely
23 #include <boost/shared_ptr.hpp>
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  class StreamerInfo {
39  public:
40  static constexpr char const* TECH_LABEL = "technology";
41  static constexpr char const* TECH_VERSION_LABEL = "tech_version";
42  static constexpr char const* CMSSW_VERSION_LABEL = "CMSSW_version";
43  static constexpr char const* ARCH_LABEL = "architecture";
44  //
45  static constexpr char const* TECHNOLOGY = "boost/serialization" ;
46  static std::string techVersion();
47  static std::string jsonString();
48  };
49 
52 
53  // call for the serialization. Setting packingOnly = TRUE the data will stay in the original memory layout
54  // ( no serialization in this case ). This option is used by the ORA backend - will be dropped after the changeover
55  template <typename T> std::pair<Binary,Binary> serialize( const T& payload, bool packingOnly = false ){
56  std::pair<Binary,Binary> ret;
57  if( !packingOnly ){
58  std::string streamerInfo( StreamerInfo::jsonString() );
59  try{
60  // save data to buffers
61  std::ostringstream dataBuffer;
62  CondOutputArchive oa( dataBuffer );
63  oa << payload;
64  //TODO: avoid (2!!) copies
65  ret.first.copy( dataBuffer.str() );
66  ret.second.copy( streamerInfo );
67  } catch ( const std::exception& e ){
68  std::string em( e.what() );
69  throwException("Serialization failed: "+em+". Serialization info:"+streamerInfo,"serialize");
70  }
71  } else {
72  // ORA objects case: nothing to serialize, the object is kept in memory in the original layout - the bare pointer is exchanged
73  ret.first = Binary( payload );
74  }
75  return ret;
76  }
77 
78  // generates an instance of T from the binary serialized data. With unpackingOnly = true the memory is already storing the object in the final
79  // format. Only a cast is required in this case - Used by the ORA backed, will be dropped in the future.
80  template <typename T> boost::shared_ptr<T> default_deserialize( const std::string& payloadType,
81  const Binary& payloadData,
82  const Binary& streamerInfoData,
83  bool unpackingOnly ){
84  boost::shared_ptr<T> payload;
85  if( !unpackingOnly ){
86  std::stringbuf sstreamerInfoBuf;
87  sstreamerInfoBuf.pubsetbuf( static_cast<char*>(const_cast<void*>(streamerInfoData.data())), streamerInfoData.size() );
88  std::string streamerInfo = sstreamerInfoBuf.str();
89  try{
90  std::stringbuf sdataBuf;
91  sdataBuf.pubsetbuf( static_cast<char*>(const_cast<void*>(payloadData.data())), payloadData.size() );
92  std::istream dataBuffer( &sdataBuf );
93  CondInputArchive ia( dataBuffer );
94  payload.reset( createPayload<T>(payloadType) );
95  ia >> (*payload);
96  } catch ( const std::exception& e ){
97  std::string errorMsg("De-serialization failed: ");
98  std::string em( e.what() );
99  if( em == "unsupported version" ) {
100  errorMsg += "the current boost version ("+StreamerInfo::techVersion()+
101  ") is unable to read the payload. Data might have been serialized with an incompatible version.";
102  } else if( em == "input stream error" ) {
103  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.";
104  } else {
105  errorMsg += em;
106  }
107  if( !streamerInfo.empty() ) errorMsg += " Payload serialization info: "+streamerInfo;
108  throwException( errorMsg, "default_deserialize" );
109  }
110  } else {
111  // ORA objects case: nothing to de-serialize, the object is already in memory in the final layout, ready to be casted
112  payload = boost::static_pointer_cast<T>(payloadData.oraObject().makeShared());
113  }
114  return payload;
115  }
116 
117  // default specialization
118  template <typename T> boost::shared_ptr<T> deserialize( const std::string& payloadType,
119  const Binary& payloadData,
120  const Binary& streamerInfoData,
121  bool unpackingOnly = false){
122  return default_deserialize<T>( payloadType, payloadData, streamerInfoData, unpackingOnly );
123  }
124 
125 }
126 
127 #define DESERIALIZE_BASE_CASE( BASETYPENAME ) \
128  if( payloadType == #BASETYPENAME ){ \
129  return default_deserialize<BASETYPENAME>( payloadType, payloadData, streamerInfoData, unpackingOnly ); \
130  }
131 
132 #define DESERIALIZE_POLIMORPHIC_CASE( BASETYPENAME, DERIVEDTYPENAME ) \
133  if( payloadType == #DERIVEDTYPENAME ){ \
134  return boost::dynamic_pointer_cast<BASETYPENAME>( default_deserialize<DERIVEDTYPENAME>( payloadType, payloadData, streamerInfoData, unpackingOnly ) ); \
135  }
136 
137 #endif
eos::portable_oarchive OutputArchive
Definition: Archive.h:16
static char const * CMSSW_VERSION_LABEL
Definition: Serialization.h:42
static std::string techVersion()
Definition: Serialization.cc:6
boost::shared_ptr< void > makeShared() const
Definition: Object.cc:73
static char const * TECH_LABEL
Definition: Serialization.h:40
cond::serialization::InputArchive CondInputArchive
Definition: Serialization.h:50
eos::portable_iarchive InputArchive
Definition: Archive.h:15
#define constexpr
size_t size() const
Definition: Binary.cc:57
std::string demangledName(const std::type_info &typeInfo)
Definition: ClassUtils.cc:156
T * createPayload(const std::string &payloadTypeName)
Definition: Serialization.h:30
static char const * TECHNOLOGY
Definition: Serialization.h:45
ora::Object oraObject() const
Definition: Binary.cc:62
static char const * TECH_VERSION_LABEL
Definition: Serialization.h:41
const void * data() const
Definition: Binary.cc:48
static std::string jsonString()
cond::serialization::OutputArchive CondOutputArchive
Definition: Serialization.h:51
void throwException(std::string const &message, std::string const &methodName)
Definition: Exception.cc:17
boost::shared_ptr< T > deserialize(const std::string &payloadType, const Binary &payloadData, const Binary &streamerInfoData, bool unpackingOnly=false)
std::pair< Binary, Binary > serialize(const T &payload, bool packingOnly=false)
Definition: Serialization.h:55
static char const * ARCH_LABEL
Definition: Serialization.h:43
boost::shared_ptr< T > default_deserialize(const std::string &payloadType, const Binary &payloadData, const Binary &streamerInfoData, bool unpackingOnly)
Definition: Serialization.h:80
long double T