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
19
22
24
25#include "StorageSvc/DbTypeInfo.h" //FIXME: Avoid new dependency
26
27#include "RootUtils/Type.h" //FIXME: Avoid new dependency
28#include "TClass.h"
29
30#include <stdexcept>
31
32
38
39bool AuxDiscoverySvc::getAuxStore(void* obj, const Guid& classId, const std::string& contId) {
40 const pool::DbTypeInfo* info = pool::DbTypeInfo::create(classId); // Needed for Properties and TClass
41 if (info == nullptr) {
42 return false;
43 }
44 if (!contId.empty() && (contId.size() < 5 || contId.substr(contId.size() - 5, 4) != "Aux.")
45 && !info->clazz().Properties().HasProperty("IAuxStore")) {
46 return false;
47 }
48 TClass* cl = info->clazz().Class();
49 if (cl == nullptr) {
50 return false;
51 }
52 TClass* holderTC = cl->GetBaseClass("SG::IAuxStoreHolder");
53 if (holderTC == nullptr) {
54 return false;
55 }
56 m_storeHolder = reinterpret_cast<SG::IAuxStoreHolder*>((char*)obj + cl->GetBaseClassOffset(holderTC));
57 if (m_storeHolder == nullptr) {
58 return false;
59 }
60 bool standalone = m_storeHolder->getStoreType() == SG::IAuxStoreHolder::AST_ObjectStore;
61 m_storeInt = new AthenaPoolAuxStore(standalone);
62 return true;
63}
64
67 if (m_storeInt->standalone()) {
68 (void)m_storeInt->getData(auxid, 1, 1);
69 registry.copy(auxid,
71 SG::AuxVectorInterface (auxid, 1, const_cast<const void*>(data)), 0, 1);
72 if (type.IsFundamental()) {
73 delete [] (char*)data; data = nullptr;
74 } else {
75 type.Destruct(data); data = nullptr;
76 }
77 } else {
78 // Move the data to the dynamic store.
79 std::unique_ptr<SG::IAuxTypeVector> vec(registry.makeVectorFromData(auxid, data, nullptr, false, true));
80 m_storeInt->addVector(std::move(vec), false);
81 }
82 return true;
83}
84
86 if (m_storeHolder == nullptr) {
87 return false;
88 }
89 m_storeHolder->setStore(m_storeInt);
90 return true;
91}
92
93SG::auxid_t AuxDiscoverySvc::getAuxID(const std::string& attrName, const std::string& elemName, const std::string& typeName) {
95 SG::auxid_t auxid = registry.findAuxID(attrName);
96 if (auxid == SG::null_auxid && m_storeInt != nullptr) {
97 try {
98 RootUtils::Type elemType(elemName);
99 const std::type_info* eti = elemType.getTypeInfo();
100 if (eti == nullptr) {
101 return SG::null_auxid;
102 }
103 auxid = SG::getDynamicAuxID(*eti, attrName, elemName, typeName, m_storeInt->standalone(), SG::null_auxid);
104 } catch (const std::runtime_error&) {
105 return SG::null_auxid;
106 }
107 }
108 return auxid;
109}
110
112AuxDiscoverySvc::getAuxIDs(const void* obj, const Guid& classId, const std::string& contId) {
113 const pool::DbTypeInfo* info = pool::DbTypeInfo::create(classId); // Needed for Properties and TClass
114 if (info == nullptr) {
115 return SG::auxid_set_t();
116 }
117 if (!contId.empty() && (contId.size() < 5 || contId.substr(contId.size() - 5, 4) != "Aux.")
118 && !info->clazz().Properties().HasProperty("IAuxStore")) {
119 return SG::auxid_set_t();
120 }
121 // Detected auxStore
122 TClass* cl = info->clazz().Class();
123 if (cl == nullptr) {
124 return SG::auxid_set_t();
125 }
126 TClass* storeTC = cl->GetBaseClass("SG::IAuxStoreIO");
127 if (storeTC == nullptr) {
128 return SG::auxid_set_t();
129 }
130 m_store = reinterpret_cast<const SG::IAuxStoreIO*>((const char*)obj + cl->GetBaseClassOffset(storeTC));
131 if (m_store == nullptr) {
132 return SG::auxid_set_t();
133 }
134 return m_store->getSelectedAuxIDs();
135}
136
138 if (m_store == nullptr) {
139 return nullptr;
140 }
141 return m_store->getIOData(auxid);
142}
143
144const std::type_info* AuxDiscoverySvc::getType(SG::auxid_t auxid) {
145 if (m_store == nullptr) {
146 return nullptr;
147 }
148 return m_store->getIOType(auxid);
149}
150
154
156 return SG::normalizedTypeinfoName(*(getType(auxid)));
157}
158
162StatusCode AuxDiscoverySvc::receiveStore(const IAthenaSerializeSvc* serSvc, IAthenaIPCTool* ipcTool, void* obj, int num) {
163 void* buffer = nullptr;
164 size_t nbytes = 0;
165 StatusCode sc = ipcTool->getObject(&buffer, nbytes, num);
166 while (sc.isRecoverable() && nbytes > 0) {
167 sc = ipcTool->getObject(&buffer, nbytes, num);
168 }
169 if (!sc.isSuccess() || nbytes == 0) { // No dynamic attributes
170 return(StatusCode::SUCCESS);
171 }
172 Guid classId;
173 classId.fromString(static_cast<const char*>(buffer));
174 if (!ipcTool->getObject(&buffer, nbytes, num).isSuccess() || nbytes == 0) {
175 return(StatusCode::FAILURE);
176 }
177 const std::string contName = std::string(static_cast<const char*>(buffer));
178 if (classId != Guid::null() && this->getAuxStore(obj, classId, contName)) {
179 void* nameData = nullptr;
180 // StreamingTool owns buffer, will stay around until last dynamic attribute is copied
181 while (ipcTool->getObject(&nameData, nbytes, num).isSuccess() && nbytes > 0) {
182 const char* del1 = static_cast<const char*>(memchr(nameData, '\n', nbytes));
183 const char* del2 = static_cast<const char*>(memchr(del1 + 1, '\n', nbytes - (del1 - static_cast<const char*>(nameData) - 1)));
184 const std::string dataStr(static_cast<const char*>(nameData));
185 const std::string& attrName = dataStr.substr(0, del1 - static_cast<const char*>(nameData));
186 const std::string& typeName = dataStr.substr(del1 - static_cast<const char*>(nameData) + 1, del2 - del1 - 1);
187 const std::string& elemName = dataStr.substr(del2 - static_cast<const char*>(nameData) + 1);
188 if (ipcTool->getObject(&buffer, nbytes, num).isSuccess()) {
189 SG::auxid_t auxid = this->getAuxID(attrName, elemName, typeName);
190 if (auxid != SG::null_auxid) {
191 const RootType type(typeName);
192 void* dynAttr = nullptr;
193 if (type.IsFundamental()) {
194 dynAttr = new char[nbytes];
195 std::memcpy(dynAttr, buffer, nbytes); buffer = nullptr;
196 } else {
197 dynAttr = serSvc->deserialize(buffer, nbytes, type); buffer = nullptr;
198 }
199 this->setData(auxid, dynAttr, type);
200 }
201 }
202 }
203 this->setAuxStore();
204 }
205 return(StatusCode::SUCCESS);
206}
207
209 IAthenaIPCTool* ipcTool,
210 const void* obj,
211 const Guid& classId,
212 const std::string& contName,
213 int num) {
214 const SG::auxid_set_t& auxIDs = this->getAuxIDs(obj, classId, contName);
215 if (!auxIDs.empty()) {
216 const std::string& classIdStr = classId.toString();
217 if (!ipcTool->putObject(classIdStr.c_str(), classIdStr.size() + 1, num).isSuccess()) {
218 return(StatusCode::FAILURE);
219 }
220 if (!ipcTool->putObject(contName.c_str(), contName.size() + 1, num).isSuccess()) {
221 return(StatusCode::FAILURE);
222 }
223 }
224 for (SG::auxid_t auxid : auxIDs) {
225 const std::string& dataStr = this->getAttrName(auxid) + "\n" + this->getTypeName(auxid) + "\n" + this->getElemName(auxid);
226 if (!ipcTool->putObject(dataStr.c_str(), dataStr.size() + 1, num).isSuccess()) {
227 return(StatusCode::FAILURE);
228 }
229 const std::type_info* tip = this->getType(auxid);
230 if (tip == nullptr) {
231 return(StatusCode::FAILURE);
232 }
233 RootType type(*tip);
234 StatusCode sc = StatusCode::FAILURE;
235 if (type.IsFundamental()) {
236 sc = ipcTool->putObject(this->getData(auxid), type.SizeOf(), num);
237 } else {
238 size_t nbytes = 0;
239 void* buffer = serSvc->serialize(this->getData(auxid), type, nbytes);
240 sc = ipcTool->putObject(buffer, nbytes, num);
241 delete [] static_cast<char*>(buffer); buffer = nullptr;
242 }
243 if (!sc.isSuccess()) {
244 return(StatusCode::FAILURE);
245 }
246 }
247 return(StatusCode::SUCCESS);
248}
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
This file contains the class definition for the Guid class (migrated from POOL).
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
Interface providing I/O for a generic auxiliary store.
static Double_t sc
TTypeAdapter RootType
Definition RootType.h:211
Wrapper for ROOT types.
AthenaPoolAuxStore(bool standalone)
bool getAuxStore(void *obj, const Guid &classId, const std::string &contId)
StatusCode sendStore(const IAthenaSerializeSvc *serSvc, IAthenaIPCTool *ipcTool, const void *obj, const Guid &classId, const std::string &contName, int num=0)
Send dynamic aux store variables to streaming tool.
std::string getElemName(SG::auxid_t auxid)
SG::auxid_set_t getAuxIDs(const void *obj, const Guid &classId, const std::string &contId)
const SG::IAuxStoreIO * m_store
std::string getTypeName(SG::auxid_t auxid)
bool setData(SG::auxid_t auxid, void *data, const RootType &type)
SG::auxid_t getAuxID(const std::string &attrName, const std::string &elemName, const std::string &typeName)
const std::type_info * getType(SG::auxid_t auxid)
AthenaPoolAuxStore * m_storeInt
const void * getData(SG::auxid_t auxid)
std::string getAttrName(SG::auxid_t auxid)
StatusCode receiveStore(const IAthenaSerializeSvc *serSvc, IAthenaIPCTool *ipcTool, void *obj, int num=0)
Receive dynamic aux store variables from streaming tool.
SG::IAuxStoreHolder * m_storeHolder
bool empty() const
Return true if there are no 1 bits in the set.
This class provides a encapsulation of a GUID/UUID/CLSID/IID data structure (128 bit number).
Definition Guid.h:25
constexpr void fromString(std::string_view s)
Automatic conversion from string representation.
Definition Guid.h:143
static const Guid & null() noexcept
NULL-Guid: static class method.
Definition Guid.cxx:14
constexpr void toString(std::span< char, StrLen > buf, bool uppercase=true) const noexcept
Automatic conversion to string representation.
virtual StatusCode putObject(const void *source, size_t nbytes, int num=0)=0
virtual StatusCode getObject(void **target, size_t &nbytes, int num=0)=0
virtual void * deserialize(void *buffer, size_t &nbytes, const std::string &name) const =0
virtual void * serialize(const void *object, const std::string &name, size_t &nbytes) const =0
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
An auxiliary data store that holds data internally.
bool standalone() const
Return the standalone flag.
void addVector(std::unique_ptr< IAuxTypeVector > vec, bool isDecoration)
Explicitly add a vector to the store.
AuxStoreInternal(bool standalone=false)
Constructor.
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.
Interface providing I/O for a generic auxiliary store.
Definition IAuxStoreIO.h:44
A set of aux data identifiers.
Definition AuxTypes.h:47
Definition of class DbTypeInfo.
Definition DbTypeInfo.h:47
static const DbTypeInfo * create(const std::string &cl_name)
Create type information using name.
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.
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...