[Add] Adding some more Filesystem stuff. This will allow you to manipulate files at your will.

-- Kinda.
This commit is contained in:
Rtch90 2012-09-02 22:00:18 +01:00
parent cb0f0858f0
commit 48d85b777f
6 changed files with 379 additions and 0 deletions

View File

@ -39,6 +39,10 @@ HEADERS += ../src/Actor/Player.h \
../src/System/ResourceManager.h \ ../src/System/ResourceManager.h \
../src/System/ConvertType.h \ ../src/System/ConvertType.h \
../src/System/Filesystem/InputStream.h \ ../src/System/Filesystem/InputStream.h \
../src/System/Filesystem/EmptyBuffer.h \
../src/System/Filesystem/IFileList.h \
../src/System/Filesystem/IFilePackage.h \
../src/System/Filesystem/FileList.h \
../src/Texture/Texture.h \ ../src/Texture/Texture.h \
../src/Sound/Music.h \ ../src/Sound/Music.h \
../src/TMXParser/base64.h \ ../src/TMXParser/base64.h \
@ -90,6 +94,7 @@ SOURCES += ../src/Actor/Player.cpp \
../src/Sprite/Sprite.cpp \ ../src/Sprite/Sprite.cpp \
../src/System/Debug.cpp \ ../src/System/Debug.cpp \
../src/System/Filesystem/InputStream.cpp \ ../src/System/Filesystem/InputStream.cpp \
../src/System/Filesystem/FileList.cpp \
../src/Texture/Texture.cpp \ ../src/Texture/Texture.cpp \
../src/Sound/Music.cpp \ ../src/Sound/Music.cpp \
../src/Actor/NPC.cpp \ ../src/Actor/NPC.cpp \

View File

@ -0,0 +1,17 @@
#pragma once
#include "InputStream.h"
namespace saracraft {
namespace filesystem {
struct EmptyBuffer: public IINputStreamBuffer {
unsigned char PopByte(void) { return 0; }
bool IsEof(void) const { return true; }
int GetSize(void) const { return 0; }
void PopBytes(char*, int) { }
};
} // Namespace filesystem.
} // Namespace saracraft.

View File

@ -0,0 +1,280 @@
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include "FileList.h"
using namespace std;
using namespace boost;
namespace saracraft {
namespace filesystem {
namespace {
struct Dir;
typedef vector<string> StringList;
typedef map<string, Dir> DirList;
typedef vector<DirList::iterator> IteratorList;
struct Dir {
StringList files;
IteratorList subDirs;
void AddFile(const string& file) {
for(unsigned int i = 0; i < files.size(); ++i) {
if(file == files[i])
return;
}
files.push_back(file);
}
};
void HaxFile(string& str) {
for(unsigned int i = 0; i < str.size(); ++i) {
if(str[i] == '\\')
str[i] = '/';
}
}
void ConvertLower(string& str) {
for(unsigned int i = 0; i < str.size(); ++i) {
str[i] = tolower(str[i]);
}
}
void GetDirPart(const string& file, string& dir) {
string::size_type index = file.find_last_of("\\/");
if(index == file.npos) {
dir = string();
return;
}
dir = file.substr(0, index);
}
int GetDirAmountImpl(const IteratorList& list) {
int result = list.size();
/*for(IteratorList::const_iterator it = list.begin(); it != list.end(); ++i) {
const DirList::const_iterator& i = *it;
result += GetDirAmountImpl(i->second.subDirs);
}*/
return result;
}
int GetDirNameImpl(const IteratorList& list, string& result, int currentIndex, int findIndex) {
int original = currentIndex;
for(IteratorList::const_iterator it = list.begin(); it != list.end(); ++it) {
const DirList::const_iterator& i = *it;
if(currentIndex++ == findIndex) {
result = i->first;
break;
}
//currentIndex += GetDirNameImpl(i->second.subDirs
}
return currentIndex - original;
}
string empty;
} // Namespace unamed.
struct FileList::Data {
bool caseSensitive;
DirList dirs;
Data(void) : caseSensitive(false) {}
// Might want to put some directory hierarchy stuff here?
void AddDir(const string& dir) {
DirList::iterator it;
if(!FindDir(it, dir)) {
dirs[dir] = Dir();
FindDir(it, dir);
// Add a parent to the list.
string current = dir;
DirList::iterator currentIt = it;
for(int i = 0; ; ++i) {
string parent;
GetDirPart(current, parent);
if(parent.empty())
break;
bool needAdd = false;
DirList::iterator parentIt;
if(!FindDir(parentIt, parent)) {
dirs[parent] = Dir();
FindDir(parentIt, parent);
needAdd = true;
}
parentIt->second.subDirs.push_back(currentIt);
if(!needAdd)
break;
current = parent;
currentIt = parentIt;
}
}
}
bool FindDir(DirList::iterator& it, const string& dir) {
it = dirs.find(dir);
if(it == dirs.end())
return false;
return true;
}
};
FileList::FileList(void) {
scoped_ptr<Data> tempData(new Data());
_data.swap(tempData);
}
FileList::~FileList(void) {
}
void FileList::SetCaseSensitivity(bool enable) {
_data->caseSensitive = enable;
}
void FileList::AddDir(const string& dir_) {
string dir = dir_;
if(!_data->caseSensitive)
ConvertLower(dir);
HaxFile(dir);
_data->AddDir(dir);
}
void FileList::AddFile(const string& file_) {
string file = file_;
if(!_data->caseSensitive)
ConvertLower(file);
HaxFile(file);
string dir;
GetDirPart(file, dir);
_data->AddDir(dir);
DirList::iterator it;
_data->FindDir(it, dir);
it->second.AddFile(file);
}
int FileList::GetDirAmount(const string& root_) const {
string root = root_;
if(!_data->caseSensitive)
ConvertLower(root);
HaxFile(root);
DirList::iterator it;
if(!_data->FindDir(it, root))
return 0;
return GetDirAmountImpl(it->second.subDirs);
}
string FileList::GetDirName(const string& root_, int index) const {
string root = root_;
if(!_data->caseSensitive)
ConvertLower(root);
HaxFile(root);
DirList::iterator it;
if(!_data->FindDir(it, root))
return empty;
string result;
GetDirNameImpl(it->second.subDirs, result, 0, index);
return result;
}
int FileList::GetFileAmount(const string& root_) const {
string root = root_;
if(!_data->caseSensitive)
ConvertLower(root);
HaxFile(root);
DirList::iterator it;
if(!_data->FindDir(it, root))
return 0;
return it->second.files.size();
}
const string& FileList::GetFileName(const string& root_, int index) const {
string root = root_;
if(!_data->caseSensitive)
ConvertLower(root);
HaxFile(root);
DirList::iterator it;
if(!_data->FindDir(it, root))
return empty;
return it->second.files[index];
}
// ============================================================
namespace {
void GetAllFilesImpl(IFileList& list, const string& root, vector<string>& result, bool recurse) {
//if(root.find("
// The hell is your problem?!
int fileAmount = list.GetFileAmount(root);
for(int i = 0; i < fileAmount; ++i) {
const string& file = list.GetFileName(root, i);
result.push_back(file);
}
if(recurse) {
int dirAmount = list.GetDirAmount(root);
for(int i = 0; i < dirAmount; ++i) {
const string& dir = list.GetDirName(root, i);
if(dir.length() > 4 && dir.substr(dir.length() - 4, 4) == ".svn") {
// We should never even get here..
} else {
GetAllFilesImpl(list, dir, result, recurse);
}
}
}
}
void GetAllDirsImpl(IFileList& list, const string& root, vector<string>& result, bool recurse) {
int dirAmount = list.GetDirAmount(root);
for(int i = 0; i < dirAmount; ++i) {
const string& dir = list.GetDirName(root, i);
if(dir.length() > 4 && dir.substr(dir.length() - 4, 4) == ".svn") {
// We should never even get here..
} else {
result.push_back(dir);
if(recurse)
GetAllDirsImpl(list, dir, result, recurse);
}
}
}
} // Unamed namespace.
void GetAllFiles(IFileList& list, const string& root_, vector<string>& result, bool recurse, bool caseSensitive) {
string root = root_;
if(!caseSensitive)
ConvertLower(root);
HaxFile(root);
GetAllFilesImpl(list, root, result, recurse);
std::sort(result.begin(), result.end());
}
void GetAllDirs(IFileList& list, const string& root_, vector<string>& result, bool recurse, bool caseSensitive) {
string root = root_;
if(!caseSensitive)
ConvertLower(root);
HaxFile(root);
GetAllDirsImpl(list, root, result, recurse);
std::sort(result.begin(), result.end());
}
} // Namespace filesystem.
} // Namespace saracraft.

View File

@ -0,0 +1,31 @@
#pragma once
#include <boost/scoped_ptr.hpp>
#include <vector>
#include <string>
#include "IFileList.h"
namespace saracraft {
namespace filesystem {
class FileList: public IFileList {
struct Data;
boost::scoped_ptr<Data> _data;
public:
FileList(void);
~FileList(void);
void SetCaseSensitivity(bool enable);
void AddDir(const std::string& dir);
void AddFile(const std::string& file);
int GetDirAmount(const std::string& root) const;
std::string GetDirName(const std::string& root, int index) const;
int GetFileAmount(const std::string& root) const;
const std::string& GetFileName(const std::string& root, int index) const;
};
} // Namespace filesystem.
} // Namespace saracraft.

View File

@ -0,0 +1,28 @@
#pragma once
#include <string>
#include <vector>
namespace saracraft {
namespace filesystem {
class IFileList {
public:
virtual ~IFileList(void) {}
virtual void SetCaseSensitivity(bool enable) = 0;
virtual void AddDir(const std::string& dir) = 0;
virtual void AddFile(const std::string& file) = 0;
virtual int GetDirAmount(const std::string& root) const = 0;
virtual std::string GetDirName(const std::string& root, int index) const = 0;
virtual int GetFileAmount(const std::string& root) const = 0;
virtual const std::string& GetFileName(const std::string& root, int index) const = 0;
};
void GetAllFiles(IFileList& list, const std::string& root, std::vector<std::string>& result, bool recurse, bool caseSensitive = false);
void GetAllDirs(IFileList& list, const std::string& root, std::vector<std::string>& result, bool recurse, bool caseSensitive = false);
} // Namespace filesystem.
} // Namespace saracraft.

View File

@ -0,0 +1,18 @@
#pragma once
#include "InputStream.h"
namespace saracraft {
namespace filesystem {
class IFileList;
class IFilePackage {
public:
virtual ~IFilePackage(void) {}
virtual void FindFiles(const std::string& dir, const std::string& extension, IFileList& result) = 0;
virtual InputStream getFile(const std::string& filename) = 0;
};
} // Namespace filesystem.
} // Namespace saracraft.