Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:01:24

0001 #ifndef CondCore_CondDB_Serialization_h
0002 #define CondCore_CondDB_Serialization_h
0003 //
0004 // Package:     CondDB
0005 //
0006 /**Serialization.h CondCore/CondDB/interface/Serialization.h
0007    Description: functions for serializing the payload objects.  
0008 */
0009 //
0010 // Author:      Giacomo Govi
0011 // Created:     October 2013
0012 //
0013 //
0014 
0015 #include "CondCore/CondDB/interface/Binary.h"
0016 #include "CondCore/CondDB/interface/Exception.h"
0017 #include "CondCore/CondDB/interface/Utils.h"
0018 //
0019 #include <sstream>
0020 #include <iostream>
0021 #include <memory>
0022 //
0023 // temporarely
0024 
0025 #include "CondFormats/Serialization/interface/Archive.h"
0026 
0027 namespace cond {
0028 
0029   // default payload factory
0030   template <typename T>
0031   T* createPayload(const std::string& payloadTypeName) {
0032     std::string userTypeName = demangledName(typeid(T));
0033     if (userTypeName != payloadTypeName)
0034       throwException(
0035           std::string("Type mismatch, user type: \"" + userTypeName + "\", target type: \"") + payloadTypeName + "\"",
0036           "createPayload");
0037     return new T;
0038   }
0039 
0040   template <>
0041   inline std::string* createPayload<std::string>(const std::string& payloadTypeName) {
0042     std::string userTypeName = demangledName(typeid(std::string));
0043     if (payloadTypeName != userTypeName && payloadTypeName != "std::string")
0044       throwException(std::string("Type mismatch, user type: \"std::string\", target type: \"") + payloadTypeName + "\"",
0045                      "createPayload");
0046     return new std::string;
0047   }
0048 
0049   class StreamerInfo {
0050   public:
0051     static constexpr char const* TECH_LABEL = "technology";
0052     static constexpr char const* TECH_VERSION_LABEL = "tech_version";
0053     static constexpr char const* CMSSW_VERSION_LABEL = "CMSSW_version";
0054     static constexpr char const* ARCH_LABEL = "architecture";
0055     //
0056     static constexpr char const* TECHNOLOGY = "boost/serialization";
0057     static std::string techVersion();
0058     static std::string jsonString();
0059   };
0060 
0061   typedef cond::serialization::InputArchive CondInputArchive;
0062   typedef cond::serialization::OutputArchive CondOutputArchive;
0063 
0064   // call for the serialization.
0065   template <typename T>
0066   std::pair<Binary, Binary> serialize(const T& payload) {
0067     std::pair<Binary, Binary> ret;
0068     std::string streamerInfo(StreamerInfo::jsonString());
0069     try {
0070       // save data to buffers
0071       std::ostringstream dataBuffer;
0072       CondOutputArchive oa(dataBuffer);
0073       oa << payload;
0074       //TODO: avoid (2!!) copies
0075       ret.first.copy(dataBuffer.str());
0076       ret.second.copy(streamerInfo);
0077     } catch (const std::exception& e) {
0078       std::string em(e.what());
0079       throwException("Serialization failed: " + em + ". Serialization info:" + streamerInfo, "serialize");
0080     }
0081     return ret;
0082   }
0083 
0084   // generates an instance of T from the binary serialized data.
0085   template <typename T>
0086   std::unique_ptr<T> default_deserialize(const std::string& payloadType,
0087                                          const Binary& payloadData,
0088                                          const Binary& streamerInfoData) {
0089     std::unique_ptr<T> payload;
0090     std::stringbuf sstreamerInfoBuf;
0091     sstreamerInfoBuf.pubsetbuf(static_cast<char*>(const_cast<void*>(streamerInfoData.data())), streamerInfoData.size());
0092     std::string streamerInfo = sstreamerInfoBuf.str();
0093     try {
0094       std::stringbuf sdataBuf;
0095       sdataBuf.pubsetbuf(static_cast<char*>(const_cast<void*>(payloadData.data())), payloadData.size());
0096       std::istream dataBuffer(&sdataBuf);
0097       CondInputArchive ia(dataBuffer);
0098       payload.reset(createPayload<T>(payloadType));
0099       ia >> (*payload);
0100     } catch (const std::exception& e) {
0101       std::string errorMsg("De-serialization failed: ");
0102       std::string em(e.what());
0103       if (em == "unsupported version") {
0104         errorMsg += "the current boost version (" + StreamerInfo::techVersion() +
0105                     ") is unable to read the payload. Data might have been serialized with an incompatible version.";
0106       } else if (em == "input stream error") {
0107         errorMsg += "data size does not fit with the current class layout. The Class " + payloadType +
0108                     " might have been changed with respect to the layout used in the upload.";
0109       } else {
0110         errorMsg += em;
0111       }
0112       if (!streamerInfo.empty())
0113         errorMsg += " Payload serialization info: " + streamerInfo;
0114       throwException(errorMsg, "default_deserialize");
0115     }
0116     return payload;
0117   }
0118 
0119   // default specialization
0120   template <typename T>
0121   std::unique_ptr<T> deserialize(const std::string& payloadType,
0122                                  const Binary& payloadData,
0123                                  const Binary& streamerInfoData) {
0124     return default_deserialize<T>(payloadType, payloadData, streamerInfoData);
0125   }
0126 
0127 }  // namespace cond
0128 
0129 #define DESERIALIZE_BASE_CASE(BASETYPENAME)                                               \
0130   if (payloadType == #BASETYPENAME) {                                                     \
0131     return default_deserialize<BASETYPENAME>(payloadType, payloadData, streamerInfoData); \
0132   }
0133 
0134 #define DESERIALIZE_POLIMORPHIC_CASE(BASETYPENAME, DERIVEDTYPENAME)                          \
0135   if (payloadType == #DERIVEDTYPENAME) {                                                     \
0136     return default_deserialize<DERIVEDTYPENAME>(payloadType, payloadData, streamerInfoData); \
0137   }
0138 
0139 #endif