1 #include "FilesystemResourceProvider.h"
6 #include <core/Platform.h>
7 #include <resource/Resource.h>
9 #ifdef CHIRA_PLATFORM_APPLE
10 #include "CoreFoundation/CoreFoundation.h"
13 using namespace chira;
15 CHIRA_CREATE_LOG(FILESYSTEM);
17 FilesystemResourceProvider::FilesystemResourceProvider(std::string path_,
bool isPathAbsolute,
const std::string& name_)
19 , path(std::move(path_))
20 , absolute(isPathAbsolute) {
21 FilesystemResourceProvider::nixifyPath(this->path);
22 this->path = String::stripRight(this->path,
'/');
23 if (!this->absolute) {
26 #ifdef CHIRA_PLATFORM_APPLE
29 if (CFBundleRef mainBundle = CFBundleGetMainBundle()) {
30 CFURLRef appUrlRef = CFBundleCopyBundleURL(mainBundle);
33 macPath = CFURLCopyFileSystemPath(appUrlRef, kCFURLPOSIXPathStyle);
40 rawpath = CFStringGetCStringPtr(macPath, kCFStringEncodingASCII);
46 std::string append =
"/Contents/Resource";
47 if (std::filesystem::exists(std::filesystem::path{rawpath + append + FILESYSTEM_ROOT_FOLDER +
'/' + this->path})) {
48 LOG_FILESYSTEM.info(
"Found resources in app bundle!");
49 this->path = rawpath + append + FILESYSTEM_ROOT_FOLDER +
'/' + this->path;
57 LOG_FILESYSTEM.warning(
"Could not find resources in our app bundle! Falling back to working directory...");
58 if (std::filesystem::exists(std::filesystem::path{FILESYSTEM_ROOT_FOLDER +
'/' + this->path})) {
59 LOG_FILESYSTEM.info(
"Found resources in working directory!");
60 this->path = FILESYSTEM_ROOT_FOLDER +
'/' + this->path;
62 LOG_FILESYSTEM.error(
"No known search path contains our required resources! Did you mistype something?");
67 this->path = FILESYSTEM_ROOT_FOLDER +
'/' + this->path;
72 bool FilesystemResourceProvider::hasResource(std::string_view name)
const {
74 return std::filesystem::exists(std::filesystem::path{this->path}.append(name));
76 return std::filesystem::exists(std::filesystem::current_path().append(this->path).append(name));
79 void FilesystemResourceProvider::compileResource(std::string_view name,
Resource* resource)
const {
80 std::filesystem::path resourcePath;
82 resourcePath = std::filesystem::path{this->path}.append(name);
84 resourcePath = std::filesystem::current_path().append(this->path).append(name);
85 std::uintmax_t fileSize = std::filesystem::file_size(resourcePath);
86 std::ifstream ifs(resourcePath.string().c_str(), std::ios::in | std::ios::binary);
87 ifs.seekg(0, std::ios::beg);
88 auto* bytes =
new byte[(std::size_t) fileSize + 1];
89 ifs.read(
reinterpret_cast<char*
>(bytes),
static_cast<std::streamsize
>(fileSize));
90 bytes[fileSize] =
'\0';
91 resource->compile(bytes, (std::size_t) fileSize + 1);
95 std::string FilesystemResourceProvider::getFolder()
const {
96 return String::stripLeft(std::string{this->getPath().data()}, FILESYSTEM_ROOT_FOLDER +
'/');
99 std::string FilesystemResourceProvider::getLocalResourceAbsolutePath(
const std::string& identifier)
const {
101 auto name = Resource::splitResourceIdentifier(identifier).second;
102 if (!this->hasResource(name))
104 auto absPath = (this->absolute ? std::filesystem::path{this->path} : std::filesystem::current_path().append(this->path)).append(name).string();
111 std::replace(path.begin(), path.end(),
'\\',
'/');
117 return FILESYSTEM_PROVIDER_NAME + RESOURCE_ID_SEPARATOR.data() + path;
123 if (absolutePath.find(FILESYSTEM_ROOT_FOLDER) == std::string_view::npos)
126 std::string path{absolutePath.data()};
132 auto index = path.rfind(FILESYSTEM_ROOT_FOLDER) + FILESYSTEM_ROOT_FOLDER.size() + 1;
133 if (index > path.length())
135 path = path.substr(index);
138 index = path.find(
'/') + 1;
139 path = path.substr(index);
144 if (
auto provider = Resource::getResourceProviderWithResource(identifier))
145 return assert_cast<FilesystemResourceProvider*>(provider)->getLocalResourceAbsolutePath(identifier);
static std::string getResourceIdentifier(std::string_view absolutePath)
Takes an absolute path of a resource file and converts it to a resource identifier.
static void nixifyPath(std::string &path)
Converts all backslashes in a string to forward slashes.
static std::string getResourceAbsolutePath(const std::string &identifier)
Takes a resource identifier and returns the full absolute path, if it exists.
static std::string getResourceFolderPath(std::string_view absolutePath)
Takes an absolute path of a resource folder and converts it to a valid input path for a FilesystemRes...
A chunk of data, usually a file. Is typically cached and shared.