ATLAS Offline Software
TConverterStreamer.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
13 #include "TBuffer.h"
14 #include "TClass.h"
15 #include "TFile.h"
16 #include "TStreamerInfo.h"
17 
18 
25  TClass* cls)
26  : fConvmap (convmap),
27  fClass (cls),
28  fStreamerChecksum (0),
29  fLastFile (0)
30 {
31 }
32 
33 
39 void TConverterStreamer::operator() (TBuffer& b, void* obj)
40 {
41  if (b.IsReading()) {
42  // Reading --- do we need to convert?
43  UInt_t startpos, bcnt;
44  Version_t version;
45  FindVersion (b, startpos, bcnt, version);
46  // find converter for the object shape checksum
47  // (checksum is read from the file in FindVersion)
48  CheckSumMap::const_iterator i = fConvmap.find (fStreamerChecksum);
49 
50  if (i != fConvmap.end()) {
51  // Found a converter --- call it.
52  i->second.first->ReadBuffer (b, obj, version, startpos, bcnt);
53  }
54  else {
55  // No converter --- read normally.
56  fClass->ReadBuffer(b, obj, version, startpos, bcnt);
57  }
58  }
59  else {
60  // Writing --- just do the standard thing.
61  fClass->WriteBuffer(b, obj);
62  }
63 }
64 
65 
76  UInt_t& startpos,
77  UInt_t& bcnt,
78  Version_t& version)
79 {
80  const UInt_t kByteCountMask = 0x40000000; // OR the byte count with this
81 
82  // before reading object save start position
83  startpos = buf.Length();
84 
85  // read byte count (older files don't have byte count)
86  // byte count is packed in two individual shorts, this to be
87  // backward compatible with old files that have at this location
88  // only a single short (i.e. the version)
89  union {
90  UInt_t cnt;
91  Version_t vers[2];
92  } v;
93 #ifdef R__BYTESWAP
94  // cppcheck-suppress uninitvar
95  buf >> v.vers[1];
96  buf >> v.vers[0];
97 #else
98  // cppcheck-suppress uninitvar
99  buf >> v.vers[0];
100  buf >> v.vers[1];
101 #endif
102  if (!(v.cnt & kByteCountMask)) {
103  // no bytecount, go back before reading version
104  buf.SetBufferOffset(buf.Length() - sizeof(UInt_t));
105  v.cnt = 0;
106  }
107  bcnt = (v.cnt & ~kByteCountMask);
108  buf >> version;
109 
110  TFile* parent = (TFile*)buf.GetParent();
111  if (fLastFile != parent) {
112  // new file, reset
113  fStreamerChecksum = 0;
114  }
115  if (fClass && fClass->GetClassVersion() != 0) {
116  if (version <= 0) {
117  buf >> fStreamerChecksum;
120  } else if (version == 1) {
121  // hand made streamer list caching,
122  // change that when TFile::GetStreamerInfoCache() is out
123  if (fLastFile == parent) {
124  // the same file, nothing changed?
125  }
126  else if (parent && parent->GetVersion() < 40000)
127  {
128  // We could have a file created using a Foreign class before
129  // the introduction of the CheckSum. We need to check
130  if ((!fClass->IsLoaded() || fClass->IsForeign()) &&
131  fClass->GetStreamerInfos()->GetLast() > 1)
132  {
133  const TList* list = parent->GetStreamerInfoList();
134  const TStreamerInfo* local = (TStreamerInfo*)list->FindObject(fClass->GetName());
135  if (local) {
136  fStreamerChecksum = local->GetCheckSum();
139  }
140  else {
141  version = 0;
142  }
143  }
144  }
145  }
146  }
147  fLastFile = parent;
148 }
149 
157 Version_t
159  UInt_t checksum)
160 {
161  //FIXME
162  // use TBuffer::R__FindStreamerInfoVersion() instead of this function
163  // with the next ROOT release
164 
165  //find the version number in the StreamerInfos corresponding to checksum
166  Version_t version = 0;
167  Int_t ninfos = cl->GetStreamerInfos()->GetEntriesFast();
168  for (Int_t i = 1; i < ninfos; i++) {
169  // TClass::fStreamerInfos has a lower bound not equal to 0,
170  // so we should use At and not use UncheckedAt
171  TStreamerInfo* info = (TStreamerInfo*)cl->GetStreamerInfos()->At(i);
172  if (!info) {
173  continue;
174  }
175  if (info->GetCheckSum() == checksum) {
176  version = i;
177  break;
178  }
179  }
180  return(version);
181 }
182 
grepfile.info
info
Definition: grepfile.py:38
CaloClusterListBadChannel.cls
cls
Definition: CaloClusterListBadChannel.py:8
TConverterStreamer::fStreamerChecksum
UInt_t fStreamerChecksum
Cached checksum for the last object read.
Definition: TConverterStreamer.h:96
lumiFormat.i
int i
Definition: lumiFormat.py:92
TConverterStreamer::R__FindStreamerInfoVersion
Version_t R__FindStreamerInfoVersion(const TClass *cl, UInt_t checksum)
Translate a Root checksum to a class version number.
Definition: TConverterStreamer.cxx:158
test_pyathena.parent
parent
Definition: test_pyathena.py:15
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
TConverterStreamer::TConverterStreamer
TConverterStreamer(const CheckSumMap &convmap, TClass *cls)
Constructor.
Definition: TConverterStreamer.cxx:24
TConverterStreamer::FindVersion
void FindVersion(TBuffer &buf, UInt_t &startpos, UInt_t &bcnt, Version_t &version)
Read the initial byte count/version from an object.
Definition: TConverterStreamer.cxx:75
TConverterStreamer::fConvmap
const CheckSumMap & fConvmap
The checksum -> converter map passed to the constructor.
Definition: TConverterStreamer.h:90
TConverterStreamer::fClass
TClass * fClass
The transient class we're reading.
Definition: TConverterStreamer.h:93
InDetDD::local
@ local
Definition: InDetDD_Defs.h:16
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
TConverterStreamer.h
Root streamer that calls our converters when reading in non-split mode.
TConverterStreamer::CheckSumMap
std::map< UInt_t, Payload > CheckSumMap
Definition: TConverterStreamer.h:48
python.PyAthena.v
v
Definition: PyAthena.py:157
get_generator_info.version
version
Definition: get_generator_info.py:33
TConverterStreamer::fLastFile
TFile * fLastFile
Cached file for the last object read.
Definition: TConverterStreamer.h:99
trigbs_pickEvents.cnt
cnt
Definition: trigbs_pickEvents.py:71
TConverterStreamer::operator()
virtual void operator()(TBuffer &b, void *obj)
Standard Root streamer interface.
Definition: TConverterStreamer.cxx:39
python.PyAthena.obj
obj
Definition: PyAthena.py:135
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26