Files
geant4/source/externals/g4tools/include/tools/rroot/branch_element
T
2022-07-01 10:44:02 +02:00

797 lines
28 KiB
Plaintext

// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_branch_element
#define tools_rroot_branch_element
#include "branch"
#include "stl_vector"
#include "info"
#include "obj_list"
//#define TOOLS_RROOT_BRANCH_ELEMENT_DUMP
namespace tools {
namespace rroot {
class branch_element : public branch {
typedef branch parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::branch_element");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<branch_element>(this,a_class)) return p;
return parent::cast(a_class);
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return branch_element_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<branch_element>(this,a_class)) {return p;}
return parent::cast(a_class);
}
public:
virtual bool stream(buffer& a_buffer) {
_clear();
short v;
unsigned int _s,_c;
if(!a_buffer.read_version(v,_s,_c)) return false;
//::printf("debug : tools::branch_element::stream : version %d, count %d\n",v,c);
if(!parent::stream(a_buffer)) {
m_out << "tools::rroot::branch_element::stream : parent::stream() failed." << std::endl;
return false;
}
if(v<=7) {
if(!a_buffer.read(fClassName)) return false;
if(!a_buffer.read(fClassVersion)) return false;
if(!a_buffer.read(fID)) return false;
if(!a_buffer.read(fType)) return false;
if(!a_buffer.read(fStreamerType)) return false;
} else { //v>=8
if(!a_buffer.read(fClassName)) return false;
//::printf("debug : tools::branch_element::stream : fClassName \"%s\"\n",fClassName.c_str());
std::string fParentName;
if(!a_buffer.read(fParentName)) return false;
//::printf("debug : tools::branch_element::stream : fParentName \"%s\"\n",fParentName.c_str());
std::string fCloneName;
if(!a_buffer.read(fCloneName)) return false;
//::printf("debug : tools::branch_element::stream : fCloneName \"%s\"\n",fCloneName.c_str());
int dummy_int;
if(!a_buffer.read(dummy_int)) return false; //fCheckSum
//::printf("debug : tools::branch_element::stream : fCheckSum %d\n",dummy_int);
if(v>=10) {
short dummy_short;
if(!a_buffer.read(dummy_short)) return false; //fClassVersion
//::printf("debug : tools::branch_element::stream : fClassVersion %d\n",dummy_short);
} else {
if(!a_buffer.read(dummy_int)) return false; //fClassVersion
}
if(!a_buffer.read(fID)) return false;
//::printf("debug : tools::branch_element::stream : fID %d\n",fID);
if(!a_buffer.read(fType)) return false;
//::printf("debug : tools::branch_element::stream : fType %d\n",fType);
if(!a_buffer.read(fStreamerType)) return false;
//::printf("debug : tools::branch_element::stream : fStreamerType %d\n",fStreamerType);
if(!a_buffer.read(dummy_int)) return false; //fMaximum
//::printf("debug : tools::branch_element::stream : fMaximum %d\n",dummy_int);
//TBranchElement* fBranchCount;
ifac::args args;
if(!pointer_stream(a_buffer,m_fac,args,fBranchCount,fBranchCount_created)) {
m_out << "tools::rroot::branch_element::stream : "
<< "can't read fBranchCount."
<< std::endl;
return false;
}
//TBranchElement* fBranchCount2;
if(!pointer_stream(a_buffer,m_fac,args,fBranchCount2,fBranchCount2_created)) {
m_out << "tools::rroot::branch_element::stream : "
<< "can't read fBranchCount2."
<< std::endl;
_clear();
return false;
}
}
if(!a_buffer.check_byte_count(_s,_c,"TBranchElement")) {_clear();return false;}
return true;
}
public: //branch
virtual bool read_leaves(ifile& a_file,buffer& a_buffer){
// For k<type> value, see the below commented enum EReadWrite from ROOT-6.12.06 code.
static int kInt = 3;
static int kDouble = 8;
static int kDouble32 = 9;
static int kUInt = 13;
static int kBits = 15; // In v4-00-01 version 8, it is Long64_t.
static int kObject = 61;
static int kObjectP = 64;
if(fType==3) { // TClonesArray master branch (has only the number of elements).
//from v4-00-01
int n;
if(!a_buffer.read(n)) return false;
/* ROOT-6.12.06 code :
if ((n < 0) || (n > fMaximum)) {
if (IsMissingCollection()) {
n = 0;
b.SetBufferOffset(b.Length() - sizeof(n));
} else {
Error("ReadLeaves", "Incorrect size read for the container in %s\nThe size read is %d when the maximum is %d\nThe size is reset to 0 for this entry (%lld)", GetName(), n, fMaximum, GetReadEntry());
n = 0;
}
}*/
//::printf("debug : uuuu : ndata %d\n",n);
fNdata = n;
//TClonesArray *clones = (TClonesArray*)fObject;
//if (!clones) return;
//if (clones->IsZombie()) return;
//clones->Clear();
//clones->ExpandCreateFast(fNdata);
//m_out << "debug : tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName
// << " : type " << fType << ", fNdata " << n
// << std::endl;
return true;
} else if(fType==31) { // TClonesArray sub-branch (contains the elements).
if(fStreamerType==kObject) { //to read EsbRoot fgd_dig.root.
int ndata = fBranchCount->get_ndata();
#ifdef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
::printf("debug : %s : fClassName %s : fID %d : kObject : ndata %d\n",m_name.c_str(),fClassName.c_str(),fID,ndata);
#endif
streamer_info* _info = a_file.find_streamer_info(fClassName);
if(!_info) {
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
<< " read(kObject) : streamer_infos for ref_cls " << fClassName << " not found."
<< std::endl;
return false;
}
streamer_element* _element = _info->find_streamer_element(fID);
if(!_element) {
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
<< " read(kObject) : for ref_cls " << fClassName << ", fID " << fID << " streamer element not found."
<< std::endl;
return false;
}
//::printf("debug : element type name %s\n",_element->type_name().c_str());
obj_list* _list = 0;
if(!m_obj) {
_list = new obj_list(m_fac);
m_obj = _list;
} else {
_list = id_cast<iro,obj_list>(*m_obj);
if(!_list) {
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
<< " read(kObject) : m_obj is not an obj_list."
<< std::endl;
return false;
}
}
_list->safe_clear();
for(int index=0;index<ndata;index++) {
ifac::args args;
iro* _obj = m_fac.create(_element->type_name(),args);
if(!_obj) {_list->safe_clear();return false;}
if(!_obj->stream(a_buffer)){
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
<< " kObject : obj stream of class " << sout(_element->type_name())
<< " failed at index " << index << " (" << ndata << ")." << std::endl;
_list->safe_clear();
return false;
}
_list->add_object(_obj); //give ownership.
}
return true;
}
if(fStreamerType==kObjectP) return true;
//from v4-00-01
if(fStreamerType==kDouble32) {
int ndata = fBranchCount->get_ndata();
#ifdef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
::printf("debug : %s : fID %d : double32 : ndata %d\n",m_name.c_str(),fID,ndata);
#endif
stl_vector<double>* vec = 0;
if(!m_obj) {
vec = new stl_vector<double>;
m_obj = vec;
} else {
vec = id_cast<iro, stl_vector<double> >(*m_obj);
if(!vec) {
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
<< " read(kDouble32) : m_obj is not a stl_vector<double>."
<< std::endl;
return false;
}
}
vec->resize(ndata);
float afloat;
for(int ii=0;ii<ndata;ii++) {
if(!a_buffer.read(afloat)) {
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
<< " read(float) failed."
<< std::endl;
vec->clear();
return false;
}
//::printf("debug : zzzz %g\n",afloat);
(*vec)[ii] = afloat;
}
return true;
} else if(fStreamerType==kDouble) {
int ndata = fBranchCount->get_ndata();
#ifdef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
::printf("debug : %s : fID %d : double : ndata %d\n",m_name.c_str(),fID,ndata);
#endif
stl_vector<double>* vec = 0;
if(!m_obj) {
vec = new stl_vector<double>;
m_obj = vec;
} else {
vec = id_cast<iro, stl_vector<double> >(*m_obj);
if(!vec) {
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
<< " read(kDouble) : m_obj is not a stl_vector<double>."
<< std::endl;
return false;
}
}
vec->resize(ndata);
double* _value = vec_data(*vec);
if(!a_buffer.read_fast_array(_value,ndata)) {
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
<< " read_fast_array(double) failed."
<< std::endl;
vec->clear();
return false;
}
return true;
} else if(fStreamerType==kInt) {
int ndata = fBranchCount->get_ndata();
#ifdef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
::printf("debug : %s : fID %d : int : ndata %d\n",m_name.c_str(),fID,ndata);
#endif
stl_vector<int>* vec = 0;
if(!m_obj) {
vec = new stl_vector<int>;
m_obj = vec;
} else {
vec = id_cast<iro, stl_vector<int> >(*m_obj);
if(!vec) {
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
<< " read(kInt) : m_obj is not a stl_vector<int>."
<< std::endl;
return false;
}
}
vec->resize(ndata);
int* _value = vec_data(*vec);
if(!a_buffer.read_fast_array(_value,ndata)) {
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
<< " read_fast_array(int) failed."
<< std::endl;
vec->clear();
return false;
}
return true;
} else if((fStreamerType==kUInt)||(fStreamerType==kBits)) {
int ndata = fBranchCount->get_ndata();
#ifdef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
if(fStreamerType==kUInt) ::printf("debug : %s : fID %d : uint : ndata %d\n",m_name.c_str(),fID,ndata);
else ::printf("debug : %s : fID %d : bits : ndata %d\n",m_name.c_str(),fID,ndata);
#endif
stl_vector<uint32>* vec = 0;
if(!m_obj) {
vec = new stl_vector<uint32>;
m_obj = vec;
} else {
vec = id_cast<iro, stl_vector<uint32> >(*m_obj);
if(!vec) {
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
<< " read(kUInt) : m_obj is not a stl_vector<uint32>."
<< std::endl;
return false;
}
}
vec->resize(ndata);
uint32* _value = vec_data(*vec);
if(!a_buffer.read_fast_array(_value,ndata)) {
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
<< " read_fast_array(uint) failed."
<< std::endl;
vec->clear();
return false;
}
return true;
} else {
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName
<< " : for type " << fType << ", stream_type " << fStreamerType << " not treated."
<< std::endl;
return false;
}
/*
//m_obj = clones_array<float>(m_fac,true,false); //true = owner of objects.
uint32 ndata = 1;
float* _value = new float[ndata];
if(!a_buffer.read_fast_array(_value,ndata)) {
m_out << "tools::rroot::branch_element::read_leaves : \"" << name() << "\" :"
<< " read_fast_array failed."
<< std::endl;
return false;
}
*/
//} else if(fType<=2) { //in v5-18-00d
} else if(fType==0) { // to read wroot.root of examples/cpp/wroot.cpp.
// if(fID>=0) {
// // branch in split mode
// m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " type 0 with ID " << fID << "."
// << std::endl;
// return true;
//
if((fID==-1)||
(fID==1) // for pmx to read LHCb files :
){
//from v4-00-01
//if (fBranchCount) fNdata = (Int_t)fBranchCount->GetValue(0,0);
//else fNdata = 1;
if(fBranchCount) {
fNdata = fBranchCount->get_ndata();
//::printf("debug : branch_element::read_leaves : (fType==0,fID==-1) : fNdata %d\n",fNdata);
} else {
fNdata = 1;
}
// read object :
bool created = false;
if(!m_obj) {
ifac::args args;
m_obj = m_fac.create(fClassName,args);
if(!m_obj) return false;
created = true;
}
if(!m_obj->stream(a_buffer)){
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << sout(m_name) << ", ref_cls " << sout(fClassName) << " :"
<< " obj stream failed."
<< std::endl;
if(created) {delete m_obj;m_obj = 0;}
return false;
}
return true;
} else {
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName << " :"
<< " type 0 with ID " << fID << " not treated."
<< std::endl;
return false;
}
}
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName
<< " : type " << fType << " not treated, stream_type is " << fStreamerType << "."
<< std::endl;
return false;
/*
///////////////////////////////////////////////////////
/// STL container /////////////////////////////////////
///////////////////////////////////////////////////////
if(fType==4) {
// STL container master branch (has only the number of elements).
//from v4-00-01
int n;
if(!a_buffer.read(n)) return false;
//fNdata = n;
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName
<< " : type " << fType << " not treated."
<< std::endl;
return false;
} else if(fType==41) {
// STL container sub-branch (contains the elements).
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName
<< " : type " << fType << " not treated."
<< std::endl;
return false;
///////////////////////////////////////////////////////
/// TClonesArray container ////////////////////////////
///////////////////////////////////////////////////////
} else if(fType==3) {
// TClonesArray master branch (has only the number of elements).
//from v4-00-01
int n;
if(!a_buffer.read(n)) return false;
//fNdata = n;
//TClonesArray *clones = (TClonesArray*)fObject;
//if (!clones) return;
//if (clones->IsZombie()) return;
//clones->Clear();
//clones->ExpandCreateFast(fNdata);
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName
<< " : type " << fType << " not treated."
<< std::endl;
return false;
} else if(fType==31) {
// TClonesArray sub-branch (contains the elements).
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName
<< " : type " << fType << " not treated."
<< std::endl;
return false;
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
} else if(fType<=2) {
// branch in split mode
//from v4-00-01
//if (fBranchCount) fNdata = (Int_t)fBranchCount->GetValue(0,0);
//else fNdata = 1;
//if (!fInfo) return;
//fInfo->ReadBuffer(b,fObject,fID);
//if (fStreamerType == 6) fNdata = (Int_t)GetValue(0,0);
//from 3.0.06
//if (fID >= 0) {
// fInfo->ReadBuffer(b,fAddress,fID);
//} else if (fID == -1) { // top level branch in non split mode
// char **ppointer = (char**)fAddress;
// fInfo->ReadBuffer(b,*ppointer,fID);
//}
//m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " type " << fType << " with ID " << fID << "."
// << " and then ?"
// << std::endl;
// read object ?
bool created = false;
if(!m_obj) {
ifac::args args;
m_obj = m_fac.create(fClassName,args);
if(!m_obj) return false;
created = true;
}
if(!m_obj->stream(a_buffer)){
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName << " :"
<< " obj stream failed."
<< std::endl;
if(created) {delete m_obj;m_obj = 0;}
return false;
}
//m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " obj streamed."
// << std::endl;
return true;
// } else if(fType==0) {
// if(fID>=0) {
// // branch in split mode
// m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " type 0 with ID " << fID << "."
// << std::endl;
// return true;
//
// } else if(fID==-1) {
// // top level branch in non split mode
// m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " type 0 with ID " << fID
// << " : fill object."
// << std::endl;
// if(!m_obj) {
// m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " m_obj is null."
// << std::endl;
// return false;
// }
// if(!m_obj->stream(a_buffer)){
// m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " obj stream failed."
// << std::endl;
// return false;
// }
// return true;
// } else {
// m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " type 0 with ID " << fID << " not treated."
// << std::endl;
// return false;
// }
// //LHCb files :
// } else if(fType==1) {
// // parent branch is a base class branch.
// // Ok, and then ?
// m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " type " << fType << " with ID " << fID << "."
// << std::endl;
// return true;
} else {
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName << " :"
<< " type " << fType << " with ID " << fID << "."
<< " unknown case."
<< std::endl;
return false;
}
*/
}
virtual bool find_entry(ifile& a_file,uint64 a_entry,uint32& a_nbytes){
//The below line will call the upper read_leaves.
if(!parent::find_entry(a_file,a_entry,a_nbytes)) return false;
if(m_branches.size()) {
//if(!m_obj) {
// m_obj = m_fac.create(fClassName);
// if(!m_obj) return false;
//}
tools_vforcit(branch*,m_branches,it) {
uint32 n;
if(!(*it)->find_entry(a_file,a_entry,n)) return false;
a_nbytes += n;
}
}
return true;
}
virtual bool show(std::ostream& a_out,ifile& a_file,uint64 a_entry){
uint32 n;
if(!find_entry(a_file,a_entry,n)) return false;
{std::string _s;
uint32 len = uint32(name().size())+128;
sprintf(_s,len," %-15s = ",name().c_str());
a_out << _s;}
a_out << m_obj << std::endl;
return true;
//return parent::show(a_out,a_file,a_entry);
}
public:
branch_element(std::ostream& a_out,ifac& a_fac)
:parent(a_out,a_fac)
,m_obj(0)
,fClassVersion(0)
,fID(0)
,fType(0)
,fStreamerType(-1)
,fBranchCount(0) //not owner
,fBranchCount_created(false)
,fBranchCount2(0) //not owner
,fBranchCount2_created(false)
,fNdata(1)
{}
virtual ~branch_element() {
_clear();
if(m_obj) delete m_obj;
}
protected:
branch_element(const branch_element& a_from):iro(a_from),parent(a_from){}
branch_element& operator=(const branch_element&){return *this;}
public:
const std::string& class_name() const {return fClassName;}
int type() const {return fType;}
int streamer_type() const {return fStreamerType;}
int id() const {return fID;}
iro* object() {return m_obj;}
int get_ndata() const {return fNdata;}
template <class T>
stl_vector<T>* object_to_stl_vector() const {
if(!m_obj) {
m_out << "tools::rroot::branch_element::object_to_stl_vector : there is no object." << std::endl;
return 0;
}
stl_vector<T>* od = id_cast<iro, stl_vector<T> >(*m_obj);
if(!od) {
m_out << "tools::rroot::branch_element::object_to_stl_vector :"
<< " object of class " << sout(m_obj->s_cls()) << " not a tools::rroot::stl_vector<T>."
<< std::endl;
return 0;
}
return od; //WARNING : we are not owner.
}
obj_list* object_to_obj_list() const {
if(!m_obj) {
m_out << "tools::rroot::branch_element::object_to_obj_list : there is no object." << std::endl;
return 0;
}
obj_list* od = id_cast<iro,obj_list>(*m_obj);
if(!od) {
m_out << "tools::rroot::branch_element::object_to_obj_list :"
<< " object of class " << sout(m_obj->s_cls()) << " not a tools::rroot::obj_list."
<< std::endl;
return 0;
}
return od; //WARNING : we are not owner.
}
template <class T>
stl_vector<T>* find_entry_vec(ifile& a_file,uint64 a_event) {
unsigned int n;
if(!find_entry(a_file,a_event,n)) {
m_out << "tools::rroot::branch_element::find_entry_vec : find_entry() failed." << std::endl;
return 0;
}
if(!m_obj) {
m_out << "tools::rroot::branch_element::find_entry_vec : no object found." << std::endl;
return 0;
}
stl_vector<T>* od = id_cast<iro, stl_vector<T> >(*m_obj);
if(!od) {
m_out << "tools::rroot::branch_element::find_entry_vec :"
<< " object not a tools::rroot::stl_vector<T>."
<< std::endl;
return 0;
}
return od; //WARNING : we are not owner.
}
protected:
void _clear() {
if(fBranchCount_created) {delete fBranchCount;fBranchCount = 0;fBranchCount_created = false;}
if(fBranchCount2_created) {delete fBranchCount2;fBranchCount2 = 0;fBranchCount2_created = false;}
}
protected:
iro* m_obj;
protected:
std::string fClassName; //Class name of referenced object
int fClassVersion; //Version number of class
int fID; //element serial number in fInfo
int fType; //branch type
int fStreamerType; //branch streamer type
branch_element* fBranchCount; // pointer to primary branchcount branch
bool fBranchCount_created;
branch_element* fBranchCount2; // pointer to secondary branchcount branch
bool fBranchCount2_created;
int fNdata; // Number of data in this branch
};
}}
#ifdef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
#undef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
#endif
#endif
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
/* In v4-00-01 version 8 :
case 1: {b.ReadFastArray((Char_t*) fAddress, n); break;}
case 2: {b.ReadFastArray((Short_t*) fAddress, n); break;}
case 3: {b.ReadFastArray((Int_t*) fAddress, n); break;}
case 4: {b.ReadFastArray((Long_t*) fAddress, n); break;}
case 5: {b.ReadFastArray((Float_t*) fAddress, n); break;}
case 6: {b.ReadFastArray((Int_t*) fAddress, n); break;}
case 8: {b.ReadFastArray((Double_t*)fAddress, n); break;}
case 11: {b.ReadFastArray((UChar_t*) fAddress, n); break;}
case 12: {b.ReadFastArray((UShort_t*)fAddress, n); break;}
case 13: {b.ReadFastArray((UInt_t*) fAddress, n); break;}
case 14: {b.ReadFastArray((ULong_t*) fAddress, n); break;}
case 15: {b.ReadFastArray((Long64_t*)fAddress, n); break;}
case 16: {b.ReadFastArray((ULong64_t*)fAddress, n); break;}
case 9: {Double_t *xx = (Double_t*)fAddress;
Float_t afloat;
for (Int_t ii=0;ii<n;ii++) {
b>> afloat; xx[ii] = Double_t(afloat);
} break;}
*/
/* 6.12.06 version 10 : fStreamerType : from meta/inc/TVirtualStreamerInfo.h :
enum EReadWrite {
kBase = 0, kOffsetL = 20, kOffsetP = 40, kCounter = 6, kCharStar = 7,
kChar = 1, kShort = 2, kInt = 3, kLong = 4, kFloat = 5,
kDouble = 8, kDouble32= 9,
kUChar = 11, kUShort = 12, kUInt = 13, kULong = 14, kBits = 15,
kLong64 = 16, kULong64 = 17, kBool = 18, kFloat16 = 19,
kObject = 61, kAny = 62, kObjectp = 63, kObjectP = 64, kTString = 65,
kTObject = 66, kTNamed = 67, kAnyp = 68, kAnyP = 69, kAnyPnoVT = 70,
kSTLp = 71,
kSkip = 100, kSkipL = 120, kSkipP = 140,
kConv = 200, kConvL = 220, kConvP = 240,
kSTL = ROOT::kSTLany, // 300
kSTLstring = ROOT::kSTLstring, // 365
kStreamer = 500, kStreamLoop = 501,
kCache = 600, // Cache the value in memory than is not part of the object but is accessible via a SchemaRule
kArtificial = 1000,
kCacheNew = 1001,
kCacheDelete = 1002,
kNeedObjectForVirtualBaseClass = 99997,
kMissing = 99999
};
// Some comments about EReadWrite
// kBase : base class element
// kOffsetL : fixed size array
// kOffsetP : pointer to object
// kCounter : counter for array size
// kCharStar: pointer to array of char
// kBits : TObject::fBits in case of a referenced object
// kObject : Class derived from TObject
// kObjectp : Class* derived from TObject and with comment field //->Class
// kObjectP : Class* derived from TObject and with NO comment field //->Class
// kAny : Class not derived from TObject
// kAnyp : Class* not derived from TObject with comment field //->Class
// kAnyP : Class* not derived from TObject with NO comment field //->Class
// kAnyPnoVT: Class* not derived from TObject with NO comment field //->Class and Class has NO virtual table
// kSTLp : Pointer to STL container.
// kTString : TString, special case
// kTObject : TObject, special case
// kTNamed : TNamed , special case
*/