PersistentData.H

Go to the documentation of this file.
00001 #ifndef PERSISTENT_D_H
00002 #define PERSISTENT_D_H
00003 
00004 // written by Thorsten Reinecke (reinecke@thorstenreinecke.de)
00005 // last change: 2004-10-06
00006 
00013 extern "C"
00014 {
00015  #include <unistd.h>
00016 }
00017 
00018 #include <map>
00019 #include <string>
00020 #include <iostream>
00021 #include <fstream>
00022 
00024 class CPersistentDataInterface
00025 {
00026  public:
00027   virtual void Load(std::istream &is) = 0;
00028   virtual void Save(std::ostream &os) const = 0;
00029   virtual ~CPersistentDataInterface() = 0;
00030 };
00031 CPersistentDataInterface::~CPersistentDataInterface() { }
00032 
00033 // gcc-4.0 (experimental) issued warnings about missing virtual destructors.
00034 // Although we don't need destructors for our implementation, we *do* define
00035 // a virtual destructor in the interface. That's because if the interface
00036 // doesn't declare a virtual destructor (and also defines a default
00037 // destructor), then no destructor will be called for the dynamically
00038 // constructed items inside CPersistentDataCollection!
00039 
00040 
00042 template <typename T>
00043 class CPersistentData : protected CPersistentDataInterface
00044 {
00045  protected:
00046   T &data; // reference of the variable to load/save
00047   CPersistentData(T &mydata) : data(mydata) { }
00048   virtual ~CPersistentData() { }
00049   virtual void Load(std::istream &is)
00050    {
00051      is >> data;
00052 #ifdef VERBOSE
00053      cout << data << endl;
00054 #endif
00055    }
00056   virtual void Save(std::ostream &os) const { os << data << std::endl; }
00057   friend class CPersistentDataCollection;
00058 };
00059 
00060 
00078 class CPersistentDataCollection : private ForbidAssignment
00079 {
00080  protected:
00081   typedef std::map<std::string,CPersistentDataInterface*> TCollection;
00082   const std::string filename;
00083   TCollection collection;
00084 
00085  public:
00086 
00088   void ClearStream()
00089    {
00090      // remove stream
00091      unlink(filename.c_str());
00092    }
00093 
00095   void ClearCollection()
00096    {
00097     while (!collection.empty())
00098      {
00099        delete collection.begin()->second;
00100        collection.erase(collection.begin());
00101      }
00102    }
00103 
00105   explicit CPersistentDataCollection(const std::string myFilename)
00106    : filename(myFilename) { }
00107   
00108   ~CPersistentDataCollection() { ClearCollection();  }
00109 
00111   template<typename T> inline void RegisterVar(const std::string ID, T &data)
00112    {
00113      if (collection.find(ID)!=collection.end()) // check for presence
00114       {
00115         // was already present!
00116         exit(1); // for debugging (we could throw an exception instead)
00117       }
00118      else collection[ID] = new CPersistentData<T>(data);
00119    }
00120 
00122   template<typename T> inline void UnregisterVar(const std::string ID)
00123    {
00124      if (collection.find(ID)==collection.end()) // check for presence
00125       {
00126         // wasn't present!
00127         exit(1); // for debugging (we could throw an exception instead)
00128       }
00129      else
00130       {
00131         delete collection[ID];
00132         collection.erase(ID);
00133       }
00134    }
00135 
00137   void Load()
00138    {
00139      std::ifstream istr(filename.c_str());
00140      while (istr)
00141       {
00142         while (isspace(istr.peek())) istr.get();
00143 
00144         // it seems that gcc-3.2.3 has some problems detecting eof,
00145         // I hope this helps...
00146         istr.get();
00147         if (istr.eof()) break;
00148         istr.unget();
00149 
00150         std::string ID;
00151         istr >> ID;
00152         if (collection.find(ID)==collection.end()) // check for presence
00153          {
00154            MARK;
00155            cout << "ID " << ID << " not found!" << endl;
00156            exit(1); // isn't present!
00157          }
00158         else
00159          {
00160 #ifdef VERBOSE
00161            cout << "Loading ID " << ID << "= "; 
00162 #endif
00163            collection[ID]->Load(istr);
00164          }
00165       }
00166      istr.close();
00167    }
00168 
00170   void Save()
00171    {
00172      std::ofstream ostr(filename.c_str(),std::ios::out|std::ios::trunc);
00173      for (TCollection::const_iterator p=collection.begin(); p!=collection.end(); ++p)
00174       {
00175         ostr << p->first << " ";
00176         p->second->Save(ostr);
00177       }
00178      ostr.close();
00179    }
00180 
00181 };
00182 
00183 #endif /* PERSISTENT_D_H */

Generated on Wed Nov 7 23:29:25 2007 for Qsieve by  doxygen 1.5.4