Belle II Software  release-05-01-25
Stream.cc
1 #include <framework/utilities/Stream.h>
2 
3 #include <framework/logging/Logger.h>
4 
5 #include <TBase64.h>
6 #include <TObject.h>
7 #include <TMessage.h>
8 
9 #include <boost/algorithm/string/replace.hpp>
10 
11 using namespace Belle2;
12 
13 namespace {
15  class StreamMsg : public TMessage {
16  public:
17  StreamMsg(const void* buf, int len) : TMessage(const_cast<void*>(buf), len)
18  {
19  this->SetBit(kIsOwner, false);
20  }
21  };
22 }
23 
24 
25 std::string Stream::serializeAndEncode(const TObject* obj)
26 {
27  TMessage::EnableSchemaEvolutionForAll();
28 
29  TMessage msg(kMESS_OBJECT);
30  msg.SetWriteMode();
31 
32  // Currently disabled, but can be made to work by copying the input buffer in deserializeEncodedRawData
33  // However, this is a workaround and thus doesn't seem like a good idea.
34  // Once https://sft.its.cern.ch/jira/browse/ROOT-4550 is fixed, this can simply be turned on,
35  // but make sure to check that old (uncompressed) data can still be deserialized.
36  msg.SetCompressionLevel(0);
37 
38  msg.WriteObject(obj);
39  msg.Compress(); //only does something if compression active
40 
41  //convert TMessage into base64-encoded string
42  char* buf = msg.Buffer();
43  UInt_t len = msg.Length();
44 
45  if (msg.CompBuffer()) {
46  B2FATAL("compression used, but broken thanks to ROOT");
47  /* for future use?
48  buf = msg.CompBuffer();
49  len = msg.CompLength();
50  */
51  }
52 
53  const std::string& encodedStr(TBase64::Encode(buf, len).Data());
54  return encodedStr;
55 }
56 
57 std::string Stream::escapeXML(const std::string& xmlString)
58 {
59  //avoid nesting CDATA sections...
60  std::string newString(xmlString);
61  boost::replace_all(newString, "]]>", "]]]]><![CDATA[>");
62  return "<![CDATA[" + newString + "]]>";
63 }
64 
65 TObject* Stream::deserializeEncodedRawData(const std::string& base64Data)
66 {
67  if (base64Data.empty())
68  return nullptr;
69 
70  //convert data back into raw byte stream
71  const TString& data(TBase64::Decode(base64Data.c_str()));
72 
73  StreamMsg msg(data.Data(), data.Length());
74  //some checking
75  if (msg.What() != kMESS_OBJECT or msg.GetClass() == nullptr) {
76  return nullptr;
77  }
78  auto* obj = static_cast<TObject*>(msg.ReadObjectAny(msg.GetClass()));
79 
80  return obj;
81 }
Belle2::Stream::escapeXML
std::string escapeXML(const std::string &xmlString)
Escape given XML string as CDATA sequence.
Definition: Stream.cc:57
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::Stream::serializeAndEncode
std::string serializeAndEncode(const TObject *obj)
Convert given TObject into encoded byte stream (for storing in XML).
Definition: Stream.cc:25
Belle2::Stream::deserializeEncodedRawData
TObject * deserializeEncodedRawData(const std::string &base64Data)
Convert given serialized raw data back into TObject.
Definition: Stream.cc:65