mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-16 14:08:59 +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 input_stream_uptr open(str_view path) const = 0;
|
||||||
virtual std::pair<buffer,bool> load(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 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>;
|
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;
|
output_stream_uptr write(const url& url, bool append) const;
|
||||||
std::future<std::pair<buffer,bool>> load_async(const url& url) 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;
|
url resolve_scheme_aliases(const url& url) const;
|
||||||
private:
|
private:
|
||||||
class state;
|
class state;
|
||||||
@@ -62,6 +67,7 @@ namespace e2d
|
|||||||
input_stream_uptr open(str_view path) const final;
|
input_stream_uptr open(str_view path) const final;
|
||||||
std::pair<buffer,bool> load(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;
|
output_stream_uptr write(str_view path, bool append) const final;
|
||||||
|
bool trace(str_view path, filesystem::trace_func func) const final;
|
||||||
private:
|
private:
|
||||||
class state;
|
class state;
|
||||||
std::unique_ptr<state> state_;
|
std::unique_ptr<state> state_;
|
||||||
@@ -76,6 +82,7 @@ namespace e2d
|
|||||||
input_stream_uptr open(str_view path) const final;
|
input_stream_uptr open(str_view path) const final;
|
||||||
std::pair<buffer,bool> load(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;
|
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,
|
scheme,
|
||||||
std::make_unique<T>(std::forward<Args>(args)...));
|
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));
|
}, 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 {
|
url vfs::resolve_scheme_aliases(const url& url) const {
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
return state_->resolve_url(url);
|
return state_->resolve_url(url);
|
||||||
@@ -276,6 +284,46 @@ namespace e2d
|
|||||||
return nullptr;
|
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
|
// filesystem_file_source
|
||||||
//
|
//
|
||||||
@@ -308,4 +356,8 @@ namespace e2d
|
|||||||
}
|
}
|
||||||
return make_write_file(path, append);
|
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
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:c72ff0ca4cd5c914d557f6e1c08c1f63f7d4da3339c15f1c2b5def5fe13d32d2
|
oid sha256:7f9dbd20a52c39630253723d3e5c0f478c8cd70de48048966c0ca5becaa97fe3
|
||||||
size 440
|
size 1423
|
||||||
|
|||||||
@@ -78,6 +78,49 @@ TEST_CASE("vfs"){
|
|||||||
|
|
||||||
REQUIRE_FALSE(v.exists({"archive", "test2.txt"}));
|
REQUIRE_FALSE(v.exists({"archive", "test2.txt"}));
|
||||||
REQUIRE_FALSE(v.exists({"archive", "folder/file2.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"));
|
auto f = v.open(url("archive://test.txt"));
|
||||||
REQUIRE(f);
|
REQUIRE(f);
|
||||||
|
|||||||
Reference in New Issue
Block a user