[Add] Adding some more Filesystem stuff. This will allow you to manipulate files at your will.
-- Kinda.
This commit is contained in:
parent
cb0f0858f0
commit
48d85b777f
@ -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 \
|
||||||
|
17
src/System/Filesystem/EmptyBuffer.h
Normal file
17
src/System/Filesystem/EmptyBuffer.h
Normal 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.
|
||||||
|
|
280
src/System/Filesystem/FileList.cpp
Normal file
280
src/System/Filesystem/FileList.cpp
Normal 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.
|
||||||
|
|
31
src/System/Filesystem/FileList.h
Normal file
31
src/System/Filesystem/FileList.h
Normal 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.
|
||||||
|
|
28
src/System/Filesystem/IFileList.h
Normal file
28
src/System/Filesystem/IFileList.h
Normal 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.
|
||||||
|
|
18
src/System/Filesystem/IFilePackage.h
Normal file
18
src/System/Filesystem/IFilePackage.h
Normal 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.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user