ATLAS Offline Software
AthenaRootStreamer.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
11 #include "AthenaRootStreamer.h"
13 
14 #include "GaudiKernel/Service.h"
15 #include "GaudiKernel/MsgStream.h"
16 
17 #include "TFile.h"
18 #include "TStreamerInfo.h"
19 
20 
21 AthenaRootStreamer::AthenaRootStreamer(const std::string& class_name, ::Service* service)
22  : m_className(class_name),
23  m_class(0),
24  m_streamerChecksum (0),
25  m_streamerVersion (0),
26  m_lastFile(0),
27  m_service(service)
28 {
29 }
30 
32 {
33 }
34 
35 
36 StatusCode AthenaRootStreamer::AddConverter(std::unique_ptr<AthenaRootConverterHandle> converter) {
37  if (m_converterMap.try_emplace (converter->StreamerChecksum(), std::move(converter)).second) {
38  return(StatusCode::SUCCESS);
39  }
40  return(StatusCode::FAILURE);
41 }
42 
43 
44 //__________________________________________________________________________
46  m_class = gROOT->GetClass(m_className.c_str());
47  if (m_class == 0) {
48  return(StatusCode::FAILURE);
49  }
50  m_class->AdoptStreamer(this);
51  return(StatusCode::SUCCESS);
52 }
53 //__________________________________________________________________________
54 void AthenaRootStreamer::operator()(TBuffer& b, void* obj) {
55  if (b.IsReading()) {
56  UInt_t R__s, R__c;
57  FindVersion(&b, &R__s, &R__c);
58  // find converter for the object shape checksum
59  // (checksum is read from the file in FindVersion)
61  if (it != m_converterMap.end()) {
62  it->second->ReadBuffer(b, obj, m_streamerVersion, R__s, R__c);
63  } else {
64  if(m_service) {
65  if( m_seenChecksums.find( m_streamerChecksum ) == m_seenChecksums.end() ) {
66  // report unknown checksums only once
67  MsgStream log(m_service->msgSvc(), m_service->name());
68  log << MSG::INFO << "Found unknown streamer checksum " << m_streamerChecksum
69  << " for class "
70  << m_className << " - using default ROOT streamer" << endmsg;
72  }
73  }
74  m_class->ReadBuffer(b, obj, m_streamerVersion, R__s, R__c);
75  }
76  } else {
77  m_class->WriteBuffer(b, obj);
78  }
79 }
80 //__________________________________________________________________________
81 // Find class version and streamer checksum
82 void AthenaRootStreamer::FindVersion(TBuffer* buf, UInt_t* startpos, UInt_t* bcnt) {
83  const UInt_t kByteCountMask = 0x40000000; // OR the byte count with this
84  const Version_t kByteCountVMask = 0x4000; // OR the version byte count with this
85 
86  if (startpos && bcnt) {
87  // before reading object save start position
88  *startpos = buf->Length();
89 
90  // read byte count (older files don't have byte count)
91  // byte count is packed in two individual shorts, this to be
92  // backward compatible with old files that have at this location
93  // only a single short (i.e. the version)
94  union {
95  UInt_t cnt;
96  Version_t vers[2];
97  } v;
98  v.cnt = 0; // to prevent Valgrind complaining about uninitialized variable
99 #ifdef R__BYTESWAP
100  *buf >> v.vers[1];
101  *buf >> v.vers[0];
102 #else
103  *buf >> v.vers[0];
104  *buf >> v.vers[1];
105 #endif
106  if( !(v.cnt & kByteCountMask) ) {
107  // no bytecount, go back before reading version
108  buf->SetBufferOffset(buf->Length() - sizeof(UInt_t));
109  v.cnt = 0;
110  }
111  *bcnt = (v.cnt & ~kByteCountMask);
112  *buf >> m_streamerVersion;
113  } else {
114  // not interested in byte count
115  *buf >> m_streamerVersion;
116 
117  // if this is a byte count, then skip next short and read version
118  if (m_streamerVersion & kByteCountVMask) {
119  *buf >> m_streamerVersion;
120  *buf >> m_streamerVersion;
121  }
122  }
123  //Version_t objectVersion = m_streamerVersion;
124  TFile* fParent = (TFile*)buf->GetParent();
125  if (m_lastFile != fParent) {
126  // new file, reset
127  m_streamerChecksum = 0;
128  }
129  if (m_class && m_class->GetClassVersion() != 0) {
130  if (m_streamerVersion <= 0) {
131  *buf >> m_streamerChecksum;
133  } else if (m_streamerVersion == 1) {
134  // hand made streamer list caching, change that when TFile::GetStreamerInfoCache() is out
135  if (m_lastFile == fParent) {
136  // the same file, nothing changed?
137  } else if (fParent && fParent->GetVersion() < 40000) {
138  // We could have a file created using a Foreign class before
139  // the introduction of the CheckSum. We need to check
140  if ((!m_class->IsLoaded() || m_class->IsForeign()) &&
141  m_class->GetStreamerInfos()->GetLast() > 1) {
142  const TList* list = fParent->GetStreamerInfoList();
143  const TStreamerInfo* local = (TStreamerInfo*)list->FindObject(m_className.c_str());
144  if (local) {
145  m_streamerChecksum = local->GetCheckSum();
147  } else {
148  m_streamerVersion = 0;
149  }
150  }
151  }
152  }
153  }
154  m_lastFile = fParent;
155 }
156 
157 
158 //__________________________________________________________________________
159 
160 //FIXME
161 // use TBuffer::R__FindStreamerInfoVersion() instead of this function
162 // with the next ROOT release
163 Version_t AthenaRootStreamer::R__FindStreamerInfoVersion(const TClass* cl, UInt_t checksum) {
164  //find the version number in the StreamerInfos corresponding to checksum
165  Version_t version = 0;
166  Int_t ninfos = cl->GetStreamerInfos()->GetEntriesFast();
167  for (Int_t i = 1; i < ninfos; i++) {
168  // TClass::fStreamerInfos has a lower bound not equal to 0,
169  // so we should use At and not use UncheckedAt
170  TStreamerInfo* info = (TStreamerInfo*)cl->GetStreamerInfos()->At(i);
171  if (!info) {
172  continue;
173  }
174  if (info->GetCheckSum() == checksum) {
175  version = i;
176  break;
177  }
178  }
179  return(version);
180 }
grepfile.info
info
Definition: grepfile.py:38
AthenaRootStreamer::FindVersion
void FindVersion(TBuffer *buf, UInt_t *startpos, UInt_t *bcnt)
Definition: AthenaRootStreamer.cxx:82
AthenaRootStreamer::m_class
TClass * m_class
Definition: AthenaRootStreamer.h:61
AthenaRootConverterHandle::StreamerChecksum
unsigned StreamerChecksum()
Definition: AthenaRootConverterHandle.h:30
AthenaRootStreamer.h
this file contains the class definition for the AthenaRootStreamer class.
AthenaRootStreamer::m_converterMap
ConverterMap m_converterMap
Definition: AthenaRootStreamer.h:67
AthenaRootStreamer::m_className
std::string m_className
Definition: AthenaRootStreamer.h:60
skel.it
it
Definition: skel.GENtoEVGEN.py:396
AthenaRootStreamer::m_service
Service * m_service
Definition: AthenaRootStreamer.h:72
AthenaRootStreamer::m_streamerVersion
Version_t m_streamerVersion
Definition: AthenaRootStreamer.h:63
AthenaRootStreamer::AddConverter
StatusCode AddConverter(std::unique_ptr< AthenaRootConverterHandle > converter)
Add a converter to this streamer.
Definition: AthenaRootStreamer.cxx:36
AthenaRootStreamer::m_lastFile
TFile * m_lastFile
Definition: AthenaRootStreamer.h:64
AthenaRootStreamer::m_seenChecksums
ChecksumSet m_seenChecksums
Definition: AthenaRootStreamer.h:70
AthenaRootConverterHandle.h
his file contains the class definition for AthenaRootConverter class.
lumiFormat.i
int i
Definition: lumiFormat.py:85
AthenaRootStreamer::Adopt
StatusCode Adopt()
Adopt (enable) this ROOT custom streamer.
Definition: AthenaRootStreamer.cxx:45
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
AthenaRootStreamer::m_streamerChecksum
UInt_t m_streamerChecksum
Definition: AthenaRootStreamer.h:62
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
AthenaRootStreamer::AthenaRootStreamer
AthenaRootStreamer(const std::string &class_name, ::Service *service=0)
Constructor.
Definition: AthenaRootStreamer.cxx:21
InDetDD::local
@ local
Definition: InDetDD_Defs.h:16
AthenaRootStreamer::~AthenaRootStreamer
virtual ~AthenaRootStreamer()
Destructor.
Definition: AthenaRootStreamer.cxx:31
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
python.PyAthena.v
v
Definition: PyAthena.py:154
get_generator_info.version
version
Definition: get_generator_info.py:33
AthenaRootStreamer::R__FindStreamerInfoVersion
static Version_t R__FindStreamerInfoVersion(const TClass *cl, UInt_t checksum)
Definition: AthenaRootStreamer.cxx:163
AthenaRootStreamer::operator()
virtual void operator()(TBuffer &b, void *obj)
this operator is colled by ROOT to ready and write objects
Definition: AthenaRootStreamer.cxx:54
trigbs_pickEvents.cnt
cnt
Definition: trigbs_pickEvents.py:71
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
python.DetectStreamerInfoChanges.class_name
class_name
Definition: DetectStreamerInfoChanges.py:57
python.PyAthena.obj
obj
Definition: PyAthena.py:132
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26