Import Geant4 11.0.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2021-06-25 16:12:29 +02:00
parent c968e26a39
commit 6399a014b6
4200 changed files with 207479 additions and 237366 deletions
+730
View File
@@ -0,0 +1,730 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_THistogram
#define tools_rroot_THistogram
// to read some files produced with BatchLab (opaw/examples/osc/analysis.root).
#include "../histo/profile_data"
#include "named"
#include "../vmanip"
namespace tools {
namespace rroot {
//typedef histo::histo_data<double,unsigned int,double> hd_data;
typedef histo::profile_data<double,unsigned int,unsigned int,double,double> pd_data_t;
typedef histo::axis<double,unsigned int> axis_t;
typedef std::map<std::string,std::string> annotations_t;
inline bool Axis_read_v0_v3(buffer& a_buffer,axis_t& a_axis) {
int idummy;
double ddummy;
if(!a_buffer.read(a_axis.m_minimum_value)) return false;
if(!a_buffer.read(a_axis.m_maximum_value)) return false;
if(!a_buffer.read(a_axis.m_offset)) return false;
if(!a_buffer.read(a_axis.m_number_of_bins)) return false;
if(!a_buffer.read(idummy)) return false; //fOverFlow
if(!a_buffer.read(idummy)) return false; //fUnderFlow
if(!a_buffer.read(a_axis.m_bin_width)) return false;
if(!a_buffer.read(ddummy)) return false; //fSxw
if(!a_buffer.read(ddummy)) return false; //fSx2w
a_axis.m_fixed = true;
a_axis.m_edges.clear();
return true;
}
inline bool Axis_read_v4_v6(buffer& a_buffer,axis_t& a_axis) {
int idummy;
double ddummy;
if(!a_buffer.read(a_axis.m_offset)) return false;
if(!a_buffer.read(idummy)) return false; //fOverFlow
if(!a_buffer.read(idummy)) return false; //fUnderFlow
if(!a_buffer.read(ddummy)) return false; //fSxw
if(!a_buffer.read(ddummy)) return false; //fSx2w
if(!a_buffer.read(a_axis.m_number_of_bins)) return false;
if(!a_buffer.read(a_axis.m_minimum_value)) return false;
if(!a_buffer.read(a_axis.m_maximum_value)) return false;
if(!a_buffer.read(a_axis.m_fixed)) return false;
if(!a_buffer.read(a_axis.m_bin_width)) return false;
int edgen;
if(!a_buffer.read(edgen)) return false;
for(int count=0;count<edgen;count++) {
double value;
if(!a_buffer.read(value)) return false;
a_axis.m_edges.push_back(value);
}
return true;
}
inline bool Axis_read_v7(buffer& a_buffer,axis_t& a_axis) {
if(!a_buffer.read(a_axis.m_offset)) return false;
if(!a_buffer.read(a_axis.m_number_of_bins)) return false;
if(!a_buffer.read(a_axis.m_minimum_value)) return false;
if(!a_buffer.read(a_axis.m_maximum_value)) return false;
if(!a_buffer.read(a_axis.m_fixed)) return false;
if(!a_buffer.read(a_axis.m_bin_width)) return false;
int edgen;
if(!a_buffer.read(edgen)) return false;
for(int count=0;count<edgen;count++) {
double value;
if(!a_buffer.read(value)) return false;
a_axis.m_edges.push_back(value);
}
return true;
}
inline unsigned int new_bin_number(const std::vector< axis_t >& aAxes) {
unsigned int number = 1;
for(unsigned int iaxis=0;iaxis<aAxes.size();iaxis++)
number *= (aAxes[iaxis].bins()+2);
return number;
}
template <class T>
inline void add_outflow(const std::vector< axis_t >& aAxes,std::vector<T>& aVector) {
// aAxes[].m_offset contains the offset without outflow.
unsigned int dim = aAxes.size();
// new size and offsets :
std::vector<int> aoff(dim);
int newn = 1;
{for(unsigned iaxis=0;iaxis<dim;iaxis++) newn *= (aAxes[iaxis].bins()+2);}
aoff[0] = 1;
{for(unsigned iaxis=1;iaxis<dim;iaxis++) {
aoff[iaxis] = aoff[iaxis-1] * (aAxes[iaxis-1].bins()+2);
}}
// copy :
std::vector<T> tmp = aVector;
int oldn = (int)tmp.size();
aVector.resize(newn,0);
// Copy :
std::vector<int> is(dim);
int offset;
for(int index=0;index<oldn;index++) {
// Get new offset of index :
offset = index;
{for(int iaxis=dim-1;iaxis>=0;iaxis--) {
is[iaxis] = offset/aAxes[iaxis].m_offset;
offset -= is[iaxis] * aAxes[iaxis].m_offset;
}}
// new offset :
offset = 0;
{for(unsigned iaxis=0;iaxis<dim;iaxis++) offset += is[iaxis] * aoff[iaxis];}
aVector[offset] = tmp[index];
}
}
inline void add_outflow(std::vector< axis_t >& aAxes) {
// Restore new offsets :
aAxes[0].m_offset = 1;
for(unsigned int iaxis=1;iaxis<aAxes.size();iaxis++)
aAxes[iaxis].m_offset = aAxes[iaxis-1].m_offset * (aAxes[iaxis-1].bins()+2);
}
inline bool read_v0(buffer& a_buffer,pd_data_t& a_data) {
int idummy;
double ddummy;
std::string sdummy;
if(!a_buffer.read(sdummy)) return false;
if(!a_buffer.read(a_data.m_title)) return false;
{int dim;
if(!a_buffer.read(dim)) return false;
a_data.m_dimension = dim;}
{int nbin;
if(!a_buffer.read(nbin)) return false;
a_data.m_bin_number = nbin;}
if(!a_buffer.read(idummy)) return false; //fEntries
if(!a_buffer.read(idummy)) return false; //fOutFlow
if(!a_buffer.read(ddummy)) return false; //fSw
std::vector<int> vec;
if(!a_buffer.read_array<int>(vec)) return false;
convert<int,unsigned int>(vec,a_data.m_bin_entries);
if(a_data.m_bin_entries.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw)) return false;
if(a_data.m_bin_Sw.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw2)) return false;
if(a_data.m_bin_Sw2.size()!=a_data.m_bin_number) return false;
if(a_data.m_dimension>0) {
a_data.m_axes.resize(a_data.m_dimension);
for(unsigned int iaxis=0;iaxis<a_data.m_dimension;iaxis++) {
if(!Axis_read_v0_v3(a_buffer,a_data.m_axes[iaxis])) return false;
}
}
axis_t axisOfValues;
if(!Axis_read_v0_v3(a_buffer,axisOfValues)) return false;
{int dummy;
if(!a_buffer.read(dummy)) return false;} //m_mode
// Add outflow :
a_data.m_bin_number = new_bin_number(a_data.m_axes);
add_outflow<unsigned int>(a_data.m_axes,a_data.m_bin_entries);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw2);
add_outflow(a_data.m_axes);
// Not here in v0 :
std::vector<double> empty;
empty.resize(a_data.m_dimension,0);
a_data.m_bin_Sxw.resize(a_data.m_bin_number,empty);
a_data.m_bin_Sx2w.resize(a_data.m_bin_number,empty);
a_data.m_is_profile = false;
a_data.m_bin_Svw.clear();
a_data.m_bin_Sv2w.clear();
return true;
}
inline bool read_v1(buffer& a_buffer,pd_data_t& a_data) {
int idummy;
double ddummy;
if(!a_buffer.read(a_data.m_title)) return false;
{int dim;
if(!a_buffer.read(dim)) return false;
a_data.m_dimension = dim;}
{int nbin;
if(!a_buffer.read(nbin)) return false;
a_data.m_bin_number = nbin;}
if(!a_buffer.read(idummy)) return false; //fEntries
if(!a_buffer.read(idummy)) return false; //fOutFlow
if(!a_buffer.read(ddummy)) return false; //fSw
std::vector<int> vec;
if(!a_buffer.read_array<int>(vec)) return false;
convert<int,unsigned int>(vec,a_data.m_bin_entries);
if(a_data.m_bin_entries.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw)) return false;
if(a_data.m_bin_Sw.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw2)) return false;
if(a_data.m_bin_Sw2.size()!=a_data.m_bin_number) return false;
if(a_data.m_dimension>0) {
a_data.m_axes.resize(a_data.m_dimension);
for(unsigned int iaxis=0;iaxis<a_data.m_dimension;iaxis++) {
if(!Axis_read_v0_v3(a_buffer,a_data.m_axes[iaxis])) return false;
}
}
axis_t axisOfValues;
if(!Axis_read_v0_v3(a_buffer,axisOfValues)) return false;
{int dummy;
if(!a_buffer.read(dummy)) return false;} //m_mode
// Add outflow :
a_data.m_bin_number = new_bin_number(a_data.m_axes);
add_outflow<unsigned int>(a_data.m_axes,a_data.m_bin_entries);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw2);
add_outflow(a_data.m_axes);
// Not here in v1 :
std::vector<double> empty;
empty.resize(a_data.m_dimension,0);
a_data.m_bin_Sxw.resize(a_data.m_bin_number,empty);
a_data.m_bin_Sx2w.resize(a_data.m_bin_number,empty);
a_data.m_is_profile = false;
a_data.m_bin_Svw.clear();
a_data.m_bin_Sv2w.clear();
return true;
}
inline bool read_v2(buffer& a_buffer,pd_data_t& a_data) {
int idummy;
double ddummy;
std::string sdummy;
if(!a_buffer.read(a_data.m_title)) return false;
if(!a_buffer.read(sdummy)) return false;
{int dim;
if(!a_buffer.read(dim)) return false;
a_data.m_dimension = dim;}
{int nbin;
if(!a_buffer.read(nbin)) return false;
a_data.m_bin_number = nbin;}
if(!a_buffer.read(idummy)) return false; //fEntries
if(!a_buffer.read(idummy)) return false; //fOutFlow
if(!a_buffer.read(ddummy)) return false; //fSw
std::vector<int> vec;
if(!a_buffer.read_array<int>(vec)) return false;
convert<int,unsigned int>(vec,a_data.m_bin_entries);
if(a_data.m_bin_entries.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw)) return false;
if(a_data.m_bin_Sw.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw2)) return false;
if(a_data.m_bin_Sw2.size()!=a_data.m_bin_number) return false;
if(a_data.m_dimension>0) {
a_data.m_axes.resize(a_data.m_dimension);
for(unsigned int iaxis=0;iaxis<a_data.m_dimension;iaxis++) {
if(!Axis_read_v0_v3(a_buffer,a_data.m_axes[iaxis])) return false;
}
}
axis_t axisOfValues;
if(!Axis_read_v0_v3(a_buffer,axisOfValues)) return false;
{int dummy;
if(!a_buffer.read(dummy)) return false;} //m_mode
// Add outflow :
a_data.m_bin_number = new_bin_number(a_data.m_axes);
add_outflow<unsigned int>(a_data.m_axes,a_data.m_bin_entries);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw2);
add_outflow(a_data.m_axes);
// Not here in v2 :
std::vector<double> empty;
empty.resize(a_data.m_dimension,0);
a_data.m_bin_Sxw.resize(a_data.m_bin_number,empty);
a_data.m_bin_Sx2w.resize(a_data.m_bin_number,empty);
a_data.m_is_profile = false;
a_data.m_bin_Svw.clear();
a_data.m_bin_Sv2w.clear();
return true;
}
inline bool read_v3(buffer& a_buffer,pd_data_t& a_data) {
int idummy;
double ddummy;
int l;
if(!a_buffer.read(l)) return false;
char* str = new char[l+1];
for (int i = 0; i < l; i++) {
if(!a_buffer.read(str[i])) { delete [] str;return false;}
}
str[l] = '\0';
a_data.m_title = str;
delete [] str;
{int dim;
if(!a_buffer.read(dim)) return false;
a_data.m_dimension = dim;}
{int nbin;
if(!a_buffer.read(nbin)) return false;
a_data.m_bin_number = nbin;}
if(!a_buffer.read(idummy)) return false; //fEntries
if(!a_buffer.read(idummy)) return false; //fOutFlow
if(!a_buffer.read(ddummy)) return false; //fSw
std::vector<int> vec;
if(!a_buffer.read_array<int>(vec)) return false;
convert<int,unsigned int>(vec,a_data.m_bin_entries);
if(a_data.m_bin_entries.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw)) return false;
if(a_data.m_bin_Sw.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw2)) return false;
if(a_data.m_bin_Sw2.size()!=a_data.m_bin_number) return false;
if(a_data.m_dimension>0) {
a_data.m_axes.resize(a_data.m_dimension);
for(unsigned int iaxis=0;iaxis<a_data.m_dimension;iaxis++) {
if(!Axis_read_v0_v3(a_buffer,a_data.m_axes[iaxis])) return false;
}
}
axis_t axisOfValues;
if(!Axis_read_v0_v3(a_buffer,axisOfValues)) return false;
{int dummy;
if(!a_buffer.read(dummy)) return false;} //m_mode
// Add outflow :
a_data.m_bin_number = new_bin_number(a_data.m_axes);
add_outflow<unsigned int>(a_data.m_axes,a_data.m_bin_entries);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw2);
add_outflow(a_data.m_axes);
// Not here in v3 :
std::vector<double> empty;
empty.resize(a_data.m_dimension,0);
a_data.m_bin_Sxw.resize(a_data.m_bin_number,empty);
a_data.m_bin_Sx2w.resize(a_data.m_bin_number,empty);
a_data.m_is_profile = false;
a_data.m_bin_Svw.clear();
a_data.m_bin_Sv2w.clear();
return true;
}
inline bool read_v4(buffer& a_buffer,pd_data_t& a_data) {
int idummy;
double ddummy;
int l;
if(!a_buffer.read(l)) return false;
char* str = new char[l+1];
for (int i = 0; i < l; i++) {
if(!a_buffer.read(str[i])) { delete [] str;return false;}
}
str[l] = '\0';
a_data.m_title = str;
delete [] str;
{int dim;
if(!a_buffer.read(dim)) return false;
a_data.m_dimension = dim;}
{int nbin;
if(!a_buffer.read(nbin)) return false;
a_data.m_bin_number = nbin;}
if(!a_buffer.read(idummy)) return false; //fEntries
if(!a_buffer.read(idummy)) return false; //fOutFlow
if(!a_buffer.read(ddummy)) return false; //fSw
std::vector<int> vec;
if(!a_buffer.read_array<int>(vec)) return false;
convert<int,unsigned int>(vec,a_data.m_bin_entries);
if(a_data.m_bin_entries.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw)) return false;
if(a_data.m_bin_Sw.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw2)) return false;
if(a_data.m_bin_Sw2.size()!=a_data.m_bin_number) return false;
if(a_data.m_dimension>0) {
a_data.m_axes.resize(a_data.m_dimension);
for(unsigned int iaxis=0;iaxis<a_data.m_dimension;iaxis++) {
if(!Axis_read_v4_v6(a_buffer,a_data.m_axes[iaxis])) return false;
}
}
{int dummy;
if(!a_buffer.read(dummy)) return false;} //m_mode
// Add outflow :
a_data.m_bin_number = new_bin_number(a_data.m_axes);
add_outflow<unsigned int>(a_data.m_axes,a_data.m_bin_entries);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw2);
add_outflow(a_data.m_axes);
// Not here in v4 :
std::vector<double> empty;
empty.resize(a_data.m_dimension,0);
a_data.m_bin_Sxw.resize(a_data.m_bin_number,empty);
a_data.m_bin_Sx2w.resize(a_data.m_bin_number,empty);
a_data.m_is_profile = false;
a_data.m_bin_Svw.clear();
a_data.m_bin_Sv2w.clear();
return true;
}
inline bool read_v5(buffer& a_buffer,pd_data_t& a_data) {
int idummy;
double ddummy;
if(!a_buffer.read(a_data.m_title)) return false;
{int dim;
if(!a_buffer.read(dim)) return false;
a_data.m_dimension = dim;}
{int nbin;
if(!a_buffer.read(nbin)) return false;
a_data.m_bin_number = nbin;}
if(!a_buffer.read(idummy)) return false; //fEntries
if(!a_buffer.read(idummy)) return false; //fOutFlow
if(!a_buffer.read(ddummy)) return false; //fSw
std::vector<int> vec;
if(!a_buffer.read_array<int>(vec)) return false;
convert<int,unsigned int>(vec,a_data.m_bin_entries);
if(a_data.m_bin_entries.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw)) return false;
if(a_data.m_bin_Sw.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw2)) return false;
if(a_data.m_bin_Sw2.size()!=a_data.m_bin_number) return false;
if(a_data.m_dimension>0) {
a_data.m_axes.resize(a_data.m_dimension);
for(unsigned int iaxis=0;iaxis<a_data.m_dimension;iaxis++) {
if(!Axis_read_v4_v6(a_buffer,a_data.m_axes[iaxis])) return false;
}
}
{int dummy;
if(!a_buffer.read(dummy)) return false;} //m_mode
// Add outflow :
a_data.m_bin_number = new_bin_number(a_data.m_axes);
add_outflow<unsigned int>(a_data.m_axes,a_data.m_bin_entries);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw2);
add_outflow(a_data.m_axes);
// Not here in v5 :
std::vector<double> empty;
empty.resize(a_data.m_dimension,0);
a_data.m_bin_Sxw.resize(a_data.m_bin_number,empty);
a_data.m_bin_Sx2w.resize(a_data.m_bin_number,empty);
a_data.m_is_profile = false;
a_data.m_bin_Svw.clear();
a_data.m_bin_Sv2w.clear();
return true;
}
inline bool read_v6(buffer& a_buffer,pd_data_t& a_data) {
int idummy;
double ddummy;
if(!a_buffer.read(a_data.m_title)) return false;
{int dim;
if(!a_buffer.read(dim)) return false;
a_data.m_dimension = dim;}
{int nbin;
if(!a_buffer.read(nbin)) return false;
a_data.m_bin_number = nbin;}
if(!a_buffer.read(idummy)) return false; //fEntries
if(!a_buffer.read(idummy)) return false; //fOutFlow
if(!a_buffer.read(ddummy)) return false; //fSw
std::vector<int> vec;
if(!a_buffer.read_array<int>(vec)) return false;
convert<int,unsigned int>(vec,a_data.m_bin_entries);
if(a_data.m_bin_entries.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw)) return false;
if(a_data.m_bin_Sw.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw2)) return false;
if(a_data.m_bin_Sw2.size()!=a_data.m_bin_number) return false;
if(a_data.m_dimension>0) {
a_data.m_axes.resize(a_data.m_dimension);
for(unsigned int iaxis=0;iaxis<a_data.m_dimension;iaxis++) {
if(!Axis_read_v4_v6(a_buffer,a_data.m_axes[iaxis])) return false;
}
}
{int dummy;
if(!a_buffer.read(dummy)) return false;} //m_mode
// Profile :
if(!a_buffer.read(a_data.m_is_profile)) return false;
if(a_data.m_is_profile) {
if(!a_buffer.read_array<double>(a_data.m_bin_Svw)) return false;
if(a_data.m_bin_Svw.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read(a_data.m_cut_v)) return false;
if(!a_buffer.read(a_data.m_min_v)) return false;
if(!a_buffer.read(a_data.m_max_v)) return false;
}
// Add outflow :
a_data.m_bin_number = new_bin_number(a_data.m_axes);
add_outflow<unsigned int>(a_data.m_axes,a_data.m_bin_entries);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Sw2);
add_outflow<double>(a_data.m_axes,a_data.m_bin_Svw);
add_outflow(a_data.m_axes);
// Not here in v6 :
std::vector<double> empty;
empty.resize(a_data.m_dimension,0);
a_data.m_bin_Sxw.resize(a_data.m_bin_number,empty); //Forget to write in v6 !
a_data.m_bin_Sx2w.resize(a_data.m_bin_number,empty);
if(a_data.m_is_profile) {
a_data.m_bin_Sv2w.resize(a_data.m_bin_number,0);
}
return true;
}
inline bool read_v7(buffer& a_buffer,pd_data_t& a_data) {
if(!a_buffer.read(a_data.m_title)) return false;
{int dim;
if(!a_buffer.read(dim)) return false;
a_data.m_dimension = dim;}
{int nbin;
if(!a_buffer.read(nbin)) return false;
a_data.m_bin_number = nbin;}
std::vector<int> vec;
if(!a_buffer.read_array<int>(vec)) return false;
convert<int,unsigned int>(vec,a_data.m_bin_entries);
if(a_data.m_bin_entries.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw)) return false;
if(a_data.m_bin_Sw.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sw2)) return false;
if(a_data.m_bin_Sw2.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array2<double>(a_data.m_bin_Sxw)) return false;
if(a_data.m_bin_Sxw.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array2<double>(a_data.m_bin_Sx2w)) return false;
if(a_data.m_bin_Sx2w.size()!=a_data.m_bin_number) return false;
if(a_data.m_dimension>0) {
a_data.m_axes.resize(a_data.m_dimension);
for(unsigned int iaxis=0;iaxis<a_data.m_dimension;iaxis++) {
if(!Axis_read_v7(a_buffer,a_data.m_axes[iaxis])) return false;
}
}
{int dummy;
if(!a_buffer.read(dummy)) return false;} //m_mode
// Profile :
if(!a_buffer.read(a_data.m_is_profile)) return false;
if(a_data.m_is_profile) {
if(!a_buffer.read_array<double>(a_data.m_bin_Svw)) return false;
if(a_data.m_bin_Svw.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read_array<double>(a_data.m_bin_Sv2w)) return false;
if(a_data.m_bin_Sv2w.size()!=a_data.m_bin_number) return false;
if(!a_buffer.read(a_data.m_cut_v)) return false;
if(!a_buffer.read(a_data.m_min_v)) return false;
if(!a_buffer.read(a_data.m_max_v)) return false;
}
return true;
}
inline bool read_annotations(buffer& a_buffer,annotations_t& a_annotations) {
a_annotations.clear(); //reset() does not remove sticky items.
int number;
if(!a_buffer.read(number)) return false;
for(int index=0;index<number;index++) {
std::string key;
if(!a_buffer.read(key)) return false;
std::string value;
if(!a_buffer.read(value)) return false;
bool sticky;
if(!a_buffer.read(sticky)) return false;
//if(!a_annotations.addItem(key,value,sticky)) return false; //FIXME : handle sticky ?
a_annotations[key] = value;
}
return true;
}
inline bool read_THistogram(buffer& a_buffer,pd_data_t& a_data,annotations_t& a_annotations) {
short v;
if(!a_buffer.read_version(v)) return false;
{std::string name,title;
if(!Named_stream(a_buffer,name,title)) return false;}
if(v==0) {
if(!read_v0(a_buffer,a_data)) return false;
} else if(v==1) {
if(!read_v1(a_buffer,a_data)) return false;
} else if(v==2) {
if(!read_v2(a_buffer,a_data)) return false;
} else if(v==3) {
if(!read_v3(a_buffer,a_data)) return false;
} else if(v==4) {
if(!read_v4(a_buffer,a_data)) return false;
} else if(v==5) {
if(!read_v5(a_buffer,a_data)) return false;
} else if(v==6) {
if(!read_v6(a_buffer,a_data)) return false;
} else if(v==7) {
if(!read_v7(a_buffer,a_data)) return false;
} else if(v==8) {
if(!read_annotations(a_buffer,a_annotations)) return false;
if(!read_v7(a_buffer,a_data)) return false;
} else {
return false;
}
//data.m_coords.resize(data.m_dimension,0);
//data.m_ints.resize(data.m_dimension,0);
a_data.update_fast_getters();
return true;
}
inline const std::string& THistogram_cls(){
static const std::string s_v("THistogram");
return s_v;
}
}}
#include "key"
namespace tools {
namespace rroot {
inline bool read_key_THistogram(ifile& a_file,key& a_key,pd_data_t& a_data,annotations_t& a_annotations,bool a_warn = true) {
std::ostream& out = a_key.out();
if(a_key.object_class()!=THistogram_cls()) {
if(a_warn) out << "tools::rroot::read_key_THisogram : key not a THistogram." << std::endl;
return 0;
}
unsigned int sz;
char* buf = a_key.get_object_buffer(a_file,sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::read_key_THisogram : can't get data buffer of " << a_key.object_name() << "." << std::endl;
return 0;
}
buffer b(out,a_file.byte_swap(),sz,buf,a_key.key_length(),false);
return read_THistogram(b,a_data,a_annotations);
}
}}
#include "../histo/h1d"
#include "../histo/h2d"
#include "../histo/p1d"
#include "../histo/p2d"
namespace tools {
namespace rroot {
inline histo::h1d* THistogram_to_h1d(const pd_data_t& a_data) {
unsigned int dim = a_data.m_dimension;
bool is_profile = a_data.m_is_profile;
if(dim!=1) return 0;
if(is_profile) return 0;
histo::h1d* histo = new histo::h1d("",10,0,1);
histo->copy_from_data(a_data);
return histo;
}
inline histo::h2d* THistogram_to_h2d(const pd_data_t& a_data) {
unsigned int dim = a_data.m_dimension;
bool is_profile = a_data.m_is_profile;
if(dim!=2) return 0;
if(is_profile) return 0;
histo::h2d* histo = new histo::h2d("",10,0,1,10,0,1);
histo->copy_from_data(a_data);
return histo;
}
inline histo::p1d* THistogram_to_p1d(const pd_data_t& a_data) {
unsigned int dim = a_data.m_dimension;
bool is_profile = a_data.m_is_profile;
if(dim!=1) return 0;
if(!is_profile) return 0;
histo::p1d* histo = new histo::p1d("",10,0,1);
histo->copy_from_data(a_data);
return histo;
}
inline histo::p2d* THistogram_to_p2d(const pd_data_t& a_data) {
unsigned int dim = a_data.m_dimension;
bool is_profile = a_data.m_is_profile;
if(dim!=2) return 0;
if(!is_profile) return 0;
histo::p2d* histo = new histo::p2d("",10,0,1,10,0,1);
histo->copy_from_data(a_data);
return histo;
}
}}
#endif
+193
View File
@@ -0,0 +1,193 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_base_leaf
#define tools_rroot_base_leaf
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include "named"
namespace tools {
namespace rroot {
class base_leaf : public virtual iro {
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::base_leaf");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<base_leaf>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return base_leaf_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<base_leaf>(this,a_class)) {return p;}
else return 0;
}
public:
virtual bool stream(buffer& a_buffer) {
if(m_own_leaf_count) {
if(a_buffer.map_objs()) a_buffer.remove_in_map(m_leaf_count);
delete m_leaf_count;
}
m_leaf_count = 0;
m_own_leaf_count = false;
int fOffset;
bool fIsUnsigned;
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
//FIXME if (v > 1) {
//TLeaf::Class()->ReadBuffer(b, this, R__v, R__s, R__c);
//FIXME } else {
//====process old versions before automatic schema evolution
if(!Named_stream(a_buffer,m_name,m_title)) return false;
// Ok with v 1 & 2
if(!a_buffer.read(m_length)) return false;
if(!a_buffer.read(m_length_type)) return false;
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(m_is_range)) return false;
if(!a_buffer.read(fIsUnsigned)) return false;
{ifac::args args;
iro* obj;
bool created;
if(!a_buffer.read_object(m_fac,args,obj,created)) {
m_out << "tools::rroot::base_leaf::stream :"
<< " can't read object."
<< std::endl;
return false;
}
if(!obj) {
//m_out << "tools::rroot::base_leaf::stream :"
// << " null leaf count object."
// << std::endl;
} else {
m_leaf_count = safe_cast<iro,base_leaf>(*obj);
if(!m_leaf_count) {
m_out << "tools::rroot::base_leaf::stream :"
<< " can't cast base_leaf."
<< std::endl;
m_leaf_count = 0;
if(created) {
if(a_buffer.map_objs()) a_buffer.remove_in_map(obj);
delete obj;
}
return false;
}
if(created) m_own_leaf_count = true;
}}
if(!a_buffer.check_byte_count(s,c,"TLeaf")) return false;
if(!m_length) m_length = 1;
/*
fNewValue = false;
if(!setAddress(0)) return false;
*/
return true;
}
public:
virtual bool read_buffer(buffer&) = 0;
virtual bool print_value(std::ostream&,uint32) const = 0;
virtual uint32 num_elem() const = 0;
public:
base_leaf(std::ostream& a_out,ifac& a_fac)
:m_out(a_out)
,m_fac(a_fac)
,m_name("")
,m_title("")
//,fIndirectAddress(false)
//,fNewValue(false)
//,m_ndata(0)
,m_length(0)
,m_length_type(0)
//,fOffset(0)
,m_is_range(false)
//,fIsUnsigned(false)
,m_leaf_count(0)
,m_own_leaf_count(false)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~base_leaf(){
if(m_own_leaf_count) delete m_leaf_count;
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
base_leaf(const base_leaf& a_from)
:iro(a_from)
,m_out(a_from.m_out)
,m_fac(a_from.m_fac)
//,m_ndata(0)
,m_length(0)
,m_length_type(0)
,m_is_range(false)
,m_leaf_count(0)
,m_own_leaf_count(false)
{}
base_leaf& operator=(const base_leaf&){return *this;}
public:
const std::string& name() const {return m_name;}
const std::string& title() const {return m_title;}
const base_leaf* leaf_count() const {return m_leaf_count;}
/*
uint32 length() const {
// Return the number of effective elements of this leaf.
if(m_leaf_count) {
m_out << "tools::rroot::base_leaf::length :"
<< " m_leaf_count not null. Case not yet handled."
<< std::endl;
return m_length;
//uint32 len = m_leaf_count->number();
//if (len > fLeafCount->maximum()) {
// m_out << "tools::rroot::base_leaf::length :"
// << fName << ", len=" << len << " and max="
// << fLeafCount->maximum()
// << std::endl;
// len = fLeafCount->maximum();
//}
//return len * fLength;
} else {
return m_length;
}
}
*/
protected:
std::ostream& m_out;
ifac& m_fac;
protected: //Named
std::string m_name;
std::string m_title;
//bool fIndirectAddress;
//bool fNewValue;
//uint32 m_ndata; //! Number of elements in fAddress data buffer
uint32 m_length; // Number of fixed length elements
uint32 m_length_type; // Number of bytes for this data type
//int fOffset; // Offset in ClonesArray object (if one)
bool m_is_range; // (=true if leaf has a range, false otherwise)
//bool fIsUnsigned; // (=kTRUE if unsigned, kFALSE otherwise)
base_leaf* m_leaf_count; // Pointer to Leaf count if variable length
bool m_own_leaf_count;
};
}}
#endif
+366
View File
@@ -0,0 +1,366 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_basket
#define tools_rroot_basket
#include "iro"
#include "key"
#include "../scast"
#include "buffer"
#include "cids"
namespace tools {
namespace rroot {
class basket : public virtual iro, public key {
typedef key parent;
static uint32 kDisplacementMask() {return 0xFF000000;}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::basket");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<basket>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return basket_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<basket>(this,a_class)) {return p;}
else return 0;
}
public:
virtual iro* copy() const {return new basket(*this);}
virtual bool stream(buffer& a_buffer) {
_clear();
uint32 startpos = a_buffer.length();
if(!parent::from_buffer(a_buffer.byte_swap(),a_buffer.eob(),a_buffer.pos(),a_buffer.verbose())) return false;
uint32 fBufferSize;
short v;
if(!a_buffer.read_version(v)) return false;
if(!a_buffer.read(fBufferSize)) return false;
if(!a_buffer.read(m_nev_buf_size)) return false;
if(!a_buffer.read(m_nev)) return false;
if(!a_buffer.read(m_last)) return false;
char flag;
if(!a_buffer.read(flag)) return false;
if(m_last>fBufferSize) fBufferSize = m_last;
uint16 basket_key_length = a_buffer.length()-startpos;
if(basket_key_length!=m_key_length) {
//m_out << "tools::rroot::basket::stream :"
// << " key length not consistent."
// << " read " << m_key_length
// << ", expected " << basket_key_length
// << ". Continue with " << basket_key_length
// << std::endl;
m_key_length = basket_key_length;
}
if(!m_object_size) {
//m_out << "tools::rroot::basket::stream :"
// << " m_object_size is found to be zero."
// << " Continue with (m_nbytes-m_key_length) "
// << (m_nbytes-m_key_length)
// << std::endl;
m_object_size = m_nbytes-m_key_length;
}
if(!flag) return true; //fHeaderOnly
//G.Barrand : add the below test.
if( (flag!=1) &&(flag!=2) &&
(flag!=11)&&(flag!=12) &&
(flag!=41)&&(flag!=42) &&
(flag!=51)&&(flag!=52) ) {
m_out << "tools::rroot::basket::stream :"
<< " bad flag " << (int)flag
<< std::endl;
return false;
}
if((flag%10)!=2) {
//due to the upper "G.Barrand if", flag is here in {1,11,41,51}
if(!m_nev_buf_size) {
m_out << "tools::rroot::basket::stream :"
<< " m_nev_buf_size is zero." << std::endl;
return false;
}
if(m_nev>m_nev_buf_size) {
m_out << "tools::rroot::basket::stream :"
<< " m_nev>m_nev_buf_size !"
<< " m_nev " << m_nev
<< " m_nev_buf_size " << m_nev_buf_size
<< std::endl;
return false;
}
m_entry_offset = new int[m_nev_buf_size];
if(m_nev) {
uint32 n;
if(!a_buffer.read_array<int>(m_nev_buf_size,m_entry_offset,n)) {
_clear();
return false;
}
if((n!=m_nev)&&(n!=(m_nev+1))) {
m_out << "tools::rroot::basket::stream :"
<< " m_entry_offset read len mismatch."
<< " n " << n
<< " m_nev " << m_nev
<< std::endl;
_clear();
return false;
}
}
/* Due to the upper "G.Barrand if", flag can't be in ]20,40[, then to quiet Coverity we comment the below test.
if((20<flag)&&(flag<40)) {
for(uint32 i=0;i<m_nev;i++){
m_entry_offset[i] &= ~kDisplacementMask();
}
}
*/
if(flag>40) {
m_displacement = new int[m_nev_buf_size];
uint32 n;
if(!a_buffer.read_array<int>(m_nev_buf_size,m_displacement,n)) {
_clear();
return false;
}
if((n!=m_nev)&&(n!=(m_nev+1))) {
m_out << "tools::rroot::basket::stream :"
<< " m_displacement read len mismatch."
<< " n " << n
<< " m_nev " << m_nev
<< std::endl;
_clear();
return false;
}
}
} else {
//m_nev_buf_size is the size in bytes of one entry.
}
if((flag==1)||(flag>10)) {
delete [] m_buffer;
m_buffer = 0;
m_buf_size = 0;
if(fBufferSize) {
char* _buf = new char[fBufferSize];
if(!_buf) {
m_out << "tools::rroot::basket::stream :"
<< " can't alloc " << fBufferSize << std::endl;
_clear();
return false;
}
if(v>1) {
if(!a_buffer.read_fast_array(_buf,m_last)) {
_clear();
delete [] _buf;
return false;
}
} else {
uint32 n;
if(!a_buffer.read_array<char>(fBufferSize,_buf,n)) {
_clear();
delete [] _buf;
return false;
}
}
m_buffer = _buf;
m_buf_size = fBufferSize;
//fBufferRef->inline_setBufferOffset(m_last);
//fBranch.tree().incrementTotalBuffers(fBufferSize);
}
}
return true;
}
public:
basket(std::ostream& a_out)
:parent(a_out)
,m_nev_buf_size(0)
,m_nev(0)
,m_last(0)
,m_entry_offset(0)
,m_displacement(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
basket(std::ostream& a_out,seek a_pos,uint32 a_nbytes)
:parent(a_out,a_pos,a_nbytes)
,m_nev_buf_size(0)
,m_nev(0)
,m_last(0)
,m_entry_offset(0)
,m_displacement(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~basket(){
_clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
basket(const basket& a_from)
:iro(a_from)
,parent(a_from)
,m_nev_buf_size(a_from.m_nev_buf_size)
,m_nev(a_from.m_nev)
,m_last(a_from.m_last)
,m_entry_offset(0)
,m_displacement(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
if(a_from.m_nev && a_from.m_entry_offset) {
m_entry_offset = new int[a_from.m_nev];
if(!m_entry_offset) {
m_out << "tools::rroot::basket::basket(cpcstor) :"
<< " can't alloc " << a_from.m_nev << "."
<< std::endl;
} else {
uint32 len = a_from.m_nev*sizeof(int);
::memcpy(m_entry_offset,a_from.m_entry_offset,len);
}
}
if(a_from.m_nev && a_from.m_displacement) {
m_displacement = new int[a_from.m_nev];
if(!m_displacement) {
m_out << "tools::rroot::basket::basket(cpcstor) :"
<< " can't alloc " << a_from.m_nev << "."
<< std::endl;
} else {
uint32 len = a_from.m_nev*sizeof(int);
::memcpy(m_displacement,a_from.m_displacement,len);
}
}
}
basket& operator=(const basket& a_from){
parent::operator=(a_from);
if(&a_from==this) return *this;
m_nev_buf_size = a_from.m_nev_buf_size;
m_nev = a_from.m_nev;
m_last = a_from.m_last;
delete [] m_entry_offset;
m_entry_offset = 0;
delete [] m_displacement;
m_displacement = 0;
if(a_from.m_nev && a_from.m_entry_offset) {
m_entry_offset = new int[a_from.m_nev];
if(!m_entry_offset) {
m_out << "tools::rroot::basket::operator=() :"
<< " can't alloc " << a_from.m_nev << "."
<< std::endl;
} else {
uint32 len = a_from.m_nev*sizeof(int);
::memcpy(m_entry_offset,a_from.m_entry_offset,len);
}
}
if(a_from.m_nev && a_from.m_displacement) {
m_displacement = new int[a_from.m_nev];
if(!m_displacement) {
m_out << "tools::rroot::basket::operator=() :"
<< " can't alloc " << a_from.m_nev << "."
<< std::endl;
} else {
uint32 len = a_from.m_nev*sizeof(int);
::memcpy(m_displacement,a_from.m_displacement,len);
}
}
return *this;
}
public:
int* entry_offset() {return m_entry_offset;}
int* displacement() {return m_displacement;}
uint32 nev_buf_size() const {return m_nev_buf_size;}
uint32 nev() const {return m_nev;}
uint32 last() const {return m_last;}
bool read_offset_tables(bool a_byte_swap) {
if(!m_buffer) return false;
if(!m_last) return false;
delete [] m_entry_offset;
m_entry_offset = 0;
buffer _buffer(m_out,a_byte_swap,m_buf_size,m_buffer,0,false);
_buffer.set_offset(m_last);
{uint32 n;
if(!_buffer.read_array<int>(0,m_entry_offset,n)) {
m_out << "tools::rroot::basket::read_offset_tables :"
<< " read_array failed."
<< std::endl;
return false;
}
if((n!=m_nev)&&(n!=(m_nev+1))) {
m_out << "tools::rroot::basket::read_offset_tables :"
<< " m_entry_offset read len mismatch."
<< " n " << n
<< " m_nev " << m_nev
<< std::endl;
return false;
}}
delete [] m_displacement;
m_displacement = 0;
if(_buffer.length()!=_buffer.size()) {
// There is more data in the buffer! It is the diplacement
// array.
uint32 n;
if(!_buffer.read_array<int>(0,m_displacement,n)) {
m_out << "tools::rroot::basket::read_offset_tables :"
<< " readArray(2) failed."
<< std::endl;
return false;
}
if((n!=m_nev)&&(n!=(m_nev+1))) {
m_out << "tools::rroot::basket::read_offset_tables :"
<< " m_displacement read len mismatch."
<< " n " << n
<< " m_nev " << m_nev
<< std::endl;
return false;
}
}
return true;
}
protected:
void _clear(){
delete [] m_entry_offset;
delete [] m_displacement;
m_entry_offset = 0;
m_displacement = 0;
}
protected: //Named
uint32 m_nev_buf_size; //Length in Int_t of m_entry_offset
uint32 m_nev; //Number of entries in basket
uint32 m_last; //Pointer to last used byte in basket
int* m_entry_offset; //[m_nev] Offset of entries in fBuffer(TKey)
int* m_displacement; //![m_nev] Displacement of entries in fBuffer(TKey)
};
}}
#endif
+952
View File
@@ -0,0 +1,952 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_branch
#define tools_rroot_branch
#include "base_leaf"
#include "basket"
#include "obj_array"
#include "seek"
#include "ifile"
#include "ifac"
#include "../mnmx"
#include "../forit"
#include "../sprintf"
#include "dummy" //for TIOFeatures streaming.
#include <map>
namespace tools {
namespace rroot {
class branch : public virtual iro {
//static uint32 kDoNotProcess() {return (1<<10);} // Active bit for branches
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::branch");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<branch>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return branch_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<branch>(this,a_class)) {return p;}
else return 0;
}
public:
virtual iro* copy() const {return new branch(*this);}
virtual bool stream(buffer& a_buffer) {
_clear();
//::printf("debug : branch::stream : begin\n");
int fCompress;
int fBasketSize;
//int fNleaves;
//uint64 m_entries;
//uint64 m_tot_bytes;
//uint64 m_zip_bytes;
int fSplitLevel;
uint32 fMaxBaskets;
int fOffset;
unsigned int s,c;
//FIXME gROOT->SetReadingObject(kTRUE);
short vers;
if(!a_buffer.read_version(vers,s,c)) return false;
//::printf("debug : branch::stream : version %d count %d\n",vers,c);
if (vers > 5) {
//TBranch::Class()->ReadBuffer(b, this, v, s, c);
//gBranch = branchSave;
//fDirectory = gDirectory;
//fNleaves = m_leaves.GetEntriesFast();
//if (fFileName.Length() != 0) fDirectory = 0;
//gROOT->SetReadingObject(kFALSE);
//return;
}
//====process old versions before automatic schema evolution
{uint32 old = a_buffer.length();
uint32 id;
uint32 m_bits;
if(!Object_stream(a_buffer,id,m_bits)) return false;
a_buffer.set_offset(old);}
if(!Named_stream(a_buffer,m_name,m_title)) return false;
//::printf("debug : branch::stream %s %s\n",m_name.c_str(),m_title.c_str());
if(vers<=5) {
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(m_write_basket)) return false;
if(!a_buffer.read(m_entry_number)) return false;
{double v;
if(!a_buffer.read(v)) return false;
//m_entries = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
if(!a_buffer.read(fOffset)) return false;
} else if(vers<=6) {
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
if(!a_buffer.read(m_entry_number)) return false;
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
{double v;
if(!a_buffer.read(v)) return false;
//m_entries = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
} else if(vers<=7) {
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
if(!a_buffer.read(m_entry_number)) return false;
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(fSplitLevel)) return false;
{double v;
if(!a_buffer.read(v)) return false;
//m_entries = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
} else if(vers<=9) {
{short color,style;
if(!AttFill_stream(a_buffer,color,style)) return false;}
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
if(!a_buffer.read(m_entry_number)) return false;
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(fSplitLevel)) return false;
{double v;
if(!a_buffer.read(v)) return false;
//m_entries = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
} else if(vers<=10) {
{short color,style;
if(!AttFill_stream(a_buffer,color,style)) return false;}
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
{uint64 v;
if(!a_buffer.read(v)) return false;
m_entry_number = uint32(v);}
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(fSplitLevel)) return false;
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_entries = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = v;
}
} else { //vers>=11
{short color,style;
if(!AttFill_stream(a_buffer,color,style)) return false;}
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
{uint64 v;
if(!a_buffer.read(v)) return false;
m_entry_number = uint32(v);}
if(vers>=13) {
dummy _dummy;
if(!_dummy.stream(a_buffer)) { //TIOFeatures fIOFeatures
m_out << "tools::rroot::branch::stream : can't read (dummy) TIOFeatures." << std::endl;
return false;
}
}
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(fSplitLevel)) return false;
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_entries = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;} //fFirstEntry
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = v;
}
}
//::printf("debug : branch::stream : %s : fSplitLevel %d\n",m_name.c_str(),fSplitLevel);
//TObjArray
//::printf("debug : branch::stream : branches : begin\n");
{ifac::args args;
if(!m_branches.stream(a_buffer,args)) {
m_out << "tools::rroot::branch::stream :"
<< " can't read branches."
<< std::endl;
return false;
}}
//::printf("debug : branch::stream : branches : end %d\n",
// m_branches.size());
/* We see that with LHCb files.
if(m_entry_number!=m_entries) {
m_out << "tools::rroot::branch::stream :"
<< " for branch " << sout(m_name) << " :"
<< " WARNING : m_entry_number!=m_entries."
<< " m_entry_number " << m_entry_number
<< " m_entries " << m_entries
<< std::endl;
//return false;
}
*/
//TObjArray
//::printf("debug : branch::stream : leaves : begin\n");
{ifac::args args;
//args[ifac::arg_branch()] = this;
if(!m_leaves.stream(a_buffer,args)) {
m_out << "tools::rroot::branch::stream :"
<< " can't read leaves."
<< std::endl;
return false;
}}
//::printf("debug : branch::stream : leaves : end\n");
//TObjArray
//IMPORTANT : accept_null=true
//::printf("debug : branch::stream : streamed_baskets : begin\n");
{ifac::args args;
if(!m_streamed_baskets.stream(a_buffer,args,true)) {
m_out << "tools::rroot::branch::stream :"
<< " can't read baskets."
<< std::endl;
return false;
}}
//::printf("debug : branch::stream : streamed_baskets : end\n");
//fNleaves = m_leaves.size();
if(fMaxBaskets<=0) {
m_out << "tools::rroot::branch::stream :"
<< " fMaxBaskets null."
<< std::endl;
return false;
}
fBasketEntry = new int[fMaxBaskets];
fBasketBytes = new int[fMaxBaskets];
fBasketSeek = new seek[fMaxBaskets];
{for(uint32 i=0;i<fMaxBaskets;i++) {
fBasketEntry[i] = 0;
fBasketBytes[i] = 0;
fBasketSeek[i] = 0;
}}
if(vers<6) {
{uint32 n;
if(!a_buffer.read_array<int>(fMaxBaskets,fBasketEntry,n)) {
_clear();
return false;
}}
if(vers<=4) {
for (uint32 i=0;i<fMaxBaskets;i++) fBasketBytes[i] = 0;
} else {
uint32 n;
if(!a_buffer.read_array<int>(fMaxBaskets,fBasketBytes,n)) {
_clear();
return false;
}
}
if(vers<2) {
//GB : comment.
//for(int i=0;i<m_write_basket;i++) {
// fBasketSeek[i] = getBasket(i)->seekKey();
//}
m_out << "tools::rroot::branch::stream :"
<< " v < 2. Not (yet) handled."
<< std::endl;
_clear();
return false;
} else {
int n;
if(!a_buffer.read(n)) {
_clear();
return false;
}
for(int i=0;i<n;i++) {
seek32 _s;
if(!a_buffer.read(_s)) {
_clear();
return false;
}
fBasketSeek[i] = _s;
}
}
} else if(vers<=9) {
// See TStreamerInfo::ReadBuffer::ReadBasicPointer
//Int_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
if(!a_buffer.read_fast_array<int>(fBasketBytes,fMaxBaskets)) {
_clear();
return false;
}
}}
//Int_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
if(!a_buffer.read_fast_array<int>(fBasketEntry,fMaxBaskets)) {
_clear();
return false;
}
}}
//Seek_t[fMaxBaskets]
{char isBigFile;
if(!a_buffer.read(isBigFile)) {
_clear();
return false;
}
if(isBigFile==2) {
if(!a_buffer.read_fast_array<seek>(fBasketSeek,fMaxBaskets)) {
_clear();
return false;
}
} else {
for(uint32 i=0;i<fMaxBaskets;i++) {
seek32 _s;
if(!a_buffer.read(_s)) {
_clear();
return false;
}
fBasketSeek[i] = _s;
}
}}
} else { //vers>=10
// See TStreamerInfo::ReadBuffer::ReadBasicPointer
//Int_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
if(!a_buffer.read_fast_array<int>(fBasketBytes,fMaxBaskets)) {
_clear();
return false;
}
}}
//Long64_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
uint64* v = new uint64[fMaxBaskets];
if(!a_buffer.read_fast_array<uint64>(v,fMaxBaskets)) {
_clear();
return false;
}
for(uint32 i=0;i<fMaxBaskets;i++) fBasketEntry[i] = int(v[i]);
delete [] v;
}}
//Long64_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
uint64* v = new uint64[fMaxBaskets];
if(!a_buffer.read_fast_array<uint64>(v,fMaxBaskets)) {
_clear();
return false;
}
for(uint32 i=0;i<fMaxBaskets;i++) fBasketSeek[i] = v[i];
delete [] v;
}}
}
if(vers>2) {
//TString
std::string fileName;
if(!a_buffer.read(fileName)) {
_clear();
return false;
}
}
//FIXME if(vers<4) SetAutoDelete(kTRUE);
//FIXME gROOT->SetReadingObject(kFALSE);
if(!a_buffer.check_byte_count(s, c,"TBranch")) {
_clear();
return false;
}
//GB : analyse fBasketEntry.
m_first_last.clear();
{// There are (m_write_basket+1) sensitive elements in fBasketEntry :
// (Do we have to check that ?)
for(uint32 i=0;i<m_write_basket;i++) {
uint64 first = fBasketEntry[i];
uint64 last = fBasketEntry[i+1]-1;
m_first_last.push_back(std::pair<uint64,uint64>(first,last));
}
if(m_entry_number) {
uint64 first = fBasketEntry[m_write_basket];
uint64 last = m_entry_number-1;
m_first_last.push_back(std::pair<uint64,uint64>(first,last));
}}
//_dump_first_last();
//GB : analyse fBasketSeek :
{uint32 num = 0;
uint32 mxi = 0;
for(uint32 i=0;i<fMaxBaskets;i++) {
if(!fBasketSeek[i]) continue;
num++;
mxi = mx<uint32>(i,mxi);
}
if(m_write_basket) {
if((num!=m_write_basket)||(mxi!=(m_write_basket-1))) {
m_out << "tools::rroot::branch::stream :"
<< " fBasketSeek[] inconsistent with m_write_basket."
<< " m_write_basket " << m_write_basket
<< " num " << num
<< " mxi " << mxi
<< std::endl;
_clear();
return false;
}
}}
//GB : analyse m_streamed_baskets :
{int index = 0;
tools_vforcit(basket*,m_streamed_baskets,it) {
if(*it) {
if(!(*it)->buf()||!(*it)->buf_size()) {
m_out << "tools::rroot::branch::stream :"
<< " expect a basket with a not empty buffer."
<< std::endl;
return false;
}
//in the below, false is to say m_baskets is not owner of *it.
m_baskets[index] = std::pair<basket*,bool>(*it,false);
}
index++;
}}
return true;
}
public:
//virtual for branch_element
virtual bool read_leaves(ifile&,buffer& a_buffer){
tools_vforcit(base_leaf*,m_leaves,it) {
if(!(*it)->read_buffer(a_buffer)) {
m_out << "tools::rroot::branch::read_leaves :"
<< " read_buffer failed."
<< std::endl;
return false;
}
}
return true;
}
virtual bool find_entry(ifile& a_file,uint64 a_entry,uint32& a_nbytes){
// Read all leaves of entry and return total number of bytes :
// The input argument entry is the entry serial number in the current tree.
a_nbytes = 0;
//if(_test_bit(kDoNotProcess())) return true;
//if(fReadEntry == (int)a_entry) return true;
if(a_entry>=m_entry_number) {
//m_out << "tools::rroot::branch::find_entry :"
// << " for branch " << sout(m_name) << " :"
// << " a_entry not within [0," << m_entry_number << "[."
// << std::endl;
//return false;
return true; //CERN-ROOT does not consider it is an error.
}
if(!m_entry_number || m_first_last.empty() ) { //GB
m_out << "tools::rroot::branch::find_entry :"
<< " nothing to read."
<< std::endl;
return false; //nothing to read.
}
if(m_read_basket>=m_first_last.size()) {
m_out << "tools::rroot::branch::find_entry :"
<< " bad m_first_last access."
<< std::endl;
return false;
}
uint64 first = m_first_last[m_read_basket].first;
uint64 last = m_first_last[m_read_basket].second;
// Are we still in the same ReadBasket?
if((a_entry<first)||(a_entry>last)) {
m__read_basket = 0;
uint32 old_read_basket = m_read_basket;
//look first in the next basket window :
bool found = false;
if((m_read_basket+1)<m_first_last.size()) {
first = m_first_last[m_read_basket+1].first;
last = m_first_last[m_read_basket+1].second;
if((a_entry>=first)&&(a_entry<=last)) {
m_read_basket++;
found = true;
}
}
if(!found) {
uint32 count = 0;
typedef std::pair<uint64,uint64> first_last;
tools_vforcit(first_last,m_first_last,it) {
first = (*it).first;
last = (*it).second;
if((a_entry>=first)&&(a_entry<=last)) {
m_read_basket = count;
found = true;
break;
}
count++;
}
}
if(!found) { //something weird in fBasketEntry.
m_out << "tools::rroot::branch::find_entry :"
<< " fancy fBasketEntry."
<< std::endl;
return false;
} else {
// if found, erase m_baskets[old_read_basket] to avoid
// having all data in memory !
std::map<uint32, std::pair<basket*,bool> >::iterator it = m_baskets.find(old_read_basket);
if(it!=m_baskets.end()) {
if((*it).second.second) {
basket* bsk = (*it).second.first;
m_baskets.erase(it);
delete bsk;
//::printf("debug : erase basket %d\n",old_read_basket);
}
}
}
}
if(!m__read_basket) {
basket* bsk = 0;
std::map<uint32, std::pair<basket*,bool> >::iterator it = m_baskets.find(m_read_basket);
if(it!=m_baskets.end()) {
bsk = (*it).second.first;
} else {
if(m_read_basket>=m_write_basket) {
m_out << "tools::rroot::branch::find_entry :"
<< " basket lacking !"
<< " wanting index " << m_read_basket
<< ". fBasketSeek entries " << m_write_basket
<< std::endl;
return false;
}
if(!fBasketSeek[m_read_basket]) {
m_out << "tools::rroot::branch::find_entry :"
<< " fBasketSeek is null for index " << m_read_basket
<< std::endl;
return false;
}
if(!fBasketBytes[m_read_basket]) {
m_out << "tools::rroot::branch::find_entry :"
<< " fBasketBytes is null for index " << m_read_basket
<< std::endl;
return false;
}
bsk = get_basket(a_file,fBasketSeek[m_read_basket],fBasketBytes[m_read_basket]);
if(!bsk) {
m_out << "tools::rroot::branch::find_entry :"
<< " can't read basket " << m_read_basket
<< " at file pos " << fBasketSeek[m_read_basket]
<< " and size " << fBasketBytes[m_read_basket]
<< std::endl;
return false;
}
//m_out << "tools::rroot::branch::find_entry :"
// << " got basket " << m_read_basket
// << " of size " << fBasketBytes[m_read_basket]
// << std::endl;
m_baskets[m_read_basket] = std::pair<basket*,bool>(bsk,true);
}
m__read_basket = bsk;
}
// Set entry offset in buffer and read data from all leaves
//buf->resetMap();
uint32 bufbegin;
{int* entry_offset = m__read_basket->entry_offset();
if(entry_offset) {
uint32 index = uint32(a_entry-first);
if(index>=m__read_basket->nev()) {
m_out << "tools::rroot::branch::find_entry :"
<< " can't access entry offset " << index
<< ". nev " << m__read_basket->nev()
<< std::endl;
return false;
}
bufbegin = entry_offset[index];
//::printf("debug : xxx++ %u : %u\n",index,bufbegin);
} else {
bufbegin = (uint32)(m__read_basket->key_length() + (a_entry-first)*m__read_basket->nev_buf_size());
}}
{int* displacement = m__read_basket->displacement();
if(displacement) {
m_out << "tools::rroot::branch::find_entry :"
<< " not null displacement. Not yet handled."
<< std::endl;
//buf->setDisplacement(displacement[a_entry-first]);
} else {
//buf->setDisplacement();
}}
/*
if(bufbegin>=m__read_basket->buf_size()) {
m_out << "tools::rroot::branch::find_entry :"
<< " bad buffer access for entry " << a_entry
<< ". bufbegin " << bufbegin
<< ", buf_size " << basket->buf_size()
<< ", (entry-first) " << (a_entry-first)
<< std::endl;
{int* entry_offset = m__read_basket->entry_offset();
if(entry_offset) {
uint32 nev = m__read_basket->nev();
::printf("debug : eoff : num %d\n",nev);
for(uint32 i=0;i<nev;i++){
::printf("debug : eoff %d : %d\n",i,entry_offset[i]);
}
}}
return false;
}
*/
buffer _buffer(m_out,a_file.byte_swap(),m__read_basket->buf_size(),m__read_basket->buf(),0,false);
_buffer.set_offset(bufbegin);
_buffer.set_map_objs(true); //for MEMPHYS/applications/read.icc
if(!read_leaves(a_file,_buffer)) {
m_out << "tools::rroot::branch::find_entry :"
<< " can't read leaves for entry " << a_entry
<< ". read_basket was " << m_read_basket
<< ", first " << first
<< ", last " << last
<< "."
<< std::endl;
return false;
}
//fReadEntry = a_entry;
a_nbytes = _buffer.length() - bufbegin;
return true;
}
virtual bool show(std::ostream& a_out,ifile& a_file,uint64 a_entry) {
// Print values of all active leaves for entry :
// if entry==-1, print current entry (default)
uint32 n;
if(!find_entry(a_file,a_entry,n)) return false;
tools_vforcit(base_leaf*,m_leaves,it) {
base_leaf* bl = *it;
uint32 num = bl->num_elem();
num = mn<uint32>(num,10);
if(!num) continue;
{std::string s;
uint32 len = uint32(bl->name().size())+128;
sprintf(s,len," %-15s = ",bl->name().c_str());
a_out << s;}
for(uint32 i=0;i<num;i++) {
if(i) a_out << ", ";
bl->print_value(a_out,i);
}
a_out << std::endl;
}
return true;
}
public:
branch(std::ostream& a_out,ifac& a_fac)
:m_out(a_out)
,m_fac(a_fac)
,m_streamed_baskets(m_fac)
,m__read_basket(0)
//,m_bits(0)
,m_name("")
,m_title("")
,fAutoDelete(false)
,m_branches(m_fac)
,m_leaves(m_fac)
,fEntryOffsetLen(0)
,m_write_basket(0)
,m_entry_number(0)
,m_read_basket(0)
,fBasketBytes(0)
,fBasketEntry(0)
,fBasketSeek(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~branch(){
_clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
branch(const branch& a_from)
:iro(a_from)
,m_out(a_from.m_out),m_fac(a_from.m_fac)
,m_streamed_baskets(m_fac)
,m__read_basket(0)
,fAutoDelete(false)
,m_branches(m_fac)
,m_leaves(m_fac)
,fEntryOffsetLen(1000)
,m_write_basket(0)
,m_entry_number(0)
,m_read_basket(0)
,fBasketBytes(0)
,fBasketEntry(0)
,fBasketSeek(0)
{}
branch& operator=(const branch&){return *this;}
public:
uint32 entry_number() const {return m_entry_number;}
const std::string& name() const {return m_name;}
const std::string& title() const {return m_title;}
const std::vector<base_leaf*>& leaves() const {return m_leaves;}
const std::vector<branch*>& branches() const {return m_branches;}
protected:
basket* get_basket(ifile& a_file,seek a_pos,uint32 a_len) {
//if(fBranch.tree().memoryFull(fBufferSize)) fBranch.dropBaskets();
if(!a_len) return 0;
basket* _basket = new basket(m_out,a_pos,a_len); //basket is a key.
if(!_basket->read_file(a_file)) {
m_out << "tools::rroot::branch::get_basket :"
<< " read_file() failed."
<< std::endl;
delete _basket;
return 0;
}
{buffer _buffer(m_out,a_file.byte_swap(),a_len,_basket->buf(),0,false);
if(!_basket->stream(_buffer)) {
m_out << "tools::rroot::branch::get_basket :"
<< " basket stream failed."
<< std::endl;
delete _basket;
return 0;
}}
unsigned int sz;
char* buf = _basket->get_object_buffer(a_file,sz); //basket owns buf.
if(!buf) {
m_out << "tools::rroot::branch::get_basket :"
<< " get_object_buffer() failed."
<< std::endl;
delete _basket;
return 0;
}
if(_basket->seek_key()!=a_pos) { //consistency check.
m_out << "tools::rroot::branch::get_basket :"
<< " seek anomaly."
<< " a_pos " << a_pos
<< " seek_key() " << _basket->seek_key()
<< std::endl;
delete _basket;
return 0;
}
//if(_basket->nbytes()!=a_len) { //consistency check.
// m_out << "tools::rroot::branch::get_basket :"
// << " WARNING : length anomaly."
// << " a_len " << a_len
// << " nbytes() " << _basket->nbytes()
// << std::endl;
//}
if(fEntryOffsetLen) {
if(!_basket->read_offset_tables(a_file.byte_swap())) {
m_out << "tools::rroot::branch::get_basket :"
<< " read_offset_tables failed."
<< std::endl;
delete _basket;
return 0;
}}
return _basket;
}
protected:
void _clear() {
delete [] fBasketEntry;
delete [] fBasketBytes;
delete [] fBasketSeek;
fBasketEntry = 0;
fBasketBytes = 0;
fBasketSeek = 0;
{typedef std::pair<basket*,bool> basket_todel;
tools_mforit(uint32,basket_todel,m_baskets,it) {
if((*it).second.second) delete (*it).second.first;
}
m_baskets.clear();}
m_branches.cleanup();
m_leaves.cleanup();
m_streamed_baskets.cleanup();
}
void _dump_first_last() {
m_out << "tools::rroot::branch::_dump_first_last :"
<< " first_last " << m_first_last.size()
<< std::endl;
typedef std::pair<uint64,uint64> first_last;
tools_vforcit(first_last,m_first_last,it) {
uint64 first = (*it).first;
uint64 last = (*it).second;
m_out << "tools::rroot::branch::stream :"
<< " first " << first
<< " last " << last
<< std::endl;
}
}
//bool _test_bit(uint32 a_f) const {
// return (bool)(m_bits & a_f);
//}
protected:
std::ostream& m_out;
ifac& m_fac;
std::vector< std::pair<uint64,uint64> > m_first_last;
std::map<uint32, std::pair<basket*,bool> > m_baskets;
obj_array<basket> m_streamed_baskets;
basket* m__read_basket; //optimization
protected:
//Object
//uint32 m_bits;
//Named
std::string m_name;
std::string m_title;
bool fAutoDelete;
obj_array<branch> m_branches;
obj_array<base_leaf> m_leaves;
uint32 fEntryOffsetLen; // Initial Length of fEntryOffset table in the basket buffers
uint32 m_write_basket; // Last basket number written
uint32 m_entry_number; // Current entry number (last one filled in this branch)
uint32 m_read_basket; //! Current basket number when reading
int* fBasketBytes; //[fMaxBaskets] Length of baskets on file
int* fBasketEntry; //[fMaxBaskets] Table of first entry in eack basket
seek* fBasketSeek; //[fMaxBaskets] Addresses of baskets on file
};
}}
#endif
@@ -0,0 +1,796 @@
// 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 : inlib::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 : inlib::branch_element::stream : fClassName \"%s\"\n",fClassName.c_str());
std::string fParentName;
if(!a_buffer.read(fParentName)) return false;
//::printf("debug : inlib::branch_element::stream : fParentName \"%s\"\n",fParentName.c_str());
std::string fCloneName;
if(!a_buffer.read(fCloneName)) return false;
//::printf("debug : inlib::branch_element::stream : fCloneName \"%s\"\n",fCloneName.c_str());
int dummy_int;
if(!a_buffer.read(dummy_int)) return false; //fCheckSum
//::printf("debug : inlib::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 : inlib::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 : inlib::branch_element::stream : fID %d\n",fID);
if(!a_buffer.read(fType)) return false;
//::printf("debug : inlib::branch_element::stream : fType %d\n",fType);
if(!a_buffer.read(fStreamerType)) return false;
//::printf("debug : inlib::branch_element::stream : fStreamerType %d\n",fStreamerType);
if(!a_buffer.read(dummy_int)) return false; //fMaximum
//::printf("debug : inlib::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
*/
@@ -0,0 +1,67 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_branch_object
#define tools_rroot_branch_object
#include "branch"
namespace tools {
namespace rroot {
class branch_object : public branch {
typedef branch parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::branch_object");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<branch_object>(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_object_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<branch_object>(this,a_class)) {return p;}
return parent::cast(a_class);
}
public:
virtual bool stream(buffer& a_buffer) {
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!parent::stream(a_buffer)) return false;
if(!a_buffer.read(fClassName)) return false;
if(!a_buffer.check_byte_count(s,c,"TBranchObject")) return false;
return true;
}
public: //branch
public:
branch_object(std::ostream& a_out,ifac& a_fac)
:parent(a_out,a_fac)
//,m_obj(0)
,fClassName()
{}
virtual ~branch_object(){
//delete m_obj;
}
protected:
branch_object(const branch_object& a_from)
:iro(a_from),parent(a_from){}
branch_object& operator=(const branch_object&){return *this;}
public:
const std::string& class_name() const {return fClassName;}
// iro* object() {return m_obj;}
protected:
// iro* m_obj;
protected:
std::string fClassName; //Class name of referenced object
};
}}
#endif
+730
View File
@@ -0,0 +1,730 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_buffer
#define tools_rroot_buffer
#include "rbuf"
#include "ifac"
#include "iro"
#include "../sout"
#include "../mapmanip"
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include <string>
#include <vector>
#include <ostream>
// in TOOLS_STL, we don't have (yet) a performant map.
#ifdef tools_stl_vector
#define TOOLS_RROOT_OBJ_MAP_HASH_TABLE
//#define TOOLS_RROOT_OBJ_MAP_OMAP
#else
#define TOOLS_RROOT_OBJ_MAP_STD_MAP
#endif
#ifdef TOOLS_RROOT_OBJ_MAP_STD_MAP
#include <map>
#endif
#ifdef TOOLS_RROOT_OBJ_MAP_OMAP
#include "../omap"
#endif
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
#include "../hash_table"
#include "../hash"
#endif
namespace tools {
namespace rroot {
class buffer : public rbuf {
typedef rbuf parent;
static const std::string& s_class() {
static const std::string s_v("tools::rroot::buffer");
return s_v;
}
#ifdef TOOLS_RROOT_OBJ_MAP_STD_MAP
typedef std::map<uint32,iro*> obj_map;
#endif
#ifdef TOOLS_RROOT_OBJ_MAP_OMAP
typedef omap<uint32,iro*> obj_map;
#endif
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
class obj_map : public hash_table<uint32,iro*> {
typedef hash_table<uint32,iro*> parent;
protected:
virtual unsigned int hash(const uint32& a_key) {
return hash(&a_key,sizeof(uint32));
}
virtual bool cmp(const uint32& a_key1,const uint32& a_key2) {
return a_key1==a_key2?true:false;
}
public:
obj_map():parent(){}
virtual ~obj_map(){}
private:
obj_map(const obj_map& a_from):parent(a_from){}
obj_map& operator=(const obj_map& a_from){
parent::operator=(a_from);
return *this;
}
};
#endif
public:
buffer(std::ostream& a_out,bool a_byte_swap,uint32 a_size,char* a_buffer,uint32 a_klen,bool a_verbose)
:parent(a_out,a_byte_swap,a_buffer+a_size,m_pos)
,m_byte_swap(a_byte_swap)
,m_verbose(a_verbose)
//,m_verbose(true)
,m_size(a_size) //expect a not zero size.
,m_buffer(a_buffer) //don't get ownership.
,m_pos(a_buffer)
,m_klen(a_klen) //to compute refs (used in read_class, read_object)
//,m_map_objs(false)
,m_map_objs(true)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~buffer(){
m_objs.clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
buffer(const buffer& a_from)
:parent(a_from.m_out,a_from.m_byte_swap,0,m_pos)
,m_byte_swap(a_from.m_byte_swap)
,m_map_objs(a_from.m_map_objs)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
buffer& operator=(const buffer&){return *this;}
public:
bool byte_swap() const {return m_byte_swap;}
bool verbose() const {return m_verbose;}
void set_offset(unsigned int a_off) {m_pos = m_buffer+a_off;}
//char* buffer() const {return m_buffer;}
uint32 length() const {return uint32(m_pos-m_buffer);}
uint32 size() const {return m_size;}
void set_map_objs(bool a_value) {m_map_objs = a_value;}
bool map_objs() const {return m_map_objs;}
protected:
// on first_int :
static uint32 kNullTag() {return 0;}
static uint32 kByteCountMask() {return 0x40000000;}
// on tag :
static uint32 kNewClassTag() {return 0xFFFFFFFF;}
static uint32 kClassMask() {return 0x80000000; }
static uint32 kMapOffset() {return 2;}
static short kByteCountVMask() {return 0x4000;}
bool read_class_tag(std::string& a_class) {
a_class.clear();
uint32 tag;
if(!parent::read(tag)) return false;
if(tag==kNewClassTag()) {
char s[80];
if(!read_string(s, 80)) {
m_out << "tools::rroot::read_class_tag :"
<< " read string." << std::endl;
return false;
}
//m_out << "tools::rroot::read_class_tag :"
// << " tag kNewClassTag"
// << " class " << s
// << std::endl;
a_class = s;
return true;
} else if(tag & kClassMask()) {
//m_out << "tools::rroot::read_class_tag :"
// << " tag & kClassMask"
// << " ref " << (uint32)(tag & ~kClassMask)
// << " recurse..."
// << std::endl;
unsigned int cl_offset = (tag & ~kClassMask());
cl_offset -= kMapOffset();
cl_offset -= m_klen;
char* old_pos = m_pos;
m_pos = m_buffer + cl_offset;
//std::string scls;
//uint32 ref;
if(!read_class_tag(a_class)) return false;
m_pos = old_pos;
return true;
} else {
std::ios::fmtflags old_flags = m_out.flags();
m_out << "tools::rroot::read_class_tag :"
<< " tag unknown case ! "
<< tag << " hex " << std::hex << tag
<< std::endl;
m_out.flags(old_flags);
return false;
}
}
bool read_class(std::string& a_class,uint32& a_bcnt,bool& a_is_ref){
//m_verbose = true;
a_class.clear();
a_bcnt = 0;
a_is_ref = false;
//uint32 fVersion = 0; //Buffer format version
// read byte count and/or tag (older files don't have byte count)
uint32 first_int = 0;
if(!parent::read(first_int)) return false;
if(m_verbose) {
std::ios::fmtflags old_flags = m_out.flags();
m_out << "tools::rroot::read_class :"
<< " first_int " << std::hex << first_int
<< std::endl;
m_out.flags(old_flags);
}
if(first_int==kNullTag()) { //GB
if(m_verbose) {
m_out << "tools::rroot::read_class :"
<< " first_int is kNullTag."
<< std::endl;
}
a_bcnt = 0;
return true;
//} else if(first_int==kNewClassTag()) { // class desc follows.
} else if(first_int & kByteCountMask()) {
// at write :
// skip int to store bcnt.
// + write class
// if(!write((clIdx | Rio_kClassMask))) return false;
// or
// if(!write(Rio_kNewClassTag)) return false;
// + write object
// + set byte cnt (cnt|kByteCountMask()) at skipped int.
if(m_verbose) {
m_out << "tools::rroot::read_class :"
<< " first_int & kByteCountMask."
<< std::endl;
}
uint32 bef_tag = uint32(m_pos-m_buffer);
//fVersion = 1;
std::string scls;
if(!read_class_tag(scls)) return false;
if(scls.empty()) {
m_out << "tools::rroot::buffer::read_class :"
<< " read_class_tag did not find a class name."
<< std::endl;
return false;
}
a_class = scls;
a_bcnt = (first_int & ~kByteCountMask());
if(m_verbose) {
m_out << "tools::rroot::read_class :"
<< " kNewClassTag : read class name " << sout(a_class)
<< " a_bcnt " << a_bcnt
<< " bef_tag " << bef_tag
<< "." << std::endl;
}
return true;
} else {
if(m_verbose) {
std::ios::fmtflags old_flags = m_out.flags();
m_out << "tools::rroot::read_class :"
<< " first_int " << std::hex << first_int
<< ". first_int is position toward object."
<< std::endl;
m_out.flags(old_flags);
}
a_bcnt = first_int; //pos toward object.
a_is_ref = true;
a_class.clear();
return true;
}
return false;
}
public:
void remove_in_map(iro* a_obj) {
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
m_out << "tools::rroot::remove_in_map : dummy." << std::endl;
#else
find_and_remove_value(m_objs,a_obj);
#endif
}
bool read_object(ifac& a_fac,const ifac::args& a_args,iro*& a_obj,bool& a_created){
a_obj = 0;
a_created = false;
//m_out << "debug : tools::rroot::buffer::read_object : begin :" << std::endl;
// before reading object save start position
uint32 startpos = (uint32)(m_pos-m_buffer);
uint32 bcnt;
std::string sclass;
bool is_ref;
if(!read_class(sclass,bcnt,is_ref)) {
m_out << "tools::rroot::buffer::read_object :"
<< " can't read class." << std::endl;
return false;
}
//::printf("debug : %d\n",length()-startpos);
if(m_verbose) {
m_out << "tools::rroot::buffer::read_object :"
<< " class " << sout(sclass) << ", is_ref " << is_ref
<< ", bcnt " << bcnt
<< std::endl;
}
if(is_ref) { //bcnt is the position toward an object or an object ref.
//m_out << "debug : tools::rroot::buffer::read_object : is_ref : bcnt " << bcnt << std::endl;
unsigned int obj_offset = bcnt;
obj_offset -= kMapOffset();
obj_offset -= m_klen;
if(!m_map_objs) {
m_out << "tools::rroot::buffer::read_object : warning :"
<< " class " << sout(sclass) << ", is_ref but map objs is not enabled on this buffer."
<< std::endl;
}
if(m_map_objs) {
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
if(m_objs.find(obj_offset,a_obj)) {
//m_out << "debug : tools::rroot::buffer::read_object : found object in map." << bcnt << std::endl;
return true;
}
#else
obj_map::const_iterator it = m_objs.find(obj_offset);
if(it!=m_objs.end()) {
a_obj = (*it).second;
//::printf("debug : find : %d %lu\n",obj_offset,a_obj);
//stay at current m_pos ?
return true;
}
#endif
}
{char* old_pos = m_pos;
m_pos = m_buffer + obj_offset;
uint32 first_int;
if(!parent::read(first_int)) {
m_out << "tools::rroot::buffer::read_object : parent::read(first_int) failed." << std::endl;
return false;
}
if(first_int & kByteCountMask()) {
std::string scls;
if(!read_class_tag(scls)) {
m_out << "tools::rroot::buffer::read_object : read_class_tag() failed." << std::endl;
return false;
}
if(scls.empty()) {
m_out << "tools::rroot::buffer::read_object :"
<< " read_class_tag did not find a class name."
<< std::endl;
return false;
}
//m_out << "tools::rroot::buffer::read_object :"
// << " is_ref : class " << sout(scls)
// << std::endl;
iro* obj = a_fac.create(scls,a_args);
if(!obj) {
m_out << "tools::rroot::buffer::read_object : is_ref : creation of object"
<< " of class " << sout(sclass) << " failed." << std::endl;
return false;
}
if(m_map_objs) {
//must be done before stream()
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
if(!m_objs.insert(obj_offset,obj)) {
m_out << "tools::rroot::buffer::read_object :"
<< " map insert failed."
<< std::endl;
}
#else
m_objs[obj_offset] = obj;
#endif
}
if(!obj->stream(*this)) {
m_out << "tools::rroot::buffer::read_object :"
<< " is_ref : streamed failed for class " << sout(scls)
<< std::endl;
//restore a good buffer position :
//m_pos = m_buffer+startpos+sizeof(unsigned int);
delete obj;
return false;
}
//m_out << "tools::rroot::buffer::read_object :"
// << " is_ref : streamed ok for class " << sout(scls)
// << std::endl;
a_obj = obj;
a_created = true;
} else {
m_out << "tools::rroot::buffer::read_object :"
<< " is_ref : zzz"
<< std::endl;
}
m_pos = old_pos;}
// in principle at this point m_pos should be
// m_buffer+startpos+sizeof(unsigned int)
// but enforce it anyway :
m_pos = m_buffer+startpos+sizeof(unsigned int);
//check_byte_count(startpos,0,sclass) would always be ok.
//a_obj = ???
} else {
if(sclass.empty()) {
//m_out << "debug : tools::rroot::buffer::read_object : found empty class name." << std::endl;
m_pos = m_buffer+startpos+bcnt+sizeof(unsigned int);
} else {
//m_out << "debug : tools::rroot::buffer::read_object : not a ref, create object." << std::endl;
// Being not a ref, it must NOT be in the map.
// We gain a lot by not doing the below find.
/*
if(m_map_objs) {
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
if(m_objs.find(startpos,a_obj)) return true;
#else
obj_map::const_iterator it = m_objs.find(startpos);
if(it!=m_objs.end()) {
a_obj = (*it).second;
::printf("debug : find xxx : %d %lu\n",startpos,a_obj);
//stay at current m_pos ?
return true;
}
#endif
}
*/
iro* obj = a_fac.create(sclass,a_args);
if(!obj) {
m_out << "tools::rroot::buffer::read_object : creation of object"
<< " of class " << sout(sclass) << " failed." << std::endl;
return false;
}
//m_out << "debug : tools::rroot::buffer::read_object : object created." << std::endl;
if(m_map_objs) {
//must be done before stream()
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
if(!m_objs.insert(startpos,obj)) {
m_out << "tools::rroot::buffer::read_object :"
<< " map insert failed."
<< std::endl;
}
#else
m_objs[startpos] = obj;
#endif
}
//::printf("debug : map : %d %lu\n",startpos,obj);
//NOTE : if class ref, "up there"-startpos = 8.
if(!obj->stream(*this)) {
m_out << "tools::rroot::buffer::read_object : object.stream() failed"
<< " for object of class " << sout(sclass) << "." << std::endl;
//restore a good buffer position :
//m_pos = m_buffer+startpos+bcnt+sizeof(unsigned int);
delete obj;
return false;
}
//NOTE : if obj stream ok, the below line is not needed.
//m_pos = m_buffer+startpos+bcnt+sizeof(unsigned int);
if(!check_byte_count(startpos,bcnt,sclass)) {
m_out << "tools::rroot::buffer::read_object :"
<< " check_byte_count failed "
<< "for object of class "
<< sout(sclass) << "." << std::endl;
delete obj;
return false;
}
a_obj = obj;
a_created = true;
}
}
if(m_verbose) {
m_out << "tools::rroot::buffer::read_object : end." << std::endl;
}
return true;
}
public:
bool read_version(short& a_version){
// Read class version from I/O buffer.
// Is read a short or three shorts.
a_version = 0;
short version = 0;
// not interested in byte count
if(!parent::read(version)) return false;
// if this is a byte count, then skip next short and read version
if(version & kByteCountVMask()) {
if(!parent::read(version)) return false;
if(!parent::read(version)) return false;
}
a_version = version;
return true;
}
bool read_version(short& a_version,uint32& a_start_pos,uint32& a_byte_count){
// Read class version from I/O buffer.
// Is read one or three shorts.
a_version = 0;
a_start_pos = 0;
a_byte_count = 0;
short version = 0;
// before reading object save start position
uint32 startpos = (uint32)(m_pos-m_buffer);
// read byte count (older files don't have byte count)
// byte count is packed in two individual shorts, this to be
// backward compatible with old files that have at this location
// only a single short (i.e. the version)
union {
unsigned int cnt;
short vers[2];
} v;
if(m_byte_swap) {
if(!parent::read(v.vers[1])) return false;
if(!parent::read(v.vers[0])) return false;
} else {
if(!parent::read(v.vers[0])) return false;
if(!parent::read(v.vers[1])) return false;
}
// no bytecount, backup and read version
uint32 bcnt = 0;
if(v.cnt & kByteCountMask()) {
bcnt = (v.cnt & ~kByteCountMask());
} else {
m_pos -= sizeof(unsigned int);
}
if(!parent::read(version)) return false;
//printf("Reading version=%d at pos=%d, bytecount=%d\n",
//version,*startpos,*bcnt);
a_version = version;
a_start_pos = startpos;
a_byte_count = bcnt;
return true;
}
bool check_byte_count(uint32 a_start_pos,uint32 a_byte_count,const std::string& a_store_cls){
if(!a_byte_count) return true;
size_t len = a_start_pos + a_byte_count + sizeof(unsigned int);
size_t diff = size_t(m_pos-m_buffer);
if(diff==len) return true;
if(diff<len) {
m_out << "tools::rroot::buffer::check_byte_count :"
<< " object of class " << sout(a_store_cls)
<< " read too few bytes ("
<< long_out(long(len-diff)) << " missing)."
<< std::endl;
}
if(diff>len) {
m_out << "tools::rroot::buffer::check_byte_count :"
<< " object of class " << sout(a_store_cls)
<< " read too many bytes ("
<< long_out(long(diff-len)) << " in excess)." << std::endl;
}
m_out << "tools::rroot::buffer::check_byte_count :"
<< " " << sout(a_store_cls)
<< " streamer not in sync with data on file, fix streamer."
<< std::endl;
m_pos = m_buffer+len;
return false;
}
protected:
bool read_string(char* a_string,uint32 a_max) {
// Read string from I/O buffer. String is read till 0 character is
// found or till max-1 characters are read (i.e. string s has max
// bytes allocated).
int nr = 0;
while (nr < int(a_max-1)) {
char ch;
if(!parent::read(ch)) return false;
// stop when 0 read
if(ch == 0) break;
a_string[nr++] = ch;
}
a_string[nr] = 0;
return true;
}
protected:
// buffer objects cannot be copied or assigned
//void checkCount(unsigned int);
//unsigned int checkObject(unsigned int,const IClass*,bool = false);
protected:
bool m_byte_swap;
bool m_verbose;
uint32 m_size;
char* m_buffer;
char* m_pos;
uint32 m_klen; //GB
bool m_map_objs;
obj_map m_objs;
};
inline bool dummy_TXxx_pointer_stream(buffer& a_buffer,ifac& a_fac) {
ifac::args args;
iro* obj;
bool created;
bool status = a_buffer.read_object(a_fac,args,obj,created);
if(obj) {
if(created) {
if(a_buffer.map_objs()) a_buffer.remove_in_map(obj);
delete obj;
}
}
return status;
}
template <class T>
inline bool pointer_stream(buffer& a_buffer,
ifac& a_fac,ifac::args& a_args,
const std::string& a_T_class,
T*& a_obj,bool& a_created){
iro* obj;
if(!a_buffer.read_object(a_fac,a_args,obj,a_created)) {
a_buffer.out() << "tools::rroot::pointer_stream : read_object failed." << std::endl;
a_obj = 0;
a_created = false;
return false;
}
if(!obj) {
a_obj = 0;
a_created = false;
} else {
a_obj = (T*)obj->cast(a_T_class);
if(!a_obj) {
a_buffer.out() << "tools::rroot::pointer_stream : "
<< " inlib::cast to " << a_T_class << " failed."
<< ". Object is a " << obj->s_cls() << "."
<< std::endl;
if(a_created) delete obj;
a_created = false;
return false;
}
}
return true;
}
template <class T>
inline bool pointer_stream(buffer& a_buffer,
ifac& a_fac,ifac::args& a_args,
cid a_T_class,
T*& a_obj,bool& a_created){
iro* obj;
if(!a_buffer.read_object(a_fac,a_args,obj,a_created)) {
a_buffer.out() << "tools::rroot::pointer_stream : read_object failed." << std::endl;
a_obj = 0;
a_created = false;
return false;
}
if(!obj) {
a_obj = 0;
a_created = false;
} else {
a_obj = (T*)obj->cast(a_T_class);
if(!a_obj) {
a_buffer.out() << "tools::rroot::pointer_stream : "
<< " inlib::cast to " << a_T_class << " failed."
<< ". Object is a " << obj->s_cls() << "."
<< std::endl;
if(a_created) delete obj;
a_created = false;
return false;
}
}
return true;
}
template <class T>
inline bool pointer_stream(buffer& a_buffer,ifac& a_fac,ifac::args& a_args,T*& a_obj,bool& a_created){
//return pointer_stream(a_buffer,a_fac,a_args,T::s_class(),a_obj,a_created);
return pointer_stream(a_buffer,a_fac,a_args,T::id_class(),a_obj,a_created);
}
template <class T>
inline bool fixed_array_stream(buffer& a_buffer,int a_n,T*& a_v){
delete [] a_v;
a_v = 0;
char is_array;
if(!a_buffer.read(is_array)) return false;
if(!is_array) return true;
if(!a_n) return true;
a_v = new T[a_n];
if(!a_buffer.read_fast_array<T>(a_v,a_n)) {
delete [] a_v;
a_v = 0;
return false;
}
return true;
}
}}
#endif
+57
View File
@@ -0,0 +1,57 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_cids
#define tools_rroot_cids
//NOTE : logic must be in sync with wroot/cids.
#include "../cid"
namespace tools {
namespace rroot {
inline cid base_cid() {return 100;} //must be > cids in ../cids.
inline cid iros_cid() {return base_cid()+0;}
inline cid obj_list_cid() {return base_cid()+1;}
inline cid hash_list_cid() {return base_cid()+2;}
inline cid obj_array_cid() {return base_cid()+3;}
inline cid dummy_cid() {return base_cid()+4;}
inline cid basket_cid() {return base_cid()+5;}
inline cid branch_cid() {return base_cid()+6;}
inline cid branch_element_cid() {return base_cid()+7;}
//inline cid tree_item() {return base_cid()+8;}
inline cid graph_cid() {return base_cid()+9;}
inline cid matrix_cid() {return base_cid()+10;}
inline cid leaf_string_cid() {return base_cid()+11;}
inline cid leaf_element_cid() {return base_cid()+12;}
inline cid streamer_info_cid() {return base_cid()+13;}
inline cid streamer_element_cid() {return base_cid()+14;}
inline cid stl_vector_string_cid() {return base_cid()+16;}
inline cid named_cid() {return base_cid()+17;}
inline cid leaf_object_cid() {return base_cid()+18;}
inline cid branch_object_cid() {return base_cid()+19;}
//base for templates :
inline cid base_leaf_cid() {return base_cid()+20;} //+12=32
//NOTE : leaf<T> = base_leaf_cid()+_cid(T)
inline cid stl_vector_cid() {return base_cid()+33;} //+12=45
inline cid stl_vector_vector_cid() {return base_cid()+46;} //+12=58
inline cid clones_array_cid() {return base_cid()+60;}
inline cid vector3_cid() {return base_cid()+61;}
inline cid stl_vector_obj_cid() {return base_cid()+100;}
}}
#endif
+69
View File
@@ -0,0 +1,69 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_clss
#define tools_rroot_clss
#include <string>
namespace tools {
namespace rroot {
inline const std::string& TH1F_cls(){
static const std::string s_v("TH1F");
return s_v;
}
inline const std::string& TH1D_cls(){
static const std::string s_v("TH1D");
return s_v;
}
inline const std::string& TH2F_cls(){
static const std::string s_v("TH2F");
return s_v;
}
inline const std::string& TH2D_cls(){
static const std::string s_v("TH2D");
return s_v;
}
inline const std::string& TH3D_cls(){
static const std::string s_v("TH3D");
return s_v;
}
inline const std::string& TProfile_cls(){
static const std::string s_v("TProfile");
return s_v;
}
inline const std::string& TProfile2D_cls(){
static const std::string s_v("TProfile2D");
return s_v;
}
inline const std::string& TDirectory_cls(){
static const std::string s_v("TDirectory");
return s_v;
}
inline const std::string& TGeoManager_cls(){
static const std::string s_v("TGeoManager");
return s_v;
}
inline const std::string& TList_cls(){
static const std::string s_v("TList");
return s_v;
}
inline const std::string& TNamed_cls(){
static const std::string s_v("TNamed");
return s_v;
}
}}
#endif
+14
View File
@@ -0,0 +1,14 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_date
#define tools_rroot_date
namespace tools {
namespace rroot {
typedef unsigned int date;
}}
#endif
+195
View File
@@ -0,0 +1,195 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_directory
#define tools_rroot_directory
#include "seek"
#include "date"
#include "key"
#include "ifile"
#include "../forit"
#include "../vmanip"
namespace tools {
namespace rroot {
class directory {
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::directory");
return s_v;
}
public:
directory(ifile& a_file)
:m_file(a_file)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_date_C = 0; //.set();
m_date_M = 0; //.set();
m_nbytes_keys = 0;
m_nbytes_name = 0;
m_seek_directory = 0;
m_seek_parent = 0;
m_seek_keys = 0;
}
virtual ~directory(){
clear_keys();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
directory(const directory& a_from):m_file(a_from.m_file){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
directory& operator=(const directory &){return *this;}
public:
ifile& file() {return m_file;}
const std::vector<key*>& keys() const {return m_keys;}
std::vector<key*>& keys() {return m_keys;}
key* find_key(const std::string& a_name) {
if(m_file.verbose()) {
m_file.out() << "tools::rroot::directory::find_key :"
<< " " << sout(a_name) << " ..."
<< std::endl;
}
tools_vforcit(key*,m_keys,it) {
if((*it)->object_name()==a_name) return *it;
}
return 0;
}
key* find_key_from_class(const std::string& a_class) {
if(m_file.verbose()) {
m_file.out() << "tools::rroot::directory::find_key_from_class :"
<< " " << sout(a_class) << " ..."
<< std::endl;
}
tools_vforcit(key*,m_keys,it) {
if((*it)->object_class()==a_class) return *it;
}
return 0;
}
uint32 nbytes_name() const {return m_nbytes_name;}
seek seek_keys() const {return m_seek_keys;}
uint32 record_size(uint32 a_version) const {
uint32 nbytes = sizeof(short);
nbytes += sizeof(date); //m_date_C.record_size();
nbytes += sizeof(date); //m_date_M.record_size();
nbytes += sizeof(m_nbytes_keys);
nbytes += sizeof(m_nbytes_name);
if(a_version>=40000) {
nbytes += sizeof(seek);
nbytes += sizeof(seek);
nbytes += sizeof(seek);
} else {
nbytes += sizeof(seek32);
nbytes += sizeof(seek32);
nbytes += sizeof(seek32);
}
return nbytes;
}
bool from_buffer(const char* aEOB,char*& a_buffer){
// Decode input buffer.
// (Name, title) are stored in the (name, title) of the associated key.
rbuf rb(m_file.out(),m_file.byte_swap(),aEOB,a_buffer);
short versiondir;
if(!rb.read(versiondir)) return false;
unsigned int _date;
if(!rb.read(_date)) return false;
//fDateC.setDate(_date);
if(!rb.read(_date)) return false;
//fDateM.setDate(_date);
{int v;
if(!rb.read(v)) return false;
m_nbytes_keys = v;}
{int v;
if(!rb.read(v)) return false;
m_nbytes_name = v;}
if(versiondir>(short)big_file_version_tag()) {
if(!rb.read(m_seek_directory)) return false;
if(!rb.read(m_seek_parent)) return false;
if(!rb.read(m_seek_keys)) return false;
} else {
{seek32 i;
if(!rb.read(i)) return false;
m_seek_directory = i;}
{seek32 i;
if(!rb.read(i)) return false;
m_seek_parent = i;}
{seek32 i;
if(!rb.read(i)) return false;
m_seek_keys = i;}
}
if(m_file.verbose()) {
m_file.out() << "tools::rroot::key::from_buffer :"
<< " nbytes keys : " << m_nbytes_keys
<< ", pos keys : " << m_seek_keys
<< std::endl;
}
return true;
}
bool read_keys(uint32& a_number) {
// Read the KEYS :
// Every directory has a list (fKeys). This list has been
// written on the file via CERN-ROOT::TDirectory::writeKeys
// as a single data record.
a_number = 0;
clear_keys();
key headerkey(m_file.out(),m_seek_keys,m_nbytes_keys);
if(!headerkey.read_file(m_file)) return false;
char* buffer = headerkey.data_buffer();
if(!headerkey.from_buffer(m_file.byte_swap(),headerkey.eob(),buffer,m_file.verbose())) return false;
int nkeys = 0;
rbuf rb(m_file.out(),m_file.byte_swap(),headerkey.eob(),buffer);
if(!rb.read(nkeys)) return false;
if(m_file.verbose()) {
m_file.out() << "tools::rroot::directory::read_keys :"
<< " nkeys " << nkeys
<< "."
<< std::endl;
}
for(int i=0;i<nkeys;i++) {
key* k = new key(m_file.out());
if(!k->from_buffer(m_file.byte_swap(),headerkey.eob(),buffer,m_file.verbose())) {
delete k;
return false;
}
m_keys.push_back(k);
}
a_number = nkeys;
return true;
}
void clear_keys() {
safe_clear<key>(m_keys);
}
protected:
ifile& m_file;
std::vector<key*> m_keys;
// Record (stored in file):
date m_date_C; //Date and time when directory is created
date m_date_M; //Date and time of last modification
uint32 m_nbytes_keys; //Number of bytes for the keys
uint32 m_nbytes_name; //Number of bytes in TNamed at creation time
seek m_seek_directory; //Location of directory on file
seek m_seek_parent; //Location of parent directory on file
seek m_seek_keys; //Location of Keys record on file
};
}}
#endif
+74
View File
@@ -0,0 +1,74 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_dummy
#define tools_rroot_dummy
// dummy class with a generic streamer.
// It is used within the reading of a tree
// to create some generic object when we get
// from the file a class name which is unknown
// from the tree factory.
#include "iro"
#include "buffer"
#include "../scast"
#include "cids"
namespace tools {
namespace rroot {
class dummy : public virtual iro {
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::dummy");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<dummy>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return dummy_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<dummy>(this,a_class)) {return p;}
return 0;
}
public:
virtual iro* copy() const {return new dummy(*this);}
virtual bool stream(buffer& a_buffer) {
//the below code skips correctly the data in the file.
uint32 startpos = a_buffer.length();
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
a_buffer.set_offset(startpos+c+sizeof(unsigned int));
if(!a_buffer.check_byte_count(s,c,"dummy")) return false;
return true;
}
public:
dummy(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~dummy(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
dummy(const dummy& a_from): iro(a_from){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
dummy& operator=(const dummy&){return *this;}
};
}}
#endif
+73
View File
@@ -0,0 +1,73 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_dummy_fac
#define tools_rroot_dummy_fac
//#include "info"
//#include "iros"
#include "graph"
namespace tools {
namespace rroot {
class dummy_fac : public virtual ifac {
public: //ifac
virtual std::ostream& out() const {return m_out;}
virtual iro* create(const std::string& a_class,const args& /*a_args*/) {
if(rcmp(a_class,"TGraph")) { //for TH_read_1D/List.
return new graph();
/*
} else if(rcmp(a_class,"TObjArray")) {
std::string* sc = ifac::arg_class(a_args);
if(sc) {
if((*sc)==streamer_element::s_class()){
return new obj_array<streamer_element>(*this);
} else {
m_out << "tools::rroot::dummy_fac::create :"
<< " Can't create TObjArray of " << *sc << "."
<< std::endl;
return 0;
}
} else {
return new iros(*this);
}
*/
/*
// for read_sinfos() :
} else if(rcmp(a_class,"TStreamerInfo")) {
return new streamer_info(*this);
} else if(rcmp(a_class,"TStreamerBase")
||rcmp(a_class,"TStreamerBasicType")
||rcmp(a_class,"TStreamerBasicPointer")
||rcmp(a_class,"TStreamerObjectAny")
||rcmp(a_class,"TStreamerObject")
||rcmp(a_class,"TStreamerObjectPointer")
||rcmp(a_class,"TStreamerString")
||rcmp(a_class,"TStreamerSTL")
||rcmp(a_class,"TStreamerLoop")
||rcmp(a_class,"TList")
) {
return new dummy_streamer_element();
*/
} else {
m_out << "tools::rroot::dummy_fac::create :"
<< " dummy. Can't create object of class " << sout(a_class) << "."
<< std::endl;
}
return 0;
}
public:
dummy_fac(std::ostream& a_out):m_out(a_out){}
virtual ~dummy_fac(){}
protected:
dummy_fac(const dummy_fac& a_from): ifac(a_from),m_out(a_from.m_out){}
dummy_fac& operator=(const dummy_fac&){return *this;}
protected:
std::ostream& m_out;
};
}}
#endif
+168
View File
@@ -0,0 +1,168 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_fac
#define tools_rroot_fac
#include "../sout"
#include "../S_STRING"
#include "branch_element"
#include "branch_object"
#include "leaf"
#include "basket"
#include "tree_index"
#include "stl_vector"
#include "dummy"
#include "obj_list"
#include "vector3"
#include "matrix"
#ifdef TOOLS_MEM
#include "../mem"
#endif
namespace tools {
namespace rroot {
class fac : public virtual ifac {
public:
TOOLS_SCLASS(tools::rroot::fac)
public: //ifac
virtual std::ostream& out() const {return m_out;}
virtual iro* create(const std::string& a_class,const args&) {
//m_out << "tools::rroot::fac::create :"
// << " create object of class " << a_class << "..."
// << std::endl;
if(a_class=="TBranch") {
return new branch(m_out,*this);
} else if(a_class=="TBranchElement") {
return new branch_element(m_out,*this);
} else if(a_class=="TBranchObject") {
return new branch_object(m_out,*this);
} else if(a_class=="TLeafB") {
return new leaf<char>(m_out,*this);
} else if(a_class=="TLeafS") {
return new leaf<short>(m_out,*this);
} else if(a_class=="TLeafI") {
return new leaf<int>(m_out,*this);
} else if(a_class=="TLeafF") {
return new leaf<float>(m_out,*this);
} else if(a_class=="TLeafD") {
return new leaf<double>(m_out,*this);
} else if(a_class=="TLeafO") {
return new leaf<bool>(m_out,*this);
} else if(a_class=="TLeafC") {
return new leaf_string(m_out,*this);
} else if(a_class=="TLeafElement") {
return new leaf_element(m_out,*this);
} else if(a_class=="TLeafObject") {
return new leaf_object(m_out,*this);
} else if(a_class=="TBasket") {
return new basket(m_out);
// L.Duflot ATLAS file :
} else if(a_class=="TTreeIndex") {
return new tree_index();
} else if(a_class=="TList") {
return new obj_list(*this);
} else if(a_class=="TVector3") {
return new vector3();
} else if(a_class=="TMatrix") {
return new matrix();
} else if(a_class=="TNamed") {
return new named();
} else if(a_class=="vector<unsigned short>") {
return new stl_vector<unsigned short>();
} else if(a_class=="vector<short>") {
return new stl_vector<short>();
} else if(a_class=="vector<unsigned int>") {
return new stl_vector<unsigned int>();
} else if(a_class=="vector<int>") {
return new stl_vector<int>();
} else if(a_class=="vector<float>") {
return new stl_vector<float>();
} else if(a_class=="vector<double>") {
return new stl_vector<double>();
} else if(a_class=="vector<unsigned long>") { //beurk
return new stl_vector<uint64>(); //is it ok to map to an uint64 ?
} else if(a_class=="vector<string>") {
return new stl_vector_string();
} else if(a_class=="vector<vector<unsigned short> >") {
return new stl_vector_vector<unsigned short>();
} else if(a_class=="vector<vector<short> >") {
return new stl_vector_vector<short>();
} else if(a_class=="vector<vector<unsigned int> >") {
return new stl_vector_vector<unsigned int>();
} else if(a_class=="vector<vector<int> >") {
return new stl_vector_vector<int>();
} else if(a_class=="vector<vector<float> >") {
return new stl_vector_vector<float>();
} else if(a_class=="vector<vector<double> >") {
return new stl_vector_vector<double>();
} else if(a_class=="TBranchRef") {
return new dummy();
} else {
m_out << "tools::rroot::fac::create :"
<< " unknown class " << sout(a_class) << "."
<< " Create a tools::rroot::dummy object."
<< std::endl;
return new dummy();
}
}
public:
fac(std::ostream& a_out):m_out(a_out){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~fac(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
fac(const fac& a_from):ifac(a_from),m_out(a_from.m_out){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
fac& operator=(const fac&){return *this;}
protected:
/*
branch* arg_branch(const args& a_args) {
void* p = ifac::find_args(a_args,ifac::arg_branch());
if(!p) {
m_out << "tools::rroot::fac::arg_branch :"
<< " branch not found in args."
<< std::endl;
return 0;
}
return (branch*)p;
}
*/
protected:
std::ostream& m_out;
};
}}
#endif
+551
View File
@@ -0,0 +1,551 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_file
#define tools_rroot_file
#include "ifile"
#include "directory"
#include "../platform"
#include "obj_list"
#include "info"
#include "streamer_fac"
#include <string>
#include <fcntl.h>
#include <errno.h>
#ifdef _MSC_VER
#include <io.h>
#include <sys/stat.h>
#else
#include <unistd.h>
#endif
namespace tools {
namespace rroot {
class file : public virtual ifile {
file& get_me() {return *this;} //_MSC_VER : to avoid warning about the usage of "this" in the constructor.
static int not_open() {return -1;}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::file");
return s_v;
}
virtual const std::string& s_cls() const {return s_class();}
public: //ifile
virtual const std::string& path() const {return m_path;}
virtual bool verbose() const {return m_verbose;}
virtual std::ostream& out() const {return m_out;}
virtual bool byte_swap() const {return is_little_endian();}
virtual bool set_pos(seek a_offset = 0,from a_from = begin){
int whence = 0;
switch(a_from) {
case begin:
whence = SEEK_SET;
break;
case current:
whence = SEEK_CUR;
break;
case end:
whence = SEEK_END;
break;
}
#if defined(__linux__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2)
if (::lseek64(m_file, a_offset, whence) < 0) {
#elif defined(_MSC_VER)
if (::_lseeki64(m_file, a_offset, whence) < 0) {
#else
if (::lseek(m_file, a_offset, whence) < 0) {
#endif
m_out << "tools::rroot::file::set_pos :"
<< " cannot set position " << a_offset
<< " in file " << sout(m_path) << "."
<< std::endl;
return false;
}
return true;
}
virtual bool read_buffer(char* a_buffer,uint32 a_length) {
// Read a buffer from the file.
// This is the basic low level read operation.
#ifdef _MSC_VER
typedef int ssize_t;
#endif
ssize_t siz;
while ((siz = ::read(m_file,a_buffer,a_length)) < 0 &&
error_number() == EINTR) reset_error_number();
if (siz < 0) {
m_out << "tools::rroot::file::read_buffer :"
<< " error reading from file " << sout(m_path) << "."
<< std::endl;
return false;
}
if (siz != ssize_t(a_length)) {
m_out << "tools::rroot::file::read_buffer :"
<< " error reading all requested bytes from file "
<< sout(m_path) << ", got " << long_out(siz)
<< " of " << a_length
<< std::endl;
return false;
}
m_bytes_read += siz;
return true;
}
virtual bool unziper(char a_key,decompress_func& a_func) const {
std::map<char,decompress_func>::const_iterator it = m_unzipers.find(a_key);
if(it==m_unzipers.end()) {
a_func = 0;
return false;
}
a_func = (*it).second;
return true;
}
virtual key& sinfos_key() {return m_streamer_infos_key;}
public:
file(std::ostream& a_out,const std::string& a_path,bool a_verbose = false)
:m_out(a_out)
,m_path(a_path)
,m_verbose(a_verbose)
,m_file(not_open())
,m_bytes_read(0)
,m_root_directory(get_me())
,m_streamer_infos_key(a_out)
,m_streamer_fac(a_out)
,m_streamer_infos(m_streamer_fac)
// begin of record :
,m_version(0)
,m_BEGIN(0)
,m_END(0)
,m_seek_free(0)
,m_seek_info(0)
,m_nbytes_free(0)
,m_nbytes_info(0)
,m_nbytes_name(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_file = _open(a_path.c_str(),
#ifdef _MSC_VER
O_RDONLY | O_BINARY,S_IREAD | S_IWRITE
#else
O_RDONLY,0644
#endif
);
if(m_file==not_open()) {
m_out << "tools::rroot::file::file :"
<< " can't open " << sout(a_path) << "."
<< std::endl;
return;
}
initialize();
}
virtual ~file() {
close();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
file(const file& a_from)
:ifile(a_from)
,m_out(a_from.m_out)
,m_root_directory(get_me())
,m_streamer_infos_key(a_from.m_out)
,m_streamer_fac(a_from.m_out)
,m_streamer_infos(m_streamer_fac)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
file& operator=(const file&){return *this;}
public:
uint32 version() const {return m_version;}
bool is_open() const {
return (m_file==not_open()?false:true);
}
void close() {
if(m_file!=not_open()) ::close(m_file);
m_file = not_open();
m_root_directory.clear_keys();
}
directory& dir() {return m_root_directory;}
const directory& dir() const {return m_root_directory;}
bool add_unziper(char a_key,decompress_func a_func){
std::map<char,decompress_func>::const_iterator it = m_unzipers.find(a_key);
if(it!=m_unzipers.end()) {
//(*it).second = a_func; //override ?
return false;
} else {
m_unzipers[a_key] = a_func;
return true;
}
}
bool dump_streamer_infos() {
// read_streamer_infos_data() done here (and not in initialize) since it may need to have unziper declared.
if(m_streamer_infos.empty()) {if(!read_streamer_infos_data()) return false;}
tools_vforcit(iro*,m_streamer_infos,it) {
streamer_info* info = safe_cast<iro,streamer_info>(*(*it));
if(!info) return false;
info->out(m_out);
}
return true;
}
streamer_info* find_streamer_info(const std::string& a_class) {
// read_streamer_infos_data() done here (and not in initialize) since it may need to have unziper declared.
if(m_streamer_infos.empty()) {if(!read_streamer_infos_data()) return 0;}
tools_vforcit(iro*,m_streamer_infos,it) {
streamer_info* info = safe_cast<iro,streamer_info>(*(*it));
if(info) {
if(info->name()==a_class) return info;
}
}
return 0;
}
protected:
static int _open(const char* a_name,int a_flags,uint32 a_mode) {
#if defined(__linux__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2)
return ::open64(a_name,a_flags,a_mode);
#else
return ::open(a_name,a_flags,a_mode);
#endif
}
static std::string sout(const std::string& a_string) {return "\""+a_string+"\"";}
bool initialize() {
if(!read_header()) {
m_out << "tools::rroot::file::initialize :"
<< " can't read header."
<< std::endl;
return false;
}
/*
fRootDirectory->setSeekDirectory(fBEGIN);
// Read Free segments structure if file is writable :
if (fWritable) {
if (fSeekFree > fBEGIN) {
if(!readFreeSegments()) {
m_out << "tools::rroot::file::initialize : Cannot read free segments."
<< std::endl;
return false;
}
} else {
m_out << "tools::rroot::file::initialize : file \"" << fName
<< "\" probably not closed, cannot read free segments" << std::endl;
}
}
*/
// Read Directory info :
uint32 nbytes = m_nbytes_name + m_root_directory.record_size(m_version);
char* header = new char[nbytes];
char* buffer = header;
if(!set_pos(m_BEGIN)) {
m_out << "tools::rroot::file::initialize :"
<< " can't set position."
<< std::endl;
delete [] header;
return false;
}
if(!read_buffer(buffer,nbytes)) {
m_out << "tools::rroot::file::initialize :"
<< " can't read buffer."
<< std::endl;
delete [] header;
return false;
}
buffer = header+m_nbytes_name;
const char* eob = header+nbytes;
if(!m_root_directory.from_buffer(eob,buffer)) {
m_out << "tools::rroot::file::initialize :"
<< " can't read buffer (2)."
<< std::endl;
delete [] header;
return false;
}
uint32 nk = //size of Key
sizeof(int) + //Key::fNumberOfBytes
sizeof(short) + //Key::fVersion
2*sizeof(int) + //Key::fObjectSize, Date
2*sizeof(short) + //Key::fKeyLength,fCycle
2*sizeof(seek32); //Key::fSeekKey,fSeekParentDirectory
//WARNING : the upper is seek32 since at begin of file.
buffer = header+nk;
std::string cname;
rbuf rb(m_out,byte_swap(),eob,buffer);
// Should be "TFile".
if(!rb.read(cname)) {
m_out << "tools::rroot::file::initialize :"
<< " can't read buffer (3)."
<< std::endl;
delete [] header;
return false;
}
if(cname!="TFile") {
m_out << "tools::rroot::file::initialize : TFile expected." << std::endl;
delete [] header;
return false;
}
if(m_verbose) {
m_out << "tools::rroot::file::initialize :"
<< " " << sout("TFile") << " found."
<< std::endl;
}
if(!rb.read(cname)) {
m_out << "tools::rroot::file::initialize :"
<< " can't read buffer (4)."
<< std::endl;
delete [] header;
return false;
}
if(m_verbose) {
m_out << "tools::rroot::file::initialize :"
<< " found file name " << sout(cname)
<< std::endl;
}
if(!rb.read(m_title)) {
m_out << "tools::rroot::file::initialize :"
<< " can't read buffer (5)."
<< std::endl;
delete [] header;
return false;
}
delete [] header;
if(m_verbose) {
m_out << "tools::rroot::file::initialize :"
<< " found title " << sout(m_title)
<< std::endl;
}
uint32 dirNbytesName = m_root_directory.nbytes_name();
if (dirNbytesName < 10 || dirNbytesName > 1000) {
m_out << "tools::rroot::file::initialize :"
<< " can't read directory info."
<< std::endl;
return false;
}
// Read keys of the top directory :
if(m_root_directory.seek_keys() > m_BEGIN) {
uint32 n;
if(!m_root_directory.read_keys(n)) {
m_out << "tools::rroot::file::initialize :"
<< " can't read keys."
<< std::endl;
return false;
}
} else {
m_out << "tools::rroot::file::initialize :"
<< " file " << sout(m_path)
<< " probably not closed."
<< std::endl;
return false;
}
// Create StreamerInfo index
if(m_seek_info > m_BEGIN) {
if(!read_streamer_infos_key()) {
m_out << "tools::rroot::file::initialize :"
<< " read_streamer_infos_key() failed."
<< std::endl;
return false;
}
} else {
m_out << "tools::rroot::file::initialize :"
<< " file " << sout(m_path)
<< " probably not closed."
<< std::endl;
return false;
}
return true;
}
bool read_header() {
static const uint32 kBegin = 64;
char header[kBegin];
if(!set_pos()) return false;
if(!read_buffer(header,kBegin)) return false;
// make sure this is a root file
if(::strncmp(header, "root", 4)) {
m_out << "tools::rroot::file::read_header :"
<< " " << sout(m_path) << " not a file at the CERN-ROOT format."
<< std::endl;
return false;
}
if(m_verbose) {
m_out << "tools::rroot::file::read_header :"
<< " file signature is " << sout("root")
<< std::endl;
}
char* buffer = header + 4; // skip the "root" file identifier
const char* eob = header + kBegin;
rbuf rb(m_out,byte_swap(),eob,buffer);
{int v;
if(!rb.read(v)) return false;
m_version = v;}
{seek32 i;
if(!rb.read(i)) return false;
m_BEGIN = i;}
if(m_version>1000000) {
if(!rb.read(m_END)) return false;
if(!rb.read(m_seek_free)) return false;
} else {
{seek32 i;
if(!rb.read(i)) return false;
m_END = i;}
{seek32 i;
if(!rb.read(i)) return false;
m_seek_free = i;}
}
if(m_verbose) {
m_out << "tools::rroot::file::read_header :"
<< " begin " << m_BEGIN
<< " end " << m_END
<< std::endl;
}
{int v;
if(!rb.read(v)) return false;
m_nbytes_free = v;}
int nfree = 0;
if(!rb.read(nfree)) return false;
{int v;
if(!rb.read(v)) return false;
m_nbytes_name = v;}
//m_out << "debug : 1002 " << m_nbytes_name << std::endl;
{char fUnits;
if(!rb.read(fUnits)) return false;}
{int fCompress;
if(!rb.read(fCompress)) return false;}
if(m_version>1000000) {
if(!rb.read(m_seek_info)) return false;
} else {
{seek32 i;
if(!rb.read(i)) return false;
m_seek_info = i;}
}
if(!rb.read(m_nbytes_info)) return false;
//m_out << "debug : seek_info " << m_seek_info << " nbytes_info " << m_nbytes_info << std::endl;
return true;
}
bool read_streamer_infos_key() {
// Read the list of StreamerInfo from this file
// The key with name holding the list of TStreamerInfo objects is read.
// The corresponding TClass objects are updated.
if(m_seek_info<=0) return false;
if(m_seek_info>=m_END) return false;
if(!set_pos(m_seek_info)) return false;
char* buffer = new char[m_nbytes_info+1];
if(!read_buffer(buffer,m_nbytes_info)) {delete [] buffer;return false;}
char* buf = buffer;
if(!m_streamer_infos_key.from_buffer(byte_swap(),buffer+m_nbytes_info,buf,m_verbose)) {
delete [] buffer;
return false;
}
delete [] buffer;
return true;
}
bool read_streamer_infos_data() {
key& k = m_streamer_infos_key;
if(k.object_class()!="TList") {
m_out << "tools::rroot::file::read_streamer_infos_data : key not a TList." << std::endl;
return false;
}
unsigned int sz;
char* buf = k.get_object_buffer(*this,sz); //we don't have ownership of buf.
if(!buf) {
m_out << "tools::rroot::file::read_streamer_infos :"
<< " can't get data buffer of " << k.object_name() << "."
<< std::endl;
return false;
}
buffer b(m_out,byte_swap(),sz,buf,k.key_length(),false);
return m_streamer_infos.stream(b);
}
#if defined(__sun) && !defined(__linux__) && (__SUNPRO_CC > 0x420)
int error_number() {return ::errno;}
void reset_error_number() {::errno = 0;}
#else
int error_number() {return errno;}
void reset_error_number() {errno = 0;}
#endif
protected:
std::ostream& m_out;
std::string m_path;
bool m_verbose;
int m_file;
uint64 m_bytes_read; //Number of bytes read from this file
directory m_root_directory;
key m_streamer_infos_key;
streamer_fac m_streamer_fac;
obj_list m_streamer_infos;
std::map<char,decompress_func> m_unzipers;
std::string m_title;
// begin of record :
uint32 m_version; //File format version
seek m_BEGIN; //First used byte in file
seek m_END; //Last used byte in file
seek m_seek_free; //Location on disk of free segments structure
seek m_seek_info; //Location on disk of StreamerInfo record
uint32 m_nbytes_free; //Number of bytes for free segments structure
uint32 m_nbytes_info; //Number of bytes for StreamerInfo record
//int nfree
uint32 m_nbytes_name; //Number of bytes in TNamed at creation time
};
}}
#endif
//doc
//
// A ROOT file is a suite of consecutive data records with the following
// format (see also the TKey class);
// TKey ---------------------
// byte 1->4 Nbytes = Length of compressed object (in bytes)
// 5->6 Version = TKey version identifier
// 7->10 ObjLen = Length of uncompressed object
// 11->14 Datime = Date and time when object was written to file
// 15->16 KeyLen = Length of the key structure (in bytes)
// 17->18 Cycle = Cycle of key
// 19->22 SeekKey = Pointer to record itself (consistency check)
// 23->26 SeekPdir = Pointer to directory header
// 27->27 lname = Number of bytes in the class name
// 28->.. ClassName = Object Class Name
// ..->.. lname = Number of bytes in the object name
// ..->.. Name = lName bytes with the name of the object
// ..->.. lTitle = Number of bytes in the object title
// ..->.. Title = Title of the object
// -----> DATA = Data bytes associated to the object
//
// The first data record starts at byte fBEGIN (currently set to kBegin)
// Bytes 1->kBegin contain the file description:
// byte 1->4 "root" = Root file identifier
// 5->8 fVersion = File format version
// 9->12 fBEGIN = Pointer to first data record
// 13->16 fEND = Pointer to first free word at the EOF
// 17->20 fSeekFree = Pointer to FREE data record
// 21->24 fNbytesFree = Number of bytes in FREE data record
// 25->28 nfree = Number of free data records
// 29->32 fNbytesName = Number of bytes in TNamed at creation time
// 33->33 fUnits = Number of bytes for file pointers
// 34->37 fCompress = Zip compression level
//
+66
View File
@@ -0,0 +1,66 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_graph
#define tools_rroot_graph
#include "../scast"
#include "buffer"
#include "cids"
namespace tools {
namespace rroot {
class graph : public virtual iro {
static const std::string& s_store_class() {
static const std::string s_v("TGraph");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::graph");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<graph>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return graph_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<graph>(this,a_class)) {return p;}
else return 0;
}
public:
virtual iro* copy() const {return new graph(*this);}
virtual bool stream(buffer& a_buffer) {
uint32 startpos = a_buffer.length();
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
a_buffer.set_offset(startpos+c+sizeof(unsigned int));
if(!a_buffer.check_byte_count(s,c,s_store_class())) return false;
return true;
}
public:
graph(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~graph(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
graph(const graph& a_from): iro(a_from){}
graph& operator=(const graph&){return *this;}
};
}}
#endif
+45
View File
@@ -0,0 +1,45 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_ifac
#define tools_rroot_ifac
#include <string>
#include <map>
#include <ostream>
namespace tools {
namespace rroot {
class iro;
}}
namespace tools {
namespace rroot {
class ifac {
public:
typedef std::map<char,void*> args;
public:
virtual ~ifac(){}
public:
virtual std::ostream& out() const = 0;
virtual iro* create(const std::string& a_class,const args&) = 0;
public:
static void* find_args(const args& a_args,char a_key) {
std::map<char,void*>::const_iterator it = a_args.find(a_key);
if(it==a_args.end()) return 0;
return (*it).second;
}
//static char arg_branch() {return 'B';}
static char arg_class() {return 'C';}
static std::string* arg_class(const args& a_args) {
void* p = ifac::find_args(a_args,ifac::arg_class());
if(!p) return 0;
return (std::string*)p;
}
};
}}
#endif
+42
View File
@@ -0,0 +1,42 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_ifile
#define tools_rroot_ifile
#include "seek"
#include "../press_func"
namespace tools {
namespace rroot {
class key;
class streamer_info;
class ifile {
public:
virtual ~ifile(){}
public:
virtual const std::string& path() const = 0;
virtual bool verbose() const = 0;
virtual std::ostream& out() const = 0;
virtual bool byte_swap() const = 0;
enum from {
begin,
current,
end
};
virtual bool set_pos(seek = 0,from = begin) = 0;
virtual bool read_buffer(char*,uint32) = 0;
virtual bool unziper(char,decompress_func&) const = 0;
virtual key& sinfos_key() = 0;
virtual streamer_info* find_streamer_info(const std::string&) = 0;
};
}}
#endif
+268
View File
@@ -0,0 +1,268 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_info
#define tools_rroot_info
//#include "buffer"
//#include "element"
#include "named"
#include "obj_array"
#include "../forit"
namespace tools {
namespace rroot {
class streamer_element : public virtual iro {
static const std::string& s_store_class() {
static const std::string s_v("TStreamerElement");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::streamer_element");
return s_v;
}
static cid id_class() {return streamer_element_cid();}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<streamer_element>(this,a_class)) return p;
return 0;
}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<streamer_element>(this,a_class)) {return p;}
else return 0;
}
virtual const std::string& s_cls() const {return s_class();}
virtual iro* copy() const {return new streamer_element(*this);}
virtual bool stream(buffer& a_buffer) {
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!Named_stream(a_buffer,fName,fTitle)) return false;
if(!a_buffer.read(fType)) return false;
if(!a_buffer.read(fSize)) return false;
if(!a_buffer.read(fArrayLength)) return false;
if(!a_buffer.read(fArrayDim)) return false;
if(!a_buffer.read_fast_array<int>(fMaxIndex,5)) return false;
if(!a_buffer.read(fTypeName)) return false;
return a_buffer.check_byte_count(s,c,s_store_class());
}
public:
virtual void out(std::ostream& aOut) const {
std::string _fname;
fullName(_fname);
char s[128];
snpf(s,sizeof(s)," %-14s%-15s offset=%3d type=%2d %-20s",
fTypeName.c_str(),_fname.c_str(),fOffset,fType,fTitle.c_str());
aOut << s << std::endl;
}
public:
streamer_element()
:fName(),fTitle(),fType(-1)
,fSize(0),fArrayLength(0),fArrayDim(0),fOffset(0)
,fTypeName(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
for(int i=0;i<5;i++) fMaxIndex[i] = 0;
}
virtual ~streamer_element(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
streamer_element(const streamer_element& a_from)
:iro(a_from)
,fName(a_from.fName),fTitle(a_from.fTitle)
,fType(a_from.fType),fSize(a_from.fSize)
,fArrayLength(a_from.fArrayLength)
,fArrayDim(a_from.fArrayDim),fOffset(a_from.fOffset)
,fTypeName(a_from.fTypeName){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
for(int i=0;i<5;i++) fMaxIndex[i] = a_from.fMaxIndex[i];
}
streamer_element& operator=(const streamer_element& a_from){
fName = a_from.fName;
fTitle = a_from.fTitle;
fType = a_from.fType;
fSize = a_from.fSize;
fArrayLength = a_from.fArrayLength;
fArrayDim = a_from.fArrayDim;
fOffset = a_from.fOffset;
fTypeName = a_from.fTypeName;
for(int i=0;i<5;i++) fMaxIndex[i] = a_from.fMaxIndex[i];
return *this;
}
public:
virtual void fullName(std::string& a_s) const {
a_s = fName;
for (int i=0;i<fArrayDim;i++) {
char cdim[32];
snpf(cdim,sizeof(cdim),"[%d]",fMaxIndex[i]);
a_s += cdim;
}
}
const std::string& type_name() const {return fTypeName;}
protected: //Named
std::string fName;
std::string fTitle;
protected:
int fType; //element type
int fSize; //sizeof element
int fArrayLength; //cumulative size of all array dims
int fArrayDim; //number of array dimensions
int fMaxIndex[5]; //Maximum array index for array dimension "dim"
int fOffset; //!element offset in class
//FIXME Int_t fNewType; //!new element type when reading
std::string fTypeName; //Data type name of data member
};
class dummy_streamer_element : public streamer_element {
typedef streamer_element parent;
public: //iro
virtual iro* copy() const {return new dummy_streamer_element(*this);}
virtual bool stream(buffer& a_buffer) {
//the below code skips correctly the data in the file.
uint32 startpos = a_buffer.length();
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!parent::stream(a_buffer)) return false;
a_buffer.set_offset(startpos+c+sizeof(unsigned int));
if(!a_buffer.check_byte_count(s,c,"dummy_streamer_element")) return false;
return true;
}
public:
dummy_streamer_element(){}
virtual ~dummy_streamer_element(){}
protected:
dummy_streamer_element(const dummy_streamer_element& a_from):iro(a_from),parent(a_from){}
dummy_streamer_element& operator=(const dummy_streamer_element& a_from){
parent::operator=(a_from);
return *this;
}
};
class streamer_info : public virtual iro {
static const std::string& s_store_class() {
static const std::string s_v("TStreamerInfo");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::streamer_info");
return s_v;
}
static cid id_class() {return streamer_info_cid();}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<streamer_info>(this,a_class)) return p;
return 0;
}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<streamer_info>(this,a_class)) {return p;}
else return 0;
}
virtual const std::string& s_cls() const {return s_class();}
virtual iro* copy() const {return new streamer_info(*this);}
virtual bool stream(buffer& a_buffer) {
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!Named_stream(a_buffer,m_name,m_title)) return false;
if(!a_buffer.read(m_check_sum)) return false;
if(!a_buffer.read(m_streamed_class_version)) return false;
//TObjArray *fElements; //Array of TStreamerElements
{obj_array<streamer_element>* obj;
ifac::args args;
args[ifac::arg_class()] = (void*)&(streamer_element::s_class());
bool obj_created;
if(!pointer_stream(a_buffer,m_fac,args,obj,obj_created)) {
a_buffer.out() << "tools::rroot::streamer_info::stream : "
<< "can't read fElements."
<< std::endl;
return false;
}
if(obj) m_elements.operator=(*obj);
if(obj_created) delete obj;}
return a_buffer.check_byte_count(s,c,s_store_class());
}
public:
void out(std::ostream& a_out) const {
a_out << "streamer_info for class :"
<< " " << m_name << ", version=" << m_streamed_class_version
<< std::endl;
tools_vforcit(streamer_element*,m_elements,it) (*it)->out(a_out);
}
public:
streamer_info(ifac& a_fac)
:m_fac(a_fac)
,m_name()
,m_title()
,m_check_sum(0)
,m_streamed_class_version(0)
,m_elements(a_fac)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~streamer_info(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
streamer_info(const streamer_info& a_from)
:iro(a_from)
,m_fac(a_from.m_fac)
,m_name(a_from.m_name)
,m_title(a_from.m_name)
,m_check_sum(a_from.m_check_sum)
,m_streamed_class_version(a_from.m_streamed_class_version)
,m_elements(a_from.m_elements)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
streamer_info& operator=(const streamer_info& a_from){
m_name = a_from.m_name;
m_title = a_from.m_name;
m_check_sum = a_from.m_check_sum;
m_streamed_class_version = a_from.m_streamed_class_version;
m_elements = a_from.m_elements;
return *this;
}
public:
const std::string& name() const {return m_name;}
streamer_element* find_streamer_element(size_t a_index) const {
if(a_index>=m_elements.size()) return 0;
return m_elements[a_index];
}
protected:
ifac& m_fac;
protected: //Named
std::string m_name;
std::string m_title;
protected:
unsigned int m_check_sum; //checksum of original class
int m_streamed_class_version; //Class version identifier
//int fNumber; //!Unique identifier
obj_array<streamer_element> m_elements; //Array of TStreamerElements
};
}}
#endif
+29
View File
@@ -0,0 +1,29 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_iobject
#define tools_rroot_iobject
#include <string>
namespace tools {
namespace rroot {
class buffer;
}}
namespace tools {
namespace rroot {
class iobject {
public:
virtual ~iobject() {}
public:
virtual const std::string& name() const = 0;
virtual const std::string& title() const = 0;
virtual const std::string& store_class_name() const = 0;
virtual bool stream(buffer&) = 0;
};
}}
#endif
+34
View File
@@ -0,0 +1,34 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_iro
#define tools_rroot_iro
#include <string>
namespace tools {
namespace rroot {
class buffer;
}}
#include "../cid"
namespace tools {
namespace rroot {
class iro {
public:
virtual ~iro(){}
public:
virtual void* cast(const std::string&) const = 0; //for ObjArray
virtual bool stream(buffer&) = 0;
virtual const std::string& s_cls() const = 0;
virtual iro* copy() const = 0;
virtual void* cast(cid) const = 0; //OPTIMIZATION (geo).
};
}}
#endif
+183
View File
@@ -0,0 +1,183 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_iros
#define tools_rroot_iros
#include "object"
#include "../vmanip"
#include "../forit"
#include "../scast"
#include "cids"
namespace tools {
namespace rroot {
class iros : public virtual iro,protected std::vector<iro*> { //proteced to avoid using std::vector::clear().
typedef std::vector<iro*> parent;
public:
static const std::string& s_store_class() {
static const std::string s_v("TObjArray");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::iros");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<iros>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return obj_list_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<iros>(this,a_class)) {return p;}
else return 0;
}
public:
virtual iro* copy() const {return new iros(*this);}
virtual bool stream(buffer& a_buffer) {
ifac::args args;
bool accept_null = false;
return stream(a_buffer,args,accept_null);
}
public:
iros(ifac& a_fac)
:m_fac(a_fac)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~iros(){
_clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
iros(const iros& a_from)
:iro(a_from)
,parent()
,m_fac(a_from.m_fac)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
tools_vforcit(iro*,a_from,it) {
parent::push_back((*it)->copy());
m_owns.push_back(true);
}
}
iros& operator=(const iros& a_from){
if(&a_from==this) return *this;
_clear();
tools_vforcit(iro*,a_from,it) {
parent::push_back((*it)->copy());
m_owns.push_back(true);
}
return *this;
}
public:
parent::const_iterator begin() const {return parent::begin();}
parent::iterator begin() {return parent::begin();}
parent::const_iterator end() const {return parent::end();}
parent::iterator end() {return parent::end();}
parent::size_type size() const {return parent::size();}
public:
void cleanup() {_clear();} //warning : clear is a function of the parent std::vector.
void dump(std::ostream& a_out) {
a_out << " iros : size " << size() << std::endl;
tools_vforcit(iro*,*this,it) {
a_out << " class " << (*it)->s_cls() << std::endl;
}
}
public:
bool stream(buffer& a_buffer,const ifac::args& a_args,bool a_accept_null = false) {
_clear();
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : iros::stream : version %d, byte count %d\n",v,c);
{uint32 id,bits;
if(!Object_stream(a_buffer,id,bits)) return false;}
std::string name;
if(!a_buffer.read(name)) return false;
int nobjects;
if(!a_buffer.read(nobjects)) return false;
int lowerBound;
if(!a_buffer.read(lowerBound)) return false;
//::printf("debug : iros : name \"%s\", nobject %d, lowerBound %d\n",
// name.c_str(),nobjects,lowerBound);
for (int i=0;i<nobjects;i++) {
//::printf("debug : iros : n=%d i=%d ...\n",nobjects,i);
iro* obj;
bool created;
if(!a_buffer.read_object(m_fac,a_args,obj,created)){
a_buffer.out() << "tools::rroot::iros::stream : can't read object." << std::endl;
return false;
}
//::printf("debug : iros : n=%d i=%d : ok\n",nobjects,i);
if(obj) {
if(created) {
parent::push_back(obj);
m_owns.push_back(true);
} else { //someone else manage this object.
parent::push_back(obj);
m_owns.push_back(false);
}
} else {
//a_accept_null for branch::stream m_baskets.
if(a_accept_null) {
parent::push_back(0);
m_owns.push_back(false);
}
}
}
return a_buffer.check_byte_count(s,c,s_store_class());
}
protected:
void _clear() {
typedef parent::iterator it_t;
typedef std::vector<bool>::iterator itb_t;
while(!parent::empty()) {
it_t it = parent::begin();
itb_t itb = m_owns.begin();
iro* entry = (*it);
bool own = (*itb);
parent::erase(it);
m_owns.erase(itb);
if(own) delete entry;
}
}
protected:
ifac& m_fac;
std::vector<bool> m_owns;
};
/*
inline bool dummy_TObjArray_pointer_stream(buffer& a_buffer,ifac& a_fac,bool a_owner,bool a_warn) {
iros oa(a_fac,a_owner,a_warn);
iros oa(a_fac,true,true);
ifac::args args;
return oa.stream(a_buffer,args);
}
*/
}}
#endif
+606
View File
@@ -0,0 +1,606 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_key
#define tools_rroot_key
#include "rbuf"
#include "seek"
#include "date"
#include "ifile"
#include "../sout"
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include <map>
#include <ostream>
#include <cstring> //memcpy
//#include <zlib.h>
#ifdef TOOLS_USE_CSZ
// CSZ code where used as default compressor in old CERN-ROOT, then it may be needed
// to read old file (as the pawdemo.root one).
//FIXME : arrange to have csz coming from the "outside" (as zip).
extern "C" {
void csz__Init_Inflate(long,unsigned char*,long,unsigned char*);
int csz__Inflate();
unsigned char* csz__obufptr();
}
#endif
namespace tools {
namespace rroot {
class key {
static uint32 class_version() {return 2;}
public:
static uint32 std_string_record_size(const std::string& x) {
// Returns size string will occupy on I/O buffer.
if (x.size() > 254)
return uint32(x.size()+sizeof(unsigned char)+sizeof(int));
else
return uint32(x.size()+sizeof(unsigned char));
}
public:
key(std::ostream& a_out)
:m_out(a_out)
,m_buf_size(0)
,m_buffer(0)
// Record :
,m_nbytes(0)
,m_version(class_version())
,m_object_size(0)
,m_date(0)
,m_key_length(0)
,m_cycle(0)
,m_seek_key(0)
,m_seek_parent_dir(0)
//,m_object_class
//,m_object_name
//,m_object_title
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_key_length = record_size(m_version);
//fDate.setDate(0);
}
key(std::ostream& a_out,seek a_pos,uint32 a_nbytes)
:m_out(a_out)
,m_buf_size(0)
,m_buffer(0)
// Record :
,m_nbytes(a_nbytes) //key len + compressed object size
,m_version(class_version())
,m_object_size(0)
,m_date(0)
,m_key_length(0)
,m_cycle(0)
,m_seek_key(a_pos)
,m_seek_parent_dir(0)
//,m_object_class
//,m_object_name
//,m_object_title
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
if(a_pos>START_BIG_FILE) m_version += big_file_version_tag();
m_buffer = new char[a_nbytes];
if(!m_buffer) {
m_out << "tools::rroot::key::key(cpcstor) :"
<< " can't alloc " << a_nbytes << "."
<< std::endl;
} else {
m_buf_size = a_nbytes;
}
}
virtual ~key(){
delete [] m_buffer;
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
key(const key& a_from)
:m_out(a_from.m_out)
,m_buf_size(0)
,m_buffer(0)
,m_nbytes(a_from.m_nbytes)
,m_version(a_from.m_version)
,m_object_size(a_from.m_object_size)
,m_date(a_from.m_date)
,m_key_length(a_from.m_key_length)
,m_cycle(a_from.m_cycle)
,m_seek_key(a_from.m_seek_key)
,m_seek_parent_dir(a_from.m_seek_parent_dir)
,m_object_class(a_from.m_object_class)
,m_object_name(a_from.m_object_name)
,m_object_title(a_from.m_object_title)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
if(a_from.m_buf_size && a_from.m_buffer) {
m_buffer = new char[a_from.m_buf_size];
if(!m_buffer) {
m_out << "tools::rroot::key::key(cpcstor) :"
<< " can't alloc " << a_from.m_buf_size << "."
<< std::endl;
} else {
m_buf_size = a_from.m_buf_size;
::memcpy(m_buffer,a_from.m_buffer,a_from.m_buf_size);
}
}
}
public:
key& operator=(const key& a_from){
if(&a_from==this) return *this;
m_nbytes = a_from.m_nbytes;
m_version = a_from.m_version;
m_object_size = a_from.m_object_size;
m_date = a_from.m_date;
m_key_length = a_from.m_key_length;
m_cycle = a_from.m_cycle;
m_seek_key = a_from.m_seek_key;
m_seek_parent_dir = a_from.m_seek_parent_dir;
m_object_class = a_from.m_object_class;
m_object_name = a_from.m_object_name;
m_object_title = a_from.m_object_title;
delete [] m_buffer;
m_buffer = 0;
m_buf_size = 0;
if(a_from.m_buf_size && a_from.m_buffer) {
m_buffer = new char[a_from.m_buf_size];
if(!m_buffer) {
m_out << "tools::rroot::key::operator=() :"
<< " can't alloc " << a_from.m_buf_size << "."
<< std::endl;
} else {
m_buf_size = a_from.m_buf_size;
::memcpy(m_buffer,a_from.m_buffer,a_from.m_buf_size);
}
}
return *this;
}
public:
std::ostream& out() const {return m_out;}
uint32 nbytes() const {return m_nbytes;}
seek seek_key() const {return m_seek_key;}
uint32 object_size() const {return m_object_size;}
const std::string& object_name() const {return m_object_name;}
const std::string& object_title() const {return m_object_title;}
const std::string& object_class() const {return m_object_class;}
bool read_file(ifile& a_file){
// Read the key structure from the file.
if(!a_file.set_pos(m_seek_key)) return false;
if(!a_file.read_buffer(m_buffer,m_nbytes)) return false;
if(a_file.verbose()) {
m_out << "tools::rroot::key::read_file :"
<< " reading " << m_nbytes << " bytes"
<< " at position " << m_seek_key
<< "."
<< std::endl;
}
return true;
}
char* buf() const {return m_buffer;}
char* data_buffer() const {return m_buffer + m_key_length;}
const char* eob() const {return m_buffer + m_buf_size;}
uint32 buf_size() const {return m_buf_size;}
uint32 key_length() const {return m_key_length;}
bool from_buffer(bool a_byte_swap,const char* aEOB,char*& a_pos,bool a_verbose) {
rbuf rb(m_out,a_byte_swap,aEOB,a_pos);
int _nbytes;
if(!rb.read(_nbytes)) return false;
/*
if(m_nbytes) {
if(_nbytes!=int(m_nbytes)) {
out << "tools::rroot::key::from_buffer :"
<< " nbytes not consistent."
<< " read " << _nbytes
<< ", expected " << m_nbytes
<< ". Continue with " << _nbytes
<< std::endl;
m_nbytes = _nbytes;
}
} else {
*/
m_nbytes = _nbytes;
//}
short version;
if(!rb.read(version)) return false;
m_version = version;
{int v;
if(!rb.read(v)) return false;
m_object_size = v;}
unsigned int _date;
if(!rb.read(_date)) return false;
//fDate.setDate(_date);
{short v;
if(!rb.read(v)) return false;
m_key_length = v;}
{short v;
if(!rb.read(v)) return false;
m_cycle = v;}
if(version>(short)big_file_version_tag()) {
if(!rb.read(m_seek_key)) return false;
if(!rb.read(m_seek_parent_dir)) return false;
} else {
{seek32 i;
if(!rb.read(i)) return false;
m_seek_key = i;}
{seek32 i;
if(!rb.read(i)) return false;
m_seek_parent_dir = i;}
}
if(!rb.read(m_object_class)) return false;
if(!rb.read(m_object_name)) return false;
if(!rb.read(m_object_title)) return false;
if(a_verbose) {
m_out << "tools::rroot::key::from_buffer :"
<< " nbytes : " << m_nbytes
<< ", object class : " << sout(m_object_class)
<< ", object name : " << sout(m_object_name)
<< ", object title : " << sout(m_object_title)
<< ", object size : " << m_object_size
<< "."
<< std::endl;
}
return true;
}
char* get_object_buffer(ifile& a_file,uint32& a_size) {
if(!m_key_length) {
m_out << "tools::rroot::key::get_object_buffer :"
<< " WARNING : m_key_length is zero."
<< std::endl;
//delete [] m_buffer;
//m_buffer = 0;
//m_buf_size = 0;
//a_size = 0;
//return 0;
}
if(!m_nbytes) {
m_out << "tools::rroot::key::get_object_buffer :"
<< " m_nbytes is zero."
<< std::endl;
delete [] m_buffer;
m_buffer = 0;
m_buf_size = 0;
a_size = 0;
return 0;
}
if(!m_object_size) {
m_out << "tools::rroot::key::get_object_buffer :"
<< " WARNING : m_object_size is zero."
<< std::endl;
}
if(a_file.verbose()) {
m_out << "tools::rroot::key::get_object_buffer :"
<< " m_nbytes : " << m_nbytes
<< " m_key_length : " << m_key_length
<< " m_object_size : " << m_object_size << "."
<< " m_seek_key : " << m_seek_key << "."
<< std::endl;
}
if(m_object_size <= (m_nbytes-m_key_length)) {
delete [] m_buffer;
m_buf_size = m_key_length+m_object_size;
if(m_buf_size<m_nbytes) {
m_out << "tools::rroot::key::get_object_buffer :"
<< " WARNING : m_buf_size<m_nbytes."
<< " m_buf_size " << m_buf_size
<< " m_nbytes " << m_nbytes
<< ". Raise m_buf_size to " << m_nbytes << "."
<< std::endl;
m_buf_size = m_nbytes; //for read_file()
}
m_buffer = new char[m_buf_size];
if(!m_buffer) {
m_out << "tools::rroot::key::get_object_buffer :"
<< " can't alloc " << m_buf_size
<< std::endl;
m_buffer = 0;
m_buf_size = 0;
a_size = 0;
return 0;
}
if(!read_file(a_file)) {
delete [] m_buffer;
m_buffer = 0;
m_buf_size = 0;
a_size = 0;
return 0;
}
} else {
// have to decompress. Need a second buffer.
uint32 decsiz = m_key_length+m_object_size;
char* decbuf = new char[decsiz];
if(!decbuf) {
m_out << "tools::rroot::key::get_object_buffer :"
<< " can't alloc " << decsiz
<< std::endl;
a_size = 0;
return 0;
}
delete [] m_buffer;
m_buffer = new char[m_nbytes];
m_buf_size = m_nbytes;
if(!read_file(a_file)) {
delete [] decbuf;
decbuf = 0;
delete [] m_buffer;
m_buffer = 0;
m_buf_size = 0;
a_size = 0;
return 0;
}
::memcpy(decbuf,m_buffer,m_key_length);
// decompress :
unsigned char* objbuf = (unsigned char*)(decbuf+m_key_length);
unsigned char* bufcur = (unsigned char*)(m_buffer+m_key_length);
int nout = 0;
uint32 noutot = 0;
while(true) {
int nin = 9 + ((int)bufcur[3] | ((int)bufcur[4] << 8) | ((int)bufcur[5] << 16));
int nbuf = (int)bufcur[6] | ((int)bufcur[7] << 8) | ((int)bufcur[8] << 16);
if(!unzip(m_out,a_file,nin,bufcur,nbuf,objbuf,nout)) break;
if(!nout) break;
noutot += nout;
if(noutot >= m_object_size) break;
bufcur += nin;
objbuf += nout;
}
delete [] m_buffer;
m_buffer = 0;
m_buf_size = 0;
if(!noutot) {
m_out << "tools::rroot::key::get_object_buffer :"
<< " nothing from decompression."
<< std::endl;
delete [] decbuf;
decbuf = 0;
a_size = 0;
return 0;
}
if(noutot!=m_object_size) {
m_out << "tools::rroot::key::get_object_buffer :"
<< " decompression mismatch."
<< " noutot " << noutot
<< " m_object_size " << m_object_size
<< std::endl;
delete [] decbuf;
decbuf = 0;
a_size = 0;
return 0;
}
m_buffer = decbuf;
m_buf_size = decsiz;
}
a_size = m_object_size;
return m_buffer+m_key_length;
}
//NOTE : print is a Python keyword.
void dump(std::ostream& a_out) const {
a_out << "class : " << sout(m_object_class)
<< ", name : " << sout(m_object_name)
<< ", title : " << sout(m_object_title)
<< ", size : " << m_object_size
<< "."
<< std::endl;
}
protected:
static const uint32 START_BIG_FILE = 2000000000;
protected:
uint32 record_size(uint32 a_version) const {
// Return the size in bytes of the key header structure.
uint32 _nbytes = sizeof(m_nbytes);
_nbytes += sizeof(short); //2
_nbytes += sizeof(m_object_size);
_nbytes += sizeof(date);
_nbytes += sizeof(m_key_length);
_nbytes += sizeof(m_cycle); //2+4*4=18
if(a_version>big_file_version_tag()) {
_nbytes += sizeof(seek);
_nbytes += sizeof(seek); //18+2*8=34
} else {
_nbytes += sizeof(seek32);
_nbytes += sizeof(seek32); //18+2*4=26
}
_nbytes += std_string_record_size(m_object_class);
_nbytes += std_string_record_size(m_object_name);
_nbytes += std_string_record_size(m_object_title);
//::printf("debug : record_size %d\n",_nbytes);
return _nbytes;
}
bool unzip(std::ostream& a_out,ifile& a_file,
int a_srcsize,unsigned char* a_src,int a_tgtsize,unsigned char* a_tgt,int& a_irep) {
// Author: E.Chernyaev (IHEP/Protvino)
// Input: scrsize - size of input buffer
// src - input buffer
// tgtsize - size of target buffer
//
// Output: tgt - target buffer (decompressed)
// irep - size of decompressed data
// 0 - if error
a_irep = 0;
// C H E C K H E A D E R
const int HDRSIZE = 9;
if (a_srcsize < HDRSIZE) {
a_out << "tools::rroot::key::unzip : too small source" << std::endl;
return false;
}
unsigned char DEFLATE = 8;
if ((a_src[0] != 'C' && a_src[0] != 'Z') ||
(a_src[1] != 'S' && a_src[1] != 'L') ||
a_src[2] != DEFLATE) {
a_out << "tools::rroot::key::unzip : error in header" << std::endl;
return false;
}
long _ibufcnt = (long)a_src[3] | ((long)a_src[4] << 8) | ((long)a_src[5] << 16);
long isize = (long)a_src[6] | ((long)a_src[7] << 8) | ((long)a_src[8] << 16);
if(a_tgtsize<isize) {
a_out << "tools::rroot::key::unzip : too small target." << std::endl;
return false;
}
if(_ibufcnt + HDRSIZE != a_srcsize) {
a_out << "tools::rroot::key::unzip :"
<< " discrepancy in source length." << std::endl;
return false;
}
// D E C O M P R E S S D A T A
if (a_src[0] == 'Z' && a_src[1] == 'L') { //compressed with zlib.
decompress_func func;
if(!a_file.unziper('Z',func)) {
a_out << "tools::rroot::key::unzip : "
<< " zlib unziper not found." << std::endl;
return false;
}
unsigned int irep;
char* src = (char*)(a_src + HDRSIZE);
if(!func(a_out,
(unsigned int)a_srcsize,src,
(unsigned int)a_tgtsize,(char*)a_tgt,irep)) {
a_out << "tools::rroot::key::unzip : "
<< " unzip function failed." << std::endl;
a_irep = 0;
return false;
}
a_irep = irep;
#ifdef TOOLS_USE_CSZ
} else if (a_src[0] == 'C' && a_src[1] == 'S') {
//compressed with Chernyaev & Smirnov
csz__Init_Inflate(_ibufcnt,a_src + HDRSIZE,a_tgtsize,a_tgt);
if (csz__Inflate()) {
a_out << "tools::rroot::key::unzip :"
<< " error during decompression." << std::endl;
return false;
}
unsigned char* obufptr = csz__obufptr();
// if (obufptr - a_tgt != isize) {
// There are some rare cases when a few more bytes are required
if (obufptr - a_tgt > a_tgtsize) {
a_out << "tools::rroot::key::_unzip :"
<< " discrepancy " << (int)(obufptr - a_tgt)
<< " with initial size: " << (int)isize
<< ", tgtsize= " << a_tgtsize
<< std::endl;
a_irep = int(obufptr - a_tgt);
//return false;
}
a_irep = isize;
//a_out << "tools::rroot::key::unzip : CS : ok "
// << a_irep << std::endl;
#endif
} else {
a_out << "tools::rroot::key::_unzip : unknown a_src[0,1]."
<< " [0] = " << a_src[0] << ", [1] = " << a_src[1]
<< std::endl;
a_irep = 0;
return false;
}
return true;
}
static const std::string& s_class() {
static const std::string s_v("tools::rroot::key");
return s_v;
}
protected:
std::ostream& m_out;
uint32 m_buf_size;
char* m_buffer;
// Record (stored in file) :
uint32 m_nbytes; //Number of bytes for the object on file
uint32 m_version; //Key version identifier
uint32 m_object_size; //Length of uncompressed object in bytes
date m_date; //Date/Time of insertion in file
uint16 m_key_length; //Number of bytes for the key itself
uint16 m_cycle; //Cycle number
seek m_seek_key; //Location of object on file
seek m_seek_parent_dir; //Location of parent directory on file
std::string m_object_class; //Object Class name.
std::string m_object_name; //name of the object.
std::string m_object_title; //title of the object.
};
}}
#endif
//doc :
//////////////////////////////////////////////////////////////////////////
// //
// The Key class includes functions to book space on a file, //
// to create I/O buffers, to fill these buffers //
// to compress/uncompress data buffers. //
// //
// Before saving (making persistent) an object on a file, a key must //
// be created. The key structure contains all the information to //
// uniquely identify a persistent object on a file. //
// fNbytes = number of bytes for the compressed object+key //
// version of the Key class //
// fObjlen = Length of uncompressed object //
// fDatime = Date/Time when the object was written //
// fKeylen = number of bytes for the key structure //
// fCycle = cycle number of the object //
// fSeekKey = Address of the object on file (points to fNbytes) //
// This is a redundant information used to cross-check //
// the data base integrity. //
// fSeekPdir = Pointer to the directory supporting this object //
// fClassName = Object class name //
// fName = name of the object //
// fTitle = title of the object //
// //
// The Key class is used by ROOT to: //
// - to write an object in the Current Directory //
// - to write a new ntuple buffer //
// //
//////////////////////////////////////////////////////////////////////////
+488
View File
@@ -0,0 +1,488 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_leaf
#define tools_rroot_leaf
#include "base_leaf"
#include "../stype"
#include "../cids"
namespace tools {
namespace rroot {
inline const std::string& leaf_store_class(char) {
static const std::string s_v("TLeafB");
return s_v;
}
inline const std::string& leaf_store_class(short) {
static const std::string s_v("TLeafS");
return s_v;
}
inline const std::string& leaf_store_class(int) {
static const std::string s_v("TLeafI");
return s_v;
}
inline const std::string& leaf_store_class(float) {
static const std::string s_v("TLeafF");
return s_v;
}
inline const std::string& leaf_store_class(double) {
static const std::string s_v("TLeafD");
return s_v;
}
inline const std::string& leaf_store_class(bool) {
static const std::string s_v("TLeafO");
return s_v;
}
inline const std::string& leaf_float_cls() {
static const std::string s_v("tools::rroot::leaf<float>");
return s_v;
}
inline const std::string& leaf_double_cls() {
static const std::string s_v("tools::rroot::leaf<double>");
return s_v;
}
inline const std::string& leaf_int_cls() {
static const std::string s_v("tools::rroot::leaf<int>");
return s_v;
}
inline const std::string& leaf_bool_cls() {
static const std::string s_v("tools::rroot::leaf<bool>");
return s_v;
}
template <class T>
class leaf : public base_leaf {
public:
typedef T value_t;
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::leaf<"+stype(T())+">");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast< leaf<T> >(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return base_leaf_cid()+_cid(T());}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<leaf>(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
public:
virtual iro* copy() const {return new leaf<T>(*this);}
virtual bool stream(buffer& a_buffer) {
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!base_leaf::stream(a_buffer)) return false;
if(!a_buffer.read(m_min)) return false;
if(!a_buffer.read(m_max)) return false;
if(!a_buffer.check_byte_count(s,c,leaf_store_class(T()))) return false;
return true;
}
public: //base_leaf
virtual bool read_buffer(buffer& a_buffer) {
if(m_leaf_count) {
leaf<int>* leaf_i = safe_cast<base_leaf, leaf<int> >(*m_leaf_count);
if(!leaf_i) {
m_out << "tools::rroot::leaf::read_buffer : leaf_count not a leaf<int>." << std::endl;
return false;
}
int len;
if(!leaf_i->value(0,len)) {
m_out << "tools::rroot::leaf::read_buffer : leaf<int>.value() failed."
<< " m_leaf_count " << m_leaf_count
<< " leaf_i " << leaf_i
<< " Name " << sout(leaf_i->name())
<< " Size " << leaf_i->num_elem() << std::endl;
return false;
}
if (len > leaf_i->get_max()) { //protection.
m_out << "tools::rroot::leaf::read_buffer : warning : " << sout(name())
<< ", len = " << len << " > max = "
<< leaf_i->get_max() << std::endl;
len = leaf_i->get_max();
}
uint32 ndata = len * m_length;
//if(!ndata) {
// delete [] m_value;
// m_value = new T[1];
// m_size = 0;
// return true;
//}
if(ndata>m_size) {
delete [] m_value;
m_value = new T[ndata];
}
m_size = ndata;
if(!a_buffer.read_fast_array(m_value,ndata)) {
m_out << "tools::rroot::leaf::read_buffer : \"" << name() << "\" :"
<< " read_fast_array failed."
<< std::endl;
return false;
}
return true;
} else {
if(m_length) {
if(m_length>m_size) {
delete [] m_value;
m_value = new T[m_length];
}
m_size = m_length;
if(!a_buffer.read_fast_array<T>(m_value,m_length)) {
m_out << "tools::rroot::leaf::read_buffer :"
<< " read_fast_array failed. m_length " << m_length
<< std::endl;
return false;
}
return true;
} else {
m_out << "tools::rroot::leaf::read_buffer :"
<< " read_fast_array failed. m_length is zero."
<< std::endl;
return false;
}
}
return true;
}
virtual bool print_value(std::ostream& a_out,uint32 a_index) const {
if(!m_value) return false;
if(a_index>=m_size) return false;
a_out << m_value[a_index];
return true;
}
//virtual uint32 num_elem() const {return m_length;}
virtual uint32 num_elem() const {return m_size;}
public:
leaf(std::ostream& a_out,ifac& a_fac)
:base_leaf(a_out,a_fac)
,m_min(T()),m_max(T())
,m_value(0),m_size(0)
{}
virtual ~leaf(){
delete [] m_value;
}
protected:
leaf(const leaf& a_from)
:iro(a_from)
,base_leaf(a_from)
,m_min(T()),m_max(T())
,m_value(0),m_size(0)
{}
leaf& operator=(const leaf&){return *this;}
public:
bool value(uint32 a_index,T& a_value) const {
if(!m_value) {a_value = T();return false;}
if(a_index>=m_size) {a_value = T();return false;}
a_value = m_value[a_index];
return true;
}
bool value(std::vector<T>& a_v) const {
if(!m_value) {a_v.clear();return false;}
a_v.resize(m_size);
for(uint32 index=0;index<m_size;index++) a_v[index] = m_value[index];
return true;
}
T get_max() const {return m_max;}
//uint32 size() const {return m_size;}
protected:
T m_min; //Minimum value if leaf range is specified
T m_max; //Maximum value if leaf range is specified
T* m_value; //!Pointer to data buffer
uint32 m_size; //size of m_value array.
};
class leaf_string : public base_leaf {
static const std::string& s_store_class() {
static const std::string s_v("TLeafC");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::leaf_string");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<leaf_string>(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return leaf_string_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<leaf_string>(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
public:
virtual iro* copy() const {return new leaf_string(*this);}
virtual bool stream(buffer& a_buffer) {
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!base_leaf::stream(a_buffer)) return false;
if(!a_buffer.read(m_min)) return false;
if(!a_buffer.read(m_max)) return false;
if(!a_buffer.check_byte_count(s,c,s_store_class())) return false;
return true;
}
public: //base_leaf
virtual bool read_buffer(buffer& a_buffer) {
delete [] m_value;
m_value = 0;
unsigned char lenchar;
if(!a_buffer.read(lenchar)) {
m_out << "tools::rroot::leaf_string::read_buffer :"
<< " read(uchar) failed."
<< std::endl;
return false;
}
uint32 len = 0;
if(lenchar < 255) {
len = lenchar;
} else {
if(!a_buffer.read(len)) {
m_out << "tools::rroot::leaf_string::read_buffer :"
<< " read(int) failed."
<< std::endl;
return false;
}
}
if(len) {
//if(!m_length) {
// m_out << "tools::rroot::leaf_string::read_buffer : m_length is zero." << std::endl;
// return false;
//}
//if(len >= m_length) len = m_length-1;
m_value = new char[len+1];
if(!a_buffer.read_fast_array(m_value,len)) {
m_out << "tools::rroot::leaf_string::read_buffer :"
<< " read_fast_array failed."
<< std::endl;
delete [] m_value;
m_value = 0;
return false;
}
m_value[len] = 0;
} else {
m_value = new char[1];
m_value[0] = 0;
}
return true;
}
virtual bool print_value(std::ostream& a_out,uint32) const {
if(m_value) a_out << m_value;
return true;
}
virtual uint32 num_elem() const {return 1;}
public:
leaf_string(std::ostream& a_out,ifac& a_fac)
:base_leaf(a_out,a_fac)
,m_min(0),m_max(0),m_value(0){}
virtual ~leaf_string(){
delete [] m_value;
}
protected:
leaf_string(const leaf_string& a_from)
:iro(a_from),base_leaf(a_from)
,m_min(0),m_max(0),m_value(0){}
leaf_string& operator=(const leaf_string&){return *this;}
public:
const char* value() const {return m_value;}
protected:
int m_min;
int m_max;
char* m_value;
};
class leaf_element : public base_leaf {
static const std::string& s_store_class() {
static const std::string s_v("TLeafElement");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::leaf_element");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<leaf_element>(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return leaf_element_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<leaf_element>(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
public:
virtual iro* copy() const {return new leaf_element(*this);}
virtual bool stream(buffer& a_buffer) {
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!base_leaf::stream(a_buffer)) return false;
if(!a_buffer.read(fID)) return false;
if(!a_buffer.read(fType)) return false;
if(!a_buffer.check_byte_count(s,c,s_store_class())) return false;
return true;
}
public: //base_leaf
virtual bool read_buffer(buffer&) {
m_out << "tools::rroot::leaf_element::read_buffer : dummy." << std::endl;
return false;
}
virtual bool print_value(std::ostream&,uint32) const {return true;}
virtual uint32 num_elem() const {return 0;}
public:
leaf_element(std::ostream& a_out,ifac& a_fac)
:base_leaf(a_out,a_fac),fID(0),fType(0){}
virtual ~leaf_element(){}
protected:
leaf_element(const leaf_element& a_from)
:iro(a_from),base_leaf(a_from),fID(0),fType(0){}
leaf_element& operator=(const leaf_element&){return *this;}
public:
//int id() const {return fID;}
int leaf_type() const {return fType;}
protected:
int fID; //element serial number in fInfo
int fType; //leaf type
};
}}
#include "iobject"
namespace tools {
namespace rroot {
class leaf_object : public base_leaf {
static const std::string& s_store_class() {
static const std::string s_v("TLeafObject");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::leaf_object");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<leaf_object>(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return leaf_object_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<leaf_object>(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
public:
virtual iro* copy() const {return new leaf_object(*this);}
virtual bool stream(buffer& a_buffer) {
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!base_leaf::stream(a_buffer)) return false;
if(!a_buffer.read(fVirtual)) return false;
if(!a_buffer.check_byte_count(s,c,s_store_class())) return false;
return true;
}
public: //base_leaf
virtual bool read_buffer(buffer& a_buffer) {
if(!m_obj) {
m_out << "tools::rroot::leaf_object::read_buffer : m_obj is null." << std::endl;
return false;
}
std::string fClassName;
if (fVirtual) {
unsigned char n;
if(!a_buffer.read(n)) {
m_out << "tools::rroot::leaf_object::read_buffer :"
<< " read(unsigned char) failed."
<< std::endl;
return false;
}
char classname[128];
if(!a_buffer.read_fast_array(classname,n+1)) {
m_out << "tools::rroot::leaf_object::read_buffer :"
<< " readFastArray failed."
<< std::endl;
return false;
}
fClassName = classname;
}
if(m_obj->store_class_name()!=fClassName) {
m_out << "tools::rroot::leaf_object::read_buffer : WARNING : class mismatch :"
<< " fClassName " << sout(fClassName)
<< ". m_obj.store_class_name() " << sout(m_obj->store_class_name())
<< std::endl;
//return false;
}
if(!m_obj->stream(a_buffer)) {
m_out << "tools::rroot::leaf_object::read_buffer :"
<< " object stream failed."
<< " Object store class was " << m_obj->store_class_name() << "."
<< std::endl;
return false;
}
// in case we had written a null pointer a Zombie object was created
// we must delete it
//FIXME
//if (object->TestBit(kInvalidObject)) {
// if (object->GetUniqueID() == 123456789) {
// delete object;
// object = 0;
// }
//}
return true;
}
virtual bool print_value(std::ostream&,uint32) const {
m_out << m_obj << std::endl;
return true;
}
virtual uint32 num_elem() const {return 0;}
public:
leaf_object(std::ostream& a_out,ifac& a_fac)
:base_leaf(a_out,a_fac),m_obj(0),fVirtual(true){}
virtual ~leaf_object(){}
protected:
leaf_object(const leaf_object& a_from)
:iro(a_from),base_leaf(a_from),m_obj(0),fVirtual(true){}
leaf_object& operator=(const leaf_object&){return *this;}
public:
void set_object(iobject* a_obj) {m_obj = a_obj;} //do not get ownership.
protected:
iobject* m_obj;
protected:
bool fVirtual; // Support for Virtuality
};
// for SWIG :
inline leaf<int>* cast_leaf_int(base_leaf& a_leaf) {return safe_cast<base_leaf, leaf<int> >(a_leaf);}
inline leaf<float>* cast_leaf_float(base_leaf& a_leaf) {return safe_cast<base_leaf, leaf<float> >(a_leaf);}
inline leaf<double>* cast_leaf_double(base_leaf& a_leaf) {return safe_cast<base_leaf, leaf<double> >(a_leaf);}
}}
#endif
+88
View File
@@ -0,0 +1,88 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_matrix
#define tools_rroot_matrix
//NOTE : not yet tested.
#include "../scast"
#include "buffer"
#include "named"
namespace tools {
namespace rroot {
class matrix : public virtual iro {
static const std::string& s_store_class() {
static const std::string s_v("TMatrix");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::matrix");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<matrix>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
virtual iro* copy() const {return new matrix(*this);}
public:
static cid id_class() {return matrix_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<matrix>(this,a_class)) {return p;}
else return 0;
}
public:
virtual bool stream(buffer& a_buffer) {
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return false;
//printf("debug : tools::rroot::matrix::stream : version %d\n",v);
// Version 2 streaming (ROOT/v3-00-6).
{uint32 id,bits;
if(!Object_stream(a_buffer,id,bits)) return false;}
int Nrows;
if(!a_buffer.read(Nrows)) return false;
int Ncols;
if(!a_buffer.read(Ncols)) return false;
int Nelems;
if(!a_buffer.read(Nelems)) return false;
int RowLwb;
if(!a_buffer.read(RowLwb)) return false;
int ColLwb;
if(!a_buffer.read(ColLwb)) return false;
//Real_t* Elements; //[fNelems]
if(!dummy_array_stream<float>(a_buffer,Nelems)) return false;
if(!a_buffer.check_byte_count(s,c,s_store_class())) return false;
return true;
}
public:
matrix(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~matrix(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
matrix(const matrix& a_from): iro(a_from){}
matrix& operator=(const matrix&){return *this;}
};
}}
#endif
@@ -0,0 +1,99 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_member_reader
#define tools_rroot_member_reader
#include "../store/iobj_visitor"
#include "buffer"
namespace tools {
namespace rroot {
class member_reader : public virtual iobj_visitor {
public:
virtual std::ostream& out() const {return m_buf.out();}
virtual bool visit(bool& a_v){return m_buf.read(a_v);}
virtual bool visit(char& a_v){return m_buf.read(a_v);}
virtual bool visit(short& a_v){return m_buf.read(a_v);}
virtual bool visit(int& a_v){return m_buf.read(a_v);}
virtual bool visit(unsigned int& a_v){return m_buf.read(a_v);}
virtual bool visit(int64&){
m_buf.out() << "tools::rroot::member_reader::visit(int64) :"
<< " dummy." << std::endl;
return false; //FIXME
}
virtual bool visit(uint64&){
m_buf.out() << "tools::rroot::member_reader::visit(uint64) :"
<< " dummy." << std::endl;
return false; //FIXME
}
virtual bool visit(float& a_v){return m_buf.read(a_v);}
virtual bool visit(double& a_v){return m_buf.read(a_v);}
virtual bool visit(std::string& a_v){return m_buf.read(a_v);}
//virtual bool visit(const char* a_v){
// return m_buf.read(std::string(a_v));
//}
virtual bool visit(std::vector<bool>& a_v){
std::vector<unsigned char> data;
if(!m_buf.read_array(data)) {a_v.clear();return false;}
size_t number = data.size();
a_v.resize(number);
for(size_t index=0;index<number;index++) {
a_v[index] = (data[index]==1?true:false);
}
return true;
}
virtual bool visit(std::vector<char>& a_v){return m_buf.read_array(a_v);}
virtual bool visit(std::vector<short>& a_v){return m_buf.read_array(a_v);}
virtual bool visit(std::vector<int>& a_v){return m_buf.read_array(a_v);}
virtual bool visit(std::vector<int64>& /*a_v*/){
//FIXME return ::Rio::writeArray<Slash::int64>(fBuffer,a_v);
m_buf.out() << "tools::rroot::member_reader::visit(vector<int64>) :"
<< " dummy." << std::endl;
return false;
}
virtual bool visit(std::vector<float>& a_v){return m_buf.read_array(a_v);}
virtual bool visit(std::vector<double>& a_v){return m_buf.read_array(a_v);}
virtual bool visit(std::vector<unsigned char>& a_v){
return m_buf.read_array(a_v);
}
virtual bool visit(std::vector<std::string>& a_v){return m_buf.read(a_v);}
virtual bool visit(std::vector< std::vector<double> >& a_v){
return m_buf.read_array2(a_v);
}
public:
member_reader(buffer& a_buf):m_buf(a_buf){}
virtual ~member_reader(){}
private:
member_reader(const member_reader& a_from)
:iobj_visitor(a_from)
,m_buf(a_from.m_buf)
{}
member_reader& operator=(const member_reader&){return *this;}
protected:
buffer& m_buf;
};
}}
#endif
+161
View File
@@ -0,0 +1,161 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_named
#define tools_rroot_named
#include "object"
#include "../scast"
#include "../vdata"
#include "cids"
namespace tools {
namespace rroot {
inline bool Named_stream(buffer& a_buffer,std::string& a_name,std::string& a_title) {
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
{uint32 id,bits;
if(!Object_stream(a_buffer,id,bits)) return false;}
if(!a_buffer.read(a_name)) return false;
if(!a_buffer.read(a_title)) return false;
if(!a_buffer.check_byte_count(s,c,"TNamed")) return false;
return true;
}
inline bool AttLine_stream(buffer& a_buffer,short& a_color,short& a_style,short& a_width){
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!a_buffer.read(a_color)) return false;
if(!a_buffer.read(a_style)) return false;
if(!a_buffer.read(a_width)) return false;
if(!a_buffer.check_byte_count(s,c,"TAttLine")) return false;
return true;
}
inline bool AttFill_stream(buffer& a_buffer,short& a_color,short& a_style){
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!a_buffer.read(a_color)) return false;
if(!a_buffer.read(a_style)) return false;
if(!a_buffer.check_byte_count(s,c,"TAttFill")) return false;
return true;
}
inline bool AttMarker_stream(buffer& a_buffer) {
short fMarkerColor;
short fMarkerStyle;
float fMarkerWidth;
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!a_buffer.read(fMarkerColor)) return false;
if(!a_buffer.read(fMarkerStyle)) return false;
if(!a_buffer.read(fMarkerWidth)) return false;
if(!a_buffer.check_byte_count(s,c,"TAttMarker")) return false;
return true;
}
inline bool GeoAtt_stream(buffer& a_buffer) {
unsigned int fGeoAtt; // option flags
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!a_buffer.read(fGeoAtt)) return false;
if(!a_buffer.check_byte_count(s,c,"TGeoAtt")) return false;
return true;
}
inline bool Att3D_stream(buffer& a_buffer) {
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!a_buffer.check_byte_count(s,c,"TAtt3D")) return false;
return true;
}
template <class T>
inline bool Array_stream(buffer& a_buffer,std::vector<T>& a_v) {
a_v.clear();
int sz;
if(!a_buffer.read(sz)) return false;
//check sz is not crazy :
if(!a_buffer.check_eob(sz)) return false;
a_v.resize(sz);
if(!a_buffer.read_fast_array<T>(vec_data(a_v),sz)) return false;
return true;
}
template <class T>
inline bool dummy_array_stream(buffer& a_buffer,int a_n){
char is_array;
if(!a_buffer.read(is_array)) return false;
if(!is_array) return true;
if(!a_n) return true;
T* v = new T[a_n];
bool status = a_buffer.read_fast_array<T>(v,a_n);
delete [] v;
return status;
}
class named : public virtual iro {
static const std::string& s_store_class() {
static const std::string s_v("TNamed");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::named");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<named>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return named_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<named>(this,a_class)) {return p;}
else return 0;
}
//virtual void* cast(cid) const {return named_cid();}
public:
virtual iro* copy() const {return new named(*this);}
virtual bool stream(buffer& a_buffer) {
return Named_stream(a_buffer,m_name,m_title);
}
public:
named() {
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~named() {
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
named(const named& a_from):iro(a_from),m_name(a_from.m_name),m_title(a_from.m_title) {
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
named& operator=(const named& a_from){
m_name = a_from.m_name;
m_title = a_from.m_title;
return *this;
}
protected:
std::string m_name;
std::string m_title;
};
}}
#endif
+771
View File
@@ -0,0 +1,771 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_ntuple
#define tools_rroot_ntuple
// to have same API than rcsv::ntuple.
#include "../rntuple"
#include "tree"
#include "leaf"
#include "stl_vector"
#include "../cids"
#include "../vfind"
#include "../vmanip"
#include "../ntuple_binding"
#include "../get_lines"
#ifdef TOOLS_MEM
#include "../mem"
#endif
namespace tools {
namespace rroot {
class ntuple : public virtual read::intuple {
typedef read::intuple parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::ntuple");
return s_v;
}
virtual const std::string& s_cls() const {return s_class();}
public: //intuple
virtual void start() {m_index = -1;}
virtual bool next() {
m_index++;
if((uint64)m_index>=m_tree.entries()) return false;
return true;
}
virtual read::icol* find_icol(const std::string& a_name){
return find_named<read::icol>(m_cols,a_name);
}
virtual const std::vector<read::icol*>& columns() const {return m_cols;}
virtual const std::string& title() const {return m_tree.title();}
virtual bool number_of_entries(uint64 & a_value) const {a_value = m_tree.entries();return true;}
public:
template <class T,class LEAF>
class column_ref : public virtual read::icolumn<T> {
typedef read::icolumn<T> parent;
public:
static cid id_class() {return 200+_cid(T())+10000;}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<column_ref>(this,a_class)) return p;
return parent::cast(a_class);
}
virtual cid id_cls() const {return id_class();}
public: //icol
virtual const std::string& name() const {return m_leaf.name();}
public: //icolumn<T>
virtual bool fetch_entry() const {return _fetch_entry();}
virtual bool get_entry(T& a_v) const {
if(!_fetch_entry()) {a_v = T();return false;}
a_v = m_ref;
return true;
}
public:
column_ref(ifile& a_file,branch& a_branch,LEAF& a_leaf,int64& a_index,T& a_ref)
:m_file(a_file)
,m_branch(a_branch)
,m_leaf(a_leaf)
,m_index(a_index) //WARNING : we keep the ref !
,m_ref(a_ref)
{}
virtual ~column_ref(){}
protected:
column_ref(const column_ref& a_from)
:read::icol(a_from)
,parent(a_from)
,m_file(a_from.m_file)
,m_branch(a_from.m_branch)
,m_leaf(a_from.m_leaf)
,m_index(a_from.m_index)
,m_ref(a_from.m_ref)
{}
column_ref& operator=(const column_ref& a_from){
if(&a_from==this) return *this;
return *this;
}
protected:
//typedef typename LEAF::value_t value_t;
bool _fetch_entry() const {
unsigned int n;
if(!m_branch.find_entry(m_file,uint32(m_index),n)) {m_ref = T();return false;}
if(!m_leaf.num_elem()) {m_ref = T();return true;} //it is ok. It may be a vector from a row_wise ntuple column.
typename LEAF::value_t _tmp;
if(!m_leaf.value(0,_tmp)) return false;
m_ref = T(_tmp);
return true;
}
protected:
ifile& m_file;
branch& m_branch;
LEAF& m_leaf;
int64& m_index; //WARNING : a ref.
T& m_ref;
//value_t m_tmp;
};
template <class T,class LEAF>
class column : public column_ref<T,LEAF> {
typedef column_ref<T,LEAF> parent;
public:
static cid id_class() {return 200+_cid(T());}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<column>(this,a_class)) return p;
return parent::cast(a_class);
}
virtual cid id_cls() const {return id_class();}
public:
column(ifile& a_file,branch& a_branch,LEAF& a_leaf,int64& a_index)
:parent(a_file,a_branch,a_leaf,a_index,m_value)
,m_value(T())
{}
virtual ~column(){}
protected:
column(const column& a_from)
:read::icol(a_from)
,read::icolumn<T>(a_from)
,parent(a_from)
,m_value(a_from.m_value)
{}
column& operator=(const column& a_from){
if(&a_from==this) return *this;
m_value = a_from.m_value;
return *this;
}
public:
const T& get_value() const {return m_value;}
protected:
T m_value;
};
class column_string_ref : public virtual read::icol {
typedef read::icol parent;
public:
static cid id_class() {
static const std::string s_v;
return _cid(s_v)+10000;
}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<column_string_ref>(this,a_class)) return p;
return 0;
}
virtual cid id_cls() const {return id_class();}
virtual const std::string& name() const {return m_leaf.name();}
public:
virtual bool fetch_entry() const {return _fetch_entry();}
public:
column_string_ref(ifile& a_file,branch& a_branch,leaf_string& a_leaf,int64& a_index,std::string& a_ref)
:m_file(a_file)
,m_branch(a_branch)
,m_leaf(a_leaf)
,m_index(a_index) //WARNING : we keep the ref !
,m_ref(a_ref)
{}
virtual ~column_string_ref(){}
protected:
column_string_ref(const column_string_ref& a_from)
:parent(a_from)
,m_file(a_from.m_file)
,m_branch(a_from.m_branch)
,m_leaf(a_from.m_leaf)
,m_index(a_from.m_index)
,m_ref(a_from.m_ref)
{}
column_string_ref& operator=(const column_string_ref& a_from){
if(&a_from==this) return *this;
return *this;
}
public:
bool get_entry(std::string& a_v) const {
if(!_fetch_entry()) {a_v.clear();return false;}
a_v = m_ref;
return true;
}
protected:
bool _fetch_entry() const {
unsigned int n;
if(!m_branch.find_entry(m_file,uint32(m_index),n)) {m_ref.clear();return false;}
const char* _cs = m_leaf.value();
if(!_cs) {m_ref.clear();return false;}
m_ref = _cs;
return true;
}
protected:
ifile& m_file;
branch& m_branch;
leaf_string& m_leaf;
int64& m_index; //WARNING : a ref.
std::string& m_ref;
};
class column_string : public column_string_ref {
typedef column_string_ref parent;
public:
static cid id_class() {
static const std::string s_v;
return _cid(s_v);
}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<column_string>(this,a_class)) return p;
return parent::cast(a_class);
}
virtual cid id_cls() const {return id_class();}
virtual const std::string& name() const {return m_leaf.name();}
public:
column_string(ifile& a_file,branch& a_branch,leaf_string& a_leaf,int64& a_index)
:parent(a_file,a_branch,a_leaf,a_index,m_value)
{}
virtual ~column_string(){}
protected:
column_string(const column_string& a_from)
:read::icol(a_from)
,parent(a_from)
,m_value(a_from.m_value)
{}
column_string& operator=(const column_string& a_from){
if(&a_from==this) return *this;
m_value = a_from.m_value;
return *this;
}
public:
const std::string& get_value() const {return m_value;}
protected:
std::string m_value;
};
class column_vector_string_ref : public column_string_ref {
typedef column_string_ref parent;
public:
static cid id_class() {return _cid_std_vector<std::string>()+10000;}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<column_vector_string_ref>(this,a_class)) return p;
return parent::cast(a_class);
}
virtual cid id_cls() const {return id_class();}
virtual const std::string& name() const {return m_leaf.name();}
public:
virtual bool fetch_entry() const {return _fetch_entry();}
public:
column_vector_string_ref(ifile& a_file,branch& a_branch,leaf_string& a_leaf,int64& a_index,
std::vector<std::string>& a_ref,char a_sep)
:parent(a_file,a_branch,a_leaf,a_index,m_value)
,m_ref(a_ref)
,m_sep(a_sep)
{}
virtual ~column_vector_string_ref(){}
protected:
column_vector_string_ref(const column_vector_string_ref& a_from)
:read::icol(a_from)
,parent(a_from)
,m_ref(a_from.m_ref)
,m_sep(a_from.m_sep)
{}
column_vector_string_ref& operator=(const column_vector_string_ref& a_from){
if(&a_from==this) return *this;
m_sep = a_from.m_sep;
return *this;
}
public:
bool get_entry(std::vector<std::string>& a_v) const {
if(!_fetch_entry()) {a_v.clear();return false;}
a_v = m_ref;
return true;
}
protected:
bool _fetch_entry() const {
if(!parent::_fetch_entry()) return false;
get_lines(m_value,m_ref);
return true;
}
protected:
std::vector<std::string>& m_ref;
char m_sep;
std::string m_value;
};
class column_vector_string : public column_vector_string_ref {
typedef column_vector_string_ref parent;
public:
static cid id_class() {return _cid_std_vector<std::string>();}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<column_vector_string>(this,a_class)) return p;
return parent::cast(a_class);
}
virtual cid id_cls() const {return id_class();}
virtual const std::string& name() const {return m_leaf.name();}
public:
column_vector_string(ifile& a_file,branch& a_branch,leaf_string& a_leaf,int64& a_index,char a_sep)
:parent(a_file,a_branch,a_leaf,a_index,m_value,a_sep)
{}
virtual ~column_vector_string(){}
protected:
column_vector_string(const column_vector_string& a_from)
:read::icol(a_from)
,parent(a_from)
,m_value(a_from.m_value)
{}
column_vector_string& operator=(const column_vector_string& a_from){
if(&a_from==this) return *this;
m_value = a_from.m_value;
return *this;
}
public:
const std::vector<std::string>& get_value() const {return m_value;}
protected:
std::vector<std::string> m_value;
};
// to read row_wise columns with vector of basic types :
template <class T>
class std_vector_column_ref : public virtual read::icolumn<T> {
typedef read::icolumn<T> parent;
public:
static cid id_class() {return 200+_cid(T())+10000;}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<std_vector_column_ref>(this,a_class)) return p;
return parent::cast(a_class);
}
virtual cid id_cls() const {return id_class();}
public: //icol
virtual const std::string& name() const {return m_leaf.name();}
public: //icolumn<T>
virtual bool fetch_entry() const {return _fetch_entry();}
virtual bool get_entry(T& a_v) const {
if(!_fetch_entry()) {a_v = T();return false;}
if(m_ref.empty()) {a_v = T();return false;}
a_v = m_ref[0];
return true;
}
public:
std_vector_column_ref(ifile& a_file,branch& a_branch,leaf<T>& a_leaf,int64& a_index,std::vector<T>& a_ref)
:m_file(a_file)
,m_branch(a_branch)
,m_leaf(a_leaf)
,m_index(a_index) //WARNING : we keep the ref !
,m_ref(a_ref)
{}
virtual ~std_vector_column_ref(){}
protected:
std_vector_column_ref(const std_vector_column_ref& a_from)
:read::icol(a_from)
,parent(a_from)
,m_file(a_from.m_file)
,m_branch(a_from.m_branch)
,m_leaf(a_from.m_leaf)
,m_index(a_from.m_index)
,m_ref(a_from.m_ref)
{}
std_vector_column_ref& operator=(const std_vector_column_ref& a_from){
if(&a_from==this) return *this;
return *this;
}
protected:
bool _fetch_entry() const {
unsigned int n;
if(!m_branch.find_entry(m_file,uint32(m_index),n)) {m_ref.clear();return false;}
m_leaf.value(m_ref);
return true;
}
protected:
ifile& m_file;
branch& m_branch;
leaf<T>& m_leaf;
int64& m_index; //WARNING : a ref.
std::vector<T>& m_ref;
};
// to read column_wise columns with vector of basic types :
template <class RT,class T>
class column_element_ref : public virtual read::icolumn<T> {
typedef read::icolumn<T> parent;
public:
static cid id_class() {return 300+_cid(T())+10000;}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<column_element_ref>(this,a_class)) return p;
return parent::cast(a_class);
}
virtual cid id_cls() const {return id_class();}
public: //icol
virtual const std::string& name() const {return m_leaf.name();}
public: //icolumn<T>
virtual bool fetch_entry() const {return _fetch_entry();}
virtual bool get_entry(T& a_v) const {
if(!_fetch_entry()) {a_v = T();return false;}
a_v = m_ref;
return true;
}
public:
column_element_ref(ifile& a_file,branch_element& a_branch,leaf_element& a_leaf,int64& a_index,T& a_ref)
:m_file(a_file)
,m_be(a_branch)
,m_leaf(a_leaf)
,m_index(a_index) //WARNING : we keep the ref !
,m_ref(a_ref)
{}
virtual ~column_element_ref(){}
protected:
column_element_ref(const column_element_ref& a_from)
:read::icol(a_from),parent(a_from)
,m_file(a_from.m_file)
,m_be(a_from.m_be)
,m_leaf(a_from.m_leaf)
,m_index(a_from.m_index)
,m_ref(a_from.m_ref)
{}
column_element_ref& operator=(const column_element_ref& a_from){
if(&a_from==this) return *this;
return *this;
}
protected:
bool _fetch_entry() const {
unsigned int n;
if(!m_be.find_entry(m_file,uint32(m_index),n)) {m_ref = T();return false;}
iro* obj = m_be.object(); //Not owner.
if(!obj) {m_ref = T();return false;}
RT* v = id_cast<iro,RT>(*obj);
if(!v) {m_ref = T();return false;}
m_ref = *v; //it assumes a T::operator=(RT)
return true;
}
protected:
ifile& m_file;
branch_element& m_be;
leaf_element& m_leaf;
int64& m_index; //WARNING : a ref.
T& m_ref;
};
template <class RT,class T>
class column_element : public column_element_ref<RT,T> {
typedef column_element_ref<RT,T> parent;
public:
static cid id_class() {return 300+_cid(T());}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<column_element>(this,a_class)) return p;
return parent::cast(a_class);
}
virtual cid id_cls() const {return id_class();}
public:
column_element(ifile& a_file,branch_element& a_branch,leaf_element& a_leaf,int64& a_index)
:parent(a_file,a_branch,a_leaf,a_index,m_value)
,m_value(T())
{}
virtual ~column_element(){}
protected:
column_element(const column_element& a_from)
:read::icol(a_from)
,read::icolumn<T>(a_from)
,parent(a_from)
,m_value(a_from.m_value)
{}
column_element& operator=(const column_element& a_from){
if(&a_from==this) return *this;
m_value = a_from.m_value;
return *this;
}
public:
const T& get_value() const {return m_value;}
protected:
T m_value;
};
public:
ntuple(tree& a_tree):m_tree(a_tree),m_index(-1){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~ntuple() {
safe_clear<read::icol>(m_cols);
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
ntuple(const ntuple& a_from)
:parent(a_from),m_tree(a_from.m_tree){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
ntuple& operator=(const ntuple&){return *this;}
public:
bool initialize(std::ostream& a_out,const ntuple_binding& a_bd = ntuple_binding(),bool a_enforce_double = false) {
safe_clear<read::icol>(m_cols);
std::vector<base_leaf*> leaves;
m_tree.find_leaves(leaves);
tools_vforcit(base_leaf*,leaves,it) {
base_leaf* bl = (*it);
if(find_named<read::icol>(m_cols,bl->name())) {
a_out << "tools::rroot::ntuple::initialize :"
<< " column with name " << sout(bl->name())
<< " already exists."
<< std::endl;
safe_clear<read::icol>(m_cols);
return false;
}
branch* _branch = m_tree.find_leaf_branch(*bl);
if(!_branch) {
a_out << "tools::rroot::ntuple::initialize :"
<< " can't find branch of leaf " << sout(bl->name()) << "."
<< std::endl;
safe_clear<read::icol>(m_cols);
return false;
}
//a_out << "tools::rroot::ntuple::initialize :"
// << " branch " << _branch->name()
// << ", entries " << _branch->entry_number() << "."
// << std::endl;
#define TOOLS_RROOT_NTUPLE_CREATE_COL(a__type) \
if(leaf<a__type>* lf_##a__type = safe_cast<base_leaf, leaf<a__type> >(*bl) ){\
cid user_cid;void* user_obj;\
a_bd.find_user_obj(bl->name(),user_cid,user_obj);\
typedef leaf<a__type> leaf_t;\
if(!user_obj) {\
if(a_enforce_double) {\
column<double,leaf_t>* col = new column<double,leaf_t>(m_tree.file(),*_branch,*lf_##a__type,m_index);\
m_cols.push_back(col);\
} else {\
column<a__type,leaf_t>* col = new column<a__type,leaf_t>(m_tree.file(),*_branch,*lf_##a__type,m_index);\
m_cols.push_back(col);\
}\
} else {\
const base_leaf* lfc = bl->leaf_count();\
if(lfc) {\
/*::printf("debug : ntuple : create col leaf count : %s\n",bl->name().c_str());*/\
if(user_cid!=_cid_std_vector<a__type>()) {\
a_out << "tools::rroot::ntuple::initialize :"\
<< " for leaf with name " << sout(bl->name())\
<< ", user variable type is not a std::vector of " << #a__type << "."\
<< std::endl;\
safe_clear<read::icol>(m_cols);\
return false;\
}\
std::vector<a__type>* user_var = (std::vector<a__type>*)user_obj;\
std_vector_column_ref<a__type>* col = new std_vector_column_ref<a__type>\
(m_tree.file(),*_branch,*lf_##a__type,m_index,*user_var);\
m_cols.push_back(col);\
} else {\
/*::printf("debug : ntuple : create col : %s\n",bl->name().c_str());*/\
if(user_cid!=_cid(a__type())) {\
a_out << "tools::rroot::ntuple::initialize :"\
<< " for leaf with name " << sout(bl->name())\
<< ", user variable type is not a " << #a__type << "."\
<< std::endl;\
safe_clear<read::icol>(m_cols);\
return false;\
}\
a__type* user_var = (a__type*)user_obj;\
column_ref<a__type,leaf_t>* col =\
new column_ref<a__type,leaf_t>(m_tree.file(),*_branch,*lf_##a__type,m_index,*user_var);\
m_cols.push_back(col);\
}\
}\
}
//below types are in sync with wroot/ntuple.
TOOLS_RROOT_NTUPLE_CREATE_COL(char)
else TOOLS_RROOT_NTUPLE_CREATE_COL(short)
else TOOLS_RROOT_NTUPLE_CREATE_COL(int)
else TOOLS_RROOT_NTUPLE_CREATE_COL(float)
else TOOLS_RROOT_NTUPLE_CREATE_COL(double)
else if(leaf_string* ls = safe_cast<base_leaf, leaf_string >(*bl) ){
char sep = '\n';
cid user_cid;void* user_obj;
if(!a_bd.find_user_obj(bl->name(),user_cid,user_obj)) {
column_vector_string* col = new column_vector_string(m_tree.file(),*_branch,*ls,m_index,sep);
m_cols.push_back(col);
} else if(user_cid==_cid_std_vector<std::string>()) {
std::vector<std::string>* user_var = (std::vector<std::string>*)user_obj;
if(user_var) {
column_vector_string_ref* col = new column_vector_string_ref(m_tree.file(),*_branch,*ls,m_index,*user_var,sep);
m_cols.push_back(col);
} else {
column_vector_string* col = new column_vector_string(m_tree.file(),*_branch,*ls,m_index,sep);
m_cols.push_back(col);
}
} else if(user_cid==_cid(std::string())) {
std::string* user_var = (std::string*)user_obj;
if(user_var) {
column_string_ref* col = new column_string_ref(m_tree.file(),*_branch,*ls,m_index,*user_var);
m_cols.push_back(col);
} else {
column_string* col = new column_string(m_tree.file(),*_branch,*ls,m_index);
m_cols.push_back(col);
}
} else {
a_out << "tools::rroot::ntuple::initialize :"
<< " for leaf with name " << sout(ls->name())
<< ", user variable type is not a std::string or a std::vector<std::string>."
<< ". It's class id is " << user_cid << "."
<< std::endl;
safe_clear<read::icol>(m_cols);
return false;
}
} else if(leaf_element* le = safe_cast<base_leaf,leaf_element>(*bl) ){
branch_element* be = safe_cast<branch,branch_element>(*_branch);
if(!be) {
a_out << "tools::rroot::ntuple::initialize : branch is not a branch_element." << std::endl;
safe_clear<read::icol>(m_cols);
return false;
}
#define TOOLS_RROOT_NTUPLE_CREATE_VEC_COL(a__name,a__type) \
if(be->class_name()==a__name) {\
/*::printf("debug : ntuple : create vec col : %s\n",bl->name().c_str());*/\
typedef a__type el_t;\
std::vector<el_t>* user_var = a_bd.find_vector_variable<el_t>(bl->name());\
if(user_var) {\
typedef column_element_ref< stl_vector<el_t> , std::vector<el_t> > ce_t;\
ce_t* col = new ce_t(m_tree.file(),*be,*le,m_index,*user_var);\
m_cols.push_back(col);\
} else {\
typedef column_element< stl_vector<el_t> , std::vector<el_t> > ce_t;\
ce_t* col = new ce_t(m_tree.file(),*be,*le,m_index);\
m_cols.push_back(col);\
}\
}
TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<char>",char)
else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<short>",short)
//else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<unsigned short>",unsigned short)
//else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<unsigned int>",unsigned int)
else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<int>",int)
else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<float>",float)
else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<double>",double)
//else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<string>",std::string)
//else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<unsigned long>",uint64) //beurk
// WARNING : take care of the space in "> >".
/* VisualC++ : the below does not compile.
else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<unsigned short> >",std::vector<unsigned short>)
else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<short> >",std::vector<short>)
else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<unsigned int> >",std::vector<unsigned int>)
else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<int> >",std::vector<short>)
else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<float> >",std::vector<float>)
else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<double> >",std::vector<double>)
*/
else {
a_out << "tools::rroot::ntuple::initialize :"
<< " WARNING : leaf element"
<< " with name " << sout(bl->name())
<< ",title " << sout(bl->title())
<< " br_elem class name " << be->class_name() << "."
<< " entries " << be->entry_number() << "."
<< std::endl;
}
} else {
a_out << "tools::rroot::ntuple::initialize :"
<< " WARNING : column type not yet handled for leaf"
<< " with name " << sout(bl->name())
<< " and title " << sout(bl->title()) << "."
<< " s_cls() is " << sout(bl->s_cls()) << "."
<< " Not fatal."
<< std::endl;
}
}
#undef TOOLS_RROOT_NTUPLE_CREATE_VEC_COL
#undef TOOLS_RROOT_NTUPLE_CREATE_COL
size_t num = m_cols.size();
if(!num) {
a_out << "tools::rroot::ntuple::initialize :"
<< " zero columns."
<< std::endl;
return false;
}
{tools_vforcit(column_binding,a_bd.columns(),it) {
if(!find_named<read::icol>(m_cols,(*it).name())) {
a_out << "tools::rroot::ntuple::initialize :"
<< " warning : for column binding with name " << sout((*it).name()) << ", no ntuple column found."
<< std::endl;
}
}}
//a_out << "tools::rroot::ntuple::initialize :"
// << " number of columns " << num << "."
// << std::endl;
return true;
}
bool get_row() const {
bool status = true;
tools_vforcit(read::icol*,m_cols,it) {
if(!(*it)->fetch_entry()) {
m_tree.out() << "tools::rroot::ntuple::get_row : fetch_entry() failed for leaf " << (*it)->name() << std::endl;
status = false;
}
}
return status;
}
protected:
tree& m_tree;
std::vector<read::icol*> m_cols;
int64 m_index;
};
// for gopaw :
class fac_tree_holder {
public:
fac_tree_holder(ifac* a_fac,tree* a_tree):m_fac(a_fac),m_tree(a_tree){} //own a_fac,a_tree.
virtual ~fac_tree_holder() {delete m_tree;delete m_fac;}
protected:
fac_tree_holder(const fac_tree_holder&){}
fac_tree_holder& operator=(const fac_tree_holder&){return *this;}
protected:
ifac* m_fac;
tree* m_tree;
};
class fac_tree_ntuple : public fac_tree_holder, public ntuple { //fac_tree_holder must be first.
typedef ntuple parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::fac_tree_ntuple");
return s_v;
}
virtual const std::string& s_cls() const {return s_class();}
public:
fac_tree_ntuple(ifac* a_fac,tree* a_tree) //own these.
:fac_tree_holder(a_fac,a_tree)
,parent(*a_tree) //deleted first.
{}
virtual ~fac_tree_ntuple() {}
protected:
fac_tree_ntuple(const fac_tree_ntuple& a_from):read::intuple(a_from),fac_tree_holder(a_from),parent(a_from){}
fac_tree_ntuple& operator=(const fac_tree_ntuple&){return *this;}
};
}}
#endif
+211
View File
@@ -0,0 +1,211 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_obj_array
#define tools_rroot_obj_array
#include "object"
#include "../vmanip"
#include "../scast"
#include "cids"
namespace tools {
namespace rroot {
template <class T>
class obj_array : public virtual iro,public std::vector<T*> {
typedef typename std::vector<T*> parent;
private:
static const std::string& s_store_class() {
static const std::string s_v("TObjArray");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::obj_array<"+T::s_class()+">");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast< obj_array<T> >(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return obj_array_cid()+T::id_class();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<obj_array>(this,a_class)) {return p;}
return 0;
}
virtual iro* copy() const {return new obj_array<T>(*this);}
virtual bool stream(buffer& a_buffer) {
ifac::args args;
bool accept_null = false;
return stream(a_buffer,args,accept_null);
}
public:
obj_array(ifac& a_fac)
:m_fac(a_fac)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~obj_array(){
_clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
obj_array(const obj_array& a_from)
:iro(a_from)
,parent()
,m_fac(a_from.m_fac)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
typedef typename parent::const_iterator it_t;
for(it_t it=a_from.begin();it!=a_from.end();++it) {
if(!(*it)) {
parent::push_back(0);
m_owns.push_back(false);
} else {
iro* _obj = (*it)->copy();
T* obj = safe_cast<iro,T>(*_obj);
if(!obj) {
m_fac.out() << "tools::rroot::obj_array::obj_array :"
<< " inlib::cast failed."
<< std::endl;
delete _obj;
parent::push_back(0);
m_owns.push_back(false);
} else {
parent::push_back(obj);
m_owns.push_back(true);
}
}
}
}
obj_array& operator=(const obj_array& a_from){
if(&a_from==this) return *this;
_clear();
typedef typename parent::const_iterator it_t;
for(it_t it=a_from.begin();it!=a_from.end();++it) {
if(!(*it)) {
parent::push_back(0);
m_owns.push_back(false);
} else {
iro* _obj = (*it)->copy();
T* obj = safe_cast<iro,T>(*_obj);
if(!obj) {
m_fac.out() << "tools::rroot::obj_array::operator= :"
<< " inlib::cast failed."
<< std::endl;
delete _obj;
parent::push_back(0);
m_owns.push_back(false);
} else {
parent::push_back(obj);
m_owns.push_back(true);
}
}
}
return *this;
}
public:
void cleanup() {_clear();}
public:
bool stream(buffer& a_buffer,const ifac::args& a_args,bool a_accept_null = false) {
_clear();
//::printf("debug : obj_array::stream : %lu : begin\n",(unsigned long)this);
short v;
unsigned int sp, bc;
if(!a_buffer.read_version(v,sp,bc)) return false;
//::printf("debug : obj_array::stream : version %d, byte count %d\n",v,bc);
{uint32 id,bits;
if(!Object_stream(a_buffer,id,bits)) return false;}
std::string name;
if(!a_buffer.read(name)) return false;
int nobjects;
if(!a_buffer.read(nobjects)) return false;
int lowerBound;
if(!a_buffer.read(lowerBound)) return false;
//::printf("debug : obj_array : name \"%s\", nobject %d, lowerBound %d\n",name.c_str(),nobjects,lowerBound);
for (int i=0;i<nobjects;i++) {
//::printf("debug : obj_array::stream : %lu : n=%d i=%d ...\n",(unsigned long)this,nobjects,i);
iro* obj;
bool created;
if(!a_buffer.read_object(m_fac,a_args,obj,created)){
a_buffer.out() << "tools::rroot::obj_array::stream : can't read object"
<< " in obj_array : name " << sout(name)
<< ", nobjects " << nobjects << ", iobject " << i << std::endl;
return false;
}
//::printf("debug : obj_array::stream : %lu : n=%d i=%d : ok, obj %lu\n",(unsigned long)this,
// nobjects,i,(unsigned long)obj);
if(obj) {
T* to = safe_cast<iro,T>(*obj);
if(!to) {
a_buffer.out() << "tools::rroot::obj_array::stream :"
<< " inlib::cast failed."
<< " " << obj->s_cls() << " is not a " << T::s_class() << "."
<< std::endl;
if(created) {
if(a_buffer.map_objs()) a_buffer.remove_in_map(obj);
delete obj;
}
} else {
if(created) {
parent::push_back(to);
m_owns.push_back(true);
} else { //someone else manage this object.
parent::push_back(to);
m_owns.push_back(false);
}
}
} else {
//a_accept_null for branch::stream m_baskets.
if(a_accept_null) {
parent::push_back(0);
m_owns.push_back(false);
}
}
}
return a_buffer.check_byte_count(sp,bc,s_store_class());
}
protected:
void _clear() {
typedef typename parent::iterator it_t;
typedef std::vector<bool>::iterator itb_t;
while(!parent::empty()) {
it_t it = parent::begin();
itb_t itb = m_owns.begin();
T* entry = (*it);
bool own = (*itb);
parent::erase(it);
m_owns.erase(itb);
if(own) delete entry;
}
}
protected:
ifac& m_fac;
std::vector<bool> m_owns;
};
}}
#endif
+187
View File
@@ -0,0 +1,187 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_obj_list
#define tools_rroot_obj_list
//#include "../vmanip"
#include "iro"
#include "object"
#include "cids"
#include "../forit"
#include "../scast"
namespace tools {
namespace rroot {
class obj_list : public virtual iro, protected std::vector<iro*> { //proteced to avoid using std::vector::clear().
typedef std::vector<iro*> parent;
public:
static const std::string& s_store_class() {
static const std::string s_v("TList");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::obj_list");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<obj_list>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return obj_list_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<obj_list>(this,a_class)) {return p;}
else return 0;
}
//virtual void* cast(cid) const {return obj_list_cid();}
public:
virtual iro* copy() const {return new obj_list(*this);}
virtual bool stream(buffer& a_buffer) {
safe_clear();
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : obj_list::stream : version %d, byte count %d\n",v,c);
{uint32 id,bits;
if(!Object_stream(a_buffer,id,bits)) return false;}
std::string name;
if(!a_buffer.read(name)) return false;
int nobjects;
if(!a_buffer.read(nobjects)) return false;
//::printf("debug : obj_list : name \"%s\", nobject %d\n",
// name.c_str(),nobjects);
ifac::args args;
for (int i=0;i<nobjects;i++) {
//::printf("debug : obj_list : n=%d i=%d ...\n",nobjects,i);
iro* obj;
bool created;
if(!a_buffer.read_object(m_fac,args,obj,created)){
a_buffer.out() << "tools::rroot::obj_list::stream : can't read object." << std::endl;
return false;
}
unsigned char nch;
if(!a_buffer.read(nch)) return false;
if(nch) {
char readOption[256];
if(!a_buffer.read_fast_array(readOption,nch)) return false;
readOption[nch] = 0;
}
if(obj) {
if(created) {
parent::push_back(obj);
m_owns.push_back(true);
} else { //someone else may manage this object.
parent::push_back(obj);
m_owns.push_back(false);
}
}
}
return a_buffer.check_byte_count(s,c,s_store_class());
}
public:
obj_list(ifac& a_fac)
:m_fac(a_fac)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~obj_list(){
safe_clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
obj_list(const obj_list& a_from)
:iro(a_from)
,parent()
,m_fac(a_from.m_fac)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
tools_vforcit(iro*,a_from,it) {
parent::push_back((*it)->copy());
m_owns.push_back(true);
}
}
obj_list& operator=(const obj_list& a_from) {
if(&a_from==this) return *this;
safe_clear();
tools_vforcit(iro*,a_from,it) {
parent::push_back((*it)->copy());
m_owns.push_back(true);
}
return *this;
}
public:
parent::const_iterator begin() const {return parent::begin();}
parent::iterator begin() {return parent::begin();}
parent::const_iterator end() const {return parent::end();}
parent::iterator end() {return parent::end();}
parent::size_type size() const {return parent::size();}
bool empty() const {return parent::empty();}
public:
void add_object(iro* a_obj) { //take ownership.
parent::push_back(a_obj);
m_owns.push_back(true);
}
template <class T>
T* get_entry(std::ostream& a_out,size_t a_index) const {
if(a_index>=size()) return 0;
iro* _obj = parent::operator[](a_index);
if(!_obj) return 0;
T* od = id_cast<iro,T>(*_obj);
if(!od) {
a_out << "tools::rroot::obj_list::get_entry :"
<< " object of class " << sout(_obj->s_cls()) << " not a " << T::s_class() << std::endl;
return 0;
}
return od;
}
void safe_clear() {
typedef parent::iterator it_t;
typedef std::vector<bool>::iterator itb_t;
while(!parent::empty()) {
it_t it = parent::begin();
itb_t itb = m_owns.begin();
iro* entry = (*it);
bool own = (*itb);
parent::erase(it);
m_owns.erase(itb);
if(own) delete entry;
}
}
void cleanup() {safe_clear();}
protected:
ifac& m_fac;
std::vector<bool> m_owns;
};
}}
#endif
+22
View File
@@ -0,0 +1,22 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_Object
#define tools_rroot_Object
#include "buffer"
namespace tools {
namespace rroot {
inline bool Object_stream(buffer& a_buffer,uint32& a_id,uint32& a_bits) {
short v;
if(!a_buffer.read_version(v)) return false;
if(!a_buffer.read(a_id)) return false;
if(!a_buffer.read(a_bits)) return false;
return true;
}
}}
#endif
+528
View File
@@ -0,0 +1,528 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_rall
#define tools_rroot_rall
#include "streamers"
#include "fac"
#include "tree"
#include "../words" //for annotations.
#define TOOLS_RROOT_NOT_OSC
#ifndef TOOLS_RROOT_NOT_OSC
#include "osc"
#endif
#include "THistogram"
namespace tools {
namespace rroot {
inline TDirectory* find_dir(directory& a_dir,const std::string& a_name) {
std::ostream& out = a_dir.file().out();
key* k = a_dir.find_key(a_name);
if(!k) {
//out << "tools::rroot::find_dir :"
// << " " << a_name << " not a key."
// << std::endl;
return 0;
}
if(k->object_class()!=TDirectory_cls()) {
out << "tools::rroot::find_dir :"
<< " key " << a_name << " not a TDirectory."
<< std::endl;
return 0;
}
uint32 sz;
char* buf = k->get_object_buffer(a_dir.file(),sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::find_dir :"
<< " can't get directory data buffer."
<< std::endl;
return 0;
}
buffer b(out,a_dir.file().byte_swap(),sz,buf,k->key_length(),false);
TDirectory* tdir = new TDirectory(a_dir.file());
if(!tdir) return 0;
if(!tdir->stream(b)) {
out << "tools::rroot::find_dir :"
<< " can't stream TDirectory."
<< std::endl;
return 0;
}
return tdir;
}
inline directory* find_path_dir(directory& a_from,const std::string& a_path) {
if(a_path.empty()) return 0;
std::vector<std::string> ws;
words(a_path,"/",false,ws);
directory* cur_dir = &a_from;
for(unsigned int index=0;index<ws.size();index++) {
TDirectory* _dir = find_dir(*cur_dir,ws[index]);
if(!_dir) return 0;
if(index==(ws.size()-1)) return _dir;
if(index) delete cur_dir;
cur_dir = _dir;
}
return 0;
}
inline bool read_key(std::ostream& a_out,ifile& a_file,key& a_key,bool a_dump){
unsigned int sz;
char* buf = a_key.get_object_buffer(a_file,sz); //we don't have ownership of buf.
if(!buf) {
a_out << "tools::rroot::read_key : can't get data buffer of " << a_key.object_name() << "." << std::endl;
return false;
}
//a_out << "tools::rroot::read_key :"
// << " get data buffer size " << sz << "."
// << std::endl;
buffer b(a_out,a_file.byte_swap(),sz,buf,a_key.key_length(),false);
if(a_key.object_class()==TNamed_cls()) {
std::string name,title;
if(!Named_stream(b,name,title)) {
a_out << "tools::rroot::read_key : TNamed streaming failed" << std::endl;
} else {
if(a_dump) {
a_out << "Named : name = " << sout(name) << ", title = " << sout(title) << std::endl;
}
}
} else if(a_key.object_class()==TH1F_cls()) {
histo::h1d* h = TH1F_stream(b);
if(!h) {
a_out << "tools::rroot::read_key : TH1F streaming failed" << std::endl;
} else {
if(a_dump) h->hprint(a_out);
}
delete h;
} else if(a_key.object_class()==TH1D_cls()) {
histo::h1d* h = TH1D_stream(b);
if(!h) {
a_out << "tools::rroot::read_key :"
<< " TH1D streaming failed"
<< std::endl;
} else {
if(a_dump) h->hprint(a_out);
}
delete h;
} else if(a_key.object_class()==TH2F_cls()) {
histo::h2d* h = TH2F_stream(b);
if(!h) {
a_out << "tools::rroot::read_key :"
<< " TH2F streaming failed"
<< std::endl;
} else {
if(a_dump) h->hprint(a_out);
}
delete h;
} else if(a_key.object_class()==TH2D_cls()) {
histo::h2d* h = TH2D_stream(b); //we get ownership of h.
if(!h) {
a_out << "tools::rroot::read_key :"
<< " TH2D streaming failed"
<< std::endl;
} else {
if(a_dump) h->hprint(a_out);
}
delete h;
} else if(a_key.object_class()==TH3D_cls()) {
histo::h3d* h = TH3D_stream(b); //we get ownership of h.
if(!h) {
a_out << "tools::rroot::read_key :"
<< " TH3D streaming failed"
<< std::endl;
} else {
if(a_dump) h->hprint(a_out);
}
delete h;
} else if(a_key.object_class()==TProfile_cls()) {
histo::p1d* p = TProfile_stream(b);
if(!p) {
a_out << "tools::rroot::read_key :"
<< " TProfile streaming failed"
<< std::endl;
} else {
if(a_dump) p->hprint(a_out);
}
delete p;
} else if(a_key.object_class()==TProfile2D_cls()) {
histo::p2d* p = TProfile2D_stream(b);
if(!p) {
a_out << "tools::rroot::read_key :"
<< " TProfile2D streaming failed"
<< std::endl;
} else {
if(a_dump) p->hprint(a_out);
}
delete p;
} else if(a_key.object_class()==TTree_cls()) {
b.set_map_objs(true); //for "root_ls -ls" on esb evetest.root files.
fac _fac(a_out);
tree tree(a_file,_fac);
if(!tree.stream(b)) {
a_out << "tools::rroot::read_key :"
<< " TTree streaming failed"
<< std::endl;
} else {
//tree->dump(a_out);
if(a_dump) {
tree.dump(a_out,""," ");
uint64 entries = tree.entries();
/*
{for(uint32 j=0;j<10;j++){ //to test memory.
for(uint32 i=0;i<entries;i++){
uint32 n;
if(!tree.find_entry(i,n)) {
a_out << " can't find entry " << i
<< std::endl;
}
}
}}
*/
{for(uint32 i=0;i<5;i++){
if(!tree.show(a_out,i)) {
a_out << " show failed for entry " << i
<< std::endl;
}
}}
{for(uint64 i=mx<int64>(5,entries-5);i<entries;i++){
if(!tree.show(a_out,(uint32)i)) {
a_out << " show failed for entry " << i
<< std::endl;
}
}}
}
}
#ifndef TOOLS_RROOT_NOT_OSC
} else if(a_key.object_class()==osc::s_h1d()) {
histo::h1d h("",10,0,1);
if(!from_osc(b,osc::s_h1d(),h)) {
a_out << "tools::rroot::read_key :"
<< " " << osc::s_h1d() << " streaming failed"
<< std::endl;
} else {
if(a_dump) h.hprint(a_out);
}
} else if(a_key.object_class()==osc::s_h2d()) {
histo::h2d h("",10,0,1,10,0,1);
if(!from_osc(b,osc::s_h2d(),h)) {
a_out << "tools::rroot::read_key :"
<< " " << osc::s_h2d() << " streaming failed"
<< std::endl;
} else {
if(a_dump) h.hprint(a_out);
}
} else if(a_key.object_class()==osc::s_h3d()) {
histo::h3d h("",10,0,1,10,0,1,10,0,1);
if(!from_osc(b,osc::s_h3d(),h)) {
a_out << "tools::rroot::read_key :"
<< " " << osc::s_h3d() << " streaming failed"
<< std::endl;
} else {
if(a_dump) h.hprint(a_out);
}
} else if(a_key.object_class()==osc::s_p1d()) {
histo::p1d h("",10,0,1);
if(!from_osc(b,osc::s_p1d(),h)) {
a_out << "tools::rroot::read_key :"
<< " " << osc::s_p1d() << " streaming failed"
<< std::endl;
} else {
if(a_dump) h.hprint(a_out);
}
} else if(a_key.object_class()==osc::s_p2d()) {
histo::p2d h("",10,0,1,10,0,1);
if(!from_osc(b,osc::s_p2d(),h)) {
a_out << "tools::rroot::read_key :"
<< " " << osc::s_p2d() << " streaming failed"
<< std::endl;
} else {
if(a_dump) h.hprint(a_out);
}
#endif
} else if(a_key.object_class()==THistogram_cls()) { //produced with osc/AIDA through BatchLab/Rio/THistogram.
pd_data_t data;
annotations_t annotations;
if(!read_THistogram(b,data,annotations)) {
a_out << "tools::rroot::read_key : read_THistogram() failed." << std::endl;
} else {
if(histo::h1d* _h1d = THistogram_to_h1d(data)) {
if(a_dump) _h1d->hprint(a_out);
delete _h1d;
} else if(histo::h2d* _h2d = THistogram_to_h2d(data)) {
if(a_dump) _h2d->hprint(a_out);
delete _h2d;
} else if(histo::p1d* _p1d = THistogram_to_p1d(data)) {
if(a_dump) _p1d->hprint(a_out);
delete _p1d;
} else if(histo::p2d* _p2d = THistogram_to_p2d(data)) {
if(a_dump) _p2d->hprint(a_out);
delete _p2d;
} else {
a_out << "tools::rroot::read_key : can't convert THistogram dat to h1d,h2d,p1d or p2d." << std::endl;
}
}
} else if(a_key.object_class()==TDirectory_cls()) {
//we should not pass here.
} else {
a_out << "tools::rroot::read_key :"
<< " dont't know how to read key with object class "
<< sout(a_key.object_class())
<< std::endl;
}
return true;
}
//typedef std::map<std::string,std::string> annotations_t;
inline bool key_to_annotations(ifile& a_file,key& a_key,std::map<std::string,std::string>& a_annotations,bool a_warn = true) {
a_annotations.clear();
std::ostream& out = a_key.out();
if(a_key.object_class()!=TNamed_cls()) {
if(a_warn) out << "tools::rroot::key_to_annotations : key not a TNamed." << std::endl;
return false;
}
unsigned int sz;
char* buf = a_key.get_object_buffer(a_file,sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::key_to_annotations : can't get data buffer of " << a_key.object_name() << "." << std::endl;
return false;
}
buffer b(out,a_file.byte_swap(),sz,buf,a_key.key_length(),false);
std::string histo_name;
std::string sas;
if(!Named_stream(b,histo_name,sas)) return false;
std::vector<std::string> ws;
words(sas,"\n",true,ws);
size_t wordn = ws.size();
if(2*(wordn/2)!=wordn) {
out << "tools::rroot::key_to_annotations : wordn should be even in " << sout(sas) << "." << std::endl;
return false;
}
std::vector<std::string>::const_iterator it;
for(it=ws.begin();it!=ws.end();) {
const std::string& key = *it;it++;
const std::string& value = *it;it++;
a_annotations[key] = value;
}
return true;
}
inline histo::h1d* key_to_h1d(ifile& a_file,key& a_key,bool a_warn = true) {
std::ostream& out = a_key.out();
if( (a_key.object_class()!=TH1D_cls()) && (a_key.object_class()!=TH1F_cls()) ) {
if(a_warn) out << "tools::rroot::key_to_h1d : key not a TH1D and not a TH1F." << std::endl;
return 0;
}
unsigned int sz;
char* buf = a_key.get_object_buffer(a_file,sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::key_to_h1d : can't get data buffer of " << a_key.object_name() << "." << std::endl;
return 0;
}
buffer b(out,a_file.byte_swap(),sz,buf,a_key.key_length(),false);
if(a_key.object_class()==TH1D_cls()) {
return TH1D_stream(b);
} else {
return TH1F_stream(b);
}
}
inline histo::h2d* key_to_h2d(ifile& a_file,key& a_key,bool a_warn = true){
std::ostream& out = a_key.out();
if( (a_key.object_class()!=TH2D_cls()) && (a_key.object_class()!=TH2F_cls()) ) {
if(a_warn) out << "tools::rroot::key_to_h2d : key not a TH2D and not a TH2F." << std::endl;
return 0;
}
unsigned int sz;
char* buf = a_key.get_object_buffer(a_file,sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::key_to_h2d : can't get data buffer of " << a_key.object_name() << "." << std::endl;
return 0;
}
buffer b(out,a_file.byte_swap(),sz,buf,a_key.key_length(),false);
if(a_key.object_class()==TH2D_cls()) {
return TH2D_stream(b);
} else {
return TH2F_stream(b);
}
}
inline histo::h3d* key_to_h3d(ifile& a_file,key& a_key){
std::ostream& out = a_key.out();
if(a_key.object_class()!=TH3D_cls()) {
out << "tools::rroot::key_to_h3d :"
<< " key not a TH3D."
<< std::endl;
return 0;
}
unsigned int sz;
char* buf = a_key.get_object_buffer(a_file,sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::key_to_h3d :"
<< " can't get data buffer of " << a_key.object_name() << "."
<< std::endl;
return 0;
}
buffer b(out,a_file.byte_swap(),sz,buf,a_key.key_length(),false);
return TH3D_stream(b);
}
inline histo::p1d* key_to_p1d(ifile& a_file,key& a_key){
std::ostream& out = a_key.out();
if(a_key.object_class()!=TProfile_cls()) {
out << "tools::rroot::key_to_p1d :"
<< " key not a TProfile."
<< std::endl;
return 0;
}
unsigned int sz;
char* buf = a_key.get_object_buffer(a_file,sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::key_to_p1d :"
<< " can't get data buffer of " << a_key.object_name() << "."
<< std::endl;
return 0;
}
buffer b(out,a_file.byte_swap(),sz,buf,a_key.key_length(),false);
return TProfile_stream(b);
}
inline histo::p2d* key_to_p2d(ifile& a_file,key& a_key){
std::ostream& out = a_key.out();
if(a_key.object_class()!=TProfile2D_cls()) {
out << "tools::rroot::key_to_p2d :"
<< " key not a TProfile2D."
<< std::endl;
return 0;
}
unsigned int sz;
char* buf = a_key.get_object_buffer(a_file,sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::key_to_p2d :"
<< " can't get data buffer of " << a_key.object_name() << "."
<< std::endl;
return 0;
}
buffer b(out,a_file.byte_swap(),sz,buf,a_key.key_length(),false);
return TProfile2D_stream(b);
}
inline tree* key_to_tree(ifile& a_file,ifac& a_fac,key& a_key,bool a_warn = true) {
std::ostream& out = a_key.out();
if(a_key.object_class()!=TTree_cls()) {
if(a_warn) out << "tools::rroot::key_to_tree : key not a TTree." << std::endl;
return 0;
}
unsigned int sz;
char* buf = a_key.get_object_buffer(a_file,sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::key_to_tree : can't get data buffer of " << a_key.object_name() << "." << std::endl;
return 0;
}
buffer b(out,a_file.byte_swap(),sz,buf,a_key.key_length(),false);
b.set_map_objs(true); //for ioda/comres/tree.py, tree.lua.
tree* _tree = new tree(a_file,a_fac);
if(!_tree->stream(b)) {
out << "tools::rroot::key_to_tree : TTree streaming failed" << std::endl;
delete _tree;
return 0;
}
return _tree;
}
inline void read(std::ostream& a_out,
ifile& a_file,
const std::vector<key*>& a_keys,
bool a_recursive,
bool a_ls,
bool a_dump,
unsigned int a_spaces) {
{std::vector<key*>::const_iterator it;
for(it=a_keys.begin();it!=a_keys.end();++it) {
key& k = *(*it);
if(k.object_class()!=TDirectory_cls()) {
if(a_ls||a_dump) {
{for(unsigned int index=0;index<a_spaces;index++) a_out << " ";}
std::string label = k.object_name();
a_out << "object : " << sout(label)
<< ", class : " << k.object_class()
<< std::endl;
//k.dump(a_out);
}
if(!read_key(a_out,a_file,k,a_dump)) return;
}
}}
{std::vector<key*>::const_iterator it;
for(it=a_keys.begin();it!=a_keys.end();++it) {
key& k = *(*it);
if(k.object_class()==TDirectory_cls()) {
if(a_ls||a_dump) {
{for(unsigned int index=0;index<a_spaces;index++) a_out << " ";}
std::string label = k.object_name();
a_out << "directory : " << label << std::endl;
}
if(!a_recursive) continue;
uint32 sz;
char* buf = k.get_object_buffer(a_file,sz);
if(!buf) {
a_out << "read :"
<< " can't get directory data buffer."
<< std::endl;
} else {
buffer b(a_out,a_file.byte_swap(),sz,buf,k.key_length(),false);
TDirectory dir(a_file);
if(!dir.stream(b)) {
a_out << "read :"
<< " can't stream TDirectory."
<< std::endl;
} else {
const std::vector<key*>& keys = dir.keys();
read(a_out,a_file,keys,a_recursive,a_ls,a_dump,a_spaces+1);
}
}
}
}}
}
}}
#endif
+412
View File
@@ -0,0 +1,412 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_rbuf
#define tools_rroot_rbuf
#include "../stype"
#include "../long_out"
#include "../charp_out"
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include <ostream>
#include <vector>
#include <cstring> //memcpy
namespace tools {
namespace rroot {
class rbuf {
/////////////////////////////////////////////////////////
/// swap ////////////////////////////////////////////////
/////////////////////////////////////////////////////////
// NOTE : on most common platforms (including Android, iPad)
// CERN-ROOT byte swaps ! (Bad luck). We have arranged to
// optimize this operation. The below "_swap_" functions
// do not have local variables and manipulates pointers
// directly.
static void read_swap_2(char* a_pos,char* a_x) {
*a_x++ = *(a_pos+1);
*a_x++ = *a_pos;
}
static void read_swap_4(char* a_pos,char* a_x) {
a_pos += 3;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos;
}
static void read_swap_8(char* a_pos,char* a_x) {
a_pos += 7;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos;
}
/////////////////////////////////////////////////////////
/// nswp ////////////////////////////////////////////////
/////////////////////////////////////////////////////////
static void read_nswp_2(char* a_pos,char* a_x) {
::memcpy(a_x,a_pos,2);
}
static void read_nswp_4(char* a_pos,char* a_x) {
::memcpy(a_x,a_pos,4);
}
static void read_nswp_8(char* a_pos,char* a_x) {
::memcpy(a_x,a_pos,8);
}
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
static const std::string& s_class() {
static const std::string s_v("tools::rroot::rbuf");
return s_v;
}
typedef void (*r_2_func)(char*,char*);
typedef void (*r_4_func)(char*,char*);
typedef void (*r_8_func)(char*,char*);
public:
rbuf(std::ostream& a_out,bool a_byte_swap,const char* a_eob,char*& a_pos)
:m_out(a_out)
,m_byte_swap(a_byte_swap)
,m_eob(a_eob)
,m_pos(a_pos)
,m_r_2_func(0)
,m_r_4_func(0)
,m_r_8_func(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
set_byte_swap(a_byte_swap);
}
virtual ~rbuf(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
rbuf(const rbuf& a_from)
:m_out(a_from.m_out)
,m_byte_swap(a_from.m_byte_swap)
,m_eob(a_from.m_eob)
,m_pos(a_from.m_pos)
,m_r_2_func(a_from.m_r_2_func)
,m_r_4_func(a_from.m_r_4_func)
,m_r_8_func(a_from.m_r_8_func)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
set_byte_swap(a_from.m_byte_swap);
}
rbuf& operator=(const rbuf& a_from){
set_byte_swap(a_from.m_byte_swap);
m_eob = a_from.m_eob;
//m_pos is a ref.
m_r_2_func = a_from.m_r_2_func;
m_r_4_func = a_from.m_r_4_func;
m_r_8_func = a_from.m_r_8_func;
return *this;
}
public:
std::ostream& out() const {return m_out;}
void skip(unsigned int a_num) {m_pos += a_num;}
void set_eob(const char* a_eob){m_eob = a_eob;}
char*& pos() {return m_pos;}
const char* eob() const {return m_eob;}
void set_byte_swap(bool a_value) {
m_byte_swap = a_value;
if(m_byte_swap) {
m_r_2_func = read_swap_2;
m_r_4_func = read_swap_4;
m_r_8_func = read_swap_8;
} else {
m_r_2_func = read_nswp_2;
m_r_4_func = read_nswp_4;
m_r_8_func = read_nswp_8;
}
}
public:
bool read(unsigned char& a_x) {
if(!_check_eob<unsigned char>(a_x)) return false;
a_x = *m_pos;m_pos++;
return true;
}
bool read(unsigned short& a_x) {
if(!_check_eob<unsigned short>(a_x)) return false;
m_r_2_func(m_pos,(char*)&a_x);
m_pos += sizeof(unsigned short);
return true;
}
bool read(unsigned int& a_x) {
if(!_check_eob<unsigned int>(a_x)) return false;
m_r_4_func(m_pos,(char*)&a_x);
m_pos += sizeof(unsigned int);
return true;
}
bool read(uint64& a_x){
if(!_check_eob<uint64>(a_x)) return false;
m_r_8_func(m_pos,(char*)&a_x);
m_pos += 8;
return true;
}
bool read(float& a_x) {
if(!_check_eob<float>(a_x)) return false;
m_r_4_func(m_pos,(char*)&a_x);
m_pos += sizeof(float);
return true;
}
bool read(double& a_x) {
if(!_check_eob<double>(a_x)) return false;
m_r_8_func(m_pos,(char*)&a_x);
m_pos += sizeof(double);
return true;
}
bool read(char& a_x) {
if(!_check_eob<char>(a_x)) return false;
a_x = *m_pos;m_pos++;
return true;
}
bool read(short& a_x) {
if(!_check_eob<short>(a_x)) return false;
m_r_2_func(m_pos,(char*)&a_x);
m_pos += sizeof(short);
return true;
}
bool read(int& a_x) {
if(!_check_eob<int>(a_x)) return false;
m_r_4_func(m_pos,(char*)&a_x);
m_pos += sizeof(int);
return true;
}
bool read(int64& a_x){
if(!_check_eob<int64>(a_x)) return false;
m_r_8_func(m_pos,(char*)&a_x);
m_pos += 8;
return true;
}
bool read(std::string& a_x) {
unsigned char nwh;
if(!read(nwh)) {a_x.clear();return false;}
int nchars;
if(nwh == 255) {
if(!read(nchars)) {a_x.clear();return false;}
} else {
nchars = nwh;
}
if(nchars<0) {
m_out << s_class() << "::read(string) :"
<< " negative char number " << nchars << "." << std::endl;
a_x.clear();
return false;
}
if((m_pos+nchars)>m_eob) {
m_out << s_class() << "::read(string) :"
<< " try to access out of buffer " << long_out(nchars) << " bytes "
<< " (pos=" << charp_out(m_pos)
<< ", eob=" << charp_out(m_eob) << ")." << std::endl;
a_x.clear();
return false;
}
a_x.resize(nchars);
::memcpy((char*)a_x.c_str(),m_pos,nchars);
m_pos += nchars;
return true;
}
bool read(bool& x){
unsigned char uc = 0;
bool status = read(uc);
x = uc?true:false;
return status;
}
bool read(std::vector<std::string>& a_a) {
int n;
if(!read(n)) {a_a.clear();return false;}
for(int index=0;index<n;index++) {
std::string s;
if(!read(s)) {a_a.clear();return false;}
a_a.push_back(s);
}
return true;
}
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
bool read_fast_array(bool* b,uint32 n){
if(!n) return true;
uint32 l = n * sizeof(unsigned char);
if(!check_eob(l)) return false;
for(uint32 i = 0; i < n; i++) {
unsigned char uc;
if(!read(uc)) return false;
b[i] = uc?true:false;
}
return true;
}
bool read_fast_array(char* c,uint32 n){
if(!n) return true;
uint32 l = n * sizeof(char);
if(!check_eob(l)) return false;
::memcpy(c,m_pos,l);
m_pos += l;
return true;
}
bool read_fast_array(unsigned char* c,uint32 n){
if(!n) return true;
uint32 l = n * sizeof(unsigned char);
if(!check_eob(l)) return false;
::memcpy(c, m_pos, l);
m_pos += l;
return true;
}
template <class T>
bool read_fast_array(T* a_a,uint32 a_n){
if(!a_n) return true;
uint32 l = a_n * sizeof(T);
if(!check_eob(l)) {
m_out << s_class() << "::read_fast_array :"
<< " try to access out of buffer " << long_out(l) << " bytes "
<< " (pos=" << charp_out(m_pos)
<< ", eob=" << charp_out(m_eob) << ")." << std::endl;
return false;
}
if(m_byte_swap) {
for(uint32 i=0;i<a_n;i++) {
if(!read(*(a_a+i))) return false;
}
} else {
::memcpy(a_a,m_pos,l);
m_pos += l;
}
return true;
}
template <class T>
bool read_array(uint32 a_sz,T*& a_a,uint32& a_n) {
a_n = 0;
{int n;
if(!read(n)) {a_n = 0;return false;}
a_n = n;}
if(!a_n) return true;
uint32 l = a_n * sizeof(T);
if(!check_eob(l)) return false;
bool owner = false;
if(!a_a) {
//ignore a_sz
a_a = new T[a_n];
if(!a_a) {a_n=0;return false;}
owner = true;
} else {
if(a_n>a_sz) return false;
}
if(m_byte_swap) {
for(uint32 i=0;i<a_n;i++) {
if(!read(*(a_a+i))) {
if(owner) {delete [] a_a;a_a = 0;}
a_n = 0;
return false;
}
}
} else {
::memcpy(a_a,m_pos,l);
m_pos += l;
}
return true;
}
template <class T>
bool read_array(std::vector<T>& a_v) {
T* buffer = 0;
uint32 n;
if(!read_array(0,buffer,n)) {a_v.clear();return false;}
if(!buffer) {a_v.clear();return true;}
a_v.resize(n);
for(uint32 index=0;index<n;index++) {
a_v[index] = buffer[index];
}
delete [] buffer;
return true;
}
template <class T>
bool read_array2(std::vector< std::vector<T> >& a_v) {
int n;
if(!read(n)) {a_v.clear();return false;}
a_v.resize(n);
for(int index=0;index<n;index++) {
if(!read_array(a_v[index])) return false;
}
return true;
}
bool check_eob(uint32 n){
if((m_pos+n)>m_eob) {
m_out << "tools::rroot::rbuf::check_eob :"
<< " try to access out of buffer " << n << " bytes."
<< std::endl;
return false;
}
return true;
}
protected:
template <class T>
bool _check_eob(T& a_x){
if((m_pos+sizeof(T))>m_eob) {
a_x = T();
m_out << s_class() << " : " << stype(T()) << " : "
<< " try to access out of buffer " << long_out(sizeof(T)) << " bytes"
<< " (pos=" << charp_out(m_pos)
<< ", eob=" << charp_out(m_eob) << ")." << std::endl;
return false;
}
return true;
}
protected:
std::ostream& m_out;
bool m_byte_swap;
const char* m_eob;
char*& m_pos;
r_2_func m_r_2_func;
r_4_func m_r_4_func;
r_8_func m_r_8_func;
};
}}
#endif
+23
View File
@@ -0,0 +1,23 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_seek
#define tools_rroot_seek
//////////////////////////////////////////////////////////////////////////
// Definition of a file pointer . //
//////////////////////////////////////////////////////////////////////////
#include "../typedefs"
namespace tools {
namespace rroot {
typedef int64 seek;
typedef int seek32;
inline uint32 big_file_version_tag() {return 1000;}
}}
#endif
+274
View File
@@ -0,0 +1,274 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_stl_vector
#define tools_rroot_stl_vector
#include "buffer"
#include "cids"
#include "../stype"
#include "../scast"
#include "../cids"
namespace tools {
namespace rroot {
template <class T>
class stl_vector : public virtual iro, public std::vector<T> {
static const std::string& s_store_class() {
static const std::string s_v("vector<"+stype(T())+">");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::stl_vector<"+stype(T())+">");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast< stl_vector<T> >(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return stl_vector_cid()+_cid(T());}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast< stl_vector<T> >(this,a_class)) {return p;}
return 0;
}
virtual iro* copy() const {return new stl_vector<T>(*this);}
virtual bool stream(buffer& a_buffer) {
std::vector<T>::clear();
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : stl_vector::stream<%s> : version %d, byte count %d\n",
// stype(T()).c_str(),v,c);
unsigned int num;
if(!a_buffer.read(num)) return false;
//::printf("debug : stl_vector : %d\n",num);
if(num) {
T* vec = new T[num];
if(!a_buffer.read_fast_array<T>(vec,num)) {
delete [] vec;
return false;
}
std::vector<T>::resize(num);
T* pos = vec;
for(unsigned int index=0;index<num;index++,pos++) {
std::vector<T>::operator[](index) = *pos;
}
delete [] vec;
}
return a_buffer.check_byte_count(s,c,s_store_class());
}
public:
stl_vector(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~stl_vector(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
stl_vector(const stl_vector& a_from)
:iro(a_from)
,std::vector<T>(a_from)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
stl_vector& operator=(const stl_vector& a_from){
std::vector<T>::operator=(a_from);
return *this;
}
};
template <class T>
class stl_vector_vector
:public virtual iro
,public std::vector< std::vector<T> >
{
static const std::string& s_store_class() {
static const std::string s_v("vector<vector<"+stype(T())+"> >");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v
("tools::rroot::stl_vector_vector<"+stype(T())+">");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p=cmp_cast< stl_vector_vector<T> >(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return stl_vector_vector_cid()+_cid(T());}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast< stl_vector_vector<T> >(this,a_class)) {return p;}
return 0;
}
virtual iro* copy() const {return new stl_vector_vector<T>(*this);}
virtual bool stream(buffer& a_buffer) {
typedef typename std::vector<T> vec_t;
std::vector<vec_t>::clear();
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : stl_vector_vector::stream<%s> : version %d, byte count %d\n",stype(T()).c_str(),v,c);
unsigned int vecn;
if(!a_buffer.read(vecn)) return false;
std::vector<vec_t>::resize(vecn);
//::printf("debug : stl_vector_vector : %d\n",vecn);
for(unsigned int veci=0;veci<vecn;veci++) {
vec_t& elem = std::vector<vec_t>::operator[](veci);
unsigned int num;
if(!a_buffer.read(num)) {
std::vector<vec_t>::clear();
return false;
}
//::printf("debug : stl_vector_vector : index %d num %d\n",veci,num);
if(num) {
T* vec = new T[num];
if(!a_buffer.read_fast_array<T>(vec,num)) {
delete [] vec;
std::vector<vec_t>::clear();
return false;
}
elem.resize(num);
T* pos = vec;
for(unsigned int index=0;index<num;index++,pos++) elem[index] = *pos;
delete [] vec;
}
}
return a_buffer.check_byte_count(s,c,s_store_class());
}
public:
stl_vector_vector(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~stl_vector_vector(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
stl_vector_vector(const stl_vector_vector& a_from)
:iro(a_from)
,std::vector< std::vector<T> >(a_from)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
stl_vector_vector& operator=(const stl_vector_vector& a_from){
std::vector< std::vector<T> >::operator=(a_from);
return *this;
}
};
class stl_vector_string : public virtual iro, public std::vector<std::string> {
static const std::string& s_store_class() {
static const std::string s_v("vector<string>");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::stl_vector_string");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<stl_vector_string>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return stl_vector_string_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<stl_vector_string>(this,a_class)) {return p;}
return 0;
}
virtual iro* copy() const {return new stl_vector_string(*this);}
virtual bool stream(buffer& a_buffer) {
std::vector<std::string>::clear();
//uint32 startpos = a_buffer.length();
//WARNING : not tested yet.
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : stl_vector_string::stream : version %d, byte count %d\n",v,c);
unsigned int num;
if(!a_buffer.read(num)) return false;
//::printf("debug : stl_vector_string : %d\n",num);
std::vector<std::string>::resize(num);
for(unsigned int index=0;index<num;index++) {
std::string& vs = std::vector<std::string>::operator[](index);
if(!a_buffer.read(vs)) {
std::vector<std::string>::clear();
return false;
}
}
//a_buffer.set_offset(startpos+c+sizeof(unsigned int));
return a_buffer.check_byte_count(s,c,s_store_class());
}
public:
stl_vector_string(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~stl_vector_string(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
stl_vector_string(const stl_vector_string& a_from)
:iro(a_from)
,std::vector<std::string>(a_from)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
stl_vector_string& operator=(const stl_vector_string& a_from){
std::vector<std::string>::operator=(a_from);
return *this;
}
};
}}
#endif
@@ -0,0 +1,66 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_streamer_fac
#define tools_rroot_streamer_fac
#include "info"
#include "iros"
namespace tools {
namespace rroot {
class streamer_fac : public virtual ifac {
public: //ifac
virtual std::ostream& out() const {return m_out;}
virtual iro* create(const std::string& a_class,const args& a_args) {
// for read_sinfos() :
if(rcmp(a_class,"TStreamerInfo")) {
return new streamer_info(*this);
} else if(rcmp(a_class,"TObjArray")) {
std::string* sc = ifac::arg_class(a_args);
if(sc) {
if((*sc)==streamer_element::s_class()){
return new obj_array<streamer_element>(*this);
} else {
m_out << "tools::rroot::streamer_fac::create :"
<< " Can't create TObjArray of " << *sc << "."
<< std::endl;
return 0;
}
} else {
return new iros(*this);
}
} else if(rcmp(a_class,"TStreamerBase")
||rcmp(a_class,"TStreamerBasicType")
||rcmp(a_class,"TStreamerBasicPointer")
||rcmp(a_class,"TStreamerObjectAny")
||rcmp(a_class,"TStreamerObject")
||rcmp(a_class,"TStreamerObjectPointer")
||rcmp(a_class,"TStreamerString")
||rcmp(a_class,"TStreamerSTL")
||rcmp(a_class,"TStreamerLoop")
||rcmp(a_class,"TList")
) {
return new dummy_streamer_element();
} else {
m_out << "tools::rroot::streamer_fac::create :"
<< " dummy. Can't create object of class " << sout(a_class) << "."
<< std::endl;
}
return 0;
}
public:
streamer_fac(std::ostream& a_out):m_out(a_out){}
virtual ~streamer_fac(){}
protected:
streamer_fac(const streamer_fac& a_from): ifac(a_from),m_out(a_from.m_out){}
streamer_fac& operator=(const streamer_fac&){return *this;}
protected:
std::ostream& m_out;
};
}}
#endif
+928
View File
@@ -0,0 +1,928 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_streamers
#define tools_rroot_streamers
#include "dummy_fac"
#include "named"
#include "date"
#include "directory"
//#include "graph"
#include "clss"
#include "dummy"
#include "obj_list"
#include "../sout"
#include "../vmanip"
//#include "../histo/histo_data"
#include "../histo/profile_data"
#include "../histo/h1d"
#include "../histo/h2d"
#include "../histo/h3d"
#include "../histo/p1d"
#include "../histo/p2d"
#include <list>
#include <cmath> //::log10, ::fabs.
//#include "../rtausmed"
namespace tools {
namespace rroot {
typedef histo::histo_data<double,unsigned int,unsigned int,double> hd_data;
typedef histo::profile_data<double,unsigned int,unsigned int,double,double> pd_data;
inline bool AttAxis_stream(buffer& a_buffer){
int fNdivisions = 510; //Number of divisions(10000*n3 + 100*n2 + n1)
short fAxisColor = 1; //color of the line axis
short fLabelColor = 1; //color of labels
short fLabelFont = 62; //font for labels
float fLabelOffset = 0.005F; //offset of labels
float fLabelSize = 0.04F; //size of labels
float fTickLength = 0.03F; //length of tick marks
float fTitleOffset = 1; //offset of axis title
float fTitleSize = 0.04F; //size of axis title
short fTitleColor = 1; //color of axis title
short fTitleFont = 62; //font for axis title
// Version 4 streaming (ROOT/v3-00-6).
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!a_buffer.read(fNdivisions)) return false;
if(!a_buffer.read(fAxisColor)) return false;
if(!a_buffer.read(fLabelColor)) return false;
if(!a_buffer.read(fLabelFont)) return false;
if(!a_buffer.read(fLabelOffset)) return false;
if(!a_buffer.read(fLabelSize)) return false;
if(!a_buffer.read(fTickLength)) return false;
if(!a_buffer.read(fTitleOffset)) return false;
if(!a_buffer.read(fTitleSize)) return false;
if(!a_buffer.read(fTitleColor)) return false;
if(!a_buffer.read(fTitleFont)) return false;
if(!a_buffer.check_byte_count(s, c,"TAttAxis")) return false;
return true;
}
inline bool Axis_stream(buffer& a_buffer,histo::axis<double,unsigned int>& a_fAxis){
// Version 6 streaming (ROOT/v3-00-6).
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
std::string name;
std::string title;
if(!Named_stream(a_buffer,name,title)) return false;
if(!AttAxis_stream(a_buffer)) return false;
int number;
if(!a_buffer.read(number)) return false;
double min;
if(!a_buffer.read(min)) return false;
double max;
if(!a_buffer.read(max)) return false;
std::vector<double> edges;
if(!Array_stream<double>(a_buffer,edges)) return false; //fXbins TArrayD
size_t edgen = edges.size();
if(!edgen) {
a_fAxis.configure(number,min,max);
} else {
std::vector<double> vedges;
for(size_t index=0;index<edgen;index++) {
vedges.push_back(edges[index]);
}
a_fAxis.configure(vedges);
}
int First;
if(!a_buffer.read(First)) return false;
int Last;
if(!a_buffer.read(Last)) return false;
if(v>=8) { //fBits2.
unsigned short dummy;
if(!a_buffer.read(dummy)) return false;
}
//Bool_t
unsigned char TimeDisplay;
if(!a_buffer.read(TimeDisplay)) return false;
//TString
std::string TimeFormat;
if(!a_buffer.read(TimeFormat)) return false;
if(v>=7) {
//THashList*
dummy_fac fac(a_buffer.out());
if(!dummy_TXxx_pointer_stream(a_buffer,fac)) return false;
}
if(!a_buffer.check_byte_count(s,c,"TAxis")) return false;
return true;
}
inline bool null_epsil(double a_1,double a_2,double a_prec = -5) {
return (::log10(::fabs(a_1-a_2))<a_prec?true:false);
}
inline bool TH_read_1D(buffer& a_buffer,hd_data& a_data,
double& a_entries,double& a_Sw,double& a_Sw2,double& a_Sxw,double& a_Sx2w){
a_entries = 0;
a_Sw = 0;
a_Sw2 = 0;
a_Sxw = 0;
a_Sx2w = 0;
unsigned int s, c;
short vers;
if(!a_buffer.read_version(vers,s,c)) return false;
//::printf("debug : tools::rroot::TH_read_1D : version %d\n",vers);
// Version 3 streaming (ROOT/v3-00-6).
std::string name;
std::string title;
if(!Named_stream(a_buffer,name,title)) return false;
a_data.m_title = title;
{short color,style,width;
if(!AttLine_stream(a_buffer,color,style,width)) return false;}
{short color,style;
if(!AttFill_stream(a_buffer,color,style)) return false;}
if(!AttMarker_stream(a_buffer)) return false;
int Ncells;
if(!a_buffer.read(Ncells)) return false;
//fXAxis
if(!Axis_stream(a_buffer,a_data.m_axes[0])) return false;
a_data.m_axes[0].m_offset = 1;
if(a_data.m_dimension==3) {
if(!Axis_stream(a_buffer,a_data.m_axes[1])) return false; //fYAxis
a_data.m_axes[1].m_offset = a_data.m_axes[0].m_offset * (a_data.m_axes[0].bins()+2);
if(!Axis_stream(a_buffer,a_data.m_axes[2])) return false; //fZAxis
a_data.m_axes[2].m_offset = a_data.m_axes[1].m_offset * (a_data.m_axes[1].bins()+2);
} else if(a_data.m_dimension==2) {
if(!Axis_stream(a_buffer,a_data.m_axes[1])) return false; //fYAxis
a_data.m_axes[1].m_offset = a_data.m_axes[0].m_offset * (a_data.m_axes[0].bins()+2);
histo::axis<double,unsigned int> dummy;
if(!Axis_stream(a_buffer,dummy)) return false; //fZAxis
} else {
histo::axis<double,unsigned int> dummy;
if(!Axis_stream(a_buffer,dummy)) return false; //fYAxis
if(!Axis_stream(a_buffer,dummy)) return false; //fZAxis
}
short barOffset;
if(!a_buffer.read(barOffset)) return false;
short barWidth;
if(!a_buffer.read(barWidth)) return false;
if(!a_buffer.read(a_entries)) return false;
if(!a_buffer.read(a_Sw)) return false; //fTsumw
if(!a_buffer.read(a_Sw2)) return false;
if(!a_buffer.read(a_Sxw)) return false;
if(!a_buffer.read(a_Sx2w)) return false;
double max;
if(!a_buffer.read(max)) return false;
double min;
if(!a_buffer.read(min)) return false;
double NormFactor;
if(!a_buffer.read(NormFactor)) return false;
{std::vector<double> v;
if(!Array_stream<double>(a_buffer,v)) return false;} //fContour TArrayD
std::vector<double> sumw2; //fSumw2 TArrayD
if(!Array_stream<double>(a_buffer,sumw2)) return false;
{std::string opt;
if(!a_buffer.read(opt)) return false; //TString fOption
//look if it is an "annotation trick" :
//if(opt.size()&&(opt[0]==0)) {
// fAnnotation = opt.substr(1,opt.size()-1);
//}
}
{dummy_fac fac(a_buffer.out());
obj_list dummy(fac);
if(!dummy.stream(a_buffer)) {
a_buffer.out() << "tools::rroot::TH_read_1D :"
<< " obj_list stream failed."
<< std::endl;
return false;
}} //Functions
if(vers>=4) {
int BufferSize;
if(!a_buffer.read(BufferSize)) return false;
//Double_t* Buffer; //[fBufferSize]
if(!dummy_array_stream<double>(a_buffer,BufferSize)) return false;
}
if(vers>=7) {
//EBinErrorOpt fBinStatErrOpt;
int dummy;
if(!a_buffer.read(dummy)) return false;
}
// Add two for outflows.
if(a_data.m_dimension==1) {
a_data.m_bin_number = a_data.m_axes[0].m_number_of_bins + 2;
} else if(a_data.m_dimension==2) {
a_data.m_bin_number =
(a_data.m_axes[0].m_number_of_bins + 2) *
(a_data.m_axes[1].m_number_of_bins + 2);
} else if(a_data.m_dimension==3) {
a_data.m_bin_number =
(a_data.m_axes[0].m_number_of_bins + 2) *
(a_data.m_axes[1].m_number_of_bins + 2) *
(a_data.m_axes[2].m_number_of_bins + 2);
}
unsigned int binn = a_data.m_bin_number;
a_data.m_bin_Sw2.resize(binn);
if(binn==sumw2.size()) {
for(unsigned int index=0;index<binn;index++){
a_data.m_bin_Sw2[index] = sumw2[index];
}
} else {
a_data.m_bin_Sw2.assign(binn,0);
}
if(!a_buffer.check_byte_count(s,c,"TH")) return false;
return true;
}
inline bool TH_read_2D(buffer& a_buffer,hd_data& a_data,
double& a_entries,double& a_Sw,double& a_Sw2,
double& a_Sxw,double& a_Sx2w,double& a_Syw,double& a_Sy2w){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return false;
// Version 3 streaming (ROOT/v3-00-6).
if(!TH_read_1D(a_buffer,a_data,a_entries,a_Sw,a_Sw2,a_Sxw,a_Sx2w)) return false;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
double ScaleFactor;
if(!a_buffer.read(ScaleFactor)) return false;
if(!a_buffer.read(a_Syw)) return false;
if(!a_buffer.read(a_Sy2w)) return false;
double Tsumwxy;
if(!a_buffer.read(Tsumwxy)) return false;
a_data.m_in_range_plane_Sxyw[0] = Tsumwxy;
if(!a_buffer.check_byte_count(s,c,"TH2")) return false;
return true;
}
inline bool TH_read_3D(buffer& a_buffer,hd_data& a_data,
double& a_entries,double& a_Sw,double& a_Sw2,
double& a_Sxw,double& a_Sx2w,
double& a_Syw,double& a_Sy2w,
double& a_Szw,double& a_Sz2w){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return false;
if(!TH_read_1D(a_buffer,a_data,a_entries,a_Sw,a_Sw2,a_Sxw,a_Sx2w)) return false;
if(!Att3D_stream(a_buffer)) return false;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
if(!a_buffer.read(a_Syw)) return false;
if(!a_buffer.read(a_Sy2w)) return false;
double Tsumwxy;
if(!a_buffer.read(Tsumwxy)) return false;
if(!a_buffer.read(a_Szw)) return false;
if(!a_buffer.read(a_Sz2w)) return false;
double Tsumwxz;
if(!a_buffer.read(Tsumwxz)) return false;
double Tsumwyz;
if(!a_buffer.read(Tsumwyz)) return false;
a_data.m_in_range_plane_Sxyw[0] = Tsumwxy;
a_data.m_in_range_plane_Sxyw[1] = Tsumwyz;
a_data.m_in_range_plane_Sxyw[2] = Tsumwxz;
if(!a_buffer.check_byte_count(s,c,"TH3")) return false;
return true;
}
inline histo::h1d* TH1F_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
// Version 1 streaming (ROOT/v3-00-6).
// Now we have to reconstruct a valid Histogram from a_buffer :
hd_data data;
data.m_dimension = 1;
//data.m_coords.resize(data.m_dimension,0);
//data.m_ints.resize(data.m_dimension,0);
data.m_axes.resize(1);
double fEntries; //in range + outflow.
double fSw; //in range.
double fSw2; //in range.
double fSxw; //in range.
double fSx2w; //in range.
if(!TH_read_1D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w)) return 0;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
std::vector<float> bins; //fArray TArrayF
if(!Array_stream<float>(a_buffer,bins)) return 0;
if(!a_buffer.check_byte_count(s,c,"TH1F")) return 0;
unsigned int binn = data.m_bin_number;
data.m_bin_Sw.resize(binn,0);
{for(unsigned int index=0;index<binn;index++){
data.m_bin_Sw[index] = double(bins[index]);
}}
data.m_bin_entries.resize(binn,0);
{std::vector<double> empty;
empty.resize(1,0);
data.m_bin_Sxw.resize(binn,empty);
data.m_bin_Sx2w.resize(binn,empty);}
data.m_all_entries = static_cast<unsigned int>(fEntries);
data.m_in_range_entries = 0;
data.m_in_range_Sw = fSw;
data.m_in_range_Sw2 = fSw2;
data.m_in_range_Sxw.resize(1,0);
data.m_in_range_Sx2w.resize(1,0);
data.m_in_range_Sxw[0] = fSxw;
data.m_in_range_Sx2w[0] = fSx2w;
histo::h1d* h = new histo::h1d("",10,0,1);
h->copy_from_data(data);
return h; //give ownership to caller.
}
inline histo::h1d* TH1D_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
// Version 1 streaming (ROOT/v3-00-6).
// Now we have to reconstruct a valid Histogram from a_buffer :
hd_data data;
data.m_dimension = 1;
data.m_axes.resize(1);
double fEntries; //in range + outflow.
double fSw; //in range.
double fSw2; //in range.
double fSxw; //in range.
double fSx2w; //in range.
if(!TH_read_1D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w)) return 0;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
std::vector<double> bins; //fArray TArrayD
if(!Array_stream<double>(a_buffer,bins)) return 0;
if(!a_buffer.check_byte_count(s,c,"TH1D")) return 0;
unsigned int binn = data.m_bin_number;
data.m_bin_Sw = bins;
data.m_bin_entries.resize(binn,0);
{std::vector<double> empty;
empty.resize(1,0);
data.m_bin_Sxw.resize(binn,empty);
data.m_bin_Sx2w.resize(binn,empty);}
data.m_all_entries = static_cast<unsigned int>(fEntries);
data.m_in_range_entries = 0;
data.m_in_range_Sw = fSw;
data.m_in_range_Sw2 = fSw2;
data.m_in_range_Sxw.resize(1,0);
data.m_in_range_Sx2w.resize(1,0);
data.m_in_range_Sxw[0] = fSxw;
data.m_in_range_Sx2w[0] = fSx2w;
histo::h1d* h = new histo::h1d("",10,0,1);
h->copy_from_data(data);
return h;
}
inline histo::h2d* TH2F_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
// Version 3 streaming (ROOT/v3-00-6).
// Now we have to reconstruct a valid Histogram from a_buffer :
hd_data data;
data.m_dimension = 2;
//data.m_coords.resize(data.m_dimension,0);
//data.m_ints.resize(data.m_dimension,0);
data.m_axes.resize(2);
data.m_in_range_plane_Sxyw.resize(1,0);
double fEntries; //in range + outflow.
double fSw; //in range.
double fSw2; //in range.
double fSxw; //in range.
double fSx2w; //in range.
double fSyw; //in range.
double fSy2w; //in range.
if(!TH_read_2D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w,fSyw,fSy2w)) return 0;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
std::vector<float> bins; //fArray TArrayF
if(!Array_stream<float>(a_buffer,bins)) return 0;
if(!a_buffer.check_byte_count(s,c,"TH2F")) return 0;
unsigned int binn = data.m_bin_number;
data.m_bin_Sw.resize(binn,0);
{for(unsigned int index=0;index<binn;index++){
data.m_bin_Sw[index] = double(bins[index]);
}}
data.m_bin_entries.resize(binn,0);
{std::vector<double> empty;
empty.resize(2,0);
data.m_bin_Sxw.resize(binn,empty);
data.m_bin_Sx2w.resize(binn,empty);}
data.m_all_entries = static_cast<unsigned int>(fEntries);
data.m_in_range_entries = 0;
data.m_in_range_Sw = fSw;
data.m_in_range_Sw2 = fSw2;
data.m_in_range_Sxw.resize(2,0);
data.m_in_range_Sx2w.resize(2,0);
data.m_in_range_Sxw[0] = fSxw;
data.m_in_range_Sx2w[0] = fSx2w;
data.m_in_range_Sxw[1] = fSyw;
data.m_in_range_Sx2w[1] = fSy2w;
histo::h2d* h = new histo::h2d("",10,0,1,10,0,1);
h->copy_from_data(data);
return h;
}
inline histo::h2d* TH2D_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
// Version 3 streaming (ROOT/v3-00-6).
// Now we have to reconstruct a valid Histogram from a_buffer :
hd_data data;
data.m_dimension = 2;
//data.m_coords.resize(data.m_dimension,0);
//data.m_ints.resize(data.m_dimension,0);
data.m_axes.resize(2);
data.m_in_range_plane_Sxyw.resize(1,0);
double fEntries; //in range + outflow.
double fSw; //in range.
double fSw2; //in range.
double fSxw; //in range.
double fSx2w; //in range.
double fSyw; //in range.
double fSy2w; //in range.
if(!TH_read_2D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w,fSyw,fSy2w)) return 0;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
std::vector<double> bins; //fArray TArrayD
if(!Array_stream<double>(a_buffer,bins)) return 0;
if(!a_buffer.check_byte_count(s,c,"TH2D")) return 0;
unsigned int binn = data.m_bin_number;
data.m_bin_Sw = bins;
data.m_bin_entries.resize(binn,0);
{std::vector<double> empty;
empty.resize(2,0);
data.m_bin_Sxw.resize(binn,empty);
data.m_bin_Sx2w.resize(binn,empty);}
data.m_all_entries = static_cast<unsigned int>(fEntries);
data.m_in_range_entries = 0;
data.m_in_range_Sw = fSw;
data.m_in_range_Sw2 = fSw2;
data.m_in_range_Sxw.resize(2,0);
data.m_in_range_Sx2w.resize(2,0);
data.m_in_range_Sxw[0] = fSxw;
data.m_in_range_Sx2w[0] = fSx2w;
data.m_in_range_Sxw[1] = fSyw;
data.m_in_range_Sx2w[1] = fSy2w;
histo::h2d* h = new histo::h2d("",10,0,1,10,0,1);
h->copy_from_data(data);
return h;
}
inline histo::h3d* TH3D_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
// Now we have to reconstruct a valid Histogram from a_buffer :
hd_data data;
data.m_dimension = 3;
//data.m_coords.resize(data.m_dimension,0);
//data.m_ints.resize(data.m_dimension,0);
data.m_axes.resize(3);
data.m_in_range_plane_Sxyw.resize(3,0);
double fEntries; //in range + outflow.
double fSw; //in range.
double fSw2; //in range.
double fSxw; //in range.
double fSx2w; //in range.
double fSyw; //in range.
double fSy2w; //in range.
double fSzw; //in range.
double fSz2w; //in range.
if(!TH_read_3D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w,fSyw,fSy2w,fSzw,fSz2w)) return 0;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
std::vector<double> bins; //fArray TArrayD
if(!Array_stream<double>(a_buffer,bins)) return 0;
if(!a_buffer.check_byte_count(s,c,"TH3D")) return 0;
unsigned int binn = data.m_bin_number;
data.m_bin_Sw = bins;
data.m_bin_entries.resize(binn,0);
{std::vector<double> empty;
empty.resize(3,0);
data.m_bin_Sxw.resize(binn,empty);
data.m_bin_Sx2w.resize(binn,empty);}
data.m_all_entries = static_cast<unsigned int>(fEntries);
data.m_in_range_entries = 0;
data.m_in_range_Sw = fSw;
data.m_in_range_Sw2 = fSw2;
data.m_in_range_Sxw.resize(3,0);
data.m_in_range_Sx2w.resize(3,0);
data.m_in_range_Sxw[0] = fSxw;
data.m_in_range_Sx2w[0] = fSx2w;
data.m_in_range_Sxw[1] = fSyw;
data.m_in_range_Sx2w[1] = fSy2w;
data.m_in_range_Sxw[2] = fSzw;
data.m_in_range_Sx2w[2] = fSz2w;
histo::h3d* h = new histo::h3d("",10,0,1,10,0,1,10,0,1);
h->copy_from_data(data);
return h;
}
inline histo::p1d* TProfile_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
// Version 3 streaming (ROOT/v3-00-6).
//WARNING : the mapping histo::p1d / TProfile is not obvious.
//p1d::m_bin_Svw <---> TProfile::fArray
//p1d::m_bin_Sv2w <---> TProfile::fSumw2
//p1d::m_bin_Sw <---> TProfile::fBinEntries
histo::h1d* h = TH1D_stream(a_buffer);
if(!h) return 0;
//NOTE : histo.m_bin_Sw <---> TH1D::TArrayD::fArray
pd_data data(h->dac());
delete h;
std::vector<double> bins; //fBinEntries TArrayD
if(!Array_stream<double>(a_buffer,bins)) return 0;
int errorMode;
if(!a_buffer.read(errorMode)) return 0;
double ymin;
if(!a_buffer.read(ymin)) return 0;
double ymax;
if(!a_buffer.read(ymax)) return 0;
if(v>=4) {
double sumwy;
if(!a_buffer.read(sumwy)) return 0;
double sumwy2;
if(!a_buffer.read(sumwy2)) return 0;
}
if(v>=5) {
std::vector<double> bins_sumw2; //fBinSumw2 TArrayD
if(!Array_stream<double>(a_buffer,bins_sumw2)) return 0;
}
if(!a_buffer.check_byte_count(s,c,"TProfile")) return 0;
data.m_is_profile = true;
data.m_cut_v = true;
data.m_min_v = ymin;
data.m_max_v = ymax;
unsigned int binn = data.m_bin_number;
data.m_bin_Svw.resize(binn);
data.m_bin_Sv2w.resize(binn);
for(unsigned int index=0;index<binn;index++){
double svw = data.m_bin_Sw[index];
double sv2w = data.m_bin_Sw2[index];
double sw = bins[index];
//data.m_bin_entries[index] = (int)sw; //FIXME : ok for w = 1 only !
data.m_bin_Sw[index] = (double)sw;
//FIXME : data.m_bin_Sxw
//FIXME : data.m_bin_Sx2w
data.m_bin_Svw[index] = svw;
data.m_bin_Sv2w[index] = sv2w;
}
histo::p1d* p = new histo::p1d("",10,0,1);
p->copy_from_data(data);
// We have now a valid histo::p1d.
return p;
}
inline histo::p2d* TProfile2D_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
// Version 3 streaming (ROOT/v3-00-6).
//WARNING : the mapping histo::p1d / TProfile is not obvious.
//p1d::m_bin_Svw <---> TProfile::fArray
//p1d::m_bin_Sv2w <---> TProfile::fSumw2
//p1d::m_bin_Sw <---> TProfile::fBinEntries
histo::h2d* h = TH2D_stream(a_buffer);
if(!h) return 0;
//NOTE : histo.m_bin_Sw <---> TH2D::TArrayD::fArray
pd_data data(h->dac());
delete h;
std::vector<double> bins; //fBinEntries TArrayD
if(!Array_stream<double>(a_buffer,bins)) return 0;
int errorMode;
if(!a_buffer.read(errorMode)) return 0;
double zmin;
if(!a_buffer.read(zmin)) return 0;
double zmax;
if(!a_buffer.read(zmax)) return 0;
if(v>=5) {
double sumwz;
if(!a_buffer.read(sumwz)) return 0;
double sumwz2;
if(!a_buffer.read(sumwz2)) return 0;
}
if(v>=7) {
std::vector<double> bins_sumw2; //fBinSumw2 TArrayD
if(!Array_stream<double>(a_buffer,bins_sumw2)) return 0;
}
if(!a_buffer.check_byte_count(s,c,"TProfile2D")) return 0;
data.m_is_profile = true;
data.m_cut_v = true;
data.m_min_v = zmin;
data.m_max_v = zmax;
unsigned int binn = data.m_bin_number;
data.m_bin_Svw.resize(binn);
data.m_bin_Sv2w.resize(binn);
for(unsigned int index=0;index<binn;index++){
double svw = data.m_bin_Sw[index];
double sv2w = data.m_bin_Sw2[index];
double sw = bins[index];
//data.m_bin_entries[index] = (int)sw; //FIXME : ok for w = 1 only !
data.m_bin_Sw[index] = (double)sw;
//FIXME : data.m_bin_Sxw
//FIXME : data.m_bin_Sx2w
data.m_bin_Svw[index] = svw;
data.m_bin_Sv2w[index] = sv2w;
}
histo::p2d* p = new histo::p2d("",10,0,1,10,0,1);
p->copy_from_data(data);
return p;
}
class TDirectory : public directory {
//public:
// static const std::string& store_class() {return TDirectory_cls();}
public:
TDirectory(ifile& a_file):directory(a_file){}
virtual ~TDirectory(){}
protected:
TDirectory(const TDirectory& a_from):directory(a_from){}
TDirectory& operator=(const TDirectory&){return *this;}
public:
bool stream(buffer& a_buffer){
initialize();
short version;
if(!a_buffer.read_version(version)) return false;
unsigned int _date;
if(!a_buffer.read(_date)) return false;
//m_date_C.setDate(_date);
if(!a_buffer.read(_date)) return false;
//m_date_M.setDate(_date);
if(!a_buffer.read(m_nbytes_keys)) return false;
if(!a_buffer.read(m_nbytes_name)) return false;
if((uint32)version>big_file_version_tag()) {
if(!a_buffer.read(m_seek_directory)) return false;
if(!a_buffer.read(m_seek_parent)) return false;
if(!a_buffer.read(m_seek_keys)) return false;
} else {
{seek32 i;
if(!a_buffer.read(i)) return false;
m_seek_directory = i;}
{seek32 i;
if(!a_buffer.read(i)) return false;
m_seek_parent = i;}
{seek32 i;
if(!a_buffer.read(i)) return false;
m_seek_keys = i;}
}
//short v = version%big_file_version_tag();
if (m_seek_keys) {
uint32 n;
if(!read_keys(n)) {
a_buffer.out() << "tools::rroot::TDirectory::stream :"
<< " cannot read keys."
<< std::endl;
return false;
}
}
return true;
}
protected:
void initialize(){
// Initialise directory to defaults :
// If directory is created via default ctor (when dir is read from file)
// don't add it here to the directory since its name is not yet known.
// It will be added to the directory in TKey::ReadObj().
m_date_C = 0;//m_date_C.set();
m_date_M = 0;//m_date_M.set();
m_nbytes_keys = 0;
m_seek_directory = 0;
m_seek_parent = 0;
m_seek_keys = 0;
}
};
inline void dump(std::ostream& a_out,
ifile& a_file,
const std::vector<key*>& a_keys,
bool a_recursive,
unsigned int a_spaces = 0) {
// dump non directory objects :
{std::vector<key*>::const_iterator it;
for(it=a_keys.begin();it!=a_keys.end();++it) {
key& k = *(*it);
if(k.object_class()==TDirectory_cls()) continue;
{for(unsigned int index=0;index<a_spaces;index++) a_out << " ";}
k.dump(a_out);
}}
// dump directories :
{std::vector<key*>::const_iterator it;
for(it=a_keys.begin();it!=a_keys.end();++it) {
key& k = *(*it);
if(k.object_class()!=TDirectory_cls()) continue;
std::string label = k.object_name();
{for(unsigned int index=0;index<a_spaces;index++) a_out << " ";}
a_out << "directory : " << label << std::endl;
if(!a_recursive) continue;
uint32 sz;
char* buf = k.get_object_buffer(a_file,sz);
//we don't have ownership of buf.
if(!buf) {
a_out << "tools::rroot::dump :"
<< " can't get directory data buffer."
<< std::endl;
} else {
buffer b(a_out,a_file.byte_swap(),sz,buf,k.key_length(),false);
TDirectory tdir(a_file);
if(!tdir.stream(b)) {
a_out << "tools::rroot::dump :"
<< " can't stream TDirectory."
<< std::endl;
} else {
const std::vector<key*>& keys = tdir.keys();
dump(a_out,a_file,keys,a_recursive,a_spaces+1);
}
}
}}
}
/*
inline bool read_sinfos(ifile& a_file){
key& k = a_file.sinfos_key();
std::ostream& out = k.out();
if(k.object_class()!=TList_cls()) {
out << "tools::rroot::read_sinfos :"
<< " key not a TList."
<< std::endl;
return false;
}
unsigned int sz;
char* buf = k.get_object_buffer(a_file,sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::read_sinfos :"
<< " can't get data buffer of " << k.object_name() << "."
<< std::endl;
return false;
}
buffer b(out,a_file.byte_swap(),sz,buf,k.key_length(),false);
dummy_fac fac(out);
obj_list infos(fac);
if(!infos.stream(b)) return false;
tools_vforcit(iro*,infos,it) {
streamer_info* info = safe_cast<iro,streamer_info>(*(*it));
if(!info) return false;
info->out(out);
}
return true;
}
*/
}}
#endif
+494
View File
@@ -0,0 +1,494 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_tree
#define tools_rroot_tree
#include "ifac"
#include "branch_element"
#include "../sout"
#include "iobject"
namespace tools {
namespace rroot {
inline const std::string& TTree_cls(){
static const std::string s_v("TTree");
return s_v;
}
class tree : public virtual iobject {
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::tree");
return s_v;
}
virtual const std::string& s_cls() const {return s_class();}
public: //iobject
virtual const std::string& name() const {return m_name;}
virtual const std::string& title() const {return m_title;}
virtual const std::string& store_class_name() const {
static const std::string s_v("TTree");
return s_v;
}
public:
tree(ifile& a_file,ifac& a_fac)
:m_file(a_file)
,m_fac(a_fac)
,m_out(a_file.out())
,m_name("")
,m_title("")
,m_branches(a_fac)
,m_entries(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~tree(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
tree(const tree& a_from)
:iobject(a_from)
,m_file(a_from.m_file)
,m_fac(a_from.m_fac)
,m_out(a_from.m_out)
,m_branches(m_fac)
{}
tree& operator=(const tree&){return *this;}
public:
std::ostream& out() const {return m_out;}
ifile& file() {return m_file;}
ifac& fac() {return m_fac;}
const std::vector<branch*>& branches() const {return m_branches;}
bool find_entry(uint64 a_entry,uint32& a_nbytes) {
a_nbytes = 0;
if(a_entry>=m_entries) return false;
int nbytes = 0;
//fReadEntry = a_entry;
tools_vforit(branch*,m_branches,it) {
uint32 n;
if(!(*it)->find_entry(m_file,a_entry,n)) return false;
nbytes += n;
}
a_nbytes = nbytes;
return true;
}
void dump(std::ostream& a_out,const std::string& a_spaces = "",const std::string& a_indent = " "){
a_out << a_spaces
<< "tree :"
<< " name=" << sout(m_name)
<< " title=" << sout(m_title)
<< " entries=" << m_entries
<< std::endl;
_dump_branches(a_out,m_branches,a_spaces+a_indent,a_indent);
}
branch* find_branch(const std::string& a_name,bool a_recursive = false) const {
return _find_branch(m_branches,a_name,a_recursive);
}
branch_element* find_branch_element(const std::string& a_name,bool a_recursive = false) const {
branch* b = _find_branch(m_branches,a_name,a_recursive);
if(!b) return 0;
return id_cast<branch,branch_element>(*b);
}
base_leaf* find_leaf(const std::string& a_name,bool a_recursive = false) const {
return _find_leaf(m_branches,a_name,a_recursive);
}
void find_leaves(std::vector<base_leaf*>& a_leaves) const {
a_leaves.clear();
_find_leaves(m_branches,a_leaves);
}
void find_branches(std::vector<branch*>& a_branches) const {
a_branches.clear();
_find_branches(m_branches,a_branches);
}
branch* find_leaf_branch(const base_leaf& a_leaf) const {return _find_leaf_branch(m_branches,a_leaf);}
bool show(std::ostream& a_out,uint64 a_entry){
a_out << "======> EVENT:" << a_entry << std::endl;
tools_vforit(branch*,m_branches,it) {
if(!(*it)->show(a_out,m_file,a_entry)) return false;
}
return true;
}
uint64 entries() const {return m_entries;}
virtual bool stream(buffer& a_buffer) { //virtual for iobject.
//uint64 m_tot_bytes;
//uint64 m_zip_bytes;
//uint64 m_saved_bytes;
short vers;
unsigned int s, c;
if(!a_buffer.read_version(vers,s,c)) return false;
//::printf("debug : tree::stream : version %d count %d\n",vers,c);
//if (vers > 4) {
//TTree::Class()->ReadBuffer(b, this, vers, s, c);
//if (fEstimate <= 10000) fEstimate = 1000000;
//m_saved_bytes = m_tot_bytes;
//fDirectory = gDirectory;
//gDirectory->Append(this);
//return;
//}
if(!Named_stream(a_buffer,m_name,m_title)) return false;
{short color,style,width;
if(!AttLine_stream(a_buffer,color,style,width)) return false;}
{short color,style;
if(!AttFill_stream(a_buffer,color,style)) return false;}
if(!AttMarker_stream(a_buffer)) return false;
if(vers<=4) {
int dummy_int;
if(!a_buffer.read(dummy_int)) return false; //fScanField
if(!a_buffer.read(dummy_int)) return false; //fMaxEntryLoop
{int fMaxVirtualSize;
if(!a_buffer.read(fMaxVirtualSize)) return false;}
{double v;
if(!a_buffer.read(v)) return false;
m_entries = uint64(v);}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
{int fAutoSave;
if(!a_buffer.read(fAutoSave)) return false;}
if(!a_buffer.read(dummy_int)) return false; //fEstimate
} else if(vers<=9) {
{double v;
if(!a_buffer.read(v)) return false;
m_entries = uint64(v);}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_saved_bytes = uint64(v);
}
int dummy_int;
if(!a_buffer.read(dummy_int)) return false; //fTimerInterval
if(!a_buffer.read(dummy_int)) return false; //fScanField
if(!a_buffer.read(dummy_int)) return false; //fUpdate
if(!a_buffer.read(dummy_int)) return false; //fMaxEntryLoop
{int fMaxVirtualSize;
if(!a_buffer.read(fMaxVirtualSize)) return false;}
{int fAutoSave;
if(!a_buffer.read(fAutoSave)) return false;}
if(!a_buffer.read(dummy_int)) return false; //fEstimate
} else if(vers<16) { //FIXME : what is the exact version ?
double dummy_double;
int dummy_int;
{double v;
if(!a_buffer.read(v)) return false;
m_entries = uint64(v);}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_saved_bytes = uint64(v);
}
if(!a_buffer.read(dummy_double)) return false; //fWeight
if(!a_buffer.read(dummy_int)) return false; //fTimerInterval
if(!a_buffer.read(dummy_int)) return false; //fScanField
if(!a_buffer.read(dummy_int)) return false; //fUpdate
if(!a_buffer.read(dummy_int)) return false; //fMaxEntryLoop
{int fMaxVirtualSize;
if(!a_buffer.read(fMaxVirtualSize)) return false;}
{int fAutoSave;
if(!a_buffer.read(fAutoSave)) return false;}
if(!a_buffer.read(dummy_int)) return false; //fEstimate
} else { //vers>=16
double dummy_double;
int dummy_int;
int64 dummy_int64;
{uint64 v;
if(!a_buffer.read(v)) return false;
m_entries = v;}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_saved_bytes = v;
}
if(vers>=18) {
if(!a_buffer.read(dummy_int64)) return false; //fFlushedBytes
}
if(!a_buffer.read(dummy_double)) return false; //fWeight
if(!a_buffer.read(dummy_int)) return false; //fTimerInterval
if(!a_buffer.read(dummy_int)) return false; //fScanField
if(!a_buffer.read(dummy_int)) return false; //fUpdate
if(vers>=18) {
if(!a_buffer.read(dummy_int)) return false; //fDefaultEntryOffsetLen
}
int fNClusterRange;
if(vers>=20) {
if(!a_buffer.read(fNClusterRange)) return false; //fNClusterRange
}
if(!a_buffer.read(dummy_int64)) return false; //fMaxEntries
if(!a_buffer.read(dummy_int64)) return false; //fMaxEntryLoop
{uint64 fMaxVirtualSize;
if(!a_buffer.read(fMaxVirtualSize)) return false;}
{uint64 fAutoSave;
if(!a_buffer.read(fAutoSave)) return false;}
if(vers>=18) {
if(!a_buffer.read(dummy_int64)) return false; //fAutoFlush
}
if(!a_buffer.read(dummy_int64)) return false; //fEstimate
if(vers>=20) {
int64* fClusterRangeEnd = 0; ///<[fNClusterRange] Last entry of a cluster range.
if(!fixed_array_stream<int64>(a_buffer,fNClusterRange,fClusterRangeEnd)) return false;
delete [] fClusterRangeEnd;
int64* fClusterSize = 0; ///<[fNClusterRange] Number of entries in each cluster for a given range.
if(!fixed_array_stream<int64>(a_buffer,fNClusterRange,fClusterSize)) return false;
delete [] fClusterSize;
dummy _dummy;
if(!_dummy.stream(a_buffer)) { //TIOFeatures fIOFeatures
m_out << "tools::rroot::tree::stream : can't read (dummy) TIOFeatures." << std::endl;
return false;
}
}
}
//FIXME if (fEstimate <= 10000) fEstimate = 1000000;
//TObjArray
//The below m_branches.read will create leaves.
//::printf("debug : tree : read branches : begin\n");
{ifac::args args;
if(!m_branches.stream(a_buffer,args)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read branches."
<< std::endl;
return false;
}}
//::printf("debug : tree : read branches : end\n");
//TObjArray
// We read leaves in order to keep streaming synchronisation.
// In fact m_leaves are references to existing leaves read by
// the branches in the upper line of code.
//::printf("debug : tree : read leaves : begin\n");
{obj_array<base_leaf> m_leaves(m_fac);
//branch b(m_out,m_fac);
ifac::args args;
//args[ifac::arg_branch()] = &b;
if(!m_leaves.stream(a_buffer,args)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read leaves."
<< std::endl;
return false;
}}
//::printf("debug : tree : read leaves : end\n");
if(vers>=10) {
//TList* fAliases
if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read fAliases."
<< std::endl;
return false;
}
}
//m_saved_bytes = m_tot_bytes;
{std::vector<double> v;
if(!Array_stream<double>(a_buffer,v)) return false;} //fIndexValues TArrayD
{std::vector<int> v;
if(!Array_stream<int>(a_buffer,v)) return false;} // fIndex (TArrayI).
if(vers>=16) {
//TVirtualIndex* fTreeIndex //FIXME ???
if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read fTreeIndex."
<< std::endl;
return false;
}
}
if(vers>=6) {
//TList* fFriends
if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read fFriends."
<< std::endl;
return false;
}
}
if(vers>=16) {
//TList* fUserInfo
if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read fUserInfo."
<< std::endl;
return false;
}
//TBranchRef* fBranchRef
if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read fBranchRef."
<< std::endl;
return false;
}
}
if(!a_buffer.check_byte_count(s,c,TTree_cls())) return false;
return true;
}
protected:
void _dump_branches(std::ostream& a_out,
const std::vector<branch*>& a_bs,
const std::string& a_spaces = "",
const std::string& a_indent = " "){
tools_vforcit(branch*,a_bs,it) {
if(branch_element* be = safe_cast<branch,branch_element>(*(*it))) {
a_out << a_spaces
<< "branch_element :"
<< " name=" << sout((*it)->name())
<< " title=" << sout((*it)->title())
<< " entry_number=" << be->entry_number()
<< " ref_cls=" << sout(be->class_name())
<< " (type=" << be->type()
<< ",id=" << be->id()
<< ",stype=" << be->streamer_type()
<< ")."
<< std::endl;
} else {
a_out << a_spaces
<< "branch :"
<< " name=" << sout((*it)->name())
<< " title=" << sout((*it)->title())
<< " entry_number=" << (*it)->entry_number()
<< std::endl;
}
{const std::vector<base_leaf*>& lvs = (*it)->leaves();
tools_vforcit(base_leaf*,lvs,itl) {
a_out << a_spaces << a_indent
<< "leave :"
<< " name=" << sout((*itl)->name())
<< " title=" << sout((*itl)->title())
<< " cls=" << sout((*itl)->s_cls())
<< std::endl;
}}
_dump_branches(a_out,(*it)->branches(),a_spaces+a_indent,a_indent);
}
}
static branch* _find_branch(const std::vector<branch*>& a_bs,const std::string& a_name,bool a_recursive) {
tools_vforcit(branch*,a_bs,it) {
if(rcmp((*it)->name(),a_name)) return *it;
if(a_recursive) {
branch* br = _find_branch((*it)->branches(),a_name,a_recursive);
if(br) return br;
}
}
return 0;
}
static base_leaf* _find_leaf(const std::vector<branch*>& a_bs,const std::string& a_name,bool a_recursive) {
tools_vforcit(branch*,a_bs,it) {
tools_vforcit(base_leaf*,(*it)->leaves(),itl) {
if(rcmp((*itl)->name(),a_name)) return *itl;
}
if(a_recursive) {
base_leaf* lf = _find_leaf((*it)->branches(),a_name,a_recursive);
if(lf) return lf;
}
}
return 0;
}
static void _find_leaves(const std::vector<branch*>& a_bs,std::vector<base_leaf*>& a_leaves) {
tools_vforcit(branch*,a_bs,it) {
tools_vforcit(base_leaf*,(*it)->leaves(),itl) a_leaves.push_back(*itl);
_find_leaves((*it)->branches(),a_leaves);
}
}
static void _find_branches(const std::vector<branch*>& a_bs,std::vector<branch*>& a_branches){
tools_vforcit(branch*,a_bs,it) {
a_branches.push_back(*it);
_find_branches((*it)->branches(),a_branches);
}
}
static branch* _find_leaf_branch(const std::vector<branch*>& a_bs,const base_leaf& a_leaf) {
tools_vforcit(branch*,a_bs,itb) {
tools_vforcit(base_leaf*,(*itb)->leaves(),itl) {if(*itl==&a_leaf) return *itb;}
{branch* br = _find_leaf_branch((*itb)->branches(),a_leaf);
if(br) return br;}
}
return 0;
}
protected:
ifile& m_file;
ifac& m_fac;
std::ostream& m_out;
//Named
std::string m_name;
std::string m_title;
obj_array<branch> m_branches;
uint64 m_entries; // Number of entries
};
}}
#endif
+105
View File
@@ -0,0 +1,105 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_tree_index
#define tools_rroot_tree_index
#include "named"
namespace tools {
namespace rroot {
class tree_index : public virtual iro {
static const std::string& s_store_class() {
static const std::string s_v("TTreeIndex");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::tree_index");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<tree_index>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return branch_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<tree_index>(this,a_class)) {return p;}
else return 0;
}
public:
virtual iro* copy() const {return new tree_index(*this);}
virtual bool stream(buffer& a_buffer) {
uint32 startpos = a_buffer.length();
unsigned int s,c;
short v;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : tree_index::stream : version %d count %d\n",v,c);
if(!virtual_index_stream(a_buffer)) return false;
std::string ds;
if(!a_buffer.read(ds)) return false; //fMajorName
//::printf("debug : tree_index::stream : fMajorName \"%s\"\n",ds.c_str());
if(!a_buffer.read(ds)) return false; //fMinorName
//::printf("debug : tree_index::stream : fMinorName \"%s\"\n",ds.c_str());
int64 m_n;
if(!a_buffer.read(m_n)) return false; //fN
//::printf("debug : tree_index::stream : fN %ld\n",m_n);
if(!dummy_array_stream<int64>(a_buffer,int(m_n))) return false;
if(!dummy_array_stream<int64>(a_buffer,int(m_n))) return false;
//FIXME : still problem with this streamer.
a_buffer.set_offset(startpos+c+sizeof(unsigned int));
if(!a_buffer.check_byte_count(s,c,s_store_class())) return false;
//::printf("debug : tree_index::stream : ok\n");
return true;
}
public:
tree_index()
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~tree_index(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
tree_index(const tree_index& a_from):iro(a_from){}
tree_index& operator=(const tree_index&){return *this;}
protected:
static const std::string& virtual_index_s_store_class() {
static const std::string s_v("TVirtualIndex");
return s_v;
}
bool virtual_index_stream(buffer& a_buffer){
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : virtual_index::stream : version %d count %d\n",v,c);
std::string ds;
if(!Named_stream(a_buffer,ds,ds)) return false;
if(!a_buffer.check_byte_count(s,c,virtual_index_s_store_class()))
return false;
return true;
}
};
}}
#endif
+190
View File
@@ -0,0 +1,190 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_tree_manip
#define tools_rroot_tree_manip
#include "file"
#include "tree"
#include "stl_vector"
namespace tools {
namespace rroot {
inline tree* find_tree(file& a_file,ifac& a_fac,const std::string& a_name,bool a_map_objs = false) {
std::ostream& out = a_file.out();
//out << "tools::rroot::find_tree : name : " << file << std::endl;
key* key = a_file.dir().find_key(a_name);
if(!key) {
out << "tools::rroot::find_tree :"
<< " key " << sout(a_name) << " not found."
<< std::endl;
return 0;
}
unsigned int sz;
char* buf = key->get_object_buffer(a_file,sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::find_tree :"
<< " can't get data buffer of "
<< sout(key->object_name()) << "."
<< std::endl;
return 0;
}
//out << "tools::rroot::find_tree :"
// << " get data buffer size " << sz << "."
// << std::endl;
if(key->object_class()!=TTree_cls()) {
out << "tools::rroot::find_tree :"
<< " key object class "
<< sout(key->object_class())
<< " is not a TTree."
<< std::endl;
return 0;
}
buffer b(out,a_file.byte_swap(),sz,buf,key->key_length(),false);
b.set_map_objs(a_map_objs);
tree* _tree = new tree(a_file,a_fac);
if(!_tree->stream(b)) {
out << "tools::rroot::find_tree :"
<< " TTree streaming failed"
<< std::endl;
delete _tree;
return 0;
}
return _tree;
}
inline branch_element* find_be(tree& a_tree,const std::string& a_name){
std::ostream& out = a_tree.file().out();
branch* _branch = a_tree.find_branch(a_name,true);
if(!_branch) {
out << "tools::rroot::find_be :"
<< " branch not found."
<< std::endl;
return 0;
}
branch_element* be = id_cast<branch,branch_element>(*_branch);
if(!be) {
out << "tools::rroot::find_be :"
<< " branch not a branch_element."
<< std::endl;
return 0;
}
return be;
}
template <class T>
inline stl_vector<T>* find_vec(ifile& a_file,branch_element& a_be,uint64 a_event){
std::ostream& out = a_file.out();
unsigned int n;
if(!a_be.find_entry(a_file,a_event,n)) {
out << "tools::rroot::find_vec : branch_element.find_entry() failed." << std::endl;
return 0;
}
iro* o = a_be.object();
stl_vector<T>* od = id_cast<iro, stl_vector<T> >(*o);
if(!od) {
out << "tools::rroot::find_vec : object not a tools::rroot::stl_vector<T>." << std::endl;
return 0;
}
return od; //WARNING : we are not owner.
}
}}
#include "leaf"
namespace tools {
namespace rroot {
template <class LEAF>
inline bool find_leaf(tree& a_tree,const std::string& a_name,branch*& a_branch,LEAF*& a_leaf) {
//used in MEMPHYS sim.
base_leaf* _base_leaf = a_tree.find_leaf(a_name);
if(!_base_leaf) {
a_tree.out() << "tools::rroot::find_leaf : base_leaf " << sout(a_name) << " not found." << std::endl;
a_branch = 0;
a_leaf = 0;
return false;
}
a_branch = a_tree.find_leaf_branch(*_base_leaf);
if(!a_branch) {
a_tree.out() << "tools::rroot::find_leaf : branch of base_leaf " << sout(a_name) << " not found." << std::endl;
a_branch = 0;
a_leaf = 0;
return false;
}
a_leaf = safe_cast<base_leaf,LEAF>(*_base_leaf);
if(!a_leaf) {
a_tree.out() << "tools::rroot::find_leaf : base_leaf " << sout(a_name) << " is not a LEAF." << std::endl;
a_branch = 0;
a_leaf = 0;
return false;
}
return true;
}
inline branch_element* find_branch_element(tree& a_tree,const std::string& a_name) {
branch* _branch = a_tree.find_branch(a_name);
if(!_branch) {
a_tree.out() << "tools::rroot::find_branch_element : branch " << sout(a_name) << " not found." << std::endl;
return 0;
}
branch_element* be = safe_cast<branch,branch_element>(*_branch);
if(!be) {
a_tree.out() << "tools::rroot::find_branch_element : branch " << sout(a_name) << " not a branch_element."
<< " It is a " << sout(_branch->s_cls()) << "."
<< std::endl;
return 0;
}
return be;
}
template <class TYPE>
inline bool read_leaf(ifile& a_file,branch& a_branch,leaf<TYPE>& a_leaf,uint64 a_event,TYPE& a_value) {
unsigned int n;
if(!a_branch.find_entry(a_file,a_event,n)) {
a_file.out() << "tools::rroot::read_leaf : a_branch.find_entry() failed." << std::endl;
a_value = TYPE(0);
return false;
}
return a_leaf.value(0,a_value);
}
inline bool read_leaf_object(ifile& a_file,branch& a_branch,leaf_object& a_leaf,uint64 a_event) {
unsigned int n;
if(!a_branch.find_entry(a_file,a_event,n)) {
a_file.out() << "tools::rroot::read_leaf_object : a_branch.find_entry() failed." << std::endl;
return false;
}
return true;
}
template <class TYPE>
inline stl_vector<TYPE>* read_std_vec(ifile& a_file,branch_element& a_branch,uint64 a_event) {
unsigned int n;
if(!a_branch.find_entry(a_file,a_event,n)) {
a_file.out() << "tools::rroot::read_std_vec : a_branch.find_entry() failed." << std::endl;
return 0;
}
iro* obj = a_branch.object(); //Not owner.
if(!obj) return 0;
return id_cast<iro, stl_vector<TYPE> >(*obj);
}
}}
#endif
+90
View File
@@ -0,0 +1,90 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_vector3
#define tools_rroot_vector3
#include "../scast"
#include "object"
#include "cids"
namespace tools {
namespace rroot {
class vector3 : public virtual iro {
typedef iro parent;
private:
static const std::string& s_store_class() {
static const std::string s_v("TVector3");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::vector3");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<vector3>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
virtual iro* copy() const {return new vector3(*this);}
public:
static cid id_class() {return vector3_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<vector3>(this,a_class)) {return p;}
else return 0;
}
public:
virtual bool stream(buffer& a_buffer) {
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return false;
//printf("debug : tools::rroot::vector3::stream : version %d\n",v);
{uint32 id,bits;
if(!Object_stream(a_buffer,id,bits)) return false;}
if(!a_buffer.read(m_x)) return false;
if(!a_buffer.read(m_y)) return false;
if(!a_buffer.read(m_z)) return false;
if(!a_buffer.check_byte_count(s,c,s_store_class())) return false;
return true;
}
public:
vector3():m_x(0),m_y(0),m_z(0){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~vector3(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
vector3(const vector3& a_from)
:parent(a_from)
,m_x(a_from.m_x),m_y(a_from.m_y),m_z(a_from.m_z)
{}
vector3& operator=(const vector3& a_from){
m_x = a_from.m_x;
m_y = a_from.m_y;
m_z = a_from.m_z;
return *this;
}
public:
double x() const {return m_x;}
double y() const {return m_y;}
double z() const {return m_z;}
private:
double m_x,m_y,m_z;
};
}}
#endif