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 // Helper function to keep track of the FairMQ message that holds the data
44 // in the data itself. We can use this to make sure the message can be reallocated
45 // even if we simply have a pointer to the data. Hopefully ROOT will not play dirty
46 // with us.
47 void* embedInItself(fair::mq::Message& msg);
48 // helper function to clean up the object holding the data after it is transported.
49 static char* fairMQrealloc(char* oldData, size_t newSize, size_t oldSize);
50};
51
53{
54 public:
55 // This is to serialise data to FairMQ. The provided message is expeted to have 8 bytes
56 // of overhead, where the source embedded the pointer for the reallocation.
57 // Notice this will break if the sender and receiver are not using the same
58 // size for a pointer.
59 FairInputTBuffer(char* data, size_t size)
60 : TBufferFile(TBuffer::kRead, size - sizeof(char*), data + sizeof(char*), false, nullptr)
61 {
62 }
63};
64
66 static void Serialize(fair::mq::Message& msg, const TObject* input);
67
68 template <typename T>
69 static void Serialize(fair::mq::Message& msg, const T* input, const TClass* cl);
70
71 template <typename T = TObject>
72 static void Deserialize(const fair::mq::Message& msg, std::unique_ptr<T>& output);
73
74 static void serialize(o2::framework::FairOutputTBuffer& msg, const TObject* input);
75
76 template <typename T>
77 static void serialize(o2::framework::FairOutputTBuffer& msg, const T* input, const TClass* cl);
78
79 template <typename T = TObject>
80 static inline std::unique_ptr<T> deserialize(FairInputTBuffer& buffer);
81};
82
84{
85 return serialize(tm, input, nullptr);
86}
87
88template <typename T>
89inline void TMessageSerializer::serialize(FairOutputTBuffer& tm, const T* input, const TClass* cl)
90{
91 // TODO: check what WriateObject and WriteObjectAny are doing
92 if (cl == nullptr) {
93 tm.WriteObject(input);
94 } else {
95 tm.WriteObjectAny(input, cl);
96 }
97}
98
99template <typename T>
101{
102 TClass* tgtClass = TClass::GetClass(typeid(T));
103 if (tgtClass == nullptr) {
104 throw runtime_error_f("class is not ROOT-serializable: %s", typeid(T).name());
105 }
106 // FIXME: we need to add consistency check for buffer data to be serialized
107 // at the moment, TMessage might simply crash if an invalid or inconsistent
108 // buffer is provided
109 buffer.SetBufferOffset(0);
110 buffer.InitMap();
111 TClass* serializedClass = buffer.ReadClass();
112 buffer.SetBufferOffset(0);
113 buffer.ResetMap();
114 if (serializedClass == nullptr) {
115 throw runtime_error_f("can not read class info from buffer");
116 }
117 if (tgtClass != serializedClass && serializedClass->GetBaseClass(tgtClass) == nullptr) {
118 throw runtime_error_f("can not convert serialized class %s into target class %s",
119 serializedClass->GetName(),
120 tgtClass->GetName());
121 }
122 return std::unique_ptr<T>(reinterpret_cast<T*>(buffer.ReadObjectAny(serializedClass)));
123}
124
125inline void TMessageSerializer::Serialize(fair::mq::Message& msg, const TObject* input)
126{
128 serialize(output, input, input->Class());
129}
130
131template <typename T>
132inline void TMessageSerializer::Serialize(fair::mq::Message& msg, const T* input, const TClass* cl)
133{
135 serialize(output, input, cl);
136}
137
138template <typename T>
139inline void TMessageSerializer::Deserialize(const fair::mq::Message& msg, std::unique_ptr<T>& output)
140{
141 // we know the message will not be modified by this,
142 // so const_cast should be OK here(IMHO).
143 FairInputTBuffer input(static_cast<char*>(msg.GetData()), static_cast<int>(msg.GetSize()));
144 output = deserialize(input);
145}
146
147} // namespace o2::framework
148#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