ATLAS Offline Software
Loading...
Searching...
No Matches
TConverterStreamer.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
11
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),
29 fLastFile (nullptr)
30{
31}
32
33
39void 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 auto 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
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
157Version_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
Root streamer that calls our converters when reading in non-split mode.
const CheckSumMap & fConvmap
The checksum -> converter map passed to the constructor.
UInt_t fStreamerChecksum
Cached checksum for the last object read.
void FindVersion(TBuffer &buf, UInt_t &startpos, UInt_t &bcnt, Version_t &version)
Read the initial byte count/version from an object.
virtual void operator()(TBuffer &b, void *obj)
Standard Root streamer interface.
TFile * fLastFile
Cached file for the last object read.
Version_t R__FindStreamerInfoVersion(const TClass *cl, UInt_t checksum)
Translate a Root checksum to a class version number.
std::map< UInt_t, Payload > CheckSumMap
TConverterStreamer(const CheckSumMap &convmap, TClass *cls)
Constructor.
TClass * fClass
The transient class we're reading.