vfshandler.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 170 行
CPP
170 行
#include "StdAfx.h"
#include "VFSHandler.h"
#include "ArchiveFactory.h"
#include "ArchiveBase.h"
#include <algorithm>
#include <set>
#include "Platform/FileSystem.h"
#include "mmgr.h"
CVFSHandler* hpiHandler=0;
CVFSHandler::CVFSHandler()
{
}
// Override determines whether if conflicts overwrites an existing entry in the virtual filesystem or not
bool CVFSHandler::AddArchive(string arName, bool override)
{
CArchiveBase* ar = archives[arName];
if (!ar) {
ar = CArchiveFactory::OpenArchive(arName);
if (!ar)
return false;
archives[arName] = ar;
}
int cur;
string name;
int size;
for (cur = ar->FindFiles(0, &name, &size); cur != 0; cur = ar->FindFiles(cur, &name, &size)) {
StringToLowerInPlace(name);
if ((!override) && (files.find(name) != files.end()))
continue;
FileData d;
d.ar = ar;
d.size = size;
files[name] = d;
}
return true;
}
CVFSHandler::~CVFSHandler(void)
{
for (map<string, CArchiveBase*>::iterator i = archives.begin(); i != archives.end(); ++i) {
delete i->second;
}
}
int CVFSHandler::LoadFile(string name, void* buffer)
{
StringToLowerInPlace(name);
filesystem.ForwardSlashes(name);
FileData fd = files[name];
int fh = fd.ar->OpenFile(name);
if (!fh)
return -1;
fd.ar->ReadFile(fh, buffer, fd.size);
fd.ar->CloseFile(fh);
return fd.size;
}
int CVFSHandler::GetFileSize(string name)
{
StringToLowerInPlace(name);
filesystem.ForwardSlashes(name);
map<string, FileData>::iterator f = files.find(name);
if (f == files.end())
return -1;
else
return f->second.size;
}
// Returns all the files in the given (virtual) directory without the preceeding pathname
vector<string> CVFSHandler::GetFilesInDir(string dir)
{
vector<string> ret;
StringToLowerInPlace(dir);
filesystem.ForwardSlashes(dir);
map<string, FileData>::const_iterator filesStart = files.begin();
map<string, FileData>::const_iterator filesEnd = files.end();
// Non-empty directories to look in should have a trailing backslash
if (!dir.empty()) {
string::size_type dirLast = (dir.length() - 1);
if (dir[dirLast] != '/') {
dir += "/";
dirLast++;
}
// limit the iterator range
string dirEnd = dir;
dirEnd[dirLast] = dirEnd[dirLast] + 1;
filesStart = files.lower_bound(dir);
filesEnd = files.upper_bound(dirEnd);
}
while (filesStart != filesEnd) {
const string path = filesystem.GetDirectory(filesStart->first);
// Test to see if this file start with the dir path
if (path.compare(0, dir.length(), dir) == 0) {
// Strip pathname
const string name = filesStart->first.substr(dir.length());
// Do not return files in subfolders
if ((name.find('/') == string::npos) &&
(name.find('\\') == string::npos)) {
ret.push_back(name);
}
}
filesStart++;
}
return ret;
}
// Returns all the sub-directories in the given (virtual) directory without the preceeding pathname
vector<string> CVFSHandler::GetDirsInDir(string dir)
{
vector<string> ret;
StringToLowerInPlace(dir);
filesystem.ForwardSlashes(dir);
map<string, FileData>::const_iterator filesStart = files.begin();
map<string, FileData>::const_iterator filesEnd = files.end();
// Non-empty directories to look in should have a trailing backslash
if (!dir.empty()) {
string::size_type dirLast = (dir.length() - 1);
if (dir[dirLast] != '/') {
dir += "/";
dirLast++;
}
// limit the iterator range
string dirEnd = dir;
dirEnd[dirLast] = dirEnd[dirLast] + 1;
filesStart = files.lower_bound(dir);
filesEnd = files.upper_bound(dirEnd);
}
set<string> dirs;
while (filesStart != filesEnd) {
const string path = filesystem.GetDirectory(filesStart->first);
// Test to see if this file start with the dir path
if (path.compare(0, dir.length(), dir) == 0) {
// Strip pathname
const string name = filesStart->first.substr(dir.length());
const string::size_type slash = name.find_first_of("/\\");
if (slash != string::npos) {
dirs.insert(name.substr(0, slash + 1));
}
}
filesStart++;
}
for (set<string>::const_iterator it = dirs.begin(); it != dirs.end(); ++it) {
ret.push_back(*it);
}
return ret;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?