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 11.2.2)


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