ATLAS Offline Software
Loading...
Searching...
No Matches
T_AthenaPoolCustCnv.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5/** @file T_AthenaPoolCustCnv.icc
6 * @brief This file contains the implementation for the templated T_AthenaPoolCustCnv class.
7 * @author Peter van Gemmeren <gemmeren@anl.gov>
8 **/
9
10#include "AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h"
11#include "AthenaPoolCnvSvc/exceptions.h"
12
13#include "GaudiKernel/StatusCode.h"
14#include "GaudiKernel/DataObject.h"
15#include "GaudiKernel/IOpaqueAddress.h"
16#include "GaudiKernel/IRegistry.h"
17
18#include "StorageSvc/DbReflex.h"
19
20#include "AthenaKernel/CLASS_DEF.h"
21#include "AthenaKernel/ClassName.h"
22#include "AthenaKernel/StorableConversions.h"
23#include "PersistentDataModel/Token.h"
24
25//__________________________________________________________________________
26template <class TRANS, class PERS>
27T_AthenaPoolCustCnv<TRANS, PERS>::T_AthenaPoolCustCnv(ISvcLocator* pSvcLocator,
28 const char* name /*= nullptr*/)
29 : T_AthenaPoolCnvBase<TRANS>(pSvcLocator, name) {
30}
31//______________________________________________________________________________
32template <class TRANS, class PERS>
33StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::initialize() {
34 ATH_MSG_DEBUG("initialize() in T_AthenaPoolCustCnv " << classID());
35 if (!T_AthenaPoolCnvBase<TRANS>::initialize().isSuccess()) {
36 ATH_MSG_FATAL("Failed to initialize AthenaPoolConverter base class.");
37 return(StatusCode::FAILURE);
38 }
39 return(this->m_athenaPoolCnvSvc->registerCleanUp(this));
40}
41//__________________________________________________________________________
42template <class TRANS, class PERS>
43const CLID& T_AthenaPoolCustCnv<TRANS, PERS>::classID() {
44 return(ClassID_traits<TRANS>::ID());
45}
46//__________________________________________________________________________
47template <class TRANS, class PERS>
48template <class P>
49Placement T_AthenaPoolCustCnv<TRANS, PERS>::setPlacementForP(P& /*p*/, const std::string& key, const std::string& output) {
50 const std::string typenm = ClassName<P>::name();
51 return(this->setPlacementWithType(typenm, key, output));
52}
53//__________________________________________________________________________
54template <class TRANS, class PERS>
55template <class P>
56StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::objectToPool(P* pObj, std::unique_ptr<Token>& token, const std::string& key, const std::string& output) {
57 const static std::string className = ClassName<P>::name();
58 // Check dictionary
59 // Allow for multiple class names
60 if (this->m_className != className) {
61 this->m_className = className;
62 // Different class name - get description
63 auto itClass = this->m_classDescs.find(className);
64 if (itClass == this->m_classDescs.end()) {
65 // For new class names, check dictionary
66 this->m_classDesc = RootType( typeid(P) );
67 this->m_classDescs[className] = this->m_classDesc;
68 } else {
69 // Set to correct class description
70 this->m_classDesc = (*itClass).second;
71 }
72 }
73 Placement placement = setPlacementForP(*pObj, key, output);
74 token.reset (this->m_athenaPoolCnvSvc->registerForWrite(&placement, pObj, this->m_classDesc));
75 return(StatusCode::SUCCESS);
76}
77//__________________________________________________________________________
78template <class TRANS, class PERS>
79template <class P>
80StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::poolToObject(const Token*& token, P*& pObj) {
81 pObj = nullptr;
82 void* voidPtr = nullptr;
83 try {
84 this->m_athenaPoolCnvSvc->setObjPtr(voidPtr, token);
85 }
86 catch (const std::exception& ex) {
87 AthenaPoolCnvSvc::throwExcCaughtException (__PRETTY_FUNCTION__,
88 "pooltoObject",
89 ex,
90 typeid(P),
91 token->toString());
92 }
93 if (voidPtr == nullptr) {
94 ATH_MSG_ERROR("poolToObject: Could not get object for Token = " << (token != nullptr ? token->toString() : ""));
95 return(StatusCode::FAILURE);
96 }
97 pObj = reinterpret_cast<P*>(voidPtr);
98 return(StatusCode::SUCCESS);
99}
100//__________________________________________________________________________
101template <class TRANS, class PERS>
102StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::DataObjectToPers(DataObject* pObj, IOpaqueAddress*& /*pAddr*/) {
103 const std::string className = ClassName<TRANS>::name();
104 ATH_MSG_DEBUG("Called DataObjectToPers for " << pObj << ": " << className << ", with key " << pObj->name());
105 return(StatusCode::SUCCESS);
106}
107//__________________________________________________________________________
108template <class TRANS, class PERS>
109StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::DataObjectToPool(IOpaqueAddress* pAddr, DataObject* pObj) {
110 const std::string className = ClassName<TRANS>::name();
111 ATH_MSG_DEBUG("Called DataObjectToPool for " << pObj << ": " << className << ", with key " << pObj->name());
112 PERS* persObj = nullptr;
113 TRANS* obj = nullptr;
114 bool success = SG::fromStorable(pObj, obj);
115 if (!success || obj == nullptr) {
116 ATH_MSG_ERROR("failed to cast to T for class (type/key) " << className << "/" << pObj->name());
117 return(StatusCode::FAILURE);
118 }
119 if (!transToPers(obj, persObj).isSuccess()) {
120 ATH_MSG_ERROR("Failed to convert to persistent DataType for class (type/key) " << className << "/" << pObj->name());
121 return(StatusCode::FAILURE);
122 }
123 std::unique_ptr<Token> token;
124 StatusCode status = objectToPool<PERS>(persObj, token, pObj->name(), *pAddr->par());
125 // Null/empty token means ERROR
126 if (token == nullptr || token->classID() == Guid::null()) {
127 ATH_MSG_ERROR("Failed to get Token for class (type/key) " << className << "/" << pObj->name());
128 return(StatusCode::FAILURE);
129 }
130 // Update IOpaqueAddress for this object.
131 TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddr);
132 if (tokAddr != nullptr) {
133 tokAddr->setToken(std::move(token));
134 } else {
135 return(StatusCode::FAILURE);
136 }
137 return(status);
138}
139//__________________________________________________________________________
140template <class TRANS, class PERS>
141StatusCode
142T_AthenaPoolCustCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj,
143 const Token* token,
144 const std::string& /*key*/)
145{
146 TRANS* transObj = nullptr;
147 PERS* obj = nullptr;
148 if (!poolToObject<PERS>(token, obj).isSuccess()) {
149 ATH_MSG_ERROR("Failed to read persistent DataType");
150 return(StatusCode::FAILURE);
151 }
152 if (!persToTrans(transObj, obj).isSuccess()) {
153 delete transObj; transObj = nullptr;
154 delete obj; obj = nullptr;
155 ATH_MSG_ERROR("Failed to convert to transient DataType");
156 return(StatusCode::FAILURE);
157 }
158 delete obj; obj = nullptr;
159 pObj = SG::asStorable(transObj);
160 return(StatusCode::SUCCESS);
161}
162//__________________________________________________________________________
163// Set the token (in std::string representation) and classID for
164// the object that will be read next. Required by compareClassGuid()
165template <class TRANS, class PERS>
166inline void T_AthenaPoolCustCnv<TRANS, PERS>::setToken(const std::string& token_str) {
167 delete this->m_i_poolToken; this->m_i_poolToken = nullptr;
168 Token* token = new Token;
169 token->fromString(token_str);
170 this->m_i_poolToken = token; token = nullptr;
171 m_classID = this->m_i_poolToken->classID();
172}
173//__________________________________________________________________________
174// Compare POOL class GUID with the one from object being read
175// To be used in createTransient()
176template <class TRANS, class PERS>
177inline bool T_AthenaPoolCustCnv<TRANS, PERS>::compareClassGuid(const pool::Guid &guid) const {
178 return(guid == m_classID);
179}