Project
Loading...
Searching...
No Matches
TMessageSerializer.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#ifndef FRAMEWORK_TMESSAGESERIALIZER_H
12#define FRAMEWORK_TMESSAGESERIALIZER_H
13
14#include <fairmq/Message.h>
15
17
18#include <TList.h>
19#include <TBufferFile.h>
20#include <TObjArray.h>
21#include <memory>
22#include <mutex>
23#include <cstddef>
24
25namespace o2::framework
26{
27class FairOutputTBuffer;
28class FairInputTBuffer;
29
30// A TBufferFile which we can use to serialise data to a FairMQ message.
32{
33 public:
34 // This is to serialise data to FairMQ. We embed the pointer to the message
35 // in the data itself, so that we can use it to reallocate the message if needed.
36 // The FairMQ message retains ownership of the data.
37 // When deserialising the root object, keep in mind one needs to skip the 8 bytes
38 // for the pointer.
39 FairOutputTBuffer(fair::mq::Message& msg)
40 : TBufferFile(TBuffer::kWrite, msg.GetSize() - sizeof(char*), embedInItself(msg), false, fairMQrealloc)
41 {
42 }
43
45 // Helper function to keep track of the FairMQ message that holds the data
46 // in the data itself. We can use this to make sure the message can be reallocated
47 // even if we simply have a pointer to the data. Hopefully ROOT will not play dirty
48 // with us.
49 void* embedInItself(fair::mq::Message& msg);
50 // helper function to clean up the object holding the data after it is transported.
51 static char* fairMQrealloc(char* oldData, size_t newSize, size_t oldSize);
52};
53
55{
56 public:
57 // This is to serialise data to FairMQ. The provided message is expeted to have 8 bytes
58 // of overhead, where the source embedded the pointer for the reallocation.
59 // Notice this will break if the sender and receiver are not using the same
60 // size for a pointer.
61 FairInputTBuffer(char* data, size_t size)
62 : TBufferFile(TBuffer::kRead, size - sizeof(char*), data + sizeof(char*), false, nullptr)
63 {
64 }
66};
67
69 static void Serialize(fair::mq::Message& msg, const TObject* input);
70
71 template <typename T>
72 static void Serialize(fair::mq::Message& msg, const T* input, const TClass* cl);
73
74 template <typename T = TObject>
75 static void Deserialize(const fair::mq::Message& msg, std::unique_ptr<T>& output);
76
77 static void serialize(o2::framework::FairOutputTBuffer& msg, const TObject* input);
78
79 template <typename T>
80 static void serialize(o2::framework::FairOutputTBuffer& msg, const T* input, const TClass* cl);
81
82 template <typename T = TObject>
83 static inline std::unique_ptr<T> deserialize(FairInputTBuffer& buffer);
84};
85
87{
88 return serialize(tm, input, nullptr);
89}
90
91template <typename T>
92inline void TMessageSerializer::serialize(FairOutputTBuffer& tm, const T* input, const TClass* cl)
93{
94 // TODO: check what WriateObject and WriteObjectAny are doing
95 if (cl == nullptr) {
96 tm.WriteObject(input);
97 } else {
98 tm.WriteObjectAny(input, cl);
99 }
100}
101
102template <typename T>
104{
105 TClass* tgtClass = TClass::GetClass(typeid(T));
106 if (tgtClass == nullptr) {
107 throw runtime_error_f("class is not ROOT-serializable: %s", typeid(T).name());
108 }
109 // FIXME: we need to add consistency check for buffer data to be serialized
110 // at the moment, TMessage might simply crash if an invalid or inconsistent
111 // buffer is provided
112 buffer.SetBufferOffset(0);
113 buffer.InitMap();
114 TClass* serializedClass = buffer.ReadClass();
115 buffer.SetBufferOffset(0);
116 buffer.ResetMap();
117 if (serializedClass == nullptr) {
118 throw runtime_error_f("can not read class info from buffer");
119 }
120 if (tgtClass != serializedClass && serializedClass->GetBaseClass(tgtClass) == nullptr) {
121 throw runtime_error_f("can not convert serialized class %s into target class %s",
122 serializedClass->GetName(),
123 tgtClass->GetName());
124 }
125 return std::unique_ptr<T>(reinterpret_cast<T*>(buffer.ReadObjectAny(serializedClass)));
126}
127
128inline void TMessageSerializer::Serialize(fair::mq::Message& msg, const TObject* input)
129{
131 serialize(output, input, input->Class());
132}
133
134template <typename T>
135inline void TMessageSerializer::Serialize(fair::mq::Message& msg, const T* input, const TClass* cl)
136{
138 serialize(output, input, cl);
139}
140
141template <typename T>
142inline void TMessageSerializer::Deserialize(const fair::mq::Message& msg, std::unique_ptr<T>& output)
143{
144 // we know the message will not be modified by this,
145 // so const_cast should be OK here(IMHO).
146 FairInputTBuffer input(static_cast<char*>(msg.GetData()), static_cast<int>(msg.GetSize()));
147 output = deserialize(input);
148}
149
150} // namespace o2::framework
151#endif // FRAMEWORK_TMESSAGESERIALIZER_H
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
FairInputTBuffer(char *data, size_t size)
void * embedInItself(fair::mq::Message &msg)
static char * fairMQrealloc(char *oldData, size_t newSize, size_t oldSize)
FairOutputTBuffer(fair::mq::Message &msg)
GLuint buffer
Definition glcorearb.h:655
GLsizeiptr size
Definition glcorearb.h:659
GLuint const GLchar * name
Definition glcorearb.h:781
GLboolean * data
Definition glcorearb.h:298
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
RuntimeErrorRef runtime_error_f(const char *,...)
static void serialize(o2::framework::FairOutputTBuffer &msg, const TObject *input)
static void Serialize(fair::mq::Message &msg, const TObject *input)
static std::unique_ptr< T > deserialize(FairInputTBuffer &buffer)
static void Deserialize(const fair::mq::Message &msg, std::unique_ptr< T > &output)
uint64_t const void const *restrict const msg
Definition x9.h:153