Skip to content

Commit c52f258

Browse files
committed
Implement ROOT read rules for PortableHostObject types
1 parent 91235b5 commit c52f258

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#ifndef DataFormats_Portable_interface_PortableHostObjectReadRules_h
2+
#define DataFormats_Portable_interface_PortableHostObjectReadRules_h
3+
4+
#include <TGenericClassInfo.h>
5+
#include <TVirtualObject.h>
6+
7+
#include "DataFormats/Portable/interface/PortableHostObject.h"
8+
#include "FWCore/Utilities/interface/concatenate.h"
9+
#include "FWCore/Utilities/interface/stringize.h"
10+
11+
// read function for PortableHostObject, called for every event
12+
template <typename T>
13+
static void readPortableHostObject_v1(char *target, TVirtualObject *from_buffer) {
14+
// extract the actual types
15+
using Object = T;
16+
using Product = typename Object::Product;
17+
18+
// valid only for PortableHostObject<T>
19+
static_assert(std::is_same_v<Object, PortableHostObject<Product>>);
20+
21+
// proxy for the object being read from file
22+
struct OnFile {
23+
Product *product_;
24+
};
25+
26+
// address in memory of the buffer containing the object being read from file
27+
char *address = static_cast<char *>(from_buffer->GetObject());
28+
// offset of the "product_" data member
29+
static ptrdiff_t product_offset = from_buffer->GetClass()->GetDataMemberOffset("product_");
30+
// pointer to the Product object being read from file
31+
OnFile onfile = {*(Product **)(address + product_offset)};
32+
33+
// pointer to the Object object being constructed in memory
34+
Object *newObj = (Object *)target;
35+
36+
// move the data from the on-file layout to the newly constructed object
37+
Object::ROOTReadStreamer(newObj, *onfile.product_);
38+
}
39+
40+
// put set_PortableHostObject_read_rules in the ROOT namespace to let it forward declare GenerateInitInstance
41+
namespace ROOT {
42+
43+
// set the read rules for PortableHostObject<T>;
44+
// this is called only once, when the dictionary is loaded.
45+
template <typename T>
46+
static bool set_PortableHostObject_read_rules(std::string const &type) {
47+
// forward declaration
48+
TGenericClassInfo *GenerateInitInstance(T const *);
49+
50+
// build the read rules
51+
std::vector<ROOT::Internal::TSchemaHelper> readrules(1);
52+
ROOT::Internal::TSchemaHelper &rule = readrules[0];
53+
rule.fTarget = "buffer_,product_";
54+
rule.fSourceClass = type;
55+
rule.fSource = type + "::Product* product_;";
56+
rule.fCode = type + "::ROOTReadStreamer(newObj, *onfile.product_)";
57+
rule.fVersion = "[1-]";
58+
rule.fChecksum = "";
59+
rule.fInclude = "";
60+
rule.fEmbed = false;
61+
rule.fFunctionPtr = reinterpret_cast<void *>(::readPortableHostObject_v1<T>);
62+
rule.fAttributes = "";
63+
64+
// set the read rules
65+
TGenericClassInfo *instance = GenerateInitInstance((T const *)nullptr);
66+
instance->SetReadRules(readrules);
67+
68+
return true;
69+
}
70+
} // namespace ROOT
71+
72+
#define SET_PORTABLEHOSTOBJECT_READ_RULES(OBJECT) \
73+
static bool EDM_CONCATENATE(set_PortableHostObject_read_rules_done_at_, __LINE__) [[maybe_unused]] = \
74+
ROOT::set_PortableHostObject_read_rules<OBJECT>(EDM_STRINGIZE(OBJECT))
75+
76+
#endif // DataFormats_Portable_interface_PortableHostObjectReadRules_h
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
#include "DataFormats/Portable/interface/PortableHostCollectionReadRules.h"
2+
#include "DataFormats/Portable/interface/PortableHostObjectReadRules.h"
23
#include "DataFormats/PortableTestObjects/interface/TestHostCollection.h"
4+
#include "DataFormats/PortableTestObjects/interface/TestHostObject.h"
35

46
SET_PORTABLEHOSTCOLLECTION_READ_RULES(portabletest::TestHostCollection);
7+
SET_PORTABLEHOSTOBJECT_READ_RULES(portabletest::TestHostObject);

0 commit comments

Comments
 (0)