ATLAS Offline Software
Loading...
Searching...
No Matches
AuxDiscoverySvc.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
9
10#include "AuxDiscoverySvc.h"
11
21
22#include "RootUtils/Type.h" //FIXME: Avoid new dependency
23#include "TClass.h"
24#include <cstring>
25#include <stdexcept>
26
28public:
29 AthenaPoolAuxStore(bool standalone) : SG::AuxStoreInternal(standalone) {}
30 using SG::AuxStoreInternal::addVector;
31};
32
33AuxDiscoverySvc::AuxDiscoverySvc(const IAthenaSerializeSvc* serSvc, IAthenaIPCTool* ipcTool) : AthMessaging("AuxDiscoverySvc"), m_serSvc(serSvc), m_ipcTool(ipcTool) {
34}
35
38
39StatusCode AuxDiscoverySvc::receiveStore(TClass* cl, void* obj, int num) {
40 TClass* holderTC = cl->GetBaseClass("SG::IAuxStoreHolder");
41 if (holderTC == nullptr) {
42 return(StatusCode::FAILURE);
43 }
44 SG::IAuxStoreHolder* storeHolder = reinterpret_cast<SG::IAuxStoreHolder*>((char*)obj + cl->GetBaseClassOffset(holderTC));
45 if (storeHolder == nullptr) {
46 return(StatusCode::FAILURE);
47 }
48 bool standalone = storeHolder->getStoreType() == SG::IAuxStoreHolder::AST_ObjectStore;
49 std::unique_ptr<AthenaPoolAuxStore> storeInt = std::make_unique<AthenaPoolAuxStore>(standalone);
50
51 void* nameData = nullptr;
52 // StreamingTool owns buffer, will stay around until last dynamic attribute is copied
53 size_t nbytes = 0;
54 while (m_ipcTool->getObject(&nameData, nbytes, num).isSuccess() && nbytes > 0) {
55 const char* del1 = static_cast<const char*>(std::memchr(nameData, '\n', nbytes));
56 if (del1 == nullptr) continue;
57 const char* del2 = static_cast<const char*>(std::memchr(del1 + 1, '\n', nbytes - (del1 - static_cast<const char*>(nameData) + 1)));
58 if (del2 == nullptr) continue;
59 const std::string dataStr(static_cast<const char*>(nameData));
60 const std::string& attrName = dataStr.substr(0, del1 - static_cast<const char*>(nameData));
61 const std::string& typeName = dataStr.substr(del1 - static_cast<const char*>(nameData) + 1, del2 - del1 - 1);
62 const std::string& elemName = dataStr.substr(del2 - static_cast<const char*>(nameData) + 1, nbytes - (del2 - static_cast<const char*>(nameData) + 1));
63 void* buffer = nullptr;
64 if (m_ipcTool->getObject(&buffer, nbytes, num).isSuccess()) {
66 SG::auxid_t auxid = registry.findAuxID(attrName);
67 if (auxid == SG::null_auxid) {
68 try {
69 RootUtils::Type elemType(elemName);
70 const std::type_info* eti = elemType.getTypeInfo();
71 if (eti != nullptr) {
72 auxid = SG::getDynamicAuxID(*eti, attrName, elemName, typeName, storeInt->standalone(), SG::null_auxid);
73 }
74 } catch (const std::runtime_error&) {
75 auxid = SG::null_auxid;
76 }
77 }
78 if (auxid != SG::null_auxid) {
79 const RootType type(typeName);
80 void* dynAttr = nullptr;
81 if (type.IsFundamental()) {
82 dynAttr = new char[nbytes];
83 std::memcpy(dynAttr, buffer, nbytes); buffer = nullptr;
84 } else {
85 dynAttr = m_serSvc->deserialize(buffer, nbytes, type); buffer = nullptr;
86 }
87 if (storeInt->standalone()) {
88 (void)storeInt->getData(auxid, 1, 1);
89 registry.copy(auxid,
90 SG::AuxVectorInterface(*storeInt), 0,
91 SG::AuxVectorInterface(auxid, 1, const_cast<const void*>(dynAttr)), 0, 1);
92 if (type.IsFundamental()) {
93 delete [] (char*)dynAttr; dynAttr = nullptr;
94 } else {
95 type.Destruct(dynAttr); dynAttr = nullptr;
96 }
97 } else {
98 // Move the data to the dynamic store.
99 std::unique_ptr<SG::IAuxTypeVector> vec(registry.makeVectorFromData(auxid, dynAttr, nullptr, false, true));
100 storeInt->addVector(std::move(vec), false);
101 }
102 }
103 }
104 }
105 storeHolder->setStore(storeInt.release());
106 return(StatusCode::SUCCESS);
107}
108
109StatusCode AuxDiscoverySvc::sendStore(TClass* cl,
110 const void* obj,
111 const std::string& classId,
112 const std::string& contName,
113 int num) {
114 TClass* storeTC = cl->GetBaseClass("SG::IAuxStoreIO");
115 if (storeTC == nullptr) {
116 return(StatusCode::SUCCESS);
117 }
118 const SG::IAuxStoreIO* store = reinterpret_cast<const SG::IAuxStoreIO*>((const char*)obj + cl->GetBaseClassOffset(storeTC));
119 if (store == nullptr) {
120 return(StatusCode::FAILURE);
121 }
122 const SG::auxid_set_t& auxIDs = store->getSelectedAuxIDs();
123 if (!auxIDs.empty()) {
124 if (!m_ipcTool->putObject(classId.c_str(), classId.size() + 1, num).isSuccess()) {
125 return(StatusCode::FAILURE);
126 }
127 if (!m_ipcTool->putObject(contName.c_str(), contName.size() + 1, num).isSuccess()) {
128 return(StatusCode::FAILURE);
129 }
130 }
131 for (SG::auxid_t auxid : auxIDs) {
132 const std::type_info* typePtr = store->getIOType(auxid);
133 if (typePtr == nullptr) continue;
134 const std::string& dataStr = SG::AuxTypeRegistry::instance().getName(auxid) + "\n" + SG::normalizedTypeinfoName(*typePtr) + "\n" + SG::AuxTypeRegistry::instance().getTypeName(auxid);
135 if (!m_ipcTool->putObject(dataStr.c_str(), dataStr.size() + 1, num).isSuccess()) {
136 return(StatusCode::FAILURE);
137 }
138 const std::type_info* tip = store->getIOType(auxid);
139 if (tip == nullptr) {
140 return(StatusCode::FAILURE);
141 }
142 RootType type(*tip);
143 StatusCode sc = StatusCode::FAILURE;
144 if (type.IsFundamental()) {
145 sc = m_ipcTool->putObject(store->getIOData(auxid), type.SizeOf(), num);
146 } else {
147 size_t nbytes = 0;
148 void* buffer = m_serSvc->serialize(store->getIOData(auxid), type, nbytes);
149 sc = m_ipcTool->putObject(buffer, nbytes, num);
150 delete [] static_cast<char*>(buffer); buffer = nullptr;
151 }
152 if (!sc.isSuccess()) {
153 return(StatusCode::FAILURE);
154 }
155 }
156 return(StatusCode::SUCCESS);
157}
This file contains the class definition for the AuxDiscoverySvc class.
An auxiliary data store that holds data internally.
Handle mappings between names and auxid_t.
Make an AuxVectorData object from either a raw vector or an aux store.
std::vector< size_t > vec
Interface providing I/O for a generic auxiliary store.
static Double_t sc
TTypeAdapter RootType
Definition RootType.h:211
Wrapper for ROOT types.
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
AthenaPoolAuxStore(bool standalone)
AuxDiscoverySvc(const IAthenaSerializeSvc *serSvc, IAthenaIPCTool *ipcTool)
StatusCode receiveStore(TClass *cl, void *obj, int num=0)
Receive dynamic aux store variables from streaming tool.
StatusCode sendStore(TClass *cl, const void *obj, const std::string &classId, const std::string &contName, int num=0)
Send dynamic aux store variables to streaming tool.
const IAthenaSerializeSvc * m_serSvc
IAthenaIPCTool * m_ipcTool
Wrapper for ROOT types.
Definition Type.h:40
const std::type_info * getTypeInfo() const
Return the type_info for the described type.
Definition Type.cxx:366
Handle mappings between names and auxid_t.
SG::auxid_t findAuxID(const std::string &name, const std::string &clsname="") const
Look up a name -> auxid_t mapping.
std::unique_ptr< IAuxTypeVector > makeVectorFromData(SG::auxid_t auxid, void *data, IAuxTypeVector *linkedVector, bool isPacked, bool ownFlag) const
Construct an IAuxTypeVector object from a vector.
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
std::string getTypeName(SG::auxid_t auxid) const
Return the type name of an aux data item.
void copy(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const
Copy elements between vectors.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Make an AuxVectorData object from either a raw array or an aux store.
Interface for objects taking part in direct ROOT I/O.
@ AST_ObjectStore
The store describes a single object.
virtual AuxStoreType getStoreType() const =0
Return the type of the store object.
virtual void setStore(IAuxStore *store)=0
Give an auxiliary store object to the holder object.
Interface providing I/O for a generic auxiliary store.
Definition IAuxStoreIO.h:44
A set of aux data identifiers.
Definition AuxTypes.h:47
Find the auxid for a dynamic branch.
Forward declaration.
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
static const auxid_t null_auxid
To signal no aux data item.
Definition AuxTypes.h:30
SG::auxid_t getDynamicAuxID(const std::type_info &ti, const std::string &name, const std::string &elementTypeName, const std::string &branch_type_name, bool standalone, SG::auxid_t linked_auxid)
Find the auxid for a dynamic branch.
AuxStoreInternal(bool standalone=false)
An auxiliary data store that holds data internally.
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27
Convert a type_info to a normalized string representation (matching the names used in the root dictio...