// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_file #define tools_file #include "forit" #include "get_env" #include "sep" #include "sout" #include "tokenize" #include #include #include namespace tools { namespace file { inline bool exists(const std::string& a_string) { FILE* file = ::fopen(a_string.c_str(),"rb"); if(!file) return false; ::fclose(file); return true; } inline bool read_bytes(const std::string& a_file,char*& a_buffer,long& a_length){ // Returned buffer should be deleted with delete []. FILE* file = ::fopen(a_file.c_str(),"rb"); if(!file) { a_buffer = 0; a_length = 0L; return false; } // Get file size : ::fseek(file,0L,SEEK_END); long filesize = ::ftell(file); if(!filesize) { ::fclose(file); a_buffer = new char[1]; a_length = 0L; return true; //empty file. } // Add one byte to be able to add \n if file contain lines. a_buffer = new char[filesize+1]; if(!a_buffer) { ::fclose(file); a_buffer = 0; a_length = 0L; return false; } ::rewind(file); size_t nitem = ::fread(a_buffer,(size_t)filesize,(size_t)1,file); if(nitem!=1){ ::fclose(file); delete [] a_buffer; a_buffer = 0; a_length = 0L; return false; } ::fclose(file); a_buffer[filesize] = 0; a_length = filesize; return true; } inline bool find_with_dirs(std::ostream& a_out, const std::vector& a_dirs, const std::string& a_file, std::string& a_path, bool a_verbose = false ) { std::vector::const_iterator it; for(it=a_dirs.begin();it!=a_dirs.end();++it) { if((*it).empty()) { // with a "" in dirs, this case could solve : // - a_file in the current directory. // - a_file with an absolute path name. a_path = a_file; //may be an absolute file name. } else { a_path = *it; a_path += sep(); a_path += a_file; } if(a_verbose) { a_out << "find_with_dirs :" << " look for " << sout(a_path) << " ..." << std::endl; } if(file::exists(a_path)) { if(a_verbose) { a_out << "find_with_dirs :" << " found " << sout(a_path) << "." << std::endl; } return true; } } a_path.clear(); if(a_verbose) { a_out << "find_with_dirs :" << " " << sout(a_file) << " not found." << std::endl; } return false; } inline bool find_with_env(std::ostream& a_out, const std::string& a_env, const std::string& a_file, std::string& a_path, bool a_verbose = false ) { std::string PATH; if(!get_env(a_env,PATH)) { //look for a a_file in current directory. if(file::exists(a_file)) { a_path = a_file; return true; } a_out << "tools::find_with_env : env variable " << sout(a_env) << " not defined." << std::endl; a_path.clear(); return false; } if(a_verbose) { a_out << "find_with_env : env " << sout(a_env) << " is " << sout(PATH) << std::endl; } std::vector dirs; words(PATH,psep(),false,dirs); //or true ? return find_with_dirs(a_out,dirs,a_file,a_path,a_verbose); } inline bool std_remove(const std::string& a_file) { if(a_file.empty()) return true; return (::remove(a_file.c_str()) ==0 ? true : false); } }} #include "file_reader" namespace tools { class FILE_reader : public virtual file::reader { public: //file_reader virtual bool open(const std::string& a_file) { if(m_FILE) return false; m_FILE = ::fopen(a_file.c_str(),"rb"); if(!m_FILE) return false; return true; } virtual void close() { if(!m_FILE) return; ::fclose(m_FILE); m_FILE = 0; } virtual bool is_open() const {return m_FILE?true:false;} virtual bool read(char* a_buff,unsigned int a_lbuf,size_t& a_length) { a_length = ::fread(a_buff,1,a_lbuf,m_FILE); return true; } virtual bool get_line(char* a_buff,unsigned int a_lbuf) { return ::fgets(a_buff,a_lbuf,m_FILE)==NULL?false:true; } virtual bool eof() const { #if defined(_MSC_VER) && _MSC_VER <= 1400 return feof(m_FILE)?true:false; #else return ::feof(m_FILE)?true:false; #endif } public: FILE_reader():m_FILE(0){} virtual ~FILE_reader() {if(m_FILE) ::fclose(m_FILE);} protected: FILE_reader(const FILE_reader& a_from) :file::reader(a_from) ,m_FILE(0) {} FILE_reader& operator=(const FILE_reader&){return *this;} protected: FILE* m_FILE; }; } #endif