Skip to content

Commit 0bfae09

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 0bfae09

5 files changed

Lines changed: 138 additions & 11 deletions

File tree

src/apps/engine/src/file_service.cpp

Lines changed: 118 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ 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();
3537
}
3638

3739
FILE_SERVICE::~FILE_SERVICE()
@@ -41,7 +43,7 @@ FILE_SERVICE::~FILE_SERVICE()
4143

4244
std::fstream FILE_SERVICE::_CreateFile(const char *filename, std::ios::openmode mode)
4345
{
44-
const auto path = filename ? std::filesystem::u8path(convert_path_sep(filename)) : std::filesystem::path();
46+
const auto path = filename ? std::filesystem::u8path(ConvertPathResource(filename)) : std::filesystem::path();
4547
std::fstream fileS(path, mode);
4648
return fileS;
4749
}
@@ -58,7 +60,7 @@ void FILE_SERVICE::_SetFilePointer(std::fstream &fileS, std::streamoff off, std:
5860

5961
bool FILE_SERVICE::_DeleteFile(const char *filename)
6062
{
61-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(filename));
63+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(filename));
6264
return std::filesystem::remove(path);
6365
}
6466

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

9597
bool FILE_SERVICE::_FileOrDirectoryExists(const char *p)
9698
{
97-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(p));
99+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(p));
98100
auto ec = std::error_code{};
99101
bool result = std::filesystem::exists(path, ec);
100102
if (ec)
@@ -133,7 +135,7 @@ std::vector<std::filesystem::path> FILE_SERVICE::_GetFsPathsByMask(const char *s
133135
}
134136
else
135137
{
136-
srcPath = std::filesystem::u8path(convert_path_sep(sourcePath));
138+
srcPath = std::filesystem::u8path(ConvertPathResource(sourcePath));
137139
}
138140

139141
std::filesystem::path curPath;
@@ -179,7 +181,7 @@ std::time_t FILE_SERVICE::_ToTimeT(std::filesystem::file_time_type tp)
179181

180182
std::filesystem::file_time_type FILE_SERVICE::_GetLastWriteTime(const char *filename)
181183
{
182-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(filename));
184+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(filename));
183185
return std::filesystem::last_write_time(path);
184186
}
185187

@@ -203,25 +205,25 @@ std::string FILE_SERVICE::_GetExecutableDirectory()
203205

204206
std::uintmax_t FILE_SERVICE::_GetFileSize(const char *filename)
205207
{
206-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(filename));
208+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(filename));
207209
return std::filesystem::file_size(path);
208210
}
209211

210212
void FILE_SERVICE::_SetCurrentDirectory(const char *pathName)
211213
{
212-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(pathName));
214+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(pathName));
213215
std::filesystem::current_path(path);
214216
}
215217

216218
bool FILE_SERVICE::_CreateDirectory(const char *pathName)
217219
{
218-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(pathName));
220+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(pathName));
219221
return std::filesystem::create_directories(path);
220222
}
221223

222224
std::uintmax_t FILE_SERVICE::_RemoveDirectory(const char *pathName)
223225
{
224-
std::filesystem::path path = std::filesystem::u8path(convert_path_sep(pathName));
226+
std::filesystem::path path = std::filesystem::u8path(ConvertPathResource(pathName));
225227
return std::filesystem::remove_all(path);
226228
}
227229

@@ -358,6 +360,113 @@ bool FILE_SERVICE::LoadFile(const char *file_name, char **ppBuffer, uint32_t *dw
358360
return true;
359361
}
360362

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

363472
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)