ATLAS Offline Software
Loading...
Searching...
No Matches
TrigTSerializer.cxx
Go to the documentation of this file.
1// -*- C++ -*-
2
3/*
4 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
5*/
6
11
12
13
14
15#include "TrigTSerializer.h"
16#include "SerializeCommon.h"
18#include "TROOT.h"
19#include "TBufferFile.h"
20#include "TClass.h"
21#include "TError.h"
22#include "TMethodCall.h"
23#include <vector>
24#include <string>
25#include <iostream>
26
27//
28#include "TFile.h"
29#include "TList.h"
30#include "TStreamerInfo.h"
32
36
37#define TRIGTSERHEADER 0xf00dbeef
38//#define TRIGTSERTRAILER 0xbeeff00d
39#define TRIGTSERVERSION 0x0005U
40
41 /*
42 * Format description:
43 * 1) versioning starts with version 0x0001
44 * 2) before that the root buffer was copied to ints
45 * 3) version 0001 introduces
46 * 4-byte header,
47 * 4-byte version,
48 * 4-bytes of the original Root buffer length buffersize
49 * buffersize/4 + bufsiz%4 integers of payload,
50 *
51 * version 2: attempt to decode non-versioned streams as
52 * version 0x0000 of the TrigTSerializer
53 *
54 * version 3: fix sending of bufsiz%4 integers (pointed out by Brian),
55 * in version 2 they do not contain useful data
56 *
57 * version 4: store an additional unsigned int identifying TP converter
58 * used to persistify the object (was never used)
59 *
60 * version 5: stores GUID along of the persistent class in the preambule
61 *
62 */
63
64
65#include "TSchemaRuleSet.h"
66#include "TExMap.h"
67
68namespace{
69 //note: cannot be constexpr
70 //cppcheck-suppress intToPointerCast
71 static const TClass* invalidPtr = reinterpret_cast<TClass*>(std::intptr_t(-1));
72}
74const Int_t kMapOffset = 2; // first 2 map entries are taken by null obj and self obj
75
76
77// Work around ROOT-8367
78
80 : public TBufferFile
81{
82public:
83 void* ReadObjectAnyNV (const TClass*);
84 static void* doReadObjectAny NO_SANITIZE_UNDEFINED (TBufferFile* buf, const TClass* cl)
85 {
86 TBufferFileWorkaround* ba = reinterpret_cast<TBufferFileWorkaround*>(buf);
87 return ba->ReadObjectAnyNV(cl);
88 }
89};
90
91
92void* TBufferFileWorkaround::ReadObjectAnyNV(const TClass *clCast)
93{
94 R__ASSERT(IsReading());
95
96 // make sure fMap is initialized
97 InitMap();
98
99 // before reading object save start position
100 UInt_t startpos = UInt_t(fBufCur-fBuffer);
101
102 // attempt to load next object as TClass clCast
103 UInt_t tag; // either tag or byte count
104 TClass *clRef = ReadClass(clCast, &tag);
105 TClass *clOnfile = 0;
106 Int_t baseOffset = 0;
107 if (clRef && (clRef!=invalidPtr) && clCast) {
108 //baseOffset will be -1 if clRef does not inherit from clCast.
109 baseOffset = clRef->GetBaseClassOffset(clCast);
110 if (baseOffset == -1) {
111 // The 2 classes are unrelated, maybe there is a converter between the 2.
112
113 if (!clCast->GetSchemaRules() ||
114 !clCast->GetSchemaRules()->HasRuleWithSourceClass(clRef->GetName()))
115 {
116 // There is no converter
117 Error("ReadObject", "got object of wrong class! requested %s but got %s",
118 clCast->GetName(), clRef->GetName());
119
120 CheckByteCount(startpos, tag, (TClass*)0); // avoid mis-leading byte count error message
121 return 0; // We better return at this point
122 }
123 baseOffset = 0; // For now we do not support requesting from a class that is the base of one of the class for which there is transformation to ....
124
125 //Info("ReadObjectAny","Using Converter StreamerInfo from %s to %s",clRef->GetName(),clCast->GetName());
126 clOnfile = clRef;
127 clRef = const_cast<TClass*>(clCast);
128
129 }
130 if (clCast->GetState() > TClass::kEmulated && clRef->GetState() <= TClass::kEmulated) {
131 //we cannot mix a compiled class with an emulated class in the inheritance
132 Error("ReadObject", "trying to read an emulated class (%s) to store in a compiled pointer (%s)",
133 clRef->GetName(),clCast->GetName());
134 CheckByteCount(startpos, tag, (TClass*)0); // avoid mis-leading byte count error message
135 return 0;
136 }
137 }
138
139 // check if object has not already been read
140 // (this can only happen when called via CheckObject())
141 char *obj;
142 if (fVersion > 0) {
143 obj = (char *) (Long_t)fMap->GetValue(startpos+kMapOffset);
144 if (obj == (void*) -1) obj = 0;
145 if (obj) {
146 CheckByteCount(startpos, tag, (TClass*)0);
147 return (obj+baseOffset);
148 }
149 }
150
151 // unknown class, skip to next object and return 0 obj
152 if (clRef == invalidPtr) {
153 if (fBufCur >= fBufMax) return 0;
154 if (fVersion > 0)
155 MapObject((TObject*) -1, startpos+kMapOffset);
156 else
157 MapObject((void*)0, 0, fMapCount);
158 CheckByteCount(startpos, tag, (TClass*)0);
159 return 0;
160 }
161
162 if (!clRef) {
163
164 // got a reference to an already read object
165 if (fVersion > 0) {
166 tag += fDisplacement;
167 tag = CheckObject(tag, clCast);
168 } else {
169 if (tag > (UInt_t)fMap->GetSize()) {
170 Error("ReadObject", "object tag too large, I/O buffer corrupted");
171 return 0;
172 // exception
173 }
174 }
175 obj = (char *) (Long_t)fMap->GetValue(tag);
176 clRef = (TClass*) (Long_t)fClassMap->GetValue(tag);
177
178 if (clRef && (clRef!=invalidPtr) && clCast) {
179 //baseOffset will be -1 if clRef does not inherit from clCast.
180 baseOffset = clRef->GetBaseClassOffset(clCast);
181 if (baseOffset == -1) {
182 Error("ReadObject", "Got object of wrong class (Got %s while expecting %s)",
183 clRef->GetName(),clCast->GetName());
184 // exception
185 baseOffset = 0;
186 }
187 }
188
189 // There used to be a warning printed here when:
190 // obj && isTObject && !((TObject*)obj)->IsA()->InheritsFrom(clReq)
191 // however isTObject was based on clReq (now clCast).
192 // If the test was to fail, then it is as likely that the object is not a TObject
193 // and then we have a potential core dump.
194 // At this point (missing clRef), we do NOT have enough information to really
195 // answer the question: is the object read of the type I requested.
196
197 } else {
198
199 // allocate a new object based on the class found
200 obj = (char*)clRef->New();
201 if (!obj) {
202 Error("ReadObject", "could not create object of class %s",
203 clRef->GetName());
204 // exception
205 return 0;
206 }
207
208 // add to fMap before reading rest of object
209 if (fVersion > 0)
210 MapObject(obj, clRef, startpos+kMapOffset);
211 else
212 MapObject(obj, clRef, fMapCount);
213
214 // let the object read itself
215 clRef->Streamer( obj, *this, clOnfile );
216
217 CheckByteCount(startpos, tag, clRef);
218 }
219
220 return obj+baseOffset;
221}
222
223
224} // namespace ROOT8367Workaround
225
226
228std::vector<std::string> TrigTSerializer::s_dictsToIgnore = {
229 "CosmicMuonCollection_tlp1", "MdtTrackSegmentCollection_tlp1",
230 "CosmicMuonCollection_p1", "CosmicMuon_p1", "MdtTrackSegmentCollection_p1",
231 "MdtTrackSegment_p1", "MdtTrackSegmentCollection_p2", "PanTauDetails_p1",
232 "SG::IAuxStoreCompression"
233};
234
235TrigTSerializer::TrigTSerializer(const std::string& toolname, const std::string& type, const IInterface* parent) : AthAlgTool(toolname, type, parent), m_streamersList{nullptr} {
236 declareInterface<ITrigSerializerToolBase>( this );
237 declareProperty("OnlineMode", m_onlineMode=false, "avoid initializations not needed in the online");
238
239 for (size_t i=0; i<4; i++) m_guid[i]=0;
240}
241
243 if (m_streamersList){
244 delete m_streamersList;
245 m_streamersList = nullptr;
246 }
247}
248
250 ATH_MSG_DEBUG( "TrigTSerializer::initialize " << name() );
251
252 // copy missing dictionary names from the property to the static member
253 s_dictsToIgnore.insert( std::end(s_dictsToIgnore), std::begin(m_ignoreMissingDicts.value()), std::end(m_ignoreMissingDicts.value()) );
254 std::string msg;
255 for( const auto& n:s_dictsToIgnore ) {
256 if( not msg.empty() ) msg += ", ";
257 msg += n;
258 }
259 ATH_MSG_DEBUG( "Suppressing missing dictionary warnings for: " << msg );
260
261 if (!m_onlineMode)
263
264 m_IgnoreErrLvl = gErrorIgnoreLevel;
265
266 return StatusCode::SUCCESS;
267
268}
269
271
272 std::map<std::string,uint32_t>::const_iterator mitr(m_errCount.begin());
273 std::map<std::string,uint32_t>::const_iterator mend(m_errCount.end());
274 bool reported(false);
275 while (mitr!=mend){
276 reported=true;
277 ATH_MSG_WARNING( "Could not interpret persistent object " << (*mitr).first
278 << " /" << (*mitr).second << " times." );
279 ++mitr;
280 }
281 if (!reported)
282 ATH_MSG_INFO( name() << " no problems encountered" );
283 return StatusCode::SUCCESS;
284}
285
286bool TrigTSerializer::bsDictWarningFilter(int level, bool abort_bool,
287 const char* location, const char *msg)
288{
289 if( level == kWarning and gDebug == 0 ) {
290 if( strstr(msg, "no dictionary for class") ) {
291 for( std::string &type : s_dictsToIgnore ) {
292 if( strstr(msg, type.c_str()) ) {
293 return false;
294 }
295 }
296 }
297 }
298 DefaultErrorHandler(level,abort_bool, location, msg);
299 return false;
300}
301
302
304{
306 //temporary
307 std::string extStreamerInfos = "bs-streamerinfos.root";
308 std::string extFile = PathResolver::find_file (extStreamerInfos, "DATAPATH");
309 ATH_MSG_DEBUG( "Using " << extFile );
310 TFile f(extFile.c_str());
311 m_streamersList = f.GetStreamerInfoList();
313 while (TObject* obj = nextinfo()) {
314 TStreamerInfo *inf = dynamic_cast<TStreamerInfo*> (obj);
315 if (!inf) continue;
316 TString t_name=inf->GetName();
317
318 if (t_name.BeginsWith("listOfRules")){
319 ATH_MSG_WARNING( "Could not re-load class " << t_name );
320 continue;
321 }
322
323 inf->BuildCheck();
324 //this triggers a crash on lcg60
325 TClass *cl = inf->GetClass();
326 if (cl)
327 ATH_MSG_DEBUG( "external TStreamerInfo for " << cl->GetName()
328 << " checksum: " << inf->GetCheckSum() );
329 }
330 f.Close();
331}
332
333
334bool TrigTSerializer::streamerErrorHandler(int level, bool abort_bool,
335 const char* location, const char *msg){
336 if( level > kInfo ) {
337 //MN: ignore stuff below kWarning
338 s_decodingError = true;
339 }
340 int oldLvl = gErrorIgnoreLevel;
341 if( gDebug > 0 ) {
342 gErrorIgnoreLevel = kPrint;
343 }
344 ::DefaultErrorHandler(level,abort_bool, location, msg);
345 gErrorIgnoreLevel = oldLvl;
346
347 return false;
348}
349
350void TrigTSerializer::prepareForTBuffer(const std::string &nameOfClass){
351 m_IgnoreErrLvl = gErrorIgnoreLevel;
352 //MN: this setting does not play well with ROOTDEBUG:
353 // gErrorIgnoreLevel = kInfo+1;
354 //had this class a problem before?
355 if (m_errCount.find(nameOfClass)!=m_errCount.end()){
356 gErrorIgnoreLevel = kError+1;
357 }
358 s_decodingError = false;
359}
360
361void TrigTSerializer::restoreAfterTBuffer(const std::string &nameOfClass){
362 if (s_decodingError){
363 s_decodingError = false;
364
365
366 if (m_errCount.find(nameOfClass)!=m_errCount.end()){
367 ++m_errCount[nameOfClass];
368 } else {
369 ATH_MSG_ERROR( "Errors while decoding " << nameOfClass
370 << " any further ROOT messages for this class will be suppressed" );
371 m_errCount[nameOfClass] = 1;
372 }
373 }
374
375 gErrorIgnoreLevel = m_IgnoreErrLvl;
376}
377
378std::vector<uint32_t> TrigTSerializer::serialize(const std::string &nameOfClass, const void* instance){
379 std::vector<uint32_t> serialized;
380 serialize(nameOfClass, instance, serialized);
381 return serialized;
382}
383
384void TrigTSerializer::serialize(const std::string &nameOfClass, const void* instance, std::vector<uint32_t> &serialized){
385
386 serialized.clear();
387
388 size_t rootDebug = gDebug;
389
390 if (msgLvl(MSG::DEBUG)){
391 ATH_MSG_DEBUG( "in serialize for " << nameOfClass );
392 /*
393 //cannot be used in production
394 //higher gDebug seems to interfere with ErrorHandler
395 if (m_outputlevel<=MSG::VERBOSE && rootDebug<5)
396 gDebug=5;
397 */
398 }
399
400 std::string noc= TrigSerializeResult::remapToDictName(nameOfClass);
401 TClass *pclass = gROOT->GetClass(noc.c_str());
402
403 // do_persistify(noc, instance);
404
405 TBufferFile *buff = new TBufferFile(TBuffer::kWrite);
406
407 //std::vector<uint32_t> serialized;
408
409 if (pclass){
410 //buff->StreamObject(instance, pclass);
411
412 ATH_MSG_DEBUG( "writing instance " << instance << " to buffer for noc " << noc );
413
415 {
417 buff->WriteObjectAny(instance, pclass);
418 }
420
421 ATH_MSG_DEBUG( "wrote buffer of length " << buff->Length() );
422
423
424 const char *pbuff = buff->Buffer();
425 const size_t bufsiz = buff->Length();
426
427 serialized.push_back(TRIGTSERHEADER);
428 serialized.push_back(TRIGTSERVERSION);
429 serialized.push_back(bufsiz);
430 serialized.push_back(m_guid[0]);
431 serialized.push_back(m_guid[1]);
432 serialized.push_back(m_guid[2]);
433 serialized.push_back(m_guid[3]);
434
435 //inefficient - to be compatible with Serializer for the moment can be avoided later
436 union {
437 uint32_t uint;
438 char pp[4];
439 } pbytes;
440
441 for (size_t i=0; i<bufsiz/4; i++){
442 pbytes.uint = 0;
443 for (size_t j=0; j<4; j++){
444 pbytes.pp[3-j] = pbuff[4*i+j];
445 }
446 // ATH_MSG_DEBUG( "packed " << std::hex << pbytes << std::dec );
447
448 serialized.push_back(pbytes.uint);
449 }
450
451 //send rest of chars as one int each
452 const size_t modb = bufsiz%4;
453 for (size_t i=0; i<modb; i++){
454 pbytes.uint = 0;
455 pbytes.pp[0] = pbuff[bufsiz-modb+i];
456 serialized.push_back(pbytes.uint);
457 }
458
459 if (msgLvl(MSG::VERBOSE)){
460 msg(MSG::VERBOSE) << "serialized dump: ";
461 for (size_t i=0; i<serialized.size(); i++){
462 msg(MSG::VERBOSE) << std::hex << serialized.at(i) <<std::dec << " ";
463 }
464 msg(MSG::VERBOSE) << endmsg;
465 }
466 }
467 else {
468 ATH_MSG_ERROR( "gROOT->GetClass failed for" << nameOfClass );
469 }
470
471 delete buff;
472 gDebug=rootDebug;
473
474 // return serialized;
475}
476
477void* TrigTSerializer::deserialize(const std::string &nameOfClass, const std::vector<uint32_t>& v){
478
479 size_t rootDebug = gDebug;
480 if (msgLvl(MSG::DEBUG)){
481 ATH_MSG_DEBUG( "in deserialize for " << nameOfClass );
482 /*
483 //cannot be used in production
484 //higher gDebug seems to interfere with ErrorHandler
485 if (m_outputlevel<=MSG::VERBOSE &&rootDebug<5)
486 gDebug=5;
487 */
488 }
489
490 const size_t vsize = v.size();
491 uint32_t rVersion(0);
492 size_t bufsiz(0);
493 bool newFormatOK=true;
494 bool decodeOldFormat=true;
495 size_t pBuffOffset(3); //adjust below
496 //
497 //
498
499 if (vsize>2){
500 if (v.at(0)==TRIGTSERHEADER){
501 rVersion = v.at(1);
502 bufsiz = v.at(2);
503 if (rVersion>3)
504 pBuffOffset++;
505 if (rVersion>4)
506 pBuffOffset += 3; //wrt ver 4
507
508 //check size with vsize
509 size_t expectsize = pBuffOffset + bufsiz/4 + bufsiz%4;
510
511 if (expectsize!=vsize){
512 newFormatOK = false;
513 ATH_MSG_WARNING( "expected payload length "<<expectsize
514 << " does not match the container size " << vsize
515 << " for " << nameOfClass << " fallback to the old format:" );
516 }
517 ATH_MSG_DEBUG( bufsiz << "bytes of payload version " << std::hex << rVersion << std::dec
518 << " for " << nameOfClass );
519 }
520 else {
521 ATH_MSG_WARNING( "not a versioned payload of "
522 << nameOfClass << " trying initial TrigTSerializer" );
523 newFormatOK = false;
524 }
525
526 } else {
527 ATH_MSG_WARNING( "zero bytes of payload for " << nameOfClass );
528 gDebug=rootDebug;
529 return NULL;
530 }
531
532 //
533 char *pbuf = NULL;
534
535 if (newFormatOK){
536 union {
537 uint32_t uint;
538 char pp[4];
539 } pbytes;
540
541 // const size_t bufsiz = v.size();
542 pbuf = new char[bufsiz];
543 size_t bufpos=0;
544 const size_t nints = bufsiz/4;
545 for (size_t i=pBuffOffset; i<nints+pBuffOffset; i++){
546 pbytes.uint = v.at(i);
547 for (size_t c=0; c<4; c++){
548 pbuf[bufpos] = pbytes.pp[3-c];
549 bufpos++;
550 }
551 }
552
553 for (size_t i=nints+pBuffOffset; i<vsize; i++){
554 pbuf[bufpos] = (char)v.at(i);
555 bufpos++;
556 }
557
558 if (msgLvl(MSG::VERBOSE)){
559 msg(MSG::VERBOSE) << "deserialized dump: ";
560 for (size_t i=0; i<v.size(); i++){
561 msg(MSG::VERBOSE) << std::hex << v.at(i) <<std::dec << " ";
562 }
563 msg(MSG::VERBOSE) << endmsg;
564 }
565
566 } else if (!newFormatOK && decodeOldFormat){
567 bufsiz = v.size();
568 pbuf = new char[bufsiz];
569
570 for (size_t i=0; i<bufsiz; i++)
571 pbuf[i] = v.at(i);
572 } else {
573 gDebug=rootDebug;
574 return NULL;
575 }
576
577 /*
578 if (newFormatOK && rVersion >3)
579 setCLID(v.at(3));
580 */
581
582 //common part
583 TBufferFile *buff = new TBufferFile(TBuffer::kRead, bufsiz, pbuf, kTRUE);
584
585 std::string noc= TrigSerializeResult::remapToDictName(nameOfClass);
586 TClass *pclass = gROOT->GetClass(noc.c_str());
587
588 TObject *pobj = NULL;
589 if (pclass){
591 {
593 //pobj = (TObject *)(buff->ReadObjectAny(pclass));
594 pobj = (TObject *)(ROOT8367Workaround::TBufferFileWorkaround::doReadObjectAny (buff, pclass));
595 }
597 //ErrorHandlerFunc_t oldhandler= ::SetErrorHandler(streamerErrorHandler);
598 //SetErrorHandler(oldhandler);
599 //buff->StreamObject(instance, pclass);
600 }
601 else {
602 ATH_MSG_ERROR( "gROOT->GetClass failed for" << nameOfClass );
603 }
604
605 delete buff; //this also deletes pbuf owned by buff
606 gDebug=rootDebug;
607
608 return (void *)pobj;
609}
610
611
612StatusCode TrigTSerializer::initClass(const std::string &nameOfClass) const {
613
614 TClass *pclass = gROOT->GetClass(nameOfClass.c_str());
615
616
617 StatusCode sc(StatusCode::FAILURE);
618
619 if (pclass)
620 sc = StatusCode::SUCCESS;
621
622
623 return sc;
624
625}
626
627
628
630 m_guid[0] = m_guid[1] = m_guid[2] = m_guid[3] = 0;
631}
632
633StatusCode TrigTSerializer::peekCLID(const std::vector<uint32_t>& v, uint32_t *guid) const {
634 if (v.size()>2){
635 if (v.at(0)==TRIGTSERHEADER){
636 const uint32_t rVersion = v.at(1);
637 if (rVersion>4){
638 guid[0] = v.at(3);
639 guid[1] = v.at(4);
640 guid[2] = v.at(5);
641 guid[3] = v.at(6);
642 return StatusCode::SUCCESS;
643 }
644 }
645 }
646 return StatusCode::FAILURE;
647}
648
649void TrigTSerializer::setCLID(const uint32_t *guid){
650 for (size_t i=0; i<4; i++)
651 m_guid[i] = guid[i];
652}
653
654
655using namespace std;
656
658 cerr << endl
659 << "ERROR! method TrigTSerializer::" << __PRETTY_FUNCTION__
660 << " was removed during migration to ROOT6" << endl;
661 abort();
662}
663
664void TrigTSerializer::do_persistify(const std::string& , void* ) { TrigTSerializerUnimplError(); }
666
667
668void TrigTSerializer::do_follow_ptr(const std::string& name, void *ptr){
669
670 ATH_MSG_VERBOSE("Entering do_follow_ptr for " << name << " at " << ptr );
671
672
673 if (ptr){
674 const std::string classname = name.substr(0, name.find_last_of('*'));
675 ATH_MSG_DEBUG( "going deeper for " << classname << " at " << ptr );
676 do_persistify(classname, ptr);
677 }
678
679}
#define endmsg
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
unsigned int uint
static Double_t sc
std::map< std::string, double > instance
#define TRIGTSERVERSION
void TrigTSerializerUnimplError()
#define TRIGTSERHEADER
Run a MT piece of code with an alternate root error handler.
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
static void *doReadObjectAny NO_SANITIZE_UNDEFINED(TBufferFile *buf, const TClass *cl)
Run a MT piece of code with an alternate root error handler.
static std::vector< std::string > s_dictsToIgnore
static copy of the IgnoreMissingDicts property for the static error handler
uint32_t m_IgnoreErrLvl
void reset()
clean internal serializer state.
StatusCode finalize()
void * deserialize(const std::string &nameOfClass, const std::vector< uint32_t > &v)
deserializes an object of a class nameOfClass (and recursively other objects) found in std::vector<ui...
TList * m_streamersList
Remember streamer info list for cleaning up later.
StringArrayProperty m_ignoreMissingDicts
IgnoreMissingDicts.
StatusCode peekCLID(const std::vector< uint32_t > &v, uint32_t *guid) const
access clid of the payload (stored in BS)
static bool s_decodingError
void add_previous_streamerinfos()
StatusCode initialize()
void setCLID(const uint32_t *guid)
access clid of the payload virtual CLID getCLID() const = 0;
static bool bsDictWarningFilter(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
std::vector< uint32_t > serialize(const std::string &nameOfClass, const void *instance)
serializes an object of a class nameOfClass pointed to by instance and recursively also other objects...
StatusCode initClass(const std::string &nameOfClass) const
initialize framework to be ready to serialize a given class method to be called to prevent delayed in...
std::map< std::string, uint32_t > m_errCount
void restoreAfterTBuffer(const std::string &nameOfClass)
void prepareForTBuffer(const std::string &nameOfClass)
void do_persistify(const std::string &nameOfClass, void *instance)
void do_persistify_obj(const std::string &nameOfClass, void *instance)
uint32_t m_guid[4]
static bool streamerErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
TrigTSerializer(const std::string &name, const std::string &type, const IInterface *parent)
void do_follow_ptr(const std::string &nameOfClass, void *instance)
singleton-like access to IMessageSvc via open function and helper
TStreamerInfo * inf
TIter nextinfo(a)
std::string remapToDictName(const std::string &s)
STL namespace.
Helper to disable undefined behavior sanitizer for a function.