Skip to content

Commit 3853910

Browse files
committed
[linux] first version for resource paths handling on linux
Based on this file (GPLv3): https://github.com/KD-lab-Open-Source/Perimeter/blob/d131aa26dce1db187416718610baa09d53c65de8/Source/XTool/XUTIL/XUTIL.CPP
1 parent d1c56c4 commit 3853910

File tree

5 files changed

+134
-11
lines changed

5 files changed

+134
-11
lines changed

src/apps/engine/src/file_service.cpp

Lines changed: 114 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ FILE_SERVICE::FILE_SERVICE()
3232
Max_File_Index = 0;
3333
for (uint32_t n = 0; n < _MAX_OPEN_INI_FILES; n++)
3434
OpenFiles[n] = nullptr;
35+
if (ResourcePathsFirstScan) {
36+
ScanResourcePaths();
37+
}
3538
}
3639

3740
FILE_SERVICE::~FILE_SERVICE()
@@ -41,7 +44,7 @@ FILE_SERVICE::~FILE_SERVICE()
4144

4245
std::fstream FILE_SERVICE::_CreateFile(const char *filename, std::ios::openmode mode)
4346
{
44-
const auto path = filename ? std::filesystem::u8path(convert_path_sep(filename)) : std::filesystem::path();
47+
const auto path = filename ? std::filesystem::u8path(ConvertPathResource(filename)) : std::filesystem::path();
4548
std::fstream fileS(path, mode);
4649
return fileS;
4750
}
@@ -58,7 +61,7 @@ void FILE_SERVICE::_SetFilePointer(std::fstream &fileS, std::streamoff off, std:
5861

5962
bool FILE_SERVICE::_DeleteFile(const char *filename)
6063
{
61-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(filename));
64+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(filename));
6265
return std::filesystem::remove(path);
6366
}
6467

@@ -94,7 +97,7 @@ bool FILE_SERVICE::_ReadFile(std::fstream &fileS, void *s, std::streamsize count
9497

9598
bool FILE_SERVICE::_FileOrDirectoryExists(const char *p)
9699
{
97-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(p));
100+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(p));
98101
auto ec = std::error_code{};
99102
bool result = std::filesystem::exists(path, ec);
100103
if (ec)
@@ -133,7 +136,7 @@ std::vector<std::filesystem::path> FILE_SERVICE::_GetFsPathsByMask(const char *s
133136
}
134137
else
135138
{
136-
srcPath = std::filesystem::u8path(convert_path_sep(sourcePath));
139+
srcPath = std::filesystem::u8path(ConvertPathResource(sourcePath));
137140
}
138141

139142
std::filesystem::path curPath;
@@ -179,7 +182,7 @@ std::time_t FILE_SERVICE::_ToTimeT(std::filesystem::file_time_type tp)
179182

180183
std::filesystem::file_time_type FILE_SERVICE::_GetLastWriteTime(const char *filename)
181184
{
182-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(filename));
185+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(filename));
183186
return std::filesystem::last_write_time(path);
184187
}
185188

@@ -203,25 +206,25 @@ std::string FILE_SERVICE::_GetExecutableDirectory()
203206

204207
std::uintmax_t FILE_SERVICE::_GetFileSize(const char *filename)
205208
{
206-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(filename));
209+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(filename));
207210
return std::filesystem::file_size(path);
208211
}
209212

210213
void FILE_SERVICE::_SetCurrentDirectory(const char *pathName)
211214
{
212-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(pathName));
215+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(pathName));
213216
std::filesystem::current_path(path);
214217
}
215218

216219
bool FILE_SERVICE::_CreateDirectory(const char *pathName)
217220
{
218-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(pathName));
221+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(pathName));
219222
return std::filesystem::create_directories(path);
220223
}
221224

222225
std::uintmax_t FILE_SERVICE::_RemoveDirectory(const char *pathName)
223226
{
224-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(pathName));
227+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(pathName));
225228
return std::filesystem::remove_all(path);
226229
}
227230

@@ -358,6 +361,108 @@ bool FILE_SERVICE::LoadFile(const char *file_name, char **ppBuffer, uint32_t *dw
358361
return true;
359362
}
360363

364+
//------------------------------------------------------------------------------------------------
365+
// Resource paths
366+
//
367+
368+
static bool startsWith(const std::string& str, const std::string& prefix)
369+
{
370+
return str.size() >= prefix.size() && 0 == str.compare(0, prefix.size(), prefix);
371+
}
372+
373+
static bool endsWith(const std::string& str, const std::string& suffix)
374+
{
375+
return str.size() >= suffix.size() && 0 == str.compare(str.size()-suffix.size(), suffix.size(), suffix);
376+
}
377+
378+
void terminate_with_char(std::string& buffer, const char chr) {
379+
//Check if already has
380+
if (!buffer.empty() && buffer[buffer.length() - 1] != chr) {
381+
//Append to end and store
382+
buffer += chr;
383+
}
384+
}
385+
386+
std::string get_dir_iterator_path(const std::filesystem::path& path)
387+
{
388+
std::string path_str = path.string();
389+
size_t pos = path_str.find(std::string(".") + PATH_SEP);
390+
if (pos != std::string::npos && pos == 0)
391+
{
392+
path_str.erase(0, 2);
393+
}
394+
return path_str;
395+
}
396+
397+
void string_replace(std::string& input, const char* find, const char* paste)
398+
{
399+
size_t pos = 0;
400+
while (true) {
401+
pos = input.find(find, pos);
402+
if(pos >= input.size())
403+
break;
404+
input.replace(pos, strlen(find), paste);
405+
pos += strlen(paste);
406+
}
407+
}
408+
409+
std::string convert_path(const char* path)
410+
{
411+
std::string conv;
412+
size_t size = strlen(path);
413+
for (int i = 0; i < size; ++i)
414+
{
415+
conv.push_back(path[i] == WRONG_PATH_SEP ? PATH_SEP : path[i]);
416+
}
417+
return conv;
418+
}
419+
420+
void FILE_SERVICE::ScanResourcePaths()
421+
{
422+
if (ResourcePathsFirstScan)
423+
{
424+
//Seems like if static code calls us we need to do this manually to avoid any bugs
425+
ResourcePaths = std::unordered_map<std::string, std::string>();
426+
}
427+
ResourcePaths.clear();
428+
for (const auto & entry : std::filesystem::recursive_directory_iterator(".")) {
429+
if (entry.is_regular_file() || entry.is_directory()) {
430+
std::string path = get_dir_iterator_path(entry.path());
431+
std::string path_lwr = convert_path(path.c_str());
432+
tolwr(path_lwr.data());
433+
if (startsWith(path_lwr, "program")
434+
|| startsWith(path_lwr, "resource")
435+
|| endsWith(path_lwr, ".ini")) {
436+
ResourcePaths[path_lwr] = path;
437+
if (entry.is_directory()) {
438+
terminate_with_char(path_lwr, PATH_SEP);
439+
ResourcePaths[path_lwr] = path;
440+
}
441+
}
442+
}
443+
}
444+
ResourcePathsFirstScan = false;
445+
}
446+
447+
std::string FILE_SERVICE::ConvertPathResource(const char* path)
448+
{
449+
if (ResourcePathsFirstScan)
450+
{
451+
ScanResourcePaths();
452+
}
453+
std::string conv = convert_path(path);
454+
tolwr(conv.data());
455+
if (startsWith(conv, "./"))
456+
{
457+
string_replace(conv, "./", "");
458+
}
459+
std::string result = ResourcePaths[conv];
460+
if (result.empty())
461+
return conv;
462+
else
463+
return result;
464+
}
465+
361466
//=================================================================================================
362467

363468
INIFILE_T::~INIFILE_T()

src/apps/engine/src/file_service.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "ifs.h"
44
#include "v_file_service.h"
55
#include <memory>
6+
#include <unordered_map>
67

78
#define _MAX_OPEN_INI_FILES 1024
89

@@ -85,6 +86,9 @@ class FILE_SERVICE : public VFILE_SERVICE
8586
IFS *OpenFiles[_MAX_OPEN_INI_FILES];
8687
uint32_t Files_Num;
8788
uint32_t Max_File_Index;
89+
// Resource paths
90+
bool ResourcePathsFirstScan = true; // Since some code may call this statically, we use a flag to know if this is the first time
91+
std::unordered_map<std::string, std::string> ResourcePaths;
8892

8993
public:
9094
FILE_SERVICE();
@@ -116,4 +120,8 @@ class FILE_SERVICE : public VFILE_SERVICE
116120
std::unique_ptr<INIFILE> OpenIniFile(const char *file_name) override;
117121
void RefDec(INIFILE *ini_obj);
118122
void FlushIniFiles();
123+
124+
// Resource paths
125+
void ScanResourcePaths() override;
126+
std::string ConvertPathResource(const char* path) override;
119127
};

src/libs/common/include/storm_platform.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
#pragma once
22
#ifdef _WIN32
3+
4+
#define PATH_SEP '\\'
5+
#define WRONG_PATH_SEP '/'
36
inline const char *convert_path_sep(const char *cPath)
47
{
58
return cPath;
69
}
7-
#else
10+
11+
#else // NOT _WIN32
812

913
#include <limits.h>
1014

@@ -17,6 +21,8 @@ inline const char *convert_path_sep(const char *cPath)
1721
#define _MAX_FNAME NAME_MAX
1822
#define MAKELONG(low, high) ((int32_t)(((uint16_t)(low)) | (((uint32_t)((uint16_t)(high))) << 16)))
1923

24+
#define PATH_SEP '/'
25+
#define WRONG_PATH_SEP '\\'
2026
inline char *convert_path_sep(const char *cPath)
2127
{
2228
const auto len = strlen(cPath) + 1;

src/libs/common/include/v_file_service.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ class VFILE_SERVICE
4343
// ini files section
4444
virtual std::unique_ptr<INIFILE> CreateIniFile(const char *file_name, bool fail_if_exist) = 0;
4545
virtual std::unique_ptr<INIFILE> OpenIniFile(const char *file_name) = 0;
46+
47+
// Resource paths
48+
virtual void ScanResourcePaths() = 0;
49+
virtual std::string ConvertPathResource(const char* path) = 0;
4650
};
4751

4852
//------------------------------------------------------------------------------------------------

src/libs/renderer/src/s_device.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,7 @@ int32_t DX9RENDER::TextureCreate(const char *fname)
13761376
return -1L;
13771377
}
13781378

1379-
std::filesystem::path path = convert_path_sep(fname);
1379+
std::filesystem::path path = fio->ConvertPathResource(fname);
13801380
std::string pathStr = path.extension().string();
13811381
if (storm::iEquals(pathStr, ".tx"))
13821382
path.replace_extension();

0 commit comments

Comments
 (0)