Description
hi -
The following short program attempts to demonstrate schema evolution using
ReadObjectAny. It saves a vector<int> to a TBufferFile using WriteObjectAny
and then tries to read it back as a vector<float> using ReadObjectAny:
#include "TBufferFile.h"
|
#include "TClass.h"
|
#include <vector>
|
#include <iostream>
|
|
int main()
|
{
|
std::vector<int> v;
|
for (int i=0; i<10; i++)
|
v.push_back(i);
|
|
TClass* cl1 = TClass::GetClass ("vector<int>");
|
TClass* cl2 = TClass::GetClass ("vector<float>");
|
|
TBufferFile *m_buff = new TBufferFile(TBuffer::kWrite);
|
m_buff->WriteObjectAny (&v, cl1);
|
m_buff->SetReadMode();
|
m_buff->Reset();
|
void* obj = m_buff->ReadObjectAny (cl2);
|
std::vector<float>* v2 = reinterpret_cast<std::vector<float>*> (obj);
|
for (float x : *v2)
|
std::cout << x << " ";
|
std::cout << "\n";
|
|
return 0;
|
}
|
However, what i get when i run it is this
(tested against /afs/cern.ch/sw/lcg/releases/LCG_85a/ROOT/6.06.06/x86_64-slc6-gcc49-dbg):
Info in <TBufferFile::ReadObjectAny>: Using Converter StreamerInfo from vector<int> to vector<float>
|
0 1.4013e-45 2.8026e-45 4.2039e-45 5.60519e-45 7.00649e-45 8.40779e-45 9.80909e-45 1.12104e-44 1.26117e-44
|
So, despite root claiming to be running a conversion, it actually does not.
If one looks in ReadObjectAny, there is some code dealing with conversions,
but the actual streamer call is
TClass *clOnfile = 0;
|
...
|
clRef->Streamer( obj, *this, clOnfile );
|
where there are no other assignments to clOnfile. So the fact that there
is a conversion does not get passed to the streamer.
If i make this change:
iff --git a/io/io/src/TBufferFile.cxx b/io/io/src/TBufferFile.cxx
|
index fce860b..67b0caf 100644
|
--- a/io/io/src/TBufferFile.cxx
|
+++ b/io/io/src/TBufferFile.cxx
|
@@ -2405,8 +2405,9 @@ void *TBufferFile::ReadObjectAny(const TClass *clCast)
|
return 0; // We better return at this point
|
}
|
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 ....
|
-
|
- Info("ReadObjectAny","Using Converter StreamerInfo from %s to %s",clRef->GetName(),clCast->GetName());
|
+
|
+ //Info("ReadObjectAny","Using Converter StreamerInfo from %s to %s",clRef->GetName(),clCast->GetName());
|
+ clOnfile = clRef;
|
clRef = const_cast<TClass*>(clCast);
|
|
}
|
then this example works.
(It also seems excessive to generate an Info message each time there is
a conversion, so i commented that out.)