mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-25 22:07:34 +00:00
SWORD25: Fix loading files with relative paths.
svn-id: r53246
This commit is contained in:
parent
f4024d7d14
commit
eb191e3590
@ -40,104 +40,17 @@
|
|||||||
namespace Sword25 {
|
namespace Sword25 {
|
||||||
|
|
||||||
const char PATH_SEPARATOR = '/';
|
const char PATH_SEPARATOR = '/';
|
||||||
const char NAVIGATION_CHARACTER = '.';
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
static Common::String normalizePath(const Common::String &path, const Common::String ¤tDirectory) {
|
||||||
// Support functions and classes
|
Common::String wholePath = (path.size() >= 1 && path[0] == PATH_SEPARATOR) ? path : currentDirectory + PATH_SEPARATOR + path;
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static Common::String RemoveRedundantPathSeparators(const Common::String &Path) {
|
if (wholePath.size() == 0) {
|
||||||
Common::String Result;
|
|
||||||
|
|
||||||
// Iterate over all the chracters of the input path
|
|
||||||
Common::String::const_iterator It = Path.begin();
|
|
||||||
while (It != Path.end()) {
|
|
||||||
if (*It == PATH_SEPARATOR) {
|
|
||||||
// Directory separater found
|
|
||||||
|
|
||||||
// Skip over directory separator(s)
|
|
||||||
while (It != Path.end() && *It == PATH_SEPARATOR) ++It;
|
|
||||||
|
|
||||||
// Unless it's the end of the path, add the separator
|
|
||||||
if (It != Path.end()) Result += PATH_SEPARATOR;
|
|
||||||
} else {
|
|
||||||
// Normal characters are copied over unchanged
|
|
||||||
Result += *It;
|
|
||||||
++It;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
|
||||||
|
|
||||||
static PathElementArray SeparatePath(const Common::String &Path, const Common::String &CurrentDirectory) {
|
|
||||||
// Determine whether the path is absolute (begins with /) or relative, in which case it's added
|
|
||||||
// to the current directory
|
|
||||||
Common::String wholePath = (Path.size() >= 1 && Path[0] == PATH_SEPARATOR) ? "" : CurrentDirectory + PATH_SEPARATOR;
|
|
||||||
|
|
||||||
// Add in the provided path
|
|
||||||
wholePath += RemoveRedundantPathSeparators(Path);
|
|
||||||
|
|
||||||
// Parse the path and divide into it's components. This ensures that occurences of ".." and "."
|
|
||||||
// are handled correctly.
|
|
||||||
PathElementArray pathElements;
|
|
||||||
size_t separatorPos = 0;
|
|
||||||
while (separatorPos < wholePath.size()) {
|
|
||||||
// Find next directory separator
|
|
||||||
const char *p = strchr(wholePath.c_str() + separatorPos + 1, PATH_SEPARATOR);
|
|
||||||
size_t nextseparatorPos = (p == NULL) ? wholePath.size() : p - wholePath.c_str();
|
|
||||||
|
|
||||||
// Calculate the beginning and end of the path element
|
|
||||||
Common::String::const_iterator elementBegin = wholePath.begin() + separatorPos + 1;
|
|
||||||
Common::String::const_iterator elementEnd = wholePath.begin() + nextseparatorPos;
|
|
||||||
|
|
||||||
if (elementEnd - elementBegin == 2 &&
|
|
||||||
elementBegin[0] == NAVIGATION_CHARACTER &&
|
|
||||||
elementBegin[1] == NAVIGATION_CHARACTER) {
|
|
||||||
// element is "..", therefore the previous path element should be removed
|
|
||||||
if (pathElements.size()) pathElements.pop_back();
|
|
||||||
} else if (elementEnd - elementBegin == 1 &&
|
|
||||||
elementBegin[0] == NAVIGATION_CHARACTER) {
|
|
||||||
// element is ".", so we do nothing
|
|
||||||
} else {
|
|
||||||
// Normal elements get added to the list
|
|
||||||
pathElements.push_back(new PathElement(wholePath.begin() + separatorPos + 1, wholePath.begin() + nextseparatorPos));
|
|
||||||
}
|
|
||||||
|
|
||||||
separatorPos = nextseparatorPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pathElements;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Common::String NormalizePath(const Common::String &Path, const Common::String &CurrentDirectory) {
|
|
||||||
// Get the path elements for the file
|
|
||||||
PathElementArray pathElements = SeparatePath(Path, CurrentDirectory);
|
|
||||||
|
|
||||||
if (pathElements.size()) {
|
|
||||||
// The individual path elements are fitted together, separated by a directory
|
|
||||||
// separator. The resulting string is returned as a result
|
|
||||||
Common::String Result;
|
|
||||||
|
|
||||||
PathElementArray::const_iterator It = pathElements.begin();
|
|
||||||
while (It != pathElements.end()) {
|
|
||||||
Result += PATH_SEPARATOR;
|
|
||||||
Result += Common::String((*It)->GetBegin(), (*It)->GetEnd());
|
|
||||||
++It;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
} else {
|
|
||||||
// The path list has no elements, therefore the root directory is returned
|
// The path list has no elements, therefore the root directory is returned
|
||||||
return Common::String(PATH_SEPARATOR);
|
return Common::String(PATH_SEPARATOR);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
return Common::normalizePath(wholePath, PATH_SEPARATOR);
|
||||||
// Constructor / Destructor
|
}
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
BS_ScummVMPackageManager::BS_ScummVMPackageManager(BS_Kernel *KernelPtr) :
|
BS_ScummVMPackageManager::BS_ScummVMPackageManager(BS_Kernel *KernelPtr) :
|
||||||
BS_PackageManager(KernelPtr),
|
BS_PackageManager(KernelPtr),
|
||||||
@ -222,7 +135,7 @@ bool BS_ScummVMPackageManager::LoadDirectoryAsPackage(const Common::String &Dire
|
|||||||
|
|
||||||
void *BS_ScummVMPackageManager::GetFile(const Common::String &FileName, unsigned int *FileSizePtr) {
|
void *BS_ScummVMPackageManager::GetFile(const Common::String &FileName, unsigned int *FileSizePtr) {
|
||||||
Common::SeekableReadStream *in;
|
Common::SeekableReadStream *in;
|
||||||
Common::ArchiveMemberPtr fileNode = GetArchiveMember(FileName);
|
Common::ArchiveMemberPtr fileNode = GetArchiveMember(normalizePath(FileName, _currentDirectory));
|
||||||
if (!fileNode)
|
if (!fileNode)
|
||||||
return 0;
|
return 0;
|
||||||
if (!(in = fileNode->createReadStream()))
|
if (!(in = fileNode->createReadStream()))
|
||||||
@ -250,23 +163,23 @@ Common::String BS_ScummVMPackageManager::GetCurrentDirectory() {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool BS_ScummVMPackageManager::ChangeDirectory(const Common::String &Directory) {
|
bool BS_ScummVMPackageManager::ChangeDirectory(const Common::String &directory) {
|
||||||
// Get the path elements for the file
|
// Get the path elements for the file
|
||||||
_currentDirectory = NormalizePath(Directory, _currentDirectory);
|
_currentDirectory = normalizePath(directory, _currentDirectory);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
Common::String BS_ScummVMPackageManager::GetAbsolutePath(const Common::String &FileName) {
|
Common::String BS_ScummVMPackageManager::GetAbsolutePath(const Common::String &FileName) {
|
||||||
return NormalizePath(FileName, _currentDirectory);
|
return normalizePath(FileName, _currentDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
unsigned int BS_ScummVMPackageManager::GetFileSize(const Common::String &FileName) {
|
unsigned int BS_ScummVMPackageManager::GetFileSize(const Common::String &FileName) {
|
||||||
Common::SeekableReadStream *in;
|
Common::SeekableReadStream *in;
|
||||||
Common::ArchiveMemberPtr fileNode = GetArchiveMember(FileName);
|
Common::ArchiveMemberPtr fileNode = GetArchiveMember(normalizePath(FileName, _currentDirectory));
|
||||||
if (!fileNode)
|
if (!fileNode)
|
||||||
return 0;
|
return 0;
|
||||||
if (!(in = fileNode->createReadStream()))
|
if (!(in = fileNode->createReadStream()))
|
||||||
@ -289,7 +202,7 @@ unsigned int BS_ScummVMPackageManager::GetFileType(const Common::String &FileNam
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool BS_ScummVMPackageManager::FileExists(const Common::String &FileName) {
|
bool BS_ScummVMPackageManager::FileExists(const Common::String &FileName) {
|
||||||
Common::ArchiveMemberPtr fileNode = GetArchiveMember(FileName);
|
Common::ArchiveMemberPtr fileNode = GetArchiveMember(normalizePath(FileName, _currentDirectory));
|
||||||
return fileNode;
|
return fileNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,7 +246,7 @@ public:
|
|||||||
BS_PackageManager::FileSearch *BS_ScummVMPackageManager::CreateSearch(
|
BS_PackageManager::FileSearch *BS_ScummVMPackageManager::CreateSearch(
|
||||||
const Common::String &Filter, const Common::String &Path, unsigned int TypeFilter) {
|
const Common::String &Filter, const Common::String &Path, unsigned int TypeFilter) {
|
||||||
#if 0
|
#if 0
|
||||||
Common::String NormalizedPath = NormalizePath(Path, _currentDirectory);
|
Common::String NormalizedPath = normalizePath(Path, _currentDirectory);
|
||||||
|
|
||||||
Common::FSNode folderNode = GetFSNode(Path);
|
Common::FSNode folderNode = GetFSNode(Path);
|
||||||
if (!folderNode.exists() || !folderNode.isDirectory()) return NULL;
|
if (!folderNode.exists() || !folderNode.isDirectory()) return NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user