Import Geant4 11.0.0.beta source tree
This commit is contained in:
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
|
||||
//
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user