Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/wroot/directory

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/g4tools/include/tools/wroot/directory (Version 11.3.0) and /externals/g4tools/include/tools/wroot/directory (Version 11.1.1)


  1 // Copyright (C) 2010, Guy Barrand. All rights      1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.            2 // See the file tools.license for terms.
  3                                                     3 
  4 #ifndef tools_wroot_directory                       4 #ifndef tools_wroot_directory
  5 #define tools_wroot_directory                       5 #define tools_wroot_directory
  6                                                     6 
  7 #include "idir"                                     7 #include "idir"
  8                                                     8 
  9 #include "date"                                     9 #include "date"
 10 #include "key"                                     10 #include "key"
 11 #include "ifile"                                   11 #include "ifile"
 12 #include "date"                                    12 #include "date"
 13 #include "buffer"                                  13 #include "buffer"
 14 #include "iobject"                                 14 #include "iobject"
 15                                                    15 
 16 #include "../strip"                                16 #include "../strip"
 17 #include "../vmanip"                               17 #include "../vmanip"
 18 #include "../forit"                                18 #include "../forit"
 19                                                    19 
 20 #include <vector>                                  20 #include <vector>
 21 #include <list>                                    21 #include <list>
 22                                                    22 
 23 namespace tools {                                  23 namespace tools {
 24 namespace wroot {                                  24 namespace wroot {
 25                                                    25 
 26 class directory : public virtual idir {            26 class directory : public virtual idir {
 27   static uint32 class_version() {return 1;}        27   static uint32 class_version() {return 1;}
 28 public:                                            28 public:
 29   static const std::string& s_class() {            29   static const std::string& s_class() {
 30     static const std::string s_v("tools::wroot     30     static const std::string s_v("tools::wroot::directory");
 31     return s_v;                                    31     return s_v;
 32   }                                                32   }
 33 public: //idir                                     33 public: //idir
 34   virtual ifile& file() {return m_file;}           34   virtual ifile& file() {return m_file;}
 35   virtual seek seek_directory() const {return      35   virtual seek seek_directory() const {return m_seek_directory;}
 36   virtual void append_object(iobject* a_object     36   virtual void append_object(iobject* a_object) {m_objs.push_back(a_object);} //take ownership of a_object
 37 public:                                            37 public:
 38   directory(ifile& a_file)                         38   directory(ifile& a_file)
 39   :m_file(a_file)                                  39   :m_file(a_file)
 40   ,m_parent(0)                                     40   ,m_parent(0)
 41   ,m_is_valid(false)                               41   ,m_is_valid(false)
 42   ,m_date_C(0)                                     42   ,m_date_C(0)
 43   ,m_date_M(0)                                     43   ,m_date_M(0)
 44   ,m_nbytes_keys(0)                                44   ,m_nbytes_keys(0)
 45   ,m_nbytes_name(0)                                45   ,m_nbytes_name(0)
 46   ,m_seek_directory(0)                             46   ,m_seek_directory(0)
 47   ,m_seek_parent(0)                                47   ,m_seek_parent(0)
 48   ,m_seek_keys(0)                                  48   ,m_seek_keys(0)
 49   {                                                49   {
 50 #ifdef TOOLS_MEM                                   50 #ifdef TOOLS_MEM
 51     mem::increment(s_class().c_str());             51     mem::increment(s_class().c_str());
 52 #endif                                             52 #endif
 53   }                                                53   }
 54   directory(ifile& a_file,const std::string& a     54   directory(ifile& a_file,const std::string& a_name,const std::string& a_title)
 55   :m_file(a_file)                                  55   :m_file(a_file)
 56   ,m_parent(0)                                     56   ,m_parent(0)
 57   ,m_is_valid(false)                               57   ,m_is_valid(false)
 58   ,m_name(a_name)                                  58   ,m_name(a_name)
 59   ,m_title(a_title)                                59   ,m_title(a_title)
 60   ,m_nbytes_keys(0)                                60   ,m_nbytes_keys(0)
 61   ,m_nbytes_name(0)                                61   ,m_nbytes_name(0)
 62   ,m_seek_directory(0)                             62   ,m_seek_directory(0)
 63   ,m_seek_parent(0)                                63   ,m_seek_parent(0)
 64   ,m_seek_keys(0)                                  64   ,m_seek_keys(0)
 65   {                                                65   {
 66 #ifdef TOOLS_MEM                                   66 #ifdef TOOLS_MEM
 67     mem::increment(s_class().c_str());             67     mem::increment(s_class().c_str());
 68 #endif                                             68 #endif
 69     m_date_C = get_date();                         69     m_date_C = get_date();
 70     m_date_M = get_date();                         70     m_date_M = get_date();
 71                                                    71 
 72     if(m_name.empty()) {                           72     if(m_name.empty()) {
 73       m_file.out() << "tools::wroot::directory     73       m_file.out() << "tools::wroot::directory::directory :"
 74                    << " directory name cannot      74                    << " directory name cannot be \"\"."
 75                    << std::endl;                   75                    << std::endl;
 76       return; //FIXME : throw                      76       return; //FIXME : throw
 77     }                                              77     }
 78     if(m_name.find('/')!=std::string::npos) {      78     if(m_name.find('/')!=std::string::npos) {
 79       m_file.out() << "tools::wroot::directory     79       m_file.out() << "tools::wroot::directory::directory :"
 80                    << " directory name " << so     80                    << " directory name " << sout(m_name)
 81                    << " cannot contain a slash     81                    << " cannot contain a slash."
 82                    << std::endl;                   82                    << std::endl;
 83       return; //FIXME : throw                      83       return; //FIXME : throw
 84     }                                              84     }
 85     if(m_title.empty()) m_title = m_name;          85     if(m_title.empty()) m_title = m_name;
 86     m_is_valid = true;                             86     m_is_valid = true;
 87   }                                                87   }
 88   directory(ifile& a_file,                         88   directory(ifile& a_file,
 89             directory* a_parent, //assume a_pa     89             directory* a_parent, //assume a_parent not nul.
 90             const std::string& a_name,             90             const std::string& a_name,
 91             const std::string& a_title)            91             const std::string& a_title)
 92   :m_file(a_file)                                  92   :m_file(a_file)
 93   ,m_parent(a_parent)                              93   ,m_parent(a_parent)
 94   ,m_is_valid(false)                               94   ,m_is_valid(false)
 95   ,m_name(a_name)                                  95   ,m_name(a_name)
 96   ,m_title(a_title)                                96   ,m_title(a_title)
 97   ,m_nbytes_keys(0)                                97   ,m_nbytes_keys(0)
 98   ,m_nbytes_name(0)                                98   ,m_nbytes_name(0)
 99   ,m_seek_directory(0)                             99   ,m_seek_directory(0)
100   ,m_seek_parent(0)                               100   ,m_seek_parent(0)
101   ,m_seek_keys(0)                                 101   ,m_seek_keys(0)
102   {                                               102   {
103 #ifdef TOOLS_MEM                                  103 #ifdef TOOLS_MEM
104     mem::increment(s_class().c_str());            104     mem::increment(s_class().c_str());
105 #endif                                            105 #endif
106     m_date_C = get_date();                        106     m_date_C = get_date();
107     m_date_M = get_date();                        107     m_date_M = get_date();
108                                                   108 
109     if(m_name.empty()) {                          109     if(m_name.empty()) {
110       m_file.out() << "tools::wroot::directory    110       m_file.out() << "tools::wroot::directory::directory :"
111                    << " directory name cannot     111                    << " directory name cannot be \"\"."
112                    << std::endl;                  112                    << std::endl;
113       return; //FIXME : throw                     113       return; //FIXME : throw
114     }                                             114     }
115     if(m_name.find('/')!=std::string::npos) {     115     if(m_name.find('/')!=std::string::npos) {
116       m_file.out() << "tools::wroot::directory    116       m_file.out() << "tools::wroot::directory::directory :"
117                    << " directory name " << so    117                    << " directory name " << sout(m_name)
118                    << " cannot contain a slash    118                    << " cannot contain a slash."
119                    << std::endl;                  119                    << std::endl;
120       return; //FIXME : throw                     120       return; //FIXME : throw
121     }                                             121     }
122                                                   122 
123     if(m_title.empty()) m_title = m_name;         123     if(m_title.empty()) m_title = m_name;
124                                                   124 
125     if(m_parent->find_key(m_name)) {              125     if(m_parent->find_key(m_name)) {
126       m_file.out() << "tools::wroot::directory    126       m_file.out() << "tools::wroot::directory::directory :"
127                    << " directory " << sout(m_    127                    << " directory " << sout(m_name) << " exists already."
128                    << std::endl;                  128                    << std::endl;
129       return; //FIXME : throw                     129       return; //FIXME : throw
130     }                                             130     }
131                                                   131 
132     m_seek_parent = m_parent->seek_directory()    132     m_seek_parent = m_parent->seek_directory();
133     uint32 nbytes = record_size();                133     uint32 nbytes = record_size();
134                                                   134 
135     wroot::key* key = new wroot::key(m_file.ou    135     wroot::key* key = new wroot::key(m_file.out(),m_file,m_parent->seek_directory(),
136                                      m_name,m_    136                                      m_name,m_title,"TDirectory",nbytes); // It does a m_file.set_END().
137     m_nbytes_name = key->key_length();            137     m_nbytes_name = key->key_length();
138     m_seek_directory = key->seek_key(); //at E    138     m_seek_directory = key->seek_key(); //at EOF
139     if(!m_seek_directory) {                       139     if(!m_seek_directory) {
140       m_file.out() << "tools::wroot::directory    140       m_file.out() << "tools::wroot::directory::directory :"
141                    << " bad key."                 141                    << " bad key."
142                    << std::endl;                  142                    << std::endl;
143       delete key;                                 143       delete key;
144       return; //FIXME : throw                     144       return; //FIXME : throw
145     }                                             145     }
146    {char* buffer = key->data_buffer();            146    {char* buffer = key->data_buffer();
147     wbuf wb(m_file.out(),m_file.byte_swap(),ke    147     wbuf wb(m_file.out(),m_file.byte_swap(),key->eob(),buffer);
148     if(!to_buffer(wb)) {                          148     if(!to_buffer(wb)) {
149       m_file.out() << "tools::wroot::directory    149       m_file.out() << "tools::wroot::directory::directory :"
150                    << " directory name " << so    150                    << " directory name " << sout(m_name)
151                    << " cannot fill buffer."      151                    << " cannot fill buffer."
152                    << std::endl;                  152                    << std::endl;
153       delete key;                                 153       delete key;
154       return; //FIXME : throw                     154       return; //FIXME : throw
155     }}                                            155     }}
156     uint16 cycle = m_parent->append_key(key);     156     uint16 cycle = m_parent->append_key(key);
157     key->set_cycle(cycle);                        157     key->set_cycle(cycle);
158     if(!key->write_self(m_file)) {                158     if(!key->write_self(m_file)) {
159       m_file.out() << "tools::wroot::directory    159       m_file.out() << "tools::wroot::directory::directory :"
160                    << " key.write_self() faile    160                    << " key.write_self() failed."
161                    << std::endl;                  161                    << std::endl;
162       return; //FIXME : throw                     162       return; //FIXME : throw
163     }                                             163     }
164     uint32 n;                                     164     uint32 n;
165     if(!key->write_file(m_file,n)) {              165     if(!key->write_file(m_file,n)) {
166       m_file.out() << "tools::wroot::directory    166       m_file.out() << "tools::wroot::directory::directory :"
167                    << " directory name " << so    167                    << " directory name " << sout(m_name)
168                    << " cannot write key to fi    168                    << " cannot write key to file."
169                    << std::endl;                  169                    << std::endl;
170       return; //FIXME : throw                     170       return; //FIXME : throw
171     }                                             171     }
172                                                   172 
173     m_is_valid = true;                            173     m_is_valid = true;
174   }                                               174   }
175   virtual ~directory(){                           175   virtual ~directory(){
176     clear_dirs();                                 176     clear_dirs();
177     clear_objs();                                 177     clear_objs();
178     clear_keys();                                 178     clear_keys();
179 #ifdef TOOLS_MEM                                  179 #ifdef TOOLS_MEM
180     mem::decrement(s_class().c_str());            180     mem::decrement(s_class().c_str());
181 #endif                                            181 #endif
182   }                                               182   }
183 protected:                                        183 protected:
184   directory(const directory& a_from)              184   directory(const directory& a_from)
185   :idir(a_from)                                   185   :idir(a_from)
186   ,m_file(a_from.m_file)                          186   ,m_file(a_from.m_file)
187   ,m_parent(0)                                    187   ,m_parent(0)
188   ,m_is_valid(false){                             188   ,m_is_valid(false){
189 #ifdef TOOLS_MEM                                  189 #ifdef TOOLS_MEM
190     mem::increment(s_class().c_str());            190     mem::increment(s_class().c_str());
191 #endif                                            191 #endif
192   }                                               192   }
193   directory& operator=(const directory &){        193   directory& operator=(const directory &){
194     m_is_valid = false;                           194     m_is_valid = false;
195     return *this;                                 195     return *this;
196   }                                               196   }
197 public:                                           197 public:
198   bool is_valid() const {return m_is_valid;}      198   bool is_valid() const {return m_is_valid;}
199   void set_seek_directory(seek a_seek) {m_seek    199   void set_seek_directory(seek a_seek) {m_seek_directory = a_seek;}
200                                                   200 
201   directory* mkdir(const std::string& a_name,c    201   directory* mkdir(const std::string& a_name,const std::string& a_title = ""){
202     // Create a sub-directory and return a poi    202     // Create a sub-directory and return a pointer to the created directory.
203     // Note that the directory name cannot con    203     // Note that the directory name cannot contain slashes.
204     if(a_name.empty()) {                          204     if(a_name.empty()) {
205       m_file.out() << "tools::wroot::directory    205       m_file.out() << "tools::wroot::directory::mkdir :"
206                    << " directory name cannot     206                    << " directory name cannot be \"\"."
207                    << std::endl;                  207                    << std::endl;
208       return 0;                                   208       return 0;
209     }                                             209     }
210     if(a_name.find('/')!=std::string::npos) {     210     if(a_name.find('/')!=std::string::npos) {
211       m_file.out() << "tools::wroot::directory    211       m_file.out() << "tools::wroot::directory::mkdir :"
212                    << " " << sout(a_name)         212                    << " " << sout(a_name)
213                    << " cannot contain a slash    213                    << " cannot contain a slash."
214                    << std::endl;                  214                    << std::endl;
215       return 0;                                   215       return 0;
216     }                                             216     }
217     directory* dir = new directory(m_file,this    217     directory* dir = new directory(m_file,this,a_name,a_title.empty()?a_name:a_title);
218     if(!dir->is_valid()) {                        218     if(!dir->is_valid()) {
219       m_file.out() << "tools::wroot::directory    219       m_file.out() << "tools::wroot::directory::mkdir :"
220                    << " directory badly create    220                    << " directory badly created."
221                    << std::endl;                  221                    << std::endl;
222       delete dir;                                 222       delete dir;
223       return 0;                                   223       return 0;
224     }                                             224     }
225     m_dirs.push_back(dir);                        225     m_dirs.push_back(dir);
226     return dir;                                   226     return dir;
227   }                                               227   }
228                                                   228 
229   //uint32 nbytes_name() const {return m_nbyte    229   //uint32 nbytes_name() const {return m_nbytes_name;}
230   void set_nbytes_name(uint32 a_n) {m_nbytes_n    230   void set_nbytes_name(uint32 a_n) {m_nbytes_name = a_n;}
231                                                   231 
232   uint32 record_size() const {                    232   uint32 record_size() const {
233     uint32 nbytes = sizeof(short);                233     uint32 nbytes = sizeof(short);
234     nbytes += sizeof(date); //m_date_C.record_    234     nbytes += sizeof(date); //m_date_C.record_size();
235     nbytes += sizeof(date); //m_date_M.record_    235     nbytes += sizeof(date); //m_date_M.record_size();
236     nbytes += sizeof(m_nbytes_keys);              236     nbytes += sizeof(m_nbytes_keys);
237     nbytes += sizeof(m_nbytes_name);              237     nbytes += sizeof(m_nbytes_name);
238     //ROOT version >= 40000:                      238     //ROOT version >= 40000:
239     nbytes += sizeof(seek);                       239     nbytes += sizeof(seek);
240     nbytes += sizeof(seek);                       240     nbytes += sizeof(seek);
241     nbytes += sizeof(seek);                       241     nbytes += sizeof(seek);
242     return nbytes;                                242     return nbytes;
243   }                                               243   }
244                                                   244 
245   bool close() {                                  245   bool close() {
246     if(!save()) return false;                     246     if(!save()) return false;
247     clear_dirs();                                 247     clear_dirs();
248     clear_objs();                                 248     clear_objs();
249     clear_keys();                                 249     clear_keys();
250     return true;                                  250     return true;
251   }                                               251   }
252                                                   252 
253   bool to_buffer(wbuf& a_wb){                     253   bool to_buffer(wbuf& a_wb){
254     // Decode input buffer.                       254     // Decode input buffer.
255     // (Name, title) are stored in the (name,     255     // (Name, title) are stored in the (name, title) of the associated key.
256     short version = class_version();              256     short version = class_version();
257     version += big_file_version_tag(); //GB :     257     version += big_file_version_tag(); //GB : enforce writing on seek (and not seek32).
258     if(!a_wb.write(version)) return false;        258     if(!a_wb.write(version)) return false;
259     if(!a_wb.write(m_date_C)) return false;       259     if(!a_wb.write(m_date_C)) return false;
260     if(!a_wb.write(m_date_M)) return false;       260     if(!a_wb.write(m_date_M)) return false;
261     if(!a_wb.write(m_nbytes_keys)) return fals    261     if(!a_wb.write(m_nbytes_keys)) return false;
262     if(!a_wb.write(m_nbytes_name)) return fals    262     if(!a_wb.write(m_nbytes_name)) return false;
263                                                   263 
264     if(!a_wb.write(m_seek_directory)) return f    264     if(!a_wb.write(m_seek_directory)) return false;
265     if(!a_wb.write(m_seek_parent)) return fals    265     if(!a_wb.write(m_seek_parent)) return false;
266     if(!a_wb.write(m_seek_keys)) return false;    266     if(!a_wb.write(m_seek_keys)) return false;
267                                                   267 
268     if(m_file.verbose()) {                        268     if(m_file.verbose()) {
269       m_file.out() << "tools::wroot::key::to_b    269       m_file.out() << "tools::wroot::key::to_buffer :"
270           << " nbytes keys : " << m_nbytes_key    270           << " nbytes keys : " << m_nbytes_keys
271           << ", pos keys : " << m_seek_keys       271           << ", pos keys : " << m_seek_keys
272           << std::endl;                           272           << std::endl;
273     }                                             273     }
274     return true;                                  274     return true;
275   }                                               275   }
276                                                   276 
277   bool write(uint32& a_nbytes){                   277   bool write(uint32& a_nbytes){
278     // Write all objects in memory to disk.       278     // Write all objects in memory to disk.
279     // Loop on all objects in memory (includin    279     // Loop on all objects in memory (including subdirectories).
280     // A new key is created in the m_keys link    280     // A new key is created in the m_keys linked list for each object.
281     // For allowed options see TObject::Write(    281     // For allowed options see TObject::Write().
282     // The directory header info is rewritten     282     // The directory header info is rewritten on the directory header record
283     a_nbytes = 0;                                 283     a_nbytes = 0;
284     if(m_file.verbose()) {                        284     if(m_file.verbose()) {
285       m_file.out() << "tools::wroot::directory    285       m_file.out() << "tools::wroot::directory::write :"
286                    << " " << sout(m_name)         286                    << " " << sout(m_name)
287                    << " : " << m_dirs.size()      287                    << " : " << m_dirs.size()
288                    << " : " << m_objs.size()      288                    << " : " << m_objs.size()
289                    << " objects."                 289                    << " objects."
290                    << std::endl;                  290                    << std::endl;
291     }                                             291     }
292                                                   292 
293     uint32 nbytes = 0;                            293     uint32 nbytes = 0;
294                                                   294 
295    {tools_vforcit(directory*,m_dirs,it) {         295    {tools_vforcit(directory*,m_dirs,it) {
296       uint32 n;                                   296       uint32 n;
297       if(!(*it)->write(n)) return false;          297       if(!(*it)->write(n)) return false;
298       nbytes += n;                                298       nbytes += n;
299     }}                                            299     }}
300                                                   300 
301    {tools_vforit(iobject*,m_objs,it) {            301    {tools_vforit(iobject*,m_objs,it) {
302       uint32 n;                                   302       uint32 n;
303       if(!write_object(*(*it),n)) {               303       if(!write_object(*(*it),n)) {
304         m_file.out() << "tools::wroot::directo    304         m_file.out() << "tools::wroot::directory::write :"
305                      << " for directory " << s    305                      << " for directory " << sout(m_name)
306                      << ", write_object " << s    306                      << ", write_object " << sout((*it)->name())
307                      << " failed."                307                      << " failed."
308                      << std::endl;                308                      << std::endl;
309         return false;                             309         return false;
310       }                                           310       }
311       nbytes += n;                                311       nbytes += n;
312     }}                                            312     }}
313                                                   313 
314     if(!save_self()) {                            314     if(!save_self()) {
315       m_file.out() << "tools::wroot::directory    315       m_file.out() << "tools::wroot::directory::write :"
316                    << " for directory " << sou    316                    << " for directory " << sout(m_name)
317                    << ", save_self failed."       317                    << ", save_self failed."
318                    << std::endl;                  318                    << std::endl;
319       return false; //it will write keys of ob    319       return false; //it will write keys of objects.
320     }                                             320     }
321                                                   321 
322     a_nbytes = nbytes;                            322     a_nbytes = nbytes;
323     return true;                                  323     return true;
324   }                                               324   }
325                                                   325 
326   void clear_dirs() {safe_clear<directory>(m_d    326   void clear_dirs() {safe_clear<directory>(m_dirs);}
327   void clear_objs() {safe_clear<iobject>(m_obj    327   void clear_objs() {safe_clear<iobject>(m_objs);}
328                                                   328 
329   const std::list<key*>& keys() const {return     329   const std::list<key*>& keys() const {return m_keys;}
330   //std::list<key*>& keys() {return m_keys;}      330   //std::list<key*>& keys() {return m_keys;}
331                                                   331 
332 protected:                                        332 protected:
333   void clear_keys() {                             333   void clear_keys() {
334     std::list<key*>::iterator it;                 334     std::list<key*>::iterator it;
335     for(it=m_keys.begin();it!=m_keys.end();) {    335     for(it=m_keys.begin();it!=m_keys.end();) {
336       key* k = *it;                               336       key* k = *it;
337       it = m_keys.erase(it);                      337       it = m_keys.erase(it);
338       delete k;                                   338       delete k;
339     }                                             339     }
340     m_keys.clear();                               340     m_keys.clear();
341   }                                               341   }
342                                                   342 
343   bool save(){                                    343   bool save(){
344     if(!save_self()) return false;                344     if(!save_self()) return false;
345     tools_vforit(directory*,m_dirs,it) {          345     tools_vforit(directory*,m_dirs,it) {
346       if(!(*it)->save()) return false;            346       if(!(*it)->save()) return false;
347     }                                             347     }
348     return true;                                  348     return true;
349   }                                               349   }
350                                                   350 
351   bool save_self() {                              351   bool save_self() {
352     // Save Directory keys and header :           352     // Save Directory keys and header :
353     //  If the directory has been modified (fM    353     //  If the directory has been modified (fModified set), write the keys
354     //  and the directory header.                 354     //  and the directory header.
355     //if (fModified || aForce) {                  355     //if (fModified || aForce) {
356     //  if(!fFile.freeSegments().empty()) {       356     //  if(!fFile.freeSegments().empty()) {
357     //    if(!writeKeys()) return false; // Wr    357     //    if(!writeKeys()) return false; // Write keys record.
358     //    if(!writeHeader()) return false; //     358     //    if(!writeHeader()) return false; // Update directory record.
359     //  }                                         359     //  }
360     //}                                           360     //}
361     if(!write_keys()) return false;               361     if(!write_keys()) return false;
362     if(!write_header()) return false;             362     if(!write_header()) return false;
363     return true;                                  363     return true;
364   }                                               364   }
365                                                   365 
366   key* find_key(const std::string& a_name) {      366   key* find_key(const std::string& a_name) {
367     if(m_file.verbose()) {                        367     if(m_file.verbose()) {
368       m_file.out() << "tools::wroot::directory    368       m_file.out() << "tools::wroot::directory::find_key :"
369                    << " " << sout(a_name) << "    369                    << " " << sout(a_name) << " ..."
370                    << std::endl;                  370                    << std::endl;
371     }                                             371     }
372     tools_lforcit(key*,m_keys,it) {               372     tools_lforcit(key*,m_keys,it) {
373       if((*it)->object_name()==a_name) return     373       if((*it)->object_name()==a_name) return *it;
374     }                                             374     }
375                                                   375 
376     return 0;                                     376     return 0;
377   }                                               377   }
378   seek seek_keys() const {return m_seek_keys;}    378   seek seek_keys() const {return m_seek_keys;}
379                                                   379 
380   uint16 append_key(key* a_key){ //take owners    380   uint16 append_key(key* a_key){ //take ownership of a_key
381     tools_lforit(key*,m_keys,it) {                381     tools_lforit(key*,m_keys,it) {
382       if((*it)->object_name()==a_key->object_n    382       if((*it)->object_name()==a_key->object_name()) {
383         m_keys.insert(it,a_key); //a_key will     383         m_keys.insert(it,a_key); //a_key will be before *it.
384         return ((*it)->cycle() + 1);              384         return ((*it)->cycle() + 1);
385       }                                           385       }
386     }                                             386     }
387     // Not found :                                387     // Not found :
388     m_keys.push_back(a_key);                      388     m_keys.push_back(a_key);
389     return 1;                                     389     return 1;
390   }                                               390   }
391                                                   391 
392   bool write_keys(){                              392   bool write_keys(){
393     // The list of keys (m_keys) is written as    393     // The list of keys (m_keys) is written as a single data record
394     // Delete the old keys structure if it exi    394     // Delete the old keys structure if it exists
395                                                   395 
396     //if(fSeekKeys) {                             396     //if(fSeekKeys) {
397     //  if(!fFile.makeFreeSegment                 397     //  if(!fFile.makeFreeSegment
398     //     (fSeekKeys, fSeekKeys + fNbytesKeys    398     //     (fSeekKeys, fSeekKeys + fNbytesKeys -1)) return false;
399     //}                                           399     //}
400                                                   400 
401     // Write new keys record :                    401     // Write new keys record :
402     uint32 nkeys  = uint32(m_keys.size());        402     uint32 nkeys  = uint32(m_keys.size());
403                                                   403 
404     // Compute size of all keys                   404     // Compute size of all keys
405     uint32 nbytes = sizeof(nkeys);                405     uint32 nbytes = sizeof(nkeys);
406                                                   406 
407    {tools_lforit(key*,m_keys,it) {                407    {tools_lforit(key*,m_keys,it) {
408       nbytes += (*it)->key_length();              408       nbytes += (*it)->key_length();
409     }}                                            409     }}
410                                                   410 
411     key headerkey(m_file.out(),m_file,m_seek_d    411     key headerkey(m_file.out(),m_file,m_seek_directory,m_name,m_title,"TDirectory",nbytes); // m_file.set_END().
412     if(!headerkey.seek_key()) return false;       412     if(!headerkey.seek_key()) return false;
413                                                   413 
414    {char* buffer = headerkey.data_buffer();       414    {char* buffer = headerkey.data_buffer();
415     wbuf wb(m_file.out(),m_file.byte_swap(),he    415     wbuf wb(m_file.out(),m_file.byte_swap(),headerkey.eob(),buffer);
416     if(!wb.write(nkeys)) return false;            416     if(!wb.write(nkeys)) return false;
417    {tools_lforit(key*,m_keys,it) {                417    {tools_lforit(key*,m_keys,it) {
418       if(!((*it)->to_buffer(wb,m_file.verbose(    418       if(!((*it)->to_buffer(wb,m_file.verbose()))) return false;
419     }}}                                           419     }}}
420                                                   420 
421     m_seek_keys = headerkey.seek_key();           421     m_seek_keys = headerkey.seek_key();
422     m_nbytes_keys = headerkey.number_of_bytes(    422     m_nbytes_keys = headerkey.number_of_bytes();
423                                                   423 
424     if(m_file.verbose()) {                        424     if(m_file.verbose()) {
425       m_file.out() << "tools::wroot::directory    425       m_file.out() << "tools::wroot::directory::write_keys :"
426                    << " write header key"         426                    << " write header key"
427                    << " " << sout(m_name)         427                    << " " << sout(m_name)
428                    << " " << sout(m_title)        428                    << " " << sout(m_title)
429                    << " (" << nkeys               429                    << " (" << nkeys
430                    << ", " << nbytes              430                    << ", " << nbytes
431                    << ", " << m_seek_keys         431                    << ", " << m_seek_keys
432                    << ", " << m_nbytes_keys       432                    << ", " << m_nbytes_keys
433                    << "):"                        433                    << "):"
434                    << std::endl;                  434                    << std::endl;
435     }                                             435     }
436                                                   436 
437     headerkey.set_cycle(1);                       437     headerkey.set_cycle(1);
438     if(!headerkey.write_self(m_file)) {           438     if(!headerkey.write_self(m_file)) {
439       m_file.out() << "tools::wroot::directory    439       m_file.out() << "tools::wroot::directory::write_keys :"
440                    << " key.write_self() faile    440                    << " key.write_self() failed."
441                    << std::endl;                  441                    << std::endl;
442       return false;                               442       return false;
443     }                                             443     }
444                                                   444 
445     uint32 n;                                     445     uint32 n;
446     return headerkey.write_file(m_file,n);        446     return headerkey.write_file(m_file,n);
447   }                                               447   }
448                                                   448 
449   bool write_header(){                            449   bool write_header(){
450     // Overwrite the Directory header record.     450     // Overwrite the Directory header record.
451     uint32 nbytes = record_size();                451     uint32 nbytes = record_size();
452     char* header = new char[nbytes];              452     char* header = new char[nbytes];
453     char* buffer = header;                        453     char* buffer = header;
454     m_date_M = get_date();                        454     m_date_M = get_date();
455     wbuf wb(m_file.out(),m_file.byte_swap(),he    455     wbuf wb(m_file.out(),m_file.byte_swap(),header+nbytes,buffer);
456     if(!to_buffer(wb)) {                          456     if(!to_buffer(wb)) {
457       delete [] header;                           457       delete [] header;
458       return false;                               458       return false;
459     }                                             459     }
460     // do not overwrite the name/title part       460     // do not overwrite the name/title part
461     seek pointer = m_seek_directory + m_nbytes    461     seek pointer = m_seek_directory + m_nbytes_name;
462     //fModified = false;                          462     //fModified = false;
463     if(!m_file.set_pos(pointer)) {                463     if(!m_file.set_pos(pointer)) {
464       delete [] header;                           464       delete [] header;
465       return false;                               465       return false;
466     }                                             466     }
467     if(!m_file.write_buffer(header,nbytes)) {     467     if(!m_file.write_buffer(header,nbytes)) {
468       delete [] header;                           468       delete [] header;
469       return false;                               469       return false;
470     }                                             470     }
471     if(!m_file.synchronize()) {                   471     if(!m_file.synchronize()) {
472       delete [] header;                           472       delete [] header;
473       return false;                               473       return false;
474     }                                             474     }
475     delete [] header;                             475     delete [] header;
476     return true;                                  476     return true;
477   }                                               477   }
478                                                   478 
479   bool write_object(iobject& a_obj,uint32& a_n    479   bool write_object(iobject& a_obj,uint32& a_nbytes){
480     buffer bref(m_file.out(),m_file.byte_swap(    480     buffer bref(m_file.out(),m_file.byte_swap(),256*128); //32768
481     if(!a_obj.stream(bref)) {                     481     if(!a_obj.stream(bref)) {
482       m_file.out() << "tools::wroot::directory    482       m_file.out() << "tools::wroot::directory::write_object :"
483                    << " cannot stream object o    483                    << " cannot stream object of store class name "
484                    << " " << sout(a_obj.store_    484                    << " " << sout(a_obj.store_class_name()) << "."
485                    << std::endl;                  485                    << std::endl;
486       a_nbytes = 0;                               486       a_nbytes = 0;
487       return false;                               487       return false;
488     }                                             488     }
489                                                   489 
490     std::string name = a_obj.name();              490     std::string name = a_obj.name();
491     strip(name);                                  491     strip(name);
492                                                   492 
493     //first create the key to get key_length()    493     //first create the key to get key_length();
494                                                   494 
495     wroot::key* key = new wroot::key(m_file.ou    495     wroot::key* key = new wroot::key(m_file.out(),m_file,m_seek_directory,
496                                      name,        496                                      name,
497                                      a_obj.tit    497                                      a_obj.title(),a_obj.store_class_name(),
498                                      bref.leng    498                                      bref.length()); // It does a m_file.set_END().
499                                                   499 
500     if(!key->seek_key()) {                        500     if(!key->seek_key()) {
501       delete key;                                 501       delete key;
502       return false;                               502       return false;
503     }                                             503     }
504                                                   504 
505     if(!bref.displace_mapped(key->key_length()    505     if(!bref.displace_mapped(key->key_length())) { //done before compression.
506       delete key;                                 506       delete key;
507       return false;                               507       return false;
508     }                                             508     }
509                                                   509 
510     char* kbuf = 0;                               510     char* kbuf = 0;
511     uint32 klen = 0;                              511     uint32 klen = 0;
512     bool kdelete = false;                         512     bool kdelete = false;
513     m_file.compress_buffer(bref,kbuf,klen,kdel    513     m_file.compress_buffer(bref,kbuf,klen,kdelete);
514                                                   514 
515     ::memcpy(key->data_buffer(),kbuf,klen);       515     ::memcpy(key->data_buffer(),kbuf,klen);
516     if(kdelete) delete [] kbuf;                   516     if(kdelete) delete [] kbuf;
517                                                   517 
518    {uint32 nkey = key->key_length()+klen;         518    {uint32 nkey = key->key_length()+klen;
519     m_file.set_END(key->seek_key()+nkey);         519     m_file.set_END(key->seek_key()+nkey);
520     key->set_number_of_bytes(nkey);}              520     key->set_number_of_bytes(nkey);}
521                                                   521 
522     uint16 cycle = append_key(key);               522     uint16 cycle = append_key(key);
523     key->set_cycle(cycle);                        523     key->set_cycle(cycle);
524                                                   524 
525     if(!key->write_self(m_file)) {                525     if(!key->write_self(m_file)) {
526       m_file.out() << "tools::wroot::directory    526       m_file.out() << "tools::wroot::directory::write_object :"
527                    << " key.write_self() faile    527                    << " key.write_self() failed."
528                    << std::endl;                  528                    << std::endl;
529       return false;                               529       return false;
530     }                                             530     }
531                                                   531 
532     //FIXME m_file.sumBuffer(key->object_size(    532     //FIXME m_file.sumBuffer(key->object_size()); //uncompressed data size.
533                                                   533 
534     if(m_file.verbose()) {                        534     if(m_file.verbose()) {
535       m_file.out() << "tools::wroot::directory    535       m_file.out() << "tools::wroot::directory::_write_buffer :"
536                    << " " << sout(a_obj.name()    536                    << " " << sout(a_obj.name()) << "."
537                    << std::endl;                  537                    << std::endl;
538     }                                             538     }
539                                                   539 
540     return key->write_file(m_file,a_nbytes);      540     return key->write_file(m_file,a_nbytes);
541   }                                               541   }
542                                                   542 
543 protected:                                        543 protected:
544   ifile& m_file;                                  544   ifile& m_file;
545   directory* m_parent;                            545   directory* m_parent;
546   bool m_is_valid;                                546   bool m_is_valid;
547   std::string m_name;                             547   std::string m_name;
548   std::string m_title;                            548   std::string m_title;
549   std::vector<directory*> m_dirs;                 549   std::vector<directory*> m_dirs;
550   std::vector<iobject*> m_objs;                   550   std::vector<iobject*> m_objs;
551   std::list<key*> m_keys;                         551   std::list<key*> m_keys;
552   // Record (stored in file):                     552   // Record (stored in file):
553   date m_date_C;           //Date and time whe    553   date m_date_C;           //Date and time when directory is created
554   date m_date_M;           //Date and time of     554   date m_date_M;           //Date and time of last modification
555   uint32 m_nbytes_keys;    //Number of bytes f    555   uint32 m_nbytes_keys;    //Number of bytes for the keys
556   uint32 m_nbytes_name;    //Number of bytes i    556   uint32 m_nbytes_name;    //Number of bytes in TNamed at creation time
557   seek m_seek_directory;   //Location of direc    557   seek m_seek_directory;   //Location of directory on file
558   seek m_seek_parent;      //Location of paren    558   seek m_seek_parent;      //Location of parent directory on file
559   seek m_seek_keys;        //Location of Keys     559   seek m_seek_keys;        //Location of Keys record on file
560 };                                                560 };
561                                                   561 
562 }}                                                562 }}
563                                                   563 
564 #endif                                            564 #endif