inlib
1.2.0
|
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved. 00002 // See the file inlib.license for terms. 00003 00004 #ifndef inlib_rroot_directory 00005 #define inlib_rroot_directory 00006 00007 #include "seek" 00008 #include "date" 00009 #include "key" 00010 #include "ifile" 00011 00012 #include <vector> 00013 00014 namespace inlib { 00015 namespace rroot { 00016 00017 class directory { 00018 public: 00019 directory(ifile& a_file) 00020 :m_file(a_file) 00021 { 00022 #ifdef INLIB_MEM 00023 mem::increment(s_class().c_str()); 00024 #endif 00025 m_date_C = 0; //.set(); 00026 m_date_M = 0; //.set(); 00027 m_nbytes_keys = 0; 00028 m_nbytes_name = 0; 00029 m_seek_directory = 0; 00030 m_seek_parent = 0; 00031 m_seek_keys = 0; 00032 } 00033 virtual ~directory(){ 00034 clear_keys(); 00035 #ifdef INLIB_MEM 00036 mem::decrement(s_class().c_str()); 00037 #endif 00038 } 00039 protected: 00040 directory(const directory& a_from):m_file(a_from.m_file){ 00041 #ifdef INLIB_MEM 00042 mem::increment(s_class().c_str()); 00043 #endif 00044 } 00045 directory& operator=(const directory &){return *this;} 00046 public: 00047 const std::vector<key*>& keys() const {return m_keys;} 00048 std::vector<key*>& keys() {return m_keys;} 00049 00050 key* find_key(const std::string& a_name) { 00051 if(m_file.verbose()) { 00052 m_file.out() << "inlib::rroot::directory::find_key :" 00053 << " " << sout(a_name) << " ..." 00054 << std::endl; 00055 } 00056 std::vector<key*>::const_iterator it; 00057 for(it=m_keys.begin();it!=m_keys.end();++it) { 00058 if((*it)->object_name()==a_name) return *it; 00059 } 00060 00061 return 0; 00062 } 00063 00064 uint32 nbytes_name() const {return m_nbytes_name;} 00065 seek seek_keys() const {return m_seek_keys;} 00066 uint32 record_size(uint32 a_version) const { 00067 uint32 nbytes = sizeof(short); 00068 nbytes += sizeof(date); //m_date_C.record_size(); 00069 nbytes += sizeof(date); //m_date_M.record_size(); 00070 nbytes += sizeof(m_nbytes_keys); 00071 nbytes += sizeof(m_nbytes_name); 00072 if(a_version>=40000) { 00073 nbytes += sizeof(seek); 00074 nbytes += sizeof(seek); 00075 nbytes += sizeof(seek); 00076 } else { 00077 nbytes += sizeof(seek32); 00078 nbytes += sizeof(seek32); 00079 nbytes += sizeof(seek32); 00080 } 00081 return nbytes; 00082 } 00083 bool from_buffer(const char* aEOB,char*& a_buffer){ 00084 // Decode input buffer. 00085 // (Name, title) are stored in the (name, title) of the associated key. 00086 rbuf rb(m_file.out(),m_file.byte_swap(),aEOB,a_buffer); 00087 short versiondir; 00088 if(!rb.read(versiondir)) return false; 00089 unsigned int date; 00090 if(!rb.read(date)) return false; 00091 //fDateC.setDate(date); 00092 if(!rb.read(date)) return false; 00093 //fDateM.setDate(date); 00094 {int v; 00095 if(!rb.read(v)) return false; 00096 m_nbytes_keys = v;} 00097 {int v; 00098 if(!rb.read(v)) return false; 00099 m_nbytes_name = v;} 00100 if(versiondir>1000) { 00101 if(!rb.read(m_seek_directory)) return false; 00102 if(!rb.read(m_seek_parent)) return false; 00103 if(!rb.read(m_seek_keys)) return false; 00104 } else { 00105 {seek32 i; 00106 if(!rb.read(i)) return false; 00107 m_seek_directory = i;} 00108 00109 {seek32 i; 00110 if(!rb.read(i)) return false; 00111 m_seek_parent = i;} 00112 00113 {seek32 i; 00114 if(!rb.read(i)) return false; 00115 m_seek_keys = i;} 00116 } 00117 if(m_file.verbose()) { 00118 m_file.out() << "inlib::rroot::key::from_buffer :" 00119 << " nbytes keys : " << m_nbytes_keys 00120 << ", pos keys : " << m_seek_keys 00121 << std::endl; 00122 } 00123 return true; 00124 } 00125 bool read_keys(uint32& a_number) { 00126 // Read the KEYS : 00127 // Every directory has a list (fKeys). This list has been 00128 // written on the file via CERN-ROOT::TDirectory::writeKeys 00129 // as a single data record. 00130 a_number = 0; 00131 00132 clear_keys(); 00133 00134 key headerkey(m_file,m_seek_keys,m_nbytes_keys); 00135 if(!headerkey.read_file()) return false; 00136 char* buffer = headerkey.data_buffer(); 00137 if(!headerkey.from_buffer(headerkey.eob(),buffer)) return false; 00138 int nkeys = 0; 00139 rbuf rb(m_file.out(),m_file.byte_swap(),headerkey.eob(),buffer); 00140 if(!rb.read(nkeys)) return false; 00141 if(m_file.verbose()) { 00142 m_file.out() << "inlib::rroot::directory::read_keys :" 00143 << " nkeys " << nkeys 00144 << "." 00145 << std::endl; 00146 } 00147 for(int i=0;i<nkeys;i++) { 00148 key* k = new key(m_file); 00149 if(!k->from_buffer(headerkey.eob(),buffer)) { 00150 delete k; 00151 return false; 00152 } 00153 m_keys.push_back(k); 00154 } 00155 a_number = nkeys; 00156 return true; 00157 } 00158 void clear_keys() { 00159 std::vector<key*>::iterator it; 00160 for(it=m_keys.begin();it!=m_keys.end();) { 00161 key* k = *it; 00162 it = m_keys.erase(it); 00163 delete k; 00164 } 00165 m_keys.clear(); 00166 } 00167 protected: 00168 static std::string sout(const std::string& a_string) { 00169 return std::string("\"")+a_string+"\""; 00170 } 00171 static const std::string& s_class() { 00172 static const std::string s_v("inlib::rroot::directory"); 00173 return s_v; 00174 } 00175 protected: 00176 ifile& m_file; 00177 std::vector<key*> m_keys; 00178 // Record (stored in file): 00179 date m_date_C; //Date and time when directory is created 00180 date m_date_M; //Date and time of last modification 00181 uint32 m_nbytes_keys; //Number of bytes for the keys 00182 uint32 m_nbytes_name; //Number of bytes in TNamed at creation time 00183 seek m_seek_directory; //Location of directory on file 00184 seek m_seek_parent; //Location of parent directory on file 00185 seek m_seek_keys; //Location of Keys record on file 00186 }; 00187 00188 }} 00189 00190 #endif