Core/VirtualDirectory: Add GetFileContent method
This commit is contained in:
parent
5f389ef0a4
commit
df55a02fa7
|
|
@ -44,6 +44,7 @@ namespace Nz
|
|||
template<typename F> void Foreach(F&& callback, bool includeDots = false);
|
||||
|
||||
template<typename F> bool GetEntry(std::string_view path, F&& callback);
|
||||
template<typename F> bool GetFileContent(std::string_view path, F&& callback);
|
||||
|
||||
inline DirectoryEntry& StoreDirectory(std::string_view path, VirtualDirectoryPtr directory);
|
||||
inline PhysicalDirectoryEntry& StoreDirectory(std::string_view path, std::filesystem::path directoryPath);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/VirtualDirectory.hpp>
|
||||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Core/StringExt.hpp>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
|
@ -153,6 +154,45 @@ namespace Nz
|
|||
});
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
bool VirtualDirectory::GetFileContent(std::string_view path, F&& callback)
|
||||
{
|
||||
return GetEntry(path, [&](const Entry& entry)
|
||||
{
|
||||
return std::visit([&](auto&& entry)
|
||||
{
|
||||
using T = std::decay_t<decltype(entry)>;
|
||||
|
||||
using P1 = const void*;
|
||||
using P2 = std::size_t;
|
||||
|
||||
if constexpr (std::is_same_v<T, DataPointerEntry>)
|
||||
{
|
||||
return CallbackReturn(callback, static_cast<P1>(entry.data), SafeCast<P2>(entry.size));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, FileContentEntry>)
|
||||
{
|
||||
return CallbackReturn(callback, static_cast<P1>(entry.data.data()), SafeCast<P2>(entry.data.size()));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, PhysicalFileEntry>)
|
||||
{
|
||||
std::optional<std::vector<UInt8>> source = File::ReadWhole(entry.filePath);
|
||||
if (!source.has_value())
|
||||
return false;
|
||||
|
||||
return CallbackReturn(callback, static_cast<P1>(source->data()), SafeCast<P2>(source->size()));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, DirectoryEntry> || std::is_same_v<T, PhysicalDirectoryEntry>)
|
||||
{
|
||||
NazaraError("entry is a directory");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
static_assert(AlwaysFalse<T>(), "incomplete visitor");
|
||||
}, entry);
|
||||
});
|
||||
}
|
||||
|
||||
inline auto VirtualDirectory::StoreDirectory(std::string_view path, VirtualDirectoryPtr directory) -> DirectoryEntry&
|
||||
{
|
||||
assert(!path.empty());
|
||||
|
|
|
|||
|
|
@ -105,8 +105,21 @@ TEST_CASE("VirtualDirectory", "[Core][VirtualDirectory]")
|
|||
}
|
||||
|
||||
const auto& contentEntry = std::get<Nz::VirtualDirectory::FileContentEntry>(entry);
|
||||
CHECK(std::equal(expectedData.begin(), expectedData.end(), contentEntry.data.begin(), contentEntry.data.end()));
|
||||
return true;
|
||||
return std::equal(expectedData.begin(), expectedData.end(), contentEntry.data.begin(), contentEntry.data.end());
|
||||
});
|
||||
};
|
||||
|
||||
auto CheckFileContent = [&](std::string_view path, const std::vector<Nz::UInt8>& expectedData)
|
||||
{
|
||||
return virtualDir->GetFileContent(path, [&](const void* data, std::size_t size)
|
||||
{
|
||||
if (expectedData.size() != size)
|
||||
{
|
||||
FAIL("size doesn't match");
|
||||
return false;
|
||||
}
|
||||
|
||||
return std::memcmp(expectedData.data(), data, expectedData.size()) == 0;
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -118,6 +131,7 @@ TEST_CASE("VirtualDirectory", "[Core][VirtualDirectory]")
|
|||
WHEN("We retrieve it")
|
||||
{
|
||||
CHECK(CheckFile("File.bin", randomData));
|
||||
CHECK(CheckFileContent("File.bin", randomData));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -165,6 +179,8 @@ TEST_CASE("VirtualDirectory", "[Core][VirtualDirectory]")
|
|||
{
|
||||
INFO("Retrieving " << file.path);
|
||||
CHECK(CheckFile(file.path, file.data));
|
||||
INFO("Retrieving " << file.path << " using GetFileContent");
|
||||
CHECK(CheckFileContent(file.path, file.data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -208,6 +224,20 @@ TEST_CASE("VirtualDirectory", "[Core][VirtualDirectory]")
|
|||
});
|
||||
};
|
||||
|
||||
auto CheckFileContentHash = [&](const char* filepath, const char* expectedHash)
|
||||
{
|
||||
return virtualDir->GetFileContent(filepath, [&](const void* data, std::size_t size)
|
||||
{
|
||||
Nz::SHA256Hash hash;
|
||||
WHEN("We compute " << hash.GetHashName() << " of " << filepath << " file")
|
||||
{
|
||||
hash.Begin();
|
||||
hash.Append(static_cast<const Nz::UInt8*>(data), size);
|
||||
CHECK(Nz::ToUpper(hash.End().ToHex()) == expectedHash);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
WHEN("Accessing files")
|
||||
{
|
||||
CHECK(CheckFileHash("Logo.png", "5C4B9387327C039A6CE9ED51983D6C2ADA9F9DD01D024C2D5D588237ADFC7423"));
|
||||
|
|
@ -244,6 +274,8 @@ TEST_CASE("VirtualDirectory", "[Core][VirtualDirectory]")
|
|||
virtualDir->StoreFile("Logo.png", GetResourceDir() / "ambience.ogg");
|
||||
CHECK(CheckFileHash("ambience.ogg", "49C486F44E43F023D54C9F375D902C21375DDB2748D3FA1863C9581D30E17F94"));
|
||||
CHECK(CheckFileHash("Logo.png", "49C486F44E43F023D54C9F375D902C21375DDB2748D3FA1863C9581D30E17F94"));
|
||||
CHECK(CheckFileContentHash("ambience.ogg", "49C486F44E43F023D54C9F375D902C21375DDB2748D3FA1863C9581D30E17F94"));
|
||||
CHECK(CheckFileContentHash("Logo.png", "49C486F44E43F023D54C9F375D902C21375DDB2748D3FA1863C9581D30E17F94"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue