vfsdirectory.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2008 by the FIFE team                              *
00003  *   http://www.fifengine.de                                               *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 // Standard C++ library includes
00023 #include <fstream>
00024 
00025 // 3rd party library includes
00026 #include <boost/filesystem/operations.hpp>
00027 #include <boost/filesystem/path.hpp>
00028 
00029 // FIFE includes
00030 // These includes are split up in two parts, separated by one empty line
00031 // First block: files included from the FIFE root src directory
00032 // Second block: files included from the same folder
00033 #include "vfs/raw/rawdata.h"
00034 #include "vfs/raw/rawdatafile.h"
00035 #include "util/log/logger.h"
00036 #include "util/base/exception.h"
00037 #include "vfsdirectory.h"
00038 
00039 namespace bfs = boost::filesystem;
00040 namespace FIFE {
00041     static Logger _log(LM_VFS);
00042 
00043     VFSDirectory::VFSDirectory(VFS* vfs, const std::string& root) : VFSSource(vfs), m_root(root) {
00044         FL_DBG(_log, LMsg("VFSDirectory created with root path ") << m_root);
00045         if(!m_root.empty() && *(m_root.end() - 1) != '/')
00046             m_root.append(1,'/');
00047     }
00048 
00049 
00050     VFSDirectory::~VFSDirectory() {
00051     }
00052 
00053 
00054     bool VFSDirectory::fileExists(const std::string& name) const {
00055         std::string fullpath = m_root + name;
00056         std::ifstream file(fullpath.c_str());
00057         if (file)
00058             return true;
00059 
00060         return false;
00061     }
00062 
00063     RawData* VFSDirectory::open(const std::string& file) const {
00064         return new RawData(new RawDataFile(m_root + file));
00065     }
00066 
00067     std::set<std::string> VFSDirectory::listFiles(const std::string& path) const {
00068         return list(path, false);
00069     }
00070 
00071     std::set<std::string> VFSDirectory::listDirectories(const std::string& path) const {
00072         return list(path, true);
00073     }
00074 
00075     std::set<std::string> VFSDirectory::list(const std::string& path, bool directorys) const {
00076         std::set<std::string> list;
00077         std::string dir = m_root;
00078 
00079         // Avoid double slashes
00080         if(path[0] == '/' && m_root[m_root.size()-1] == '/') {
00081             dir.append(path.substr(1));
00082         }
00083         else {
00084             dir.append(path);
00085         }
00086 
00087         try {
00088             bfs::path boost_path(dir);
00089             if (!bfs::exists(boost_path) || !bfs::is_directory(boost_path))
00090                 return list;
00091 
00092             bfs::directory_iterator end;
00093             for (bfs::directory_iterator i(boost_path); i != end; ++i) {
00094                 if (bfs::is_directory(*i) != directorys)
00095                     continue;
00096 
00097                 // This only works with boost 1.34 and up
00098                 // list.insert(i->path().leaf());
00099                 // This one should be ok with both 1.33 and above
00100                 list.insert(i->path().leaf());
00101             }
00102         }
00103         catch (const bfs::filesystem_error& ex) {
00104             throw Exception(ex.what());
00105         }
00106 
00107         return list;
00108     }
00109 }