Guest

Untitled

By: a guest on Mar 19th, 2010  |  syntax: C++  |  size: 3.42 KB  |  hits: 82  |  expires: Never
download  |  raw  |  embed  |  report abuse
Copied
  1.  
  2. #include <map>
  3. #include <string>
  4. #include <vector>
  5. #include <fstream>
  6.  
  7. using std::map;
  8. using std::string;
  9. using std::vector;
  10. using std::ifstream;
  11. using std::ios;
  12.  
  13. char directoryChar = '/';
  14.  
  15. string getExtension(const string& filepath) {
  16.         size_t lastPoint = filepath.find_last_of('.');
  17.         size_t lastDirectory = filepath.find_last_of(directoryChar);
  18.         if (lastPoint == string::npos || (lastDirectory != string::npos && lastDirectory > lastPoint)) {
  19.                 return "";
  20.         }
  21.         return filepath.substr(lastPoint+1);
  22. }
  23.  
  24. template <class T>
  25. class FileReader {
  26. protected:
  27.         /**Creates a filereader being able to possibly load files
  28.          * from the specified extension
  29.          **/
  30.         FileReader(char** extensions) {
  31.                 fileReaders.push_back(this);
  32.                 char** nextExtension = extensions;
  33.                 while (nextExtension != NULL) {
  34.                         string extensionString(*nextExtension);
  35.                         vector<FileReader<T> const * const>* curPossibleReaders = fileReaderByExtension[extensionString];
  36.                         if (curPossibleReaders == NULL) {
  37.                                 fileReaderByExtension[extensionString] = (curPossibleReaders = new vector<FileReader<T> const * const>(1));
  38.                         }
  39.                         curPossibleReaders->push_back(this);
  40.                         nextExtension = ++nextExtension;
  41.                 }
  42.         }
  43.  
  44.         FileReader() {
  45.                 fileReaders.push_back(this);
  46.         }
  47.  
  48. private:
  49.         static map<string, vector<FileReader<T> const * const>* > fileReaderByExtension;
  50.         static vector<FileReader<T> const * const> fileReaders;
  51.  
  52.         static inline T* readFromFileReaders(vector<FileReader<T> const * const>* readers, const string& filepath) {
  53.                 for (vector<FileReader<T> const * const>::const_iterator i = readers->begin(); i != readers->end(); ++i) {
  54.                         try {
  55.                                 FileReader<T> const * const reader = *i;               
  56.                                 T* ret = reader->read(filepath); //It is guaranteed that at least the filepath matches ...
  57.                                 if (ret != NULL) {
  58.                                         return ret;
  59.                                 }
  60.                         } catch (...) { //TODO: Specific exceptions
  61.                         }
  62.                 }
  63.                 return NULL;
  64.         }
  65. public:
  66.  
  67.         /**Tries to read a file
  68.          * This method tries to read the file with the specified filepath.
  69.          * If it fails, either <code>null</code> is returned or an exception
  70.          * is thrown*/
  71.         static T* readPath(const string& filepath) {
  72.                 const string& extension = getExtension(filepath);
  73.                 vector<FileReader<T> const * const>* possibleReaders = fileReaderByExtension(filepath);
  74.                 if (possibleReaders != NULL) {
  75.                         //Search in these possible readers
  76.                         T* ret = readFromFileReaders(possibleReaders, filepath);
  77.                         if (ret != NULL) {
  78.                                 return ret;
  79.                         }
  80.                 }
  81.                 T* ret = readFromFileReaders(fileReaders, filepath); //Try all other
  82.                 return ret;
  83.         }
  84.  
  85.         /**Reads a file
  86.          * This method tries to read the file with the specified filepath
  87.          * If it fails, either <code>null</code> is returned or an exception
  88.          * is thrown
  89.          */
  90.         virtual T* read(const string& filepath) const {
  91.                 ifstream file(filepath, ios::in | ios::binary);
  92.                 if (!file.is_open()) { //An error occured; TODO: Which one - throw an exception, print error message?
  93.                         return NULL;
  94.                 }
  95.                 return read(file);
  96.         }
  97.  
  98.         /**Reads a file
  99.          * This method tries to read the specified file
  100.          * If it failes, either <code>null</code> is returned or an exception
  101.          * is thrown
  102.          */
  103.         virtual T* read(const ifstream& file) const = 0;
  104.  
  105.         virtual ~FileReader() {
  106.                 for (vector<FileReader<T> const * const>::const_iterator i = fileReaders.begin(); i != fileReaders.end(); ++i) {
  107.                         delete const_cast<FileReader<T>* >(*i);
  108.                 }
  109.         }; //Well ... these objects aren't supposed to be destroyed
  110. };