Files
Xenia-Canary/src/xenia/vfs/virtual_file_system.cc
2015-06-27 22:37:49 -07:00

93 lines
2.6 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/vfs/virtual_file_system.h"
#include "xenia/base/filesystem.h"
#include "xenia/base/logging.h"
#include "xenia/base/string.h"
namespace xe {
namespace vfs {
VirtualFileSystem::VirtualFileSystem() {}
VirtualFileSystem::~VirtualFileSystem() {
// Delete all devices.
// This will explode if anyone is still using data from them.
devices_.clear();
symlinks_.clear();
}
bool VirtualFileSystem::RegisterDevice(std::unique_ptr<Device> device) {
devices_.emplace_back(std::move(device));
return true;
}
bool VirtualFileSystem::RegisterSymbolicLink(std::string path,
std::string target) {
symlinks_.insert({path, target});
return true;
}
bool VirtualFileSystem::UnregisterSymbolicLink(std::string path) {
auto& it = symlinks_.find(path);
if (it == symlinks_.end()) {
return false;
}
symlinks_.erase(it);
return true;
}
Entry* VirtualFileSystem::ResolvePath(std::string path) {
// Resolve relative paths
std::string normalized_path(xe::filesystem::CanonicalizePath(path));
// Resolve symlinks.
std::string device_path;
std::string relative_path;
for (const auto& it : symlinks_) {
if (xe::find_first_of_case(normalized_path, it.first) == 0) {
// Found symlink!
device_path = it.second;
relative_path = normalized_path.substr(it.first.size());
break;
}
}
// Not to fret, check to see if the path is fully qualified.
if (device_path.empty()) {
for (auto& device : devices_) {
if (xe::find_first_of_case(normalized_path, device->mount_path()) == 0) {
device_path = device->mount_path();
relative_path = normalized_path.substr(device_path.size());
}
}
}
if (device_path.empty()) {
XELOGE("ResolvePath(%s) failed - no root found", path.c_str());
return nullptr;
}
// Scan all devices.
for (auto& device : devices_) {
if (strcasecmp(device_path.c_str(), device->mount_path().c_str()) == 0) {
return device->ResolvePath(relative_path.c_str());
}
}
XELOGE("ResolvePath(%s) failed - device not found (%s)", path.c_str(),
device_path.c_str());
return nullptr;
}
} // namespace vfs
} // namespace xe