// 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) { 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(); } protected: directory(const directory& a_from):m_file(a_from.m_file){ } directory& operator=(const directory &){return *this;} public: ifile& file() {return m_file;} const std::vector& keys() const {return m_keys;} std::vector& 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; if(!rb.read(_date)) return false; {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;ifrom_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(m_keys); } protected: ifile& m_file; std::vector 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