Belle II Software  release-08-01-10
MsgHandler.h
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #pragma once
10 
11 #include <framework/pcore/EvtMessage.h>
12 #include <TMessage.h>
13 
14 #include <string>
15 #include <memory>
16 
17 class TObject;
18 
19 namespace Belle2 {
30  class CharBuffer {
31  std::unique_ptr<char[]> m_data;
32  size_t m_capacity{0};
33  size_t m_size{0};
34  public:
38  explicit CharBuffer(size_t initial_capacity = 0): m_data{initial_capacity > 0 ? new char[initial_capacity] : nullptr}
39  {}
43  void add(const void* data, size_t len)
44  {
45  auto old_size = m_size;
46  resize(m_size + len);
47  memcpy(m_data.get() + old_size, data, len);
48  }
52  char* data() { return m_data.get(); }
54  size_t size() const { return m_size; }
56  void clear() { m_size = 0; }
60  void resize(size_t size)
61  {
62  if (size > m_capacity) {
63  // grow by basically doubling each time, except if the size we need to
64  // grow to is even more than that
65  m_capacity = std::max(size, m_capacity * 2);
66  //c++14: auto newbuf = std::make_unique<char[]>(m_capacity);
67  std::unique_ptr<char[]> newbuf{new char[m_capacity]};
68  memcpy(newbuf.get(), m_data.get(), m_size);
69  std::swap(m_data, newbuf);
70  }
71  m_size = size;
72  }
73  };
74 
76  class InMessage : public TMessage {
77  public:
78  InMessage() : TMessage()
79  {
80  SetReadMode();
81  SetWhat(kMESS_OBJECT);
82  }
83 
85  void SetBuffer(const void* ptr, UInt_t bufsize)
86  {
87  TBuffer::SetBuffer(const_cast<void*>(ptr), bufsize, false);
88  // TMessage has an extra header of two ints: a reserved size field and a
89  // fWhat pointer indicating the type of the message. We force the message
90  // to be MESS_OBJECT so we don't care. Let's put the buffer where we need
91  // it to be. The original constructor has a ReadClass() here but we skip
92  // it since we read everything as TObject.
93  SetBufferOffset(sizeof(UInt_t) * 2);
94  // and reset the map of objects/classes seen so far
95  ResetMap();
96  }
97 
99  TObject* readTObject() { return static_cast<TObject*>(ReadObjectAny(TObject::Class())); }
100  };
101 
103  class MsgHandler {
104  public:
115  explicit MsgHandler(int complevel = 0);
117  virtual ~MsgHandler();
118 
120  virtual void clear();
122  virtual void add(const TObject*, const std::string& name);
123 
125  virtual EvtMessage* encode_msg(ERecordType rectype);
127  virtual void decode_msg(EvtMessage* msg, std::vector<TObject*>& objlist, std::vector<std::string>& namelist);
128 
129  private:
132  std::unique_ptr<TMessage> m_msg;
138  };
139 
141 } // namespace Belle2
dynamic character buffer that knows its size.
Definition: MsgHandler.h:30
std::unique_ptr< char[]> m_data
data buffer.
Definition: MsgHandler.h:31
size_t m_size
current size, <= m_capacity
Definition: MsgHandler.h:33
size_t size() const
return buffer size (do not access data() beyond this)
Definition: MsgHandler.h:54
void resize(size_t size)
resize, similar to std::vector<char>::resize in that it will copy the existing buffer to a new,...
Definition: MsgHandler.h:60
size_t m_capacity
size of allocated memory in m_data
Definition: MsgHandler.h:32
char * data()
return raw pointer.
Definition: MsgHandler.h:52
CharBuffer(size_t initial_capacity=0)
Constructor, with the initial capacity of the buffer to allocate (in bytes).
Definition: MsgHandler.h:38
void clear()
reset (without deallocating)
Definition: MsgHandler.h:56
void add(const void *data, size_t len)
copy data to end of buffer, expanding buffer if needed.
Definition: MsgHandler.h:43
Class to manage streamed object.
Definition: EvtMessage.h:59
Reusable Message class derived from TMessage (for reading only)
Definition: MsgHandler.h:76
void SetBuffer(const void *ptr, UInt_t bufsize)
Replace buffer (doesn't take ownership).
Definition: MsgHandler.h:85
TObject * readTObject()
Read one object from the message assuming it inherits from TObject.
Definition: MsgHandler.h:99
A class to encode/decode an EvtMessage.
Definition: MsgHandler.h:103
virtual ~MsgHandler()
Destructor.
int m_complevel
compression algorithm * 100 + compression level.
Definition: MsgHandler.h:134
InMessage m_inMsg
Used for deserializing in decode_msg()
Definition: MsgHandler.h:133
virtual void decode_msg(EvtMessage *msg, std::vector< TObject * > &objlist, std::vector< std::string > &namelist)
Decode an EvtMessage into a vector list of objects with names.
Definition: MsgHandler.cc:106
MsgHandler(int complevel=0)
Constructor.
Definition: MsgHandler.cc:25
CharBuffer m_buf
EvtMessage character buffer for encode_msg().
Definition: MsgHandler.h:130
virtual void add(const TObject *, const std::string &name)
Add an object to be streamed.
Definition: MsgHandler.cc:46
CharBuffer m_compBuf
EvtMessage character buffer for compressing/decompressing.
Definition: MsgHandler.h:131
std::unique_ptr< TMessage > m_msg
Used for serialising objects into m_buf.
Definition: MsgHandler.h:132
virtual EvtMessage * encode_msg(ERecordType rectype)
Stream object list into an EvtMessage.
Definition: MsgHandler.cc:67
virtual void clear()
Clear object list.
Definition: MsgHandler.cc:40
ERecordType
What type of message is this?
Definition: EvtMessage.h:25
Abstract base class for different kinds of events.