Geant4 Cross Reference

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

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/file (Version 11.3.0) and /externals/g4tools/include/tools/wroot/file (Version 10.1)


  1 // Copyright (C) 2010, Guy Barrand. All rights    
  2 // See the file tools.license for terms.          
  3                                                   
  4 #ifndef tools_wroot_file                          
  5 #define tools_wroot_file                          
  6                                                   
  7 #include "ifile"                                  
  8                                                   
  9 #include "directory"                              
 10                                                   
 11 #include "infos"                                  
 12 #include "free_seg"                               
 13                                                   
 14 #include "../platform"                            
 15                                                   
 16 #include "../path"                                
 17                                                   
 18 #include <map>                                    
 19                                                   
 20 #include <fcntl.h>                                
 21 #include <errno.h>                                
 22 #include <sys/stat.h>                             
 23                                                   
 24 #if defined(_MSC_VER) || defined(__MINGW32__)     
 25 #include <direct.h>                               
 26 #include <io.h>                                   
 27 #else                                             
 28 #include <unistd.h>                               
 29 #endif                                            
 30                                                   
 31 namespace tools {                                 
 32 namespace wroot {                                 
 33                                                   
 34 class file : public virtual ifile {               
 35   file& get_me() {return *this;} //_MSC_VER :     
 36   static int not_open() {return -1;}              
 37   static uint32 kBegin() {return 64;}             
 38 public:                                           
 39   static const std::string& s_class() {           
 40     static const std::string s_v("tools::wroot    
 41     return s_v;                                   
 42   }                                               
 43   virtual const std::string& s_cls() const {re    
 44 public: //ifile                                   
 45   virtual bool verbose() const {return m_verbo    
 46   virtual std::ostream& out() const {return m_    
 47                                                   
 48   virtual bool byte_swap() const {return is_li    
 49   virtual bool set_pos(seek a_offset = 0,from     
 50     int whence = 0;                               
 51     switch(a_from) {                              
 52     case begin:                                   
 53       whence = SEEK_SET;                          
 54       break;                                      
 55     case current:                                 
 56       whence = SEEK_CUR;                          
 57       break;                                      
 58     case end:                                     
 59       whence = SEEK_END;                          
 60       break;                                      
 61     }                                             
 62                                                   
 63 #if defined(__linux__) && (__GLIBC__ == 2) &&     
 64     if (::lseek64(m_file, a_offset, whence) <     
 65 #elif defined(_MSC_VER) || defined(__MINGW32__    
 66     if (::_lseeki64(m_file, a_offset, whence)     
 67 #else                                             
 68     if (::lseek(m_file, a_offset, whence) < 0)    
 69 #endif                                            
 70       m_out << "tools::wroot::file::set_pos :"    
 71             << " cannot set position " << a_of    
 72             << " in file " << sout(m_path) <<     
 73             << std::endl;                         
 74       return false;                               
 75     }                                             
 76     return true;                                  
 77   }                                               
 78                                                   
 79   virtual seek END() const {return m_END;}        
 80   virtual void set_END(seek a_end){               
 81     m_END = a_end;                                
 82                                                   
 83     if(m_free_segs.empty()) {                     
 84       m_out << "tools::wroot::file::set_END :"    
 85             << " free_seg list should not be e    
 86             << std::endl;                         
 87     } else {                                      
 88       free_seg* end_seg = m_free_segs.back();     
 89       if(end_seg->last()!=START_BIG_FILE()) {     
 90         m_out << "tools::wroot::file::set_END     
 91               << " last free_seg is not the en    
 92               << " free_seg list looks corrupt    
 93               << std::endl;                       
 94       } else {                                    
 95         m_free_segs.back()->set_first(m_END);     
 96       }                                           
 97     }                                             
 98   }                                               
 99                                                   
100   virtual bool write_buffer(const char* a_buff    
101     // Write a buffer to the file. This is the    
102 #ifdef _MSC_VER                                   
103     typedef int ssize_t;                          
104 #endif                                            
105     ssize_t siz;                                  
106     while ((siz = ::write(m_file,a_buffer,a_le    
107             error_number() == EINTR) reset_err    
108                                                   
109     if(siz < 0) {                                 
110       m_out << "tools::wroot::file::write_buff    
111             << " error writing to file " << so    
112             << std::endl;                         
113       return false;                               
114     }                                             
115     if(siz!=(ssize_t)a_length) {                  
116       m_out << "tools::wroot::file::write_buff    
117            << "error writing all requested byt    
118            << ", wrote " << long_out(siz) << "    
119            << std::endl;                          
120       return false;                               
121     }                                             
122     //m_bytes_write  += siz;                      
123     return true;                                  
124   }                                               
125                                                   
126   virtual uint32 version() const {                
127     // Return version id as an integer, i.e. "    
128     static const uint32 ROOT_MAJOR_VERSION = 4    
129     static const uint32 ROOT_MINOR_VERSION = 0    
130     static const uint32 ROOT_PATCH_VERSION = 0    
131     return                                        
132       10000 * ROOT_MAJOR_VERSION +                
133       100 * ROOT_MINOR_VERSION +                  
134       ROOT_PATCH_VERSION;                         
135   }                                               
136                                                   
137   virtual bool synchronize(){                     
138     // Synchornize a file's in-core and on-dis    
139 #ifdef _MSC_VER                                   
140     if(::_commit(m_file)) {                       
141       m_out << "tools::wroot::file::synchroniz    
142             << " in _commit() for file " << so    
143             << std::endl;                         
144       return false;                               
145     }                                             
146 #elif defined(__MINGW32__)                        
147     return true;                                  
148 #else                                             
149     if (::fsync(m_file) < 0) {                    
150       m_out << "tools::wroot::file::synchroniz    
151             << " error in fsync() for file " <    
152             << std::endl;                         
153       return false;                               
154     }                                             
155 #endif                                            
156     return true;                                  
157   }                                               
158                                                   
159   virtual bool ziper(char a_key,compress_func&    
160     std::map<char,compress_func>::const_iterat    
161     if(it==m_zipers.end()) {                      
162       a_func = 0;                                 
163       return false;                               
164     }                                             
165     a_func = (*it).second;                        
166     return true;                                  
167   }                                               
168   virtual uint32 compression() const {return m    
169   virtual void compress_buffer(const buffer& a    
170     //NOTE: if(kdelete) delete [] kbuf;           
171                                                   
172     a_kbuf = 0;                                   
173     a_klen = 0;                                   
174     a_kdel = false;                               
175                                                   
176     uint32 nbytes = a_buffer.length();            
177     uint32 cxlevel = m_compress;                  
178     if(cxlevel && (nbytes>256)) {                 
179       compress_func func;                         
180       if(!ziper('Z',func)) {                      
181         //m_out << "tools::wroot::file::compre    
182         //      << " zlib ziper not found."       
183         //      << std::endl;                     
184         a_kbuf = (char*)a_buffer.buf();           
185         a_klen = a_buffer.length();               
186         a_kdel = false;                           
187       } else {                                    
188         const uint32 kMAXBUF = 0xffffff;          
189         const uint32 HDRSIZE = 9;                 
190         uint32 nbuffers = nbytes/kMAXBUF;         
191         uint32 buf_out_size = kMAXBUF+HDRSIZE+    
192         uint32 buflen = (nbuffers+1)*buf_out_s    
193         a_kbuf = new char[buflen];                
194         a_kdel = true;                            
195         char* src = (char*)a_buffer.buf();        
196         char* tgt = a_kbuf;                       
197         uint32 nzip = 0;                          
198         for(uint32 i=0;i<=nbuffers;i++) {         
199           uint32 bufmax = ((i == nbuffers) ? n    
200           uint32 nout;                            
201           if(!zip(m_out,func,cxlevel,bufmax,sr    
202             delete [] a_kbuf;                     
203             a_kbuf = (char*)a_buffer.buf();       
204             a_klen = a_buffer.length();           
205             a_kdel = false;                       
206             return;                               
207           }                                       
208           tgt += nout; //nout includes HDRSIZE    
209           a_klen += nout;                         
210           src += kMAXBUF;                         
211           nzip += kMAXBUF;                        
212         }                                         
213         if(a_klen>=a_buffer.length()) {           
214           //NOTE: It is in the ROOT/IO specifi    
215           //      are detected at read time by    
216           //      the overall output size (fNb    
217           //      By using the zlib-ng compres    
218           //      output size (a_klen here at     
219           //      induces problem when reading    
220           delete [] a_kbuf;                       
221           a_kbuf = (char*)a_buffer.buf();         
222           a_klen = a_buffer.length();             
223           a_kdel = false;                         
224         }                                         
225       }                                           
226     } else {                                      
227       a_kbuf = (char*)a_buffer.buf();             
228       a_klen = a_buffer.length();                 
229       a_kdel = false;                             
230     }                                             
231   }                                               
232 public:                                           
233   file(std::ostream& a_out,const std::string&     
234   :m_out(a_out)                                   
235   ,m_path(a_path)                                 
236   ,m_verbose(a_verbose)                           
237   ,m_file(not_open())                             
238   //,m_bytes_write(0)                             
239   ,m_root_directory(get_me(),nosuffix(a_path),    
240   // begin of record :                            
241   ,m_version(0)                                   
242   ,m_BEGIN(0)                                     
243   ,m_END(0)                                       
244   ,m_seek_free(0)                                 
245   ,m_nbytes_free(0)                               
246   ,m_nbytes_name(0)                               
247   ,m_units(4)                                     
248   ,m_compress(1)                                  
249   ,m_seek_info(0)                                 
250   ,m_nbytes_info(0)                               
251   {                                               
252 #ifdef TOOLS_MEM                                  
253     mem::increment(s_class().c_str());            
254 #endif                                            
255                                                   
256     m_version = version();                        
257                                                   
258     if(access_path(m_path,kFileExists)) unlink    
259                                                   
260     if(!m_root_directory.is_valid()) {            
261       m_out << "tools::wroot::file::file :"       
262             << " " << sout(m_path) << " root d    
263             << std::endl;                         
264       return;                                     
265     }                                             
266                                                   
267     m_file = _open(a_path.c_str(),                
268 #if defined(_MSC_VER) || defined(__MINGW32__)     
269                                O_RDWR | O_CREA    
270 #else                                             
271                                O_RDWR | O_CREA    
272 #endif                                            
273     );                                            
274     if(m_file==not_open()) {                      
275       m_out << "tools::wroot::file::file :"       
276             << " can't open " << sout(a_path)     
277             << std::endl;                         
278       return;                                     
279     }                                             
280                                                   
281     //initialize :                                
282                                                   
283     m_BEGIN = kBegin();  // First used word in    
284     m_END = m_BEGIN;   // Pointer to end of fi    
285                                                   
286     m_free_segs.push_back(new free_seg(m_out,m    
287                                                   
288     // Write Directory info :                     
289     uint32 namelen =                              
290       key::std_string_record_size(m_path) +       
291       key::std_string_record_size(m_title);       
292     uint32 nbytes = namelen + m_root_directory    
293                                                   
294     //TUUID version 1:                            
295     nbytes += sizeof(unsigned int);               
296     nbytes += 2*sizeof(unsigned short);           
297     nbytes += 8*sizeof(unsigned char);            
298                                                   
299     wroot::key key(m_out,*this,0,m_path,m_titl    
300                                                   
301     // m_nbytes_name = start point of director    
302     m_nbytes_name = key.key_length() + namelen    
303     m_root_directory.set_nbytes_name(m_nbytes_    
304     m_root_directory.set_seek_directory(key.se    
305                                                   
306     //the below write 45 bytes at BOF (Begin O    
307     if(!write_header()) { //need m_nbytes_name    
308       m_out << "tools::wroot::file::file :"       
309             << " can't write file header."        
310             << std::endl;                         
311       return;                                     
312     }                                             
313                                                   
314    {char* pos = key.data_buffer();                
315     wbuf wb(m_out,byte_swap(),key.eob(),pos);     
316     if(!wb.write(m_path)) return;                 
317     if(!wb.write(m_title)) return;                
318     if(!m_root_directory.to_buffer(wb)) return    
319     //TUUID version 1:                            
320     if(!wb.write((unsigned int)0)) return;        
321     if(!wb.write((unsigned short)0)) return;      
322     if(!wb.write((unsigned short)0)) return;      
323    {for(size_t count=0;count<8;count++) if(!wb    
324                                                   
325     if(m_verbose) {                               
326       m_out << "tools::wroot::file::file :"       
327             << " write key ("                     
328             << namelen                            
329             << ", "                               
330             << m_root_directory.record_size()     
331             << ", "                               
332             << nbytes                             
333             << ", "                               
334             << m_nbytes_name                      
335             << ", "                               
336             << key.seek_key()                     
337             << ")."                               
338             << std::endl;                         
339     }                                             
340                                                   
341     key.set_cycle(1);                             
342     if(!key.write_self(*this)) {                  
343       m_out << "tools::wroot::file::file :"       
344             << " key.write_self() failed."        
345             << std::endl;                         
346       return;                                     
347     }                                             
348                                                   
349     //the below write at kBegin + nbytes.         
350     //64+52                                       
351     uint32 n;                                     
352     if(!key.write_file(*this,n)) {                
353       m_out << "tools::wroot::file::file :"       
354             << " can't write key in file."        
355             << std::endl;                         
356       return;                                     
357     }                                             
358     //::printf("debug : file::file : write key    
359                                                   
360   }                                               
361   virtual ~file() {                               
362     close();                                      
363 #ifdef TOOLS_MEM                                  
364     mem::decrement(s_class().c_str());            
365 #endif                                            
366   }                                               
367 protected:                                        
368   file(const file& a_from)                        
369   :ifile(a_from)                                  
370   ,m_out(a_from.m_out)                            
371   ,m_root_directory(get_me())                     
372   {                                               
373 #ifdef TOOLS_MEM                                  
374     mem::increment(s_class().c_str());            
375 #endif                                            
376   }                                               
377   file& operator=(const file&){return *this;}     
378 public:                                           
379   const std::string& path() const {return m_pa    
380                                                   
381   void set_compression(uint32 a_level) {          
382     // level = 0 objects written to this file     
383     // level = 1 minimal compression level but    
384     // ....                                       
385     // level = 9 maximal compression level but    
386     m_compress = a_level;                         
387     if(m_compress>9) m_compress = 9;              
388   }                                               
389                                                   
390   bool is_open() const {return (m_file==not_op    
391                                                   
392   void close() {                                  
393     if(m_file==not_open()) return;                
394     m_root_directory.close();                     
395                                                   
396     if(m_free_segs.size()) {                      
397       if(!write_free_segments()) {                
398         m_out << "tools::wroot::file::close :"    
399               << " can't write free segments."    
400               << std::endl;                       
401       }                                           
402       if(!write_header())  { // Now write file    
403         m_out << "tools::wroot::file::close :"    
404               << " can't write file header."      
405               << std::endl;                       
406       }                                           
407     }                                             
408                                                   
409    {std::list<free_seg*>::iterator it;            
410     for(it=m_free_segs.begin();                   
411         it!=m_free_segs.end();                    
412         it = m_free_segs.erase(it)) {             
413       delete (*it);                               
414     }}                                            
415                                                   
416     ::close(m_file);                              
417     m_file = not_open();                          
418   }                                               
419                                                   
420   directory& dir() {return m_root_directory;}     
421   const directory& dir() const {return m_root_    
422                                                   
423   bool write(uint32& a_nbytes){                   
424     // Write memory objects to this file :        
425     //  Loop on all objects in m_root_director    
426     //  A new key is created in the directorie    
427     //  for each object.                          
428     //  The list of keys is then saved on the     
429     //  as a single data record.                  
430     //  The directory header info is rewritten    
431     //  //The linked list of FREE segments is     
432     //  The file header is written (bytes 1->m    
433     a_nbytes = 0;                                 
434                                                   
435     if(m_verbose) {                               
436       m_out << "tools::wroot::file::write :"      
437             << " writing Name=" << sout(m_path    
438             << " Title=" << sout(m_title) << "    
439             << std::endl;                         
440     }                                             
441                                                   
442     uint32 nbytes;                                
443     if(!m_root_directory.write(nbytes)) return    
444                                                   
445     if(!write_streamer_infos()) {                 
446       m_out << "tools::wroot::file::write :"      
447             << " write_streamer_infos failed."    
448             << std::endl;                         
449       return false;                               
450     }                                             
451                                                   
452     if(!write_free_segments()) {                  
453       m_out << "tools::wroot::file::write :"      
454             << " can't write free segments."      
455             << std::endl;                         
456       return false;                               
457     }                                             
458                                                   
459     if(!write_header()) { //write 45 bytes at     
460       m_out << "tools::wroot::file::write :"      
461             << " can't write file header."        
462             << std::endl;                         
463       return false;                               
464     }                                             
465                                                   
466     a_nbytes = nbytes;                            
467     return true;                                  
468   }                                               
469                                                   
470   bool add_ziper(char a_key,compress_func a_fu    
471     std::map<char,compress_func>::const_iterat    
472     if(it!=m_zipers.end()) {                      
473       //(*it).second = a_func; //override ?       
474       return false;                               
475     } else {                                      
476       m_zipers[a_key] = a_func;                   
477       return true;                                
478     }                                             
479   }                                               
480 protected:                                        
481   enum EAccessMode {                              
482     kFileExists        = 0,                       
483     kExecutePermission = 1,                       
484     kWritePermission   = 2,                       
485     kReadPermission    = 4                        
486   };                                              
487   static bool access_path(const std::string& a    
488     // Returns true if one can access a file u    
489     // Mode is the same as for the WinNT acces    
490 #ifdef _MSC_VER                                   
491     return (::_access(a_path.c_str(),a_mode) =    
492 #else                                             
493     return (::access(a_path.c_str(),a_mode) ==    
494 #endif                                            
495   }                                               
496   static bool unlink(const std::string& a_path    
497     // Unlink, i.e. remove, a file or director    
498     // false in case of failure.                  
499     struct stat finfo;                            
500     if (::stat(a_path.c_str(),&finfo) < 0) ret    
501 #ifdef _MSC_VER                                   
502     if (finfo.st_mode & S_IFDIR)                  
503       return (::_rmdir(a_path.c_str())==-1 ? f    
504     else                                          
505       return (::unlink(a_path.c_str())==-1 ? f    
506 #else                                             
507     if (S_ISDIR(finfo.st_mode))                   
508       return (::rmdir(a_path.c_str())==-1 ? fa    
509     else                                          
510       return (::unlink(a_path.c_str())==-1 ? f    
511 #endif                                            
512   }                                               
513                                                   
514   static int _open(const char* a_name,int a_fl    
515 #if defined(__linux__) && (__GLIBC__ == 2) &&     
516      return ::open64(a_name,a_flags,a_mode);      
517 #else                                             
518      return ::open(a_name,a_flags,a_mode);        
519 #endif                                            
520   }                                               
521   bool write_header() {                           
522     const char root[] = "root";                   
523     //char psave[kBegin()];                       
524     char psave[128];                              
525     const char* eob = psave + kBegin();           
526     char* pos = psave;                            
527     ::memcpy(pos,root,4); pos += 4;               
528     uint32 vers = m_version;                      
529     if((m_END>START_BIG_FILE())        ||         
530        (m_seek_free>START_BIG_FILE())  ||         
531        (m_seek_info>START_BIG_FILE())  ){         
532       vers += 1000000;                            
533       m_units = 8;                                
534     }                                             
535     wbuf wb(m_out,byte_swap(),eob,pos);           
536     if(!wb.write(vers)) return false;             
537     if(!wb.write((seek32)m_BEGIN)) return fals    
538     if(vers>1000000) {                            
539       if(!wb.write(m_END)) return false;          
540       if(!wb.write(m_seek_free)) return false;    
541     } else {                                      
542       if(!wb.write((seek32)m_END)) return fals    
543       if(!wb.write((seek32)m_seek_free)) retur    
544     }                                             
545     if(!wb.write(m_nbytes_free)) return false;    
546     //int nfree  = fFreeSegments.size();          
547     uint32 nfree  = 0; //FIXME                    
548     if(!wb.write(nfree)) return false;            
549     if(!wb.write(m_nbytes_name)) return false;    
550     if(!wb.write(m_units)) return false;          
551     if(!wb.write(m_compress)) return false;       
552     if(vers>1000000) {                            
553       if(!wb.write(m_seek_info)) return false;    
554     } else {                                      
555       if(!wb.write((seek32)m_seek_info)) retur    
556     }                                             
557     if(!wb.write(m_nbytes_info)) return false;    
558     if(!set_pos()) return false; //BOF            
559     uint32 nbytes = uint32(pos - psave);          
560     //::printf("debug : write_header : %d\n",n    
561     if(!write_buffer(psave,nbytes)) return fal    
562     if(!synchronize()) return false;              
563     return true;                                  
564   }                                               
565                                                   
566   bool write_streamer_infos() {                   
567     obj_list<streamer_info> sinfos;               
568     fill_infos(sinfos,m_out);                     
569                                                   
570     if(sinfos.empty()) return false;              
571                                                   
572     buffer bref(m_out,byte_swap(),256);           
573                                                   
574     if(!sinfos.stream(bref)) {                    
575       m_out << "tools::wroot::file::write_stre    
576             << " cannot stream obj_list<stream    
577             << std::endl;                         
578       return false;                               
579     }                                             
580     uint32 nbytes = bref.length();                
581                                                   
582     wroot::key key(m_out,*this,                   
583                    m_root_directory.seek_direc    
584                    "StreamerInfo","",             
585                    sinfos.store_cls(),            
586                    nbytes); // It does a (*thi    
587     if(!key.seek_key()) return false;             
588                                                   
589     if(!bref.displace_mapped(key.key_length())    
590                                                   
591     ::memcpy(key.data_buffer(),bref.buf(),nbyt    
592                                                   
593     //key.set_cycle(1);                           
594     if(!key.write_self(*this)) {                  
595       m_out << "tools::wroot::file::write_stre    
596             << " key.write_self() failed."        
597             << std::endl;                         
598       return false;                               
599     }                                             
600                                                   
601     m_seek_info = key.seek_key();                 
602     m_nbytes_info = key.number_of_bytes();        
603     //FIXME sumBuffer(key.objectSize());          
604                                                   
605     uint32 n;                                     
606     if(!key.write_file(*this,n)) return false;    
607     if(!n) return false;                          
608                                                   
609     return true;                                  
610   }                                               
611                                                   
612   bool make_free_seg(seek a_first,seek a_last)    
613     // Mark unused bytes on the file :            
614     //  The list of free segments is in the m_    
615     //  When an object is deleted from the fil    
616     //  into the FREE linked list (m_free_segs    
617     //  of a chain  of consecutive free segmen    
618     //  time, the first 4 bytes of the freed r    
619     //  are overwritten by GAPSIZE where          
620     //    GAPSIZE = -(Number of bytes occupied    
621                                                   
622     if(m_free_segs.empty()) {                     
623       m_out << "tools::wroot::file::make_free_    
624             << " free_seg list should not be e    
625             << std::endl;                         
626       return false;                               
627     }                                             
628                                                   
629     free_seg* newfree = add_free(m_free_segs,a    
630     if(!newfree) {                                
631       m_out << "tools::wroot::file::make_free_    
632             << " add_free failed."                
633             << std::endl;                         
634       return false;                               
635     }                                             
636                                                   
637     seek nfirst = newfree->first();               
638     seek nlast = newfree->last();                 
639                                                   
640     seek _nbytes = nlast-nfirst+1;                
641     if(_nbytes>START_BIG_FILE()) _nbytes = STA    
642     int nbytes = -int(_nbytes);                   
643                                                   
644     int nb = sizeof(int);                         
645                                                   
646     char psave[128];                              
647     const char* eob = psave + nb;                 
648     char* pos = psave;                            
649                                                   
650     wbuf wb(m_out,byte_swap(),eob,pos);           
651     if(!wb.write(nbytes)) return false;           
652                                                   
653     if(nlast == (m_END-1)) m_END = nfirst;        
654     if(!set_pos(nfirst)) return false;            
655     if(!write_buffer(psave,nb)) return false;     
656     if(!synchronize()) return false;              
657     return true;                                  
658   }                                               
659                                                   
660   bool write_free_segments(){                     
661     //  The linked list of FREE segments (fFre    
662                                                   
663     // Delete old record if it exists :           
664     if(m_seek_free){                              
665       if(!make_free_seg(m_seek_free, m_seek_fr    
666         m_out << "tools::wroot::file::write_fr    
667               << " key.write_self() failed."      
668               << std::endl;                       
669         return false;                             
670       }                                           
671     }                                             
672                                                   
673     //::printf("debug : write_free_segments :     
674                                                   
675     uint32 nbytes = 0;                            
676    {tools_lforcit(free_seg*,m_free_segs,it) {     
677       nbytes += (*it)->record_size();             
678       //::printf("debug : write_free_segments     
679       //         (*it)->first(),(*it)->last())    
680     }}                                            
681     if(!nbytes) return true;                      
682                                                   
683     wroot::key key(m_out,*this,                   
684                    m_root_directory.seek_direc    
685                    m_path,m_title,"TFile",        
686                    nbytes); // It does a (*thi    
687     if(!key.seek_key()) return false;             
688                                                   
689    {char* pos = key.data_buffer();                
690     wbuf wb(m_out,byte_swap(),key.eob(),pos);     
691     tools_lforcit(free_seg*,m_free_segs,it) {     
692       if(!(*it)->fill_buffer(wb)) return false    
693     }}                                            
694                                                   
695     //key.set_cycle(1);                           
696     if(!key.write_self(*this)) {                  
697       m_out << "tools::wroot::file::write_free    
698             << " key.write_self() failed."        
699             << std::endl;                         
700       return false;                               
701     }                                             
702                                                   
703     m_seek_free = key.seek_key();                 
704     m_nbytes_free = key.number_of_bytes();        
705     if(m_verbose) {                               
706       m_out << "tools::wroot::file::write_free    
707             << " write key." << std::endl;        
708     }                                             
709                                                   
710     uint32 n;                                     
711     if(!key.write_file(*this,n)) return false;    
712     if(!n) return false;                          
713                                                   
714     return true;                                  
715   }                                               
716                                                   
717   static bool zip(std::ostream& a_out,            
718                   compress_func a_func,           
719                   int a_level,                    
720                   uint32 a_srcsize,char* a_src    
721                   uint32 a_tgtsize,char* a_tgt    
722                   uint32& a_irep){                
723                                                   
724     // from Rio/Bits/R__zip using zlib.           
725                                                   
726     const uint32 HDRSIZE = 9;                     
727                                                   
728     if(a_tgtsize<HDRSIZE) {                       
729       a_out << "tools::wroot::file::zip :"        
730             << " target buffer too small."        
731             << std::endl;                         
732       a_irep = 0;                                 
733       return false;                               
734     }                                             
735     if(a_srcsize>0xffffff) {                      
736       a_out << "tools::wroot::file::zip :"        
737             << " source buffer too big."          
738             << std::endl;                         
739       a_irep = 0;                                 
740       return false;                               
741     }                                             
742                                                   
743     uint32 out_size;                              
744     if(!a_func(a_out,a_level,                     
745                a_srcsize,a_src,                   
746                a_tgtsize,a_tgt+HDRSIZE,           
747                out_size)) {                       
748       a_out << "tools::wroot::file::zip :"        
749             << " zipper failed."                  
750             << std::endl;                         
751       a_irep = 0;                                 
752       return false;                               
753     }                                             
754                                                   
755     if((HDRSIZE+out_size)>a_tgtsize) {            
756       a_out << "tools::wroot::file::zip :"        
757             << " target buffer overflow."         
758             << std::endl;                         
759       a_irep = 0;                                 
760       return false;                               
761     }                                             
762                                                   
763     // HEADER :                                   
764     a_tgt[0] = 'Z'; // Signature ZLib             
765     a_tgt[1] = 'L';                               
766     a_tgt[2] = 8; //DEFLATE                       
767                                                   
768     a_tgt[3] = (char)(out_size & 0xff);           
769     a_tgt[4] = (char)((out_size >> 8) & 0xff);    
770     a_tgt[5] = (char)((out_size >> 16) & 0xff)    
771                                                   
772     a_tgt[6] = (char)(a_srcsize & 0xff);          
773     a_tgt[7] = (char)((a_srcsize >> 8) & 0xff)    
774     a_tgt[8] = (char)((a_srcsize >> 16) & 0xff    
775                                                   
776     a_irep = HDRSIZE+out_size;                    
777                                                   
778     return true;                                  
779   }                                               
780                                                   
781 #if defined(__sun) && !defined(__linux__) && (    
782   int error_number() {return ::errno;}            
783   void reset_error_number() {::errno = 0;}        
784 #else                                             
785   int error_number() {return errno;}              
786   void reset_error_number() {errno = 0;}          
787 #endif                                            
788                                                   
789 protected:                                        
790   std::ostream& m_out;                            
791   std::string m_path;                             
792   bool m_verbose;                                 
793   int m_file;                                     
794   //uint64 m_bytes_write; //Number of bytes wr    
795   std::string m_title; //must be before the be    
796   directory m_root_directory;                     
797   std::map<char,compress_func> m_zipers;          
798   std::list<free_seg*> m_free_segs; //Free seg    
799   // begin of record :                            
800   // "root"                                       
801   uint32 m_version;       //File format versio    
802   seek m_BEGIN;           //First used byte in    
803   seek m_END;             //Last used byte in     
804   seek m_seek_free;       //Location on disk o    
805   uint32 m_nbytes_free;   //Number of bytes fo    
806   //int nfree                                     
807   uint32 m_nbytes_name;   //Number of bytes in    
808   char m_units;           //Number of bytes fo    
809   uint32 m_compress;      //(=1 file is compre    
810   seek m_seek_info;       //Location on disk o    
811   uint32 m_nbytes_info;   //Number of bytes fo    
812 };                                                
813                                                   
814                                                   
815 }}                                                
816                                                   
817 #endif                                            
818                                                   
819 //doc                                             
820 //                                                
821 //  A ROOT file is a suite of consecutive data    
822 //    format (see also the TKey class);           
823 // TKey ---------------------                     
824 //      byte 1->4  Nbytes    = Length of compr    
825 //           5->6  Version   = TKey version id    
826 //           7->10 ObjLen    = Length of uncom    
827 //          11->14 Datime    = Date and time w    
828 //          15->16 KeyLen    = Length of the k    
829 //          17->18 Cycle     = Cycle of key       
830 //          19->22 SeekKey   = Pointer to reco    
831 //          23->26 SeekPdir  = Pointer to dire    
832 //          27->27 lname     = Number of bytes    
833 //          28->.. ClassName = Object Class Na    
834 //          ..->.. lname     = Number of bytes    
835 //          ..->.. Name      = lName bytes wit    
836 //          ..->.. lTitle    = Number of bytes    
837 //          ..->.. Title     = Title of the ob    
838 //          -----> DATA      = Data bytes asso    
839 //                                                
840 //  The first data record starts at byte fBEGI    
841 //  Bytes 1->kBegin contain the file descripti    
842 //       byte  1->4  "root"      = Root file i    
843 //             5->8  fVersion    = File format    
844 //             9->12 fBEGIN      = Pointer to     
845 //            13->16 fEND        = Pointer to     
846 //            17->20 fSeekFree   = Pointer to     
847 //            21->24 fNbytesFree = Number of b    
848 //            25->28 nfree       = Number of f    
849 //            29->32 fNbytesName = Number of b    
850 //            33->33 fUnits      = Number of b    
851 //            34->37 fCompress   = Zip compres    
852 //