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