335 lines
9.4 KiB
Plaintext
335 lines
9.4 KiB
Plaintext
// 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_key_length = basket_key_length;
|
|
}
|
|
if(!m_object_size) {
|
|
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;
|
|
}
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
}
|
|
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)
|
|
{
|
|
}
|
|
virtual ~basket(){
|
|
_clear();
|
|
}
|
|
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)
|
|
{
|
|
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
|