File indexing completed on 2024-04-06 12:01:24
0001 #ifndef CondCore_CondDB_Serialization_h
0002 #define CondCore_CondDB_Serialization_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
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
0024
0025 #include "CondFormats/Serialization/interface/Archive.h"
0026
0027 namespace cond {
0028
0029
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
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
0071 std::ostringstream dataBuffer;
0072 CondOutputArchive oa(dataBuffer);
0073 oa << payload;
0074
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
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
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 }
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