inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/fcache
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file inlib.license for terms.
00003 
00004 #ifndef inlib_fcache
00005 #define inlib_fcache
00006 
00007 #include <ostream>
00008 #include <map>
00009 #include <string>
00010 #include <cstdio> //::remove
00011 
00012 #include "sys/file"
00013 
00014 namespace inlib {
00015 namespace file {
00016 
00017 class cache {
00018 public:
00019   virtual ~cache(){}
00020 public:
00021   virtual bool fetch(const std::string& a_what,std::string& a_file) = 0;
00022 };
00023 
00024 class base_cache : public virtual cache {
00025 public:
00026   virtual bool fetch(const std::string& a_what,std::string& a_file){
00027     std::map<std::string,std::string>::iterator it = m_cache.find(a_what);
00028     if(it!=m_cache.end()) { //a_what in the cache.
00029       if(exists((*it).second)) {
00030         a_file = (*it).second;
00031         //std::cout << "inlib::file::base_cache::fetch :"
00032         //          << " for what " << sout(a_what)
00033         //          << " file in the cache : " << sout(a_file)
00034         //          << std::endl;
00035         return true;
00036       }
00037       m_out << "inlib::file::base_cache::fetch :"
00038             << " WARNING : for " << sout(a_what)
00039             << ", file in the map no more here. We fetch again the file."
00040             << std::endl;
00041       m_cache.erase(it);
00042     }
00043 
00044     std::string file;
00045     if(!inlib::tmpname(m_tmp_dir,"inlib_base_cache_",m_tmp_suffix,file)) {
00046       m_out << "inlib::file::base_cache::fetch :"
00047             << " can't get a tmpname."
00048             << std::endl;
00049       a_file.clear();
00050       return false;
00051     }
00052   
00053     //std::cout << "inlib::file::base_cache::fetch :"
00054     //          << " for what " << sout(a_what)
00055     //          << " fetch ..."
00056     //          << std::endl;
00057 
00058     if(!fetch_file(a_what,file)) {
00059       m_out << "inlib::file::base_cache::fetch :"
00060             << " failed to fetch " << sout(a_what)
00061             << std::endl;
00062       ::remove(file.c_str());
00063       a_file.clear();
00064       return false;
00065     }
00066     m_cache[a_what] = file;
00067     a_file = file;
00068 
00069     //std::cout << "inlib::file::base_cache::fetch :"
00070     //          << " for what " << sout(a_what)
00071     //          << " fetch done."
00072     //          << std::endl;
00073 
00074     return true;
00075   }
00076 protected:
00077   virtual bool fetch_file(const std::string& a_what,const std::string& a_file) = 0;
00078 public:
00079   base_cache(std::ostream& a_out,bool a_verbose)
00080   :m_out(a_out)
00081   ,m_verbose(a_verbose)
00082   {}
00083   virtual ~base_cache(){clear();}
00084 protected:
00085   base_cache(const base_cache& a_from)
00086   : cache(a_from)
00087   ,m_out(a_from.m_out)
00088   ,m_verbose(a_from.m_verbose)
00089   {}
00090   base_cache& operator=(const base_cache&){return *this;}
00091 public:
00092   void set_tmp_dir(const std::string& a_dir) {m_tmp_dir = a_dir;}
00093   void set_tmp_suffix(const std::string& a_suffix) {
00094     m_tmp_suffix = a_suffix;
00095   }
00096   void clear() {
00097     std::map<std::string,std::string>::iterator it;
00098     for(it = m_cache.begin();it!=m_cache.end();++it) {
00099       ::remove((*it).second.c_str());    
00100     }
00101     m_cache.clear();
00102   }
00103 private:
00104   //to avoid a #include "file".
00105   static std::string sout(const std::string& a_string) {
00106     return std::string("\"")+a_string+"\"";
00107   }
00108   static bool exists(const std::string& a_string) {
00109     FILE* file = ::fopen(a_string.c_str(),"rb");
00110     if(!file) return false;
00111     ::fclose(file);
00112     return true;
00113   }
00114 protected:
00115   std::ostream& m_out;
00116   bool m_verbose;
00117 private:
00118   std::map<std::string,std::string> m_cache; 
00119   std::string m_tmp_dir;
00120   std::string m_tmp_suffix;
00121 };
00122 
00123 }}
00124 
00125 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines