Skip to content

Commit 827c9f5

Browse files
author
Pavel Kovalenko
committed
Add initial support for 'external' filesystem.
1 parent f89ae79 commit 827c9f5

File tree

6 files changed

+123
-33
lines changed

6 files changed

+123
-33
lines changed

res/gamedata/scripts/lua_help.script

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2628,6 +2628,12 @@ C++ class CLevelChanger : CGameObject {
26282628

26292629
};
26302630

2631+
C++ class FileStatus
2632+
{
2633+
bool Exists const;
2634+
bool External const;
2635+
};
2636+
26312637
C++ class FS {
26322638
const FS_ClampExt = 4;
26332639
const FS_ListFiles = 1;
@@ -2640,6 +2646,10 @@ C++ class FS {
26402646
const FS_sort_by_size_down = 3;
26412647
const FS_sort_by_size_up = 2;
26422648

2649+
const FSType_Virtual = 1;
2650+
const FSType_External = 2;
2651+
const FSType_Any = 3;
2652+
26432653
function get_file_age(string);
26442654

26452655
function file_length(string);

src/utils/xrCompress/xrCompressDifference.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ struct file_comparer{
2525
// xr_strcpy(m_short_name,c+xr_strlen(arget_folder)+1);
2626
xr_strcpy(m_full_name,c);
2727

28-
const CLocatorAPI::file* f = m_fs_new->exist("$target_folder$",m_full_name);
29-
if(f)
30-
m_file_size = f->size_real;
28+
string_path path;
29+
m_fs_new->update_path(path, "$target_folder$", m_full_name);
30+
if (m_fs_new->exist(path))
31+
m_file_size = m_fs_new->file_length(path);
3132
}
3233

3334
bool operator ()(char* o){
@@ -40,10 +41,12 @@ struct file_comparer{
4041

4142
if( !m_flags.test(eDontCheckFileSize) ){
4243
//compare file size
43-
const CLocatorAPI::file* f = m_fs_old->exist("$target_folder$",o);
44-
u32 file_size = f->size_real;
45-
46-
if ( (f->vfs==0xffffffff) && (file_size != m_file_size) )
44+
string_path path;
45+
m_fs_old->update_path(path, "$target_folder$", o);
46+
if (!m_fs_old->exist(path))
47+
return false;
48+
auto fileDesc = m_fs_old->GetFileDesc(path);
49+
if (fileDesc->vfs == 0xffffffff && fileDesc->size_real != m_file_size)
4750
return false;
4851
};
4952
//compare file crc

src/xrCore/LocatorAPI.cpp

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,16 @@ CLocatorAPI::~CLocatorAPI()
203203
_dump_open_files(1);
204204
}
205205

206-
void CLocatorAPI::Register(LPCSTR name, u32 vfs, u32 crc, u32 ptr, u32 size_real, u32 size_compressed, u32 modif)
206+
const CLocatorAPI::file* CLocatorAPI::RegisterExternal(const char* name)
207+
{
208+
struct stat buffer;
209+
if (stat(name, &buffer) == -1)
210+
return nullptr;
211+
return Register(name, u32(-1), 0, 0, buffer.st_size, buffer.st_size, u32(buffer.st_mtime));
212+
}
213+
214+
const CLocatorAPI::file* CLocatorAPI::Register(LPCSTR name, u32 vfs, u32 crc, u32 ptr,
215+
u32 size_real, u32 size_compressed, u32 modif)
207216
{
208217
//Msg("Register[%d] [%s]",vfs,name);
209218
string256 temp_file_name;
@@ -231,15 +240,15 @@ void CLocatorAPI::Register(LPCSTR name, u32 vfs, u32 crc, u32 ptr, u32 size_real
231240
// sad but true, performance option
232241
// correct way is to erase and then insert new record:
233242
const_cast<file&>(*I) = desc;
234-
return;
243+
return &*I;
235244
}
236245
else
237246
{
238247
desc.name = xr_strdup(desc.name);
239248
}
240249

241250
// otherwise insert file
242-
m_files.insert(desc);
251+
auto result = m_files.insert(desc).first;
243252

244253
// Try to register folder(s)
245254
string_path temp;
@@ -265,6 +274,7 @@ void CLocatorAPI::Register(LPCSTR name, u32 vfs, u32 crc, u32 ptr, u32 size_real
265274
xr_strcpy(temp, sizeof(temp), folder);
266275
if (xr_strlen(temp)) temp[xr_strlen(temp) - 1] = 0;
267276
}
277+
return &*result;
268278
}
269279

270280
IReader* open_chunk(void* ptr, u32 ID)
@@ -874,31 +884,50 @@ void CLocatorAPI::_destroy()
874884
m_archives.clear();
875885
}
876886

877-
const CLocatorAPI::file* CLocatorAPI::exist(const char* fn)
887+
const CLocatorAPI::file* CLocatorAPI::GetFileDesc(const char* path)
878888
{
879-
files_it it = file_find_it(fn);
880-
return (it != m_files.end()) ? &(*it) : 0;
889+
auto it = file_find_it(path);
890+
return it != m_files.end() ? &*it : nullptr;
891+
}
892+
893+
FileStatus CLocatorAPI::exist(const char* fn, FSType fsType /*= FSType::Virtual*/)
894+
{
895+
if ((fsType | FSType::Virtual) == FSType::Virtual)
896+
{
897+
files_it it = file_find_it(fn);
898+
if (it != m_files.end())
899+
return FileStatus(true, false);
900+
}
901+
if ((fsType | FSType::External) == FSType::External)
902+
{
903+
struct stat buffer;
904+
buffer.st_size;
905+
return FileStatus(stat(fn, &buffer) == 0, true);
906+
}
907+
return FileStatus(false, false);
881908
}
882909

883-
const CLocatorAPI::file* CLocatorAPI::exist(const char* path, const char* name)
910+
FileStatus CLocatorAPI::exist(const char* path, const char* name, FSType fsType /*= FSType::Virtual*/)
884911
{
885912
string_path temp;
886913
update_path(temp, path, name);
887-
return exist(temp);
914+
return exist(temp, fsType);
888915
}
889916

890-
const CLocatorAPI::file* CLocatorAPI::exist(string_path& fn, LPCSTR path, LPCSTR name)
917+
FileStatus CLocatorAPI::exist(string_path& fn, LPCSTR path, LPCSTR name,
918+
FSType fsType /*= FSType::Virtual*/)
891919
{
892920
update_path(fn, path, name);
893-
return exist(fn);
921+
return exist(fn, fsType);
894922
}
895923

896-
const CLocatorAPI::file* CLocatorAPI::exist(string_path& fn, LPCSTR path, LPCSTR name, LPCSTR ext)
924+
FileStatus CLocatorAPI::exist(string_path& fn, LPCSTR path, LPCSTR name, LPCSTR ext,
925+
FSType fsType /*= FSType::Virtual*/)
897926
{
898927
string_path nm;
899928
strconcat(sizeof(nm), nm, name, ext);
900929
update_path(fn, path, nm);
901-
return exist(fn);
930+
return exist(fn, fsType);
902931
}
903932

904933
xr_vector<char*>* CLocatorAPI::file_list_open(const char* initial, const char* folder, u32 flags)
@@ -1306,13 +1335,19 @@ bool CLocatorAPI::check_for_file(LPCSTR path, LPCSTR _fname, string_path& fname,
13061335
// Search entry
13071336
file desc_f;
13081337
desc_f.name = fname;
1309-
13101338
files_it I = m_files.find(desc_f);
13111339
if (I == m_files.end())
1312-
return (false);
1313-
1340+
{
1341+
if (!exist(fname, FSType::External))
1342+
return false;
1343+
const file* extFile = RegisterExternal(fname);
1344+
if (!extFile)
1345+
return false;
1346+
desc = extFile;
1347+
}
1348+
else
1349+
desc = &*I;
13141350
++dwOpenCounter;
1315-
desc = &*I;
13161351
return (true);
13171352
}
13181353

@@ -1546,8 +1581,13 @@ void CLocatorAPI::file_rename(LPCSTR src, LPCSTR dest, bool bOwerwrite)
15461581

15471582
int CLocatorAPI::file_length(LPCSTR src)
15481583
{
1549-
files_it I = file_find_it(src);
1550-
return (I != m_files.end()) ? I->size_real : -1;
1584+
files_it it = file_find_it(src);
1585+
if (it != m_files.end())
1586+
return it->size_real;
1587+
struct stat buffer;
1588+
if (stat(src, &buffer) != -1)
1589+
return buffer.st_size;
1590+
return -1;
15511591
}
15521592

15531593
bool CLocatorAPI::path_exist(LPCSTR path)

src/xrCore/LocatorAPI.h

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,35 @@
1010
#pragma warning(disable:4995)
1111
#include <io.h>
1212
#pragma warning(pop)
13-
13+
#include "Common/Util.hpp"
1414
#include "LocatorAPI_defs.h"
1515

1616
class XRCORE_API CStreamReader;
1717

18+
enum class FSType
19+
{
20+
Virtual = 1,
21+
External = 2,
22+
Any = Virtual | External,
23+
};
24+
25+
IMPLEMENT_ENUM_FLAG_OPERATORS(FSType, int);
26+
27+
class FileStatus
28+
{
29+
public:
30+
bool Exists;
31+
bool External; // File can be accessed only as external
32+
33+
inline FileStatus(bool exists, bool external)
34+
{
35+
Exists = exists;
36+
External = external;
37+
}
38+
39+
inline operator bool() { return Exists; }
40+
};
41+
1842
class XRCORE_API CLocatorAPI
1943
{
2044
friend class FS_Path;
@@ -69,7 +93,8 @@ class XRCORE_API CLocatorAPI
6993
xrCriticalSection m_auth_lock;
7094
u64 m_auth_code;
7195

72-
void Register(LPCSTR name, u32 vfs, u32 crc, u32 ptr, u32 size_real, u32 size_compressed, u32 modif);
96+
const file* RegisterExternal(const char* name);
97+
const file* Register(LPCSTR name, u32 vfs, u32 crc, u32 ptr, u32 size_real, u32 size_compressed, u32 modif);
7398
void ProcessArchive(LPCSTR path);
7499
void ProcessOne(LPCSTR path, const _finddata_t& entry);
75100
bool Recurse(LPCSTR path);
@@ -136,11 +161,13 @@ class XRCORE_API CLocatorAPI
136161
IWriter* w_open_ex(LPCSTR initial, LPCSTR N);
137162
IC IWriter* w_open_ex(LPCSTR N) { return w_open_ex(0, N); }
138163
void w_close(IWriter*& S);
164+
// For registered files only
165+
const file* GetFileDesc(const char* path);
139166

140-
const file* exist(LPCSTR N);
141-
const file* exist(LPCSTR path, LPCSTR name);
142-
const file* exist(string_path& fn, LPCSTR path, LPCSTR name);
143-
const file* exist(string_path& fn, LPCSTR path, LPCSTR name, LPCSTR ext);
167+
FileStatus exist(LPCSTR N, FSType fsType = FSType::Virtual);
168+
FileStatus exist(LPCSTR path, LPCSTR name, FSType fsType = FSType::Virtual);
169+
FileStatus exist(string_path& fn, LPCSTR path, LPCSTR name, FSType fsType = FSType::Virtual);
170+
FileStatus exist(string_path& fn, LPCSTR path, LPCSTR name, LPCSTR ext, FSType fsType = FSType::Virtual);
144171

145172
BOOL can_write_to_folder(LPCSTR path);
146173
BOOL can_write_to_alias(LPCSTR path);

src/xrCore/stdafx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "xrCore.h"
1212
#include "xrCore_platform.h"
13+
#include "Common/Util.hpp"
1314
//.#include "../../Include/xrAPI/xrAPI.h"
1415
#endif
1516

src/xrGame/fs_registrator_script.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ void fs_registrator::script_register(lua_State *L)
189189
.def_readonly("size_compressed", &CLocatorAPI::file::size_compressed)
190190
.def_readonly("modif", &CLocatorAPI::file::modif),
191191

192+
class_<FileStatus>("FileStatus")
193+
.def_readonly("Exists", &FileStatus::Exists)
194+
.def_readonly("External", &FileStatus::External),
192195

193196
class_<CLocatorAPI>("FS")
194197
.enum_("FS_sort_mode")
@@ -207,6 +210,12 @@ void fs_registrator::script_register(lua_State *L)
207210
value("FS_ClampExt", int(FS_ClampExt)),
208211
value("FS_RootOnly", int(FS_RootOnly))
209212
]
213+
.enum_("FSType")
214+
[
215+
value("FSType_Virtual", int(FSType::Virtual)),
216+
value("FSType_External", int(FSType::External)),
217+
value("FSType_Any", int(FSType::Any))
218+
]
210219
.def("path_exist", &CLocatorAPI::path_exist)
211220
.def("update_path", &update_path_script)
212221
.def("get_path", &CLocatorAPI::get_path)
@@ -222,8 +231,8 @@ void fs_registrator::script_register(lua_State *L)
222231
.def("file_length", &CLocatorAPI::file_length)
223232
.def("file_copy", &CLocatorAPI::file_copy)
224233

225-
.def("exist", (const CLocatorAPI::file* (CLocatorAPI::*)(LPCSTR)) (&CLocatorAPI::exist))
226-
.def("exist", (const CLocatorAPI::file* (CLocatorAPI::*)(LPCSTR, LPCSTR)) (&CLocatorAPI::exist))
234+
.def("exist", (FileStatus (CLocatorAPI::*)(LPCSTR, FSType))(&CLocatorAPI::exist))
235+
.def("exist", (FileStatus (CLocatorAPI::*)(LPCSTR, LPCSTR, FSType))(&CLocatorAPI::exist))
227236

228237
.def("get_file_age", &CLocatorAPI::get_file_age)
229238
.def("get_file_age_str", &get_file_age_str)

0 commit comments

Comments
 (0)