StreamerInfo

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
#ifndef CondCore_CondDB_Serialization_h
#define CondCore_CondDB_Serialization_h
//
// Package:     CondDB
//
/**Serialization.h CondCore/CondDB/interface/Serialization.h
   Description: functions for serializing the payload objects.  
*/
//
// Author:      Giacomo Govi
// Created:     October 2013
//
//

#include "CondCore/CondDB/interface/Binary.h"
#include "CondCore/CondDB/interface/Exception.h"
#include "CondCore/CondDB/interface/Utils.h"
//
#include <sstream>
#include <iostream>
#include <memory>
//
// temporarely

#include "CondFormats/Serialization/interface/Archive.h"

namespace cond {

  // default payload factory
  template <typename T>
  T* createPayload(const std::string& payloadTypeName) {
    std::string userTypeName = demangledName(typeid(T));
    if (userTypeName != payloadTypeName)
      throwException(
          std::string("Type mismatch, user type: \"" + userTypeName + "\", target type: \"") + payloadTypeName + "\"",
          "createPayload");
    return new T;
  }

  template <>
  inline std::string* createPayload<std::string>(const std::string& payloadTypeName) {
    std::string userTypeName = demangledName(typeid(std::string));
    if (payloadTypeName != userTypeName && payloadTypeName != "std::string")
      throwException(std::string("Type mismatch, user type: \"std::string\", target type: \"") + payloadTypeName + "\"",
                     "createPayload");
    return new std::string;
  }

  class StreamerInfo {
  public:
    static constexpr char const* TECH_LABEL = "technology";
    static constexpr char const* TECH_VERSION_LABEL = "tech_version";
    static constexpr char const* CMSSW_VERSION_LABEL = "CMSSW_version";
    static constexpr char const* ARCH_LABEL = "architecture";
    //
    static constexpr char const* TECHNOLOGY = "boost/serialization";
    static std::string techVersion();
    static std::string jsonString();
  };

  typedef cond::serialization::InputArchive CondInputArchive;
  typedef cond::serialization::OutputArchive CondOutputArchive;

  // call for the serialization.
  template <typename T>
  std::pair<Binary, Binary> serialize(const T& payload) {
    std::pair<Binary, Binary> ret;
    std::string streamerInfo(StreamerInfo::jsonString());
    try {
      // save data to buffers
      std::ostringstream dataBuffer;
      CondOutputArchive oa(dataBuffer);
      oa << payload;
      //TODO: avoid (2!!) copies
      ret.first.copy(dataBuffer.str());
      ret.second.copy(streamerInfo);
    } catch (const std::exception& e) {
      std::string em(e.what());
      throwException("Serialization failed: " + em + ". Serialization info:" + streamerInfo, "serialize");
    }
    return ret;
  }

  // generates an instance of T from the binary serialized data.
  template <typename T>
  std::unique_ptr<T> default_deserialize(const std::string& payloadType,
                                         const Binary& payloadData,
                                         const Binary& streamerInfoData) {
    std::unique_ptr<T> payload;
    std::stringbuf sstreamerInfoBuf;
    sstreamerInfoBuf.pubsetbuf(static_cast<char*>(const_cast<void*>(streamerInfoData.data())), streamerInfoData.size());
    std::string streamerInfo = sstreamerInfoBuf.str();
    try {
      std::stringbuf sdataBuf;
      sdataBuf.pubsetbuf(static_cast<char*>(const_cast<void*>(payloadData.data())), payloadData.size());
      std::istream dataBuffer(&sdataBuf);
      CondInputArchive ia(dataBuffer);
      payload.reset(createPayload<T>(payloadType));
      ia >> (*payload);
    } catch (const std::exception& e) {
      std::string errorMsg("De-serialization failed: ");
      std::string em(e.what());
      if (em == "unsupported version") {
        errorMsg += "the current boost version (" + StreamerInfo::techVersion() +
                    ") is unable to read the payload. Data might have been serialized with an incompatible version.";
      } else if (em == "input stream error") {
        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.";
      } else {
        errorMsg += em;
      }
      if (!streamerInfo.empty())
        errorMsg += " Payload serialization info: " + streamerInfo;
      throwException(errorMsg, "default_deserialize");
    }
    return payload;
  }

  // default specialization
  template <typename T>
  std::unique_ptr<T> deserialize(const std::string& payloadType,
                                 const Binary& payloadData,
                                 const Binary& streamerInfoData) {
    return default_deserialize<T>(payloadType, payloadData, streamerInfoData);
  }

}  // namespace cond

#define DESERIALIZE_BASE_CASE(BASETYPENAME)                                               \
  if (payloadType == #BASETYPENAME) {                                                     \
    return default_deserialize<BASETYPENAME>(payloadType, payloadData, streamerInfoData); \
  }

#define DESERIALIZE_POLIMORPHIC_CASE(BASETYPENAME, DERIVEDTYPENAME)                          \
  if (payloadType == #DERIVEDTYPENAME) {                                                     \
    return default_deserialize<DERIVEDTYPENAME>(payloadType, payloadData, streamerInfoData); \
  }

#endif