mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-15 00:11:55 +07:00
vfs: trace, extract
This commit is contained in:
@@ -30,6 +30,7 @@ namespace e2d
|
||||
virtual input_stream_uptr open(str_view path) const = 0;
|
||||
virtual std::pair<buffer,bool> load(str_view path) const = 0;
|
||||
virtual output_stream_uptr write(str_view path, bool append) const = 0;
|
||||
virtual bool trace(str_view path, filesystem::trace_func func) const = 0;
|
||||
};
|
||||
using file_source_uptr = std::unique_ptr<file_source>;
|
||||
|
||||
@@ -47,6 +48,10 @@ namespace e2d
|
||||
output_stream_uptr write(const url& url, bool append) const;
|
||||
std::future<std::pair<buffer,bool>> load_async(const url& url) const;
|
||||
|
||||
template < typename Iter >
|
||||
bool extract(const url& url, Iter result_iter) const;
|
||||
bool trace(const url& url, filesystem::trace_func func) const;
|
||||
|
||||
url resolve_scheme_aliases(const url& url) const;
|
||||
private:
|
||||
class state;
|
||||
@@ -62,6 +67,7 @@ namespace e2d
|
||||
input_stream_uptr open(str_view path) const final;
|
||||
std::pair<buffer,bool> load(str_view path) const final;
|
||||
output_stream_uptr write(str_view path, bool append) const final;
|
||||
bool trace(str_view path, filesystem::trace_func func) const final;
|
||||
private:
|
||||
class state;
|
||||
std::unique_ptr<state> state_;
|
||||
@@ -76,6 +82,7 @@ namespace e2d
|
||||
input_stream_uptr open(str_view path) const final;
|
||||
std::pair<buffer,bool> load(str_view path) const final;
|
||||
output_stream_uptr write(str_view path, bool append) const final;
|
||||
bool trace(str_view path, filesystem::trace_func func) const final;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -87,4 +94,12 @@ namespace e2d
|
||||
scheme,
|
||||
std::make_unique<T>(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template < typename Iter >
|
||||
bool vfs::extract(const url& url, Iter result_iter) const {
|
||||
return trace(url, [&result_iter](str_view filename, bool directory){
|
||||
*result_iter++ = std::pair<str,bool>{filename, directory};
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,6 +173,14 @@ namespace e2d
|
||||
}, open(url));
|
||||
}
|
||||
|
||||
bool vfs::trace(const url& url, filesystem::trace_func func) const {
|
||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||
return state_->with_file_source(url,
|
||||
[&func](const file_source_uptr& source, const str& path) {
|
||||
return source->trace(path, func);
|
||||
}, false);
|
||||
}
|
||||
|
||||
url vfs::resolve_scheme_aliases(const url& url) const {
|
||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||
return state_->resolve_url(url);
|
||||
@@ -276,6 +284,46 @@ namespace e2d
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool archive_file_source::trace(str_view path, filesystem::trace_func func) const {
|
||||
str parent = make_utf8(path);
|
||||
if ( !parent.empty() ) {
|
||||
if ( parent.back() != '/' ) {
|
||||
parent += '/';
|
||||
}
|
||||
mz_uint32 dir_index = 0;
|
||||
if ( !mz_zip_reader_locate_file_v2(
|
||||
state_->archive.get(),
|
||||
parent.c_str(),
|
||||
nullptr,
|
||||
MZ_ZIP_FLAG_CASE_SENSITIVE,
|
||||
&dir_index) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
mz_zip_archive_file_stat dir_stat;
|
||||
if ( !mz_zip_reader_file_stat(
|
||||
state_->archive.get(),
|
||||
dir_index, &dir_stat) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( !dir_stat.m_is_directory ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
mz_uint num_files = mz_zip_reader_get_num_files(state_->archive.get());
|
||||
for ( mz_uint i = 0; i < num_files; ++i ) {
|
||||
mz_zip_archive_file_stat file_stat;
|
||||
if ( mz_zip_reader_file_stat(state_->archive.get(), i, &file_stat) ) {
|
||||
const str_view filename{file_stat.m_filename};
|
||||
if ( filename.length() > parent.length() && filename.starts_with(parent) ) {
|
||||
func(file_stat.m_filename, file_stat.m_is_directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// filesystem_file_source
|
||||
//
|
||||
@@ -308,4 +356,8 @@ namespace e2d
|
||||
}
|
||||
return make_write_file(path, append);
|
||||
}
|
||||
|
||||
bool filesystem_file_source::trace(str_view path, filesystem::trace_func func) const {
|
||||
return filesystem::trace_directory_recursive(path, func);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c72ff0ca4cd5c914d557f6e1c08c1f63f7d4da3339c15f1c2b5def5fe13d32d2
|
||||
size 440
|
||||
oid sha256:7f9dbd20a52c39630253723d3e5c0f478c8cd70de48048966c0ca5becaa97fe3
|
||||
size 1423
|
||||
|
||||
@@ -78,6 +78,49 @@ TEST_CASE("vfs"){
|
||||
|
||||
REQUIRE_FALSE(v.exists({"archive", "test2.txt"}));
|
||||
REQUIRE_FALSE(v.exists({"archive", "folder/file2.txt"}));
|
||||
{
|
||||
vector<std::pair<str,bool>> result;
|
||||
REQUIRE(v.extract(url("archive://"), std::back_inserter(result)));
|
||||
REQUIRE(result == vector<std::pair<str, bool>>{
|
||||
{"folder/", true},
|
||||
{"folder/file.txt", false},
|
||||
{"test.txt", false},
|
||||
{"folder/subfolder/", true},
|
||||
{"folder/subfolder/file.txt", false},
|
||||
{"folder2/", true},
|
||||
{"folder2/file.txt", false},
|
||||
{"folder2/subfolder2/", true},
|
||||
{"folder2/subfolder2/file.txt", false}
|
||||
});
|
||||
}
|
||||
{
|
||||
vector<std::pair<str,bool>> result;
|
||||
REQUIRE(v.extract(url("archive://folder"), std::back_inserter(result)));
|
||||
REQUIRE(result == vector<std::pair<str, bool>>{
|
||||
{"folder/file.txt", false},
|
||||
{"folder/subfolder/", true},
|
||||
{"folder/subfolder/file.txt", false}
|
||||
});
|
||||
}
|
||||
{
|
||||
vector<std::pair<str,bool>> result;
|
||||
REQUIRE(v.extract(url("archive://folder2/subfolder2"), std::back_inserter(result)));
|
||||
REQUIRE(result == vector<std::pair<str, bool>>{
|
||||
{"folder2/subfolder2/file.txt", false}
|
||||
});
|
||||
}
|
||||
{
|
||||
vector<std::pair<str,bool>> result, result2;
|
||||
REQUIRE(v.extract(url("archive://folder"), std::back_inserter(result)));
|
||||
REQUIRE(v.extract(url("archive://folder/"), std::back_inserter(result2)));
|
||||
REQUIRE(result == result2);
|
||||
}
|
||||
{
|
||||
vector<std::pair<str,bool>> result;
|
||||
REQUIRE_FALSE(v.extract(url("archive://fold"), std::back_inserter(result)));
|
||||
REQUIRE_FALSE(v.extract(url("archive://folder3"), std::back_inserter(result)));
|
||||
REQUIRE_FALSE(v.extract(url("archive://test.txt"), std::back_inserter(result)));
|
||||
}
|
||||
{
|
||||
auto f = v.open(url("archive://test.txt"));
|
||||
REQUIRE(f);
|
||||
|
||||
Reference in New Issue
Block a user