Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/file is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_file
0005 #define tools_file
0006 
0007 #include "gzip"
0008 #include "forit"
0009 #include "words" //is_hippo
0010 #include "path" //suffix
0011 #include "S_STRING"
0012 
0013 #include <cstdlib>
0014 #include <cstring>
0015 
0016 #ifdef TOOLS_MEM
0017 #include "mem"
0018 #endif
0019 
0020 namespace tools {
0021 namespace file {
0022 
0023 inline bool exists(const std::string& a_string) {
0024   FILE* file = ::fopen(a_string.c_str(),"rb");
0025   if(!file) return false;
0026   ::fclose(file);
0027   return true;
0028 }
0029 
0030 inline bool write(const std::string& a_file,const std::string& a_string) {
0031   // a_string could contain \n separated lines.
0032   FILE* file = ::fopen(a_file.c_str(),"wb");
0033   if(!file) return false;
0034   if(::fprintf(file,"%s",a_string.c_str())<0) {
0035     ::fclose(file);
0036     return false;
0037   }
0038   ::fclose(file);
0039   return true;
0040 }
0041 
0042 inline bool write(const std::string& a_file,const std::vector<std::string>& a_text){
0043   FILE* file = ::fopen(a_file.c_str(),"wb");
0044   if(!file) return false;
0045   tools_vforcit(std::string,a_text,it) {
0046     if(::fprintf(file,"%s\n",(*it).c_str())<0) {
0047       ::fclose(file);
0048       return false;
0049     }
0050   }
0051   ::fclose(file);
0052   return true;
0053 }
0054 
0055 inline bool make_empty(const std::string& a_file) {
0056   FILE* file = ::fopen(a_file.c_str(),"wb");
0057   if(!file) return false;
0058   ::fclose(file);
0059   return true;
0060 }
0061 
0062 inline bool read_buff(FILE* a_file,char* a_buff,unsigned int a_lbuf,size_t& a_length) {
0063   a_length = ::fread(a_buff,1,a_lbuf,a_file);
0064   return true;
0065 }
0066 
0067 inline bool read_cstring(FILE* a_file,char* a_buff,unsigned int a_lbuf,size_t& a_length) {
0068   if(::fgets(a_buff,a_lbuf,a_file)==NULL) {
0069     a_length = 0;
0070     return false; //EOF
0071   }
0072 
0073   size_t l = ::strlen(a_buff);
0074   //  On Windows, editors when saving binary files,
0075   // put \r\n at place of \n ; we then look for \r\n.
0076   if( (l>=2) && (a_buff[l-2]=='\r') && (a_buff[l-1]=='\n') ) {
0077     a_buff[l-2] = '\0';
0078     l -= 2;
0079   } else if( (l>=1) && (a_buff[l-1]=='\n') ) {
0080     a_buff[l-1] = '\0';
0081     l -= 1;
0082   }
0083 
0084   a_length = l;
0085   return true;
0086 }
0087 
0088 
0089 inline bool read(FILE* a_FILE,std::vector<std::string>& a_text){
0090   a_text.clear();
0091   unsigned int BUFSIZE = 65536;
0092   char* buffer = new char[BUFSIZE+1];
0093   if(!buffer) return false;
0094   while(true) {
0095     size_t l;
0096     if(!read_cstring(a_FILE,buffer,BUFSIZE,l)) break; // EOF.
0097     a_text.push_back(buffer);
0098   }
0099   delete [] buffer;
0100   return true;
0101 }
0102 
0103 inline bool read(const std::string& a_file,std::vector<std::string>& a_text){
0104   FILE* file = ::fopen(a_file.c_str(),"rb");
0105   if(!file) {a_text.clear();return false;}
0106   bool status = read(file,a_text);
0107   ::fclose(file);
0108   return status;
0109 }
0110 
0111 inline bool read_num(const std::string& a_file,std::vector<std::string>::size_type a_num,std::vector<std::string>& a_text,const std::string& a_cmt = ""){
0112   a_text.clear();
0113   FILE* file = ::fopen(a_file.c_str(),"rb");
0114   if(!file) return false;
0115   unsigned int BUFSIZE = 65536;
0116   char* buffer = new char[BUFSIZE+1];
0117   if(!buffer) {::fclose(file);return false;}
0118   while(true) {
0119     size_t l;
0120     if(!read_cstring(file,buffer,BUFSIZE,l)) break; // EOF.
0121     if(a_cmt.size()&&(!strncmp(a_cmt.c_str(),buffer,a_cmt.size()))) continue;
0122     if(a_text.size()<a_num) {
0123       a_text.push_back(buffer);
0124     } else {
0125       break;
0126     }
0127   }
0128   delete [] buffer;
0129   ::fclose(file);
0130   return true;
0131 }
0132 
0133 inline bool read_bytes(const std::string& a_file,char*& a_buffer,long& a_length){
0134   // Returned buffer should be deleted with delete [].
0135   FILE* file = ::fopen(a_file.c_str(),"rb");
0136   if(!file) {
0137     a_buffer = 0;
0138     a_length = 0L;
0139     return false;
0140   }
0141   // Get file size :
0142   ::fseek(file,0L,SEEK_END);
0143   long filesize = ::ftell(file);
0144   if(!filesize) {
0145     ::fclose(file);
0146     a_buffer = new char[1];
0147 #ifdef TOOLS_MEM
0148     mem::increment(s_new().c_str());
0149 #endif
0150     a_length = 0L;
0151     return true; //empty file.
0152   }
0153   // Add one byte to be able to add \n if file contain lines.
0154   a_buffer = new char[filesize+1];
0155   if(!a_buffer) {
0156     ::fclose(file);
0157     a_buffer = 0;
0158     a_length = 0L;
0159     return false;
0160   }
0161 #ifdef TOOLS_MEM
0162   mem::increment(s_new().c_str());
0163 #endif
0164   ::rewind(file);
0165   size_t nitem = ::fread(a_buffer,(size_t)filesize,(size_t)1,file);
0166   if(nitem!=1){
0167     ::fclose(file);
0168     delete [] a_buffer;
0169 #ifdef TOOLS_MEM
0170     mem::decrement(s_new().c_str());
0171 #endif
0172     a_buffer = 0;
0173     a_length = 0L;
0174     return false;
0175   }
0176   ::fclose(file);
0177   a_buffer[filesize] = 0;
0178   a_length = filesize;
0179   return true;
0180 }
0181 
0182 inline bool write_bytes(const std::string& a_file,const char* a_buffer,size_t a_length){
0183   FILE* file = ::fopen(a_file.c_str(),"wb");
0184   if(!file) return false;
0185   if(!a_length) {
0186     ::fclose(file);
0187     return true;
0188   }
0189   size_t nitem = ::fwrite((char*)a_buffer,a_length,(size_t)1,file);
0190   ::fclose(file);
0191   return (nitem!=1?false:true);
0192 }
0193 
0194 inline bool num_csv_doubles(const std::string& a_string,char& a_sep,unsigned int& a_number){
0195   if(a_string.empty()) {a_sep=0;a_number=0;return true;} //it is ok.
0196 
0197   //guess sep :
0198   char sep = 0;
0199  {const char* buffer = a_string.c_str();
0200   //::printf("debug : |%s|\n",buffer);
0201   const char* pos = buffer;
0202   const char* mx = buffer+a_string.size();
0203   char* end;
0204  {double d = ::strtod(pos,&end);(void)d;}
0205   //::printf("debug : d first %g\n",d);
0206   if(end==pos) {a_sep=0;a_number=0;return false;} //not starting with a number.
0207   if(end==mx) {a_sep=0;a_number=1;return true;} //is ok, one number only.
0208   sep = *end;}
0209 
0210   //::printf("debug : %d\n",sep);
0211 
0212   unsigned int number = 0;
0213 
0214   const char* buffer = a_string.c_str();
0215   //::printf("debug : |%s|\n",buffer);
0216   const char* pos = buffer;
0217   const char* mx = buffer+a_string.size();
0218   while(true) {
0219     char* end;
0220    {double d = ::strtod(pos,&end);(void)d;}
0221     if(end==pos) {
0222       if(end>=mx) break;
0223       a_sep = sep;
0224       a_number = number;
0225       return false; //since a number expected.
0226     }
0227     //::printf("debug : d %g\n",d);
0228     number++;
0229     if(*end!=sep) {
0230       if(end>=mx) break;
0231       a_sep = sep;
0232       a_number = number;
0233       return false; //since a sep is expected.
0234     }
0235     pos = end+1;
0236     if(pos>mx) break;
0237   }
0238 
0239   a_sep = sep;
0240   a_number = number;
0241   return true;
0242 }
0243 
0244 // NOTE : take care of the open in exlib/app/tntnet/main_cpp which can't work by using suffix.
0245 
0246 inline bool is_hippo(const std::string& a_file,bool& a_is){
0247   //if((suffix(a_file)=="hiptxt")||(suffix(a_file)=="tnt")) {
0248   //  a_is = true;
0249   //  return true;
0250   //}
0251   // An hippo file as :
0252   //  one line for title.
0253   //  one line with n labels separated by \t
0254   //  data lines with n numbers separated by a char sep (not necessary \t) (at least one data line expected).
0255   std::vector<std::string> txt;
0256   if(!file::read_num(a_file,3,txt)) {a_is=false;return false;}
0257   if(txt.size()<3) {a_is=false;return true;}
0258   char csep;
0259   unsigned int number;
0260   if(!num_csv_doubles(txt[2],csep,number)) {a_is=false;return true;}
0261   std::vector<std::string> ws;
0262   words(txt[1],"\t",false,ws);
0263   if(ws.size()!=number) {a_is=false;return true;}
0264   bool all_doubles = true;
0265   tools_vforcit(std::string,ws,it) {
0266     const char* pos = (*it).c_str();
0267     char* end;
0268     double d = ::strtod(pos,&end);(void)d;
0269     if(end==pos) {all_doubles=false;break;}
0270   }
0271   a_is = all_doubles?false:true; //all_double=false then we assume the second line is labels of columns.
0272   return true;
0273 }
0274 
0275 // NOTE : the below is_csv() does not take into account a column with strings.
0276 
0277 inline bool is_csv(const std::vector<std::string>& a_txt,bool& a_is){
0278   //a_sep = 0;
0279   a_is = false;
0280   if(a_txt.empty()) return true;
0281 
0282   //guess sep from first data line :
0283   char sep = 0;
0284  {const char* buffer = a_txt[0].c_str();
0285   //::printf("debug : |%s|\n",buffer);
0286   const char* pos = buffer;
0287   char* end;
0288  {double d = ::strtod(pos,&end);(void)d;}
0289   //::printf("debug : d first %g\n",d);
0290   if(end==pos) return true; //not starting with a number.
0291   //end==mx is ok, one column only.
0292   sep = *end;}
0293 
0294   //::printf("debug : %d\n",sep);
0295 
0296   unsigned int first_coln = 0;
0297 
0298   tools_vforcit(std::string,a_txt,it) {
0299     const char* buffer = (*it).c_str();
0300     //::printf("debug : |%s|\n",buffer);
0301     const char* pos = buffer;
0302     const char* mx = buffer+(*it).size();
0303     unsigned int coln = 0;
0304     while(true) {
0305       char* end;
0306      {double d = ::strtod(pos,&end);(void)d;}
0307       if(end==pos) break;
0308       //::printf("debug : d %g\n",d);
0309       if(*end!=sep) return true;
0310       coln++;
0311       pos = end+1;
0312       if(pos>mx) break;
0313     }
0314     //::printf("debug : coln %d\n",coln);
0315     if(it==a_txt.begin()) {
0316       first_coln = coln;
0317     } else {
0318       if(coln!=first_coln) return true;
0319     }
0320   }
0321 
0322   //a_sep = sep;
0323   a_is = true;
0324   return true;
0325 }
0326 
0327 inline bool is_csv(const std::string& a_file,bool& a_is){
0328   // look at suffix. Some file can't be guessed.
0329   if(suffix(a_file)=="csv") {a_is = true;return true;}
0330   //try to guess :
0331   std::vector<std::string> txt;
0332   if(!file::read_num(a_file,3,txt,"#")) {a_is=false;return false;}
0333   return is_csv(txt,a_is);
0334 }
0335 
0336 inline bool is_lua(const std::string& a_file,bool& a_is){
0337   // look at suffix. Some file can't be guessed.
0338   if(suffix(a_file)=="lua") {a_is = true;return true;}
0339   //try to guess ?
0340   a_is = false;
0341   return true;
0342 }
0343 
0344 inline bool is_py(const std::string& a_file,bool& a_is){
0345   // look at suffix. Some file can't be guessed.
0346   if(suffix(a_file)=="py") {a_is = true;return true;}
0347   //try to guess ?
0348   a_is = false;
0349   return true;
0350 }
0351 
0352 inline bool is_kumac(const std::string& a_file,bool& a_is){
0353   // look at suffix. Some file can't be guessed.
0354   if(suffix(a_file)=="kumac") {a_is = true;return true;}
0355   //try to guess ?
0356   a_is = false;
0357   return true;
0358 }
0359 
0360 inline bool is_insh(const std::string& a_file,bool& a_is){
0361   if(suffix(a_file)=="insh") {a_is = true;return true;}
0362   unsigned char head[6];
0363  {unsigned int num = 6;
0364   if(!signature(a_file,head,num)) {a_is = false;return false;}
0365   if(num!=6) {a_is = false;return true;}}
0366   if(head[0]!='#') {a_is = false;return true;}
0367   if(head[1]!='!') {a_is = false;return true;}
0368   if(head[2]!='i') {a_is = false;return true;}
0369   if(head[3]!='n') {a_is = false;return true;}
0370   if(head[4]!='s') {a_is = false;return true;}
0371   if(head[5]!='h') {a_is = false;return true;}
0372   a_is = true;
0373   return true;
0374 }
0375 
0376 }}
0377 
0378 #include "fileis"
0379 
0380 namespace tools {
0381 namespace file {
0382 
0383 inline bool mime_type(const std::string& a_file,std::string& a_mime){
0384   ////////////////
0385   // binaries :
0386   ////////////////
0387  {bool is;
0388   if(is_jpeg(a_file,is)&&is) {
0389     a_mime = "image/jpeg";
0390     return true;
0391   }}
0392 
0393  {bool is;
0394   if(is_png(a_file,is)&&is) {
0395     a_mime = "image/png";
0396     return true;
0397   }}
0398 
0399  {bool is;
0400   if(is_ico(a_file,is)&&is) {
0401     a_mime = "image/vnd.microsoft.icon";
0402     return true;
0403   }}
0404 
0405  {bool is;
0406   if(is_fits(a_file,is)&&is) {
0407     a_mime = "image/fits";
0408     return true;
0409   }}
0410 
0411  {bool is;
0412   if(is_gzip(a_file,is)&&is) {
0413     a_mime = "application/gzip";
0414     return true;
0415   }}
0416 
0417  {bool is;
0418   if(is_zip(a_file,is)&&is) {
0419     a_mime = "application/zip";
0420     return true;
0421   }}
0422 
0423  {bool is;
0424   if(is_root(a_file,is)&&is) {
0425     a_mime = "application/octet-stream";
0426     return true;
0427   }}
0428 
0429   ////////////////
0430   // text :
0431   ////////////////
0432  {bool is;
0433   if(is_aida(a_file,is)&&is) {
0434     a_mime = "text/xml";
0435     return true;
0436   }}
0437  {bool is;
0438   if(is_exsg(a_file,is)&&is) {
0439     a_mime = "text/xml";
0440     return true;
0441   }}
0442  {bool is;
0443   if(is_scenarios(a_file,is)&&is) {
0444     a_mime = "text/xml";
0445     return true;
0446   }}
0447  {bool is;
0448   if(is_slides(a_file,is)&&is) {
0449     a_mime = "text/xml";
0450     return true;
0451   }}
0452  {bool is;
0453   if(is_gdml(a_file,is)&&is) {
0454     a_mime = "text/xml";
0455     return true;
0456   }}
0457 
0458  {bool is;
0459   if(is_ps(a_file,is)&&is) {
0460     a_mime = "application/postscript";
0461     return true;
0462   }}
0463 
0464  {bool is;
0465   if(is_fog(a_file,is)&&is) {
0466     a_mime = "text/plain";
0467     return true;
0468   }}
0469 
0470  {bool is;
0471   if(is_csv(a_file,is)&&is) {
0472     a_mime = "text/csv";
0473     return true;
0474   }}
0475 
0476  {bool is;
0477   if(is_hippo(a_file,is)&&is) {
0478     a_mime = "text/plain";
0479     return true;
0480   }}
0481 
0482  {bool is;
0483   if(is_dot(a_file,is)&&is) {
0484     a_mime = "text/plain";
0485     return true;
0486   }}
0487 
0488  {bool is;
0489   if(is_iv(a_file,is)&&is) {
0490     a_mime = "application/octet-stream";
0491     return true;
0492   }}
0493 
0494   a_mime = "application/octet-stream";
0495   return false;
0496 }
0497 
0498 /*
0499 inline bool copy(const std::string& a_from,const std::string& a_to){
0500   if(a_to==a_from) return true; //done
0501   std::vector<std::string> text;
0502   if(!file::read(a_from,text)) return false;
0503   return file::write(a_to,text);
0504 }
0505 */
0506 
0507 inline bool found(const std::string& a_file,const std::string& a_what,std::vector<std::string>& a_found){
0508   a_found.clear();
0509   std::vector<std::string> text;
0510   if(!file::read(a_file,text)) return false;
0511   tools_vforcit(std::string,text,it) {
0512     if((*it).find(a_what)!=std::string::npos) {
0513       a_found.push_back(*it);
0514     }
0515   }
0516   return true;
0517 }
0518 
0519 inline bool std_remove(const std::string& a_file) {
0520   if(a_file.empty()) return true;
0521   return (::remove(a_file.c_str()) ==0 ? true : false);
0522 }
0523 
0524 inline bool std_remove(std::vector<std::string>& a_files) {
0525   bool status = true;
0526   tools_vforit(std::string,a_files,it) {
0527     if(!std_remove(*it)) status = false;
0528   }
0529   a_files.clear();
0530   return status;
0531 }
0532 
0533 inline bool std_rename(const std::string& a_from,const std::string& a_to) {
0534   //NOTE : a_from must not be a path !
0535   //       Darwin is ok with a path but not Linux !
0536   //       For example :
0537   //         ::rename("/tmp/tmp01","x");
0538   //       return -1 on Linux.
0539   //       To do the upper then someone must use move.
0540   //       But there is no move in the standard lib C !
0541   return (::rename(a_from.c_str(),a_to.c_str()) == 0 ? true : false);
0542 }
0543 
0544 inline bool copy_bytes(const std::string& a_from,const std::string& a_to) {
0545   if(a_to==a_from) return true;
0546   char* buffer;
0547   long length;
0548   if(!read_bytes(a_from,buffer,length)) return false;
0549   bool status = write_bytes(a_to,buffer,(size_t)length);
0550   delete [] buffer;
0551 #ifdef TOOLS_MEM
0552   mem::decrement(s_new().c_str());
0553 #endif
0554   return status;
0555 }
0556 
0557 /*
0558 class holder {
0559 public:
0560   TOOLS_SCLASS(tools::file::holder)
0561 public:
0562   holder(const std::string& a_path):m_path(a_path){
0563 #ifdef TOOLS_MEM
0564     mem::increment(s_class().c_str());
0565 #endif
0566   }
0567   virtual ~holder() {
0568     std_remove(m_path);
0569 #ifdef TOOLS_MEM
0570     mem::decrement(s_class().c_str());
0571 #endif
0572   }
0573 public:
0574   holder(const holder& a_from):m_path(a_from.m_path){
0575 #ifdef TOOLS_MEM
0576     mem::increment(s_class().c_str());
0577 #endif
0578   }
0579   holder& operator=(const holder& a_from){
0580     m_path = a_from.m_path;
0581     return *this;
0582   }
0583 protected:
0584   std::string m_path;
0585 };
0586 */
0587 
0588 }}
0589 
0590 #include "file_reader"
0591 
0592 namespace tools {
0593 
0594 class FILE_reader : public virtual file::reader {
0595 public: //file_reader
0596   virtual bool open(const std::string& a_file) {
0597     if(m_FILE) return false;
0598     m_FILE = ::fopen(a_file.c_str(),"rb");
0599     if(!m_FILE) return false;
0600     return true;
0601   }
0602   virtual void close() {
0603     if(!m_FILE) return;
0604     ::fclose(m_FILE);
0605     m_FILE = 0;
0606   }
0607   virtual bool is_open() const {return m_FILE?true:false;}
0608   virtual bool read(char* a_buff,unsigned int a_lbuf,size_t& a_length) {
0609     a_length = ::fread(a_buff,1,a_lbuf,m_FILE);
0610     return true;
0611   }
0612   virtual bool get_line(char* a_buff,unsigned int a_lbuf) {
0613     return ::fgets(a_buff,a_lbuf,m_FILE)==NULL?false:true;
0614   }
0615   virtual bool eof() const {
0616 #if defined(_MSC_VER) && _MSC_VER <= 1400
0617     return feof(m_FILE)?true:false;
0618 #else
0619     return ::feof(m_FILE)?true:false;
0620 #endif
0621   }
0622 public:
0623   FILE_reader():m_FILE(0){}
0624   virtual ~FILE_reader() {if(m_FILE) ::fclose(m_FILE);}
0625 protected:
0626   FILE_reader(const FILE_reader& a_from)
0627   :file::reader(a_from)
0628   ,m_FILE(0)
0629   {}
0630   FILE_reader& operator=(const FILE_reader&){return *this;}
0631 protected:
0632   FILE* m_FILE;
0633 };
0634 
0635 }
0636 
0637 #include "file_format" //backcomp
0638 #include "fsize"       //backcomp
0639 
0640 #endif