code review refactoring

This commit is contained in:
ohyzha
2024-12-21 17:11:29 +02:00
parent 9d6756bbad
commit d3750f2b8a
10 changed files with 88 additions and 117 deletions

View File

@@ -7,50 +7,21 @@
#include "ExeAppendedZipResourceLoader.hpp" #include "ExeAppendedZipResourceLoader.hpp"
#include "Base/Logger.hpp" #include "Base/Logger.hpp"
#include "IO/Archive/ArchiveReader.hpp" #include "IO/Archive/ArchiveReader.hpp"
#include "Base/Utils.hpp"
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
namespace OpenVulkano namespace OpenVulkano
{ {
std::string ExeAppendedZipResourceLoader::GetResourcePath(const std::string& resourceName) Array<char> ExeAppendedZipResourceLoader::GetResource(const std::string& resourceName)
{ {
return GetCurrentExecutablePath(); Array<char> zipData = Utils::ReadFile(GetCurrentExecutablePath());
}
Array<char> ExeAppendedZipResourceLoader::GetResource(const std::string& exeName)
{
std::string ext = std::filesystem::path(exeName).extension().string();
if (ext != ".exe" && ext != "")
{
Logger::DATA->debug("Given file {} is not a valid executable", exeName);
return {};
}
std::ifstream ifs(exeName, std::ios::in | std::ios::binary);
if (!ifs.is_open())
{
Logger::DATA->debug("Could not open file {}.", exeName);
return {};
}
ifs.seekg(0, std::ios_base::end);
size_t zipSize = ifs.tellg();
ifs.seekg(0, std::ios_base::beg);
Array<char> zipData(zipSize);
ifs.read(zipData.Data(), zipSize);
ifs.close();
return zipData;
}
std::vector<std::pair<FileDescription, Array<char>>> ExeAppendedZipResourceLoader::GetZipArchiveFiles(const std::string& exePath)
{
Array<char> zipData = GetResource(exePath);
ArchiveReader reader(zipData.Data(), zipData.Size(), nullptr, ArchiveType::ZIP); ArchiveReader reader(zipData.Data(), zipData.Size(), nullptr, ArchiveType::ZIP);
std::vector<std::pair<FileDescription, Array<char>>> filesFromZip; if (auto data = reader.GetFile(resourceName))
while (reader.HasNext())
{ {
filesFromZip.push_back(*reader.GetNextFile()); return data->second;
} }
return filesFromZip; return {};
} }
} }

View File

@@ -16,9 +16,9 @@ namespace OpenVulkano
class ExeAppendedZipResourceLoader : public ResourceLoader class ExeAppendedZipResourceLoader : public ResourceLoader
{ {
public: public:
std::string GetResourcePath(const std::string& resourceName) override; std::string GetResourcePath(const std::string& resourceName) final { return ""; }
Array<char> GetResource(const std::string& exePath) override; Array<char> GetResource(const std::string& resourceName) override;
std::vector<std::pair<FileDescription, Array<char>>> GetZipArchiveFiles(const std::string& exePath); protected:
virtual std::string GetCurrentExecutablePath() const = 0; virtual std::string GetCurrentExecutablePath() const = 0;
}; };
} }

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "ExeAppendedZipLoaderLinux.hpp" #include "ExeAppendedZipResourceLoaderLinux.hpp"
#include <unistd.h> #include <unistd.h>
#include <climits> #include <climits>
@@ -12,19 +12,15 @@ namespace OpenVulkano
{ {
namespace namespace
{ {
void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique<ExeAppendedZipLoaderLinux>()); void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique<ExeAppendedZipResourceLoaderLinux>());
} }
std::string OpenVulkano::ExeAppendedZipLoaderLinux::GetCurrentExecutablePath() const std::string OpenVulkano::ExeAppendedZipResourceLoaderLinux::GetCurrentExecutablePath() const
{ {
char dest[PATH_MAX]; std::string path(PATH_MAX, '\0');
memset(dest, 0, sizeof(dest)); // readlink does not null terminate! ssize_t sz = readlink("/proc/self/exe", path.data(), path.capacity()));
size_t sz = 0; path.resize(std::max<ssize_t>(0, sz));
if ((sz = readlink("/proc/self/exe", dest, PATH_MAX)) != -1) return path;
{
return std::string(dest, sz);
}
return "";
} }
} }

View File

@@ -6,11 +6,11 @@
#pragma once #pragma once
#include "Host/ExeAppendedZipLoader.hpp" #include "Host/ExeAppendedZipResourceLoader.hpp"
namespace OpenVulkano namespace OpenVulkano
{ {
class ExeAppendedZipLoaderLinux final : public ExeAppendedZipLoader class ExeAppendedZipResourceLoaderLinux final : public ExeAppendedZipResourceLoader
{ {
public: public:
std::string GetCurrentExecutablePath() const override; std::string GetCurrentExecutablePath() const override;

View File

@@ -16,9 +16,10 @@ namespace OpenVulkano
std::string OpenVulkano::ExeAppendedZipResourceLoaderWindows::GetCurrentExecutablePath() const std::string OpenVulkano::ExeAppendedZipResourceLoaderWindows::GetCurrentExecutablePath() const
{ {
CHAR nameBuf[MAX_PATH] = {}; std::string exe(MAX_PATH, '\0');
DWORD len = GetModuleFileNameA(NULL, nameBuf, MAX_PATH); DWORD len = GetModuleFileNameA(NULL, exe.data(), MAX_PATH);
return std::string(nameBuf, len); exe.resize(std::max<size_t>(len, exe.size()));
return exe;
} }
} }

View File

@@ -20,21 +20,21 @@ namespace OpenVulkano
constexpr int BUFFER_SIZE = 16384; constexpr int BUFFER_SIZE = 16384;
} }
ArchiveReader::ArchiveReader(const std::shared_ptr<spdlog::logger>& logger, ArchiveType::Type archiveType) ArchiveReader::ArchiveReader(const std::shared_ptr<spdlog::logger>& logger, std::optional<ArchiveType::Type> archiveType)
: ArchiveBase(archive_read_new(), nullptr, logger), m_archiveType(archiveType) : ArchiveBase(archive_read_new(), nullptr, logger), m_archiveType(archiveType)
{} {}
ArchiveReader::ArchiveReader(const std::string& archiveFile, const std::shared_ptr<spdlog::logger>& logger, ArchiveType::Type archiveType) ArchiveReader::ArchiveReader(const std::string& archiveFile, const std::shared_ptr<spdlog::logger>& logger, std::optional<ArchiveType::Type> archiveType)
: ArchiveReader(archiveFile.c_str(), logger, archiveType) : ArchiveReader(archiveFile.c_str(), logger, archiveType)
{} {}
ArchiveReader::ArchiveReader(const char* archiveFile, const std::shared_ptr<spdlog::logger>& logger, ArchiveType::Type archiveType) ArchiveReader::ArchiveReader(const char* archiveFile, const std::shared_ptr<spdlog::logger>& logger, std::optional<ArchiveType::Type> archiveType)
: ArchiveReader(logger, archiveType) : ArchiveReader(logger, archiveType)
{ {
Open(archiveFile); Open(archiveFile);
} }
ArchiveReader::ArchiveReader(const void* archiveBuffer, const size_t size, const std::shared_ptr<spdlog::logger>& logger, ArchiveType::Type archiveType) ArchiveReader::ArchiveReader(const void* archiveBuffer, const size_t size, const std::shared_ptr<spdlog::logger>& logger, std::optional<ArchiveType::Type> archiveType)
: ArchiveReader(logger, archiveType) : ArchiveReader(logger, archiveType)
{ {
OpenMemory(archiveBuffer, size); OpenMemory(archiveBuffer, size);
@@ -51,32 +51,7 @@ namespace OpenVulkano
m_archive = archive_read_new(); m_archive = archive_read_new();
} }
ChkErr(archive_read_support_filter_all(m_archive)); ChkErr(archive_read_support_filter_all(m_archive));
std::function<int(archive*)> pFunc; std::function<int(archive*)> pFunc = GetCurrentFormatReadFunc();
switch (m_archiveType)
{
case ArchiveType::ZIP:
pFunc = archive_read_support_format_zip;
break;
case ArchiveType::SEVEN_ZIP:
pFunc = archive_read_support_format_7zip;
break;
case ArchiveType::CPIO:
pFunc = archive_read_support_format_cpio;
break;
case ArchiveType::ISO:
pFunc = archive_read_support_format_iso9660;
case ArchiveType::TAR:
pFunc = archive_read_support_format_tar;
break;
case ArchiveType::WARC:
pFunc = archive_read_support_format_warc;
break;
case ArchiveType::XAR:
pFunc = archive_read_support_format_xar;
break;
default:
pFunc = archive_read_support_format_all;
}
ChkErr(pFunc(m_archive)); ChkErr(pFunc(m_archive));
m_open = true; m_open = true;
} }
@@ -182,6 +157,33 @@ namespace OpenVulkano
} }
} }
std::function<int(archive*)> ArchiveReader::GetCurrentFormatReadFunc() const
{
if (!m_archiveType)
{
return archive_read_support_format_all;
}
ArchiveType::Type type = *m_archiveType;
switch (type)
{
case ArchiveType::ZIP:
return archive_read_support_format_zip;
case ArchiveType::SEVEN_ZIP:
return archive_read_support_format_7zip;
case ArchiveType::CPIO:
return archive_read_support_format_cpio;
case ArchiveType::ISO:
return archive_read_support_format_iso9660;
case ArchiveType::TAR:
return archive_read_support_format_tar;
case ArchiveType::WARC:
return archive_read_support_format_warc;
case ArchiveType::XAR:
return archive_read_support_format_xar;
}
return archive_read_support_format_all;
}
size_t ArchiveReader::ExtractRemaining(std::string_view targetDir) size_t ArchiveReader::ExtractRemaining(std::string_view targetDir)
{ {
size_t count = 0; size_t count = 0;
@@ -289,6 +291,19 @@ namespace OpenVulkano
return std::nullopt; return std::nullopt;
} }
std::optional<std::pair<FileDescription, Array<char>>> ArchiveReader::GetFile(const std::string& path)
{
while (HasNext())
{
const std::pair<FileDescription, Array<char>> info = *GetNextFile();
if (info.first.path == path)
{
return info;
}
}
return {};
}
bool ArchiveReader::GetNextFileAsStream(const std::function<void(const FileDescription&, std::istream&)>& streamReader) bool ArchiveReader::GetNextFileAsStream(const std::function<void(const FileDescription&, std::istream&)>& streamReader)
{ {
if (SkipTill(std::filesystem::file_type::regular)) if (SkipTill(std::filesystem::file_type::regular))

View File

@@ -21,17 +21,17 @@ namespace OpenVulkano
{ {
bool m_open = false; bool m_open = false;
bool m_eof = false; bool m_eof = false;
ArchiveType::Type m_archiveType; std::optional<ArchiveType::Type> m_archiveType;
std::queue<std::string> m_archivesToRead; std::queue<std::string> m_archivesToRead;
public: public:
explicit ArchiveReader(const std::shared_ptr<spdlog::logger>& logger = nullptr, ArchiveType::Type archiveType = ArchiveType::ANY); explicit ArchiveReader(const std::shared_ptr<spdlog::logger>& logger = nullptr, std::optional<ArchiveType::Type> archiveType = std::nullopt);
explicit ArchiveReader(const char* archiveFile, const std::shared_ptr<spdlog::logger>& logger = nullptr, ArchiveType::Type archiveType = ArchiveType::ANY); explicit ArchiveReader(const char* archiveFile, const std::shared_ptr<spdlog::logger>& logger = nullptr, std::optional<ArchiveType::Type> archiveType = std::nullopt);
explicit ArchiveReader(const std::string& archiveFile, const std::shared_ptr<spdlog::logger>& logger = nullptr, ArchiveType::Type archiveType = ArchiveType::ANY); explicit ArchiveReader(const std::string& archiveFile, const std::shared_ptr<spdlog::logger>& logger = nullptr, std::optional<ArchiveType::Type> archiveType = std::nullopt);
ArchiveReader(const void* archiveBuffer, size_t size, const std::shared_ptr<spdlog::logger>& logger = nullptr, ArchiveType::Type archiveType = ArchiveType::ANY); ArchiveReader(const void* archiveBuffer, size_t size, const std::shared_ptr<spdlog::logger>& logger = nullptr, std::optional<ArchiveType::Type> archiveType = std::nullopt);
~ArchiveReader() override; ~ArchiveReader() override;
@@ -66,13 +66,15 @@ namespace OpenVulkano
std::optional<std::pair<FileDescription, std::vector<char>>> GetNextFileAsVector(); std::optional<std::pair<FileDescription, std::vector<char>>> GetNextFileAsVector();
std::optional<std::pair<FileDescription, Array<char>>> GetFile(const std::string& path);
std::optional<FileDescription> StreamNextFile(std::ostream& stream); std::optional<FileDescription> StreamNextFile(std::ostream& stream);
bool GetNextFileAsStream(const std::function<void(const FileDescription&, std::istream&)>& streamReader); bool GetNextFileAsStream(const std::function<void(const FileDescription&, std::istream&)>& streamReader);
private: private:
void ReadNextHeader(); void ReadNextHeader();
std::function<int(archive*)> GetCurrentFormatReadFunc() const;
void PrepOpen(); void PrepOpen();
}; };
} }

View File

@@ -17,7 +17,7 @@ namespace OpenVulkano
static inline constexpr std::string_view TYPE_NAMES[] = { ".tar", ".cpio", ".iso", ".zip", ".xar", ".7z", ".warc", ".shar" }; static inline constexpr std::string_view TYPE_NAMES[] = { ".tar", ".cpio", ".iso", ".zip", ".xar", ".7z", ".warc", ".shar" };
public: public:
enum Type { TAR = 0, CPIO, ISO, ZIP, XAR, SEVEN_ZIP, WARC, SHAR, ANY }; enum Type { TAR = 0, CPIO, ISO, ZIP, XAR, SEVEN_ZIP, WARC, SHAR };
constexpr ArchiveType(Type type) : m_type(type) {} constexpr ArchiveType(Type type) : m_type(type) {}

View File

@@ -12,7 +12,7 @@ if (NOT ENABLE_CURL)
endif() endif()
if (APPLE) if (APPLE)
list(FILTER SOURCES EXCLUDE REGEX "ExeAppendedZipLoader") list(FILTER SOURCES EXCLUDE REGEX "ExeAppendedZipResourceLoader")
endif() endif()
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SOURCES}) source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SOURCES})
@@ -21,7 +21,7 @@ list(APPEND SOURCES ${RESOURCES})
add_executable(OpenVulkano_Tests ${SOURCES}) add_executable(OpenVulkano_Tests ${SOURCES})
# append zip file at the end of executable file # append zip file at the end of executable file
if (WIN32 OR (LINUX AND NOT APPLE)) if (WIN32 OR LINUX)
set(ZIP_FILE ${ROOT_FOLDER}/resources/arch.zip) set(ZIP_FILE ${ROOT_FOLDER}/resources/arch.zip)
add_custom_command(TARGET OpenVulkano_Tests POST_BUILD COMMAND ${CMAKE_COMMAND} -E cat ${ZIP_FILE} >> $<TARGET_FILE:OpenVulkano_Tests>) add_custom_command(TARGET OpenVulkano_Tests POST_BUILD COMMAND ${CMAKE_COMMAND} -E cat ${ZIP_FILE} >> $<TARGET_FILE:OpenVulkano_Tests>)
endif() endif()

View File

@@ -7,9 +7,9 @@
#include <catch2/catch_all.hpp> #include <catch2/catch_all.hpp>
#ifdef _WIN32 #ifdef _WIN32
#include "Host/Windows/ExeAppendedZipLoaderWindows.hpp" #include "Host/Windows/ExeAppendedZipResourceLoaderWindows.hpp"
#else #else
#include "Host/Linux/ExeAppendedZipLoaderLinux.hpp" #include "Host/Linux/ExeAppendedZipResourceLoaderLinux.hpp"
#endif #endif
#include "Base/Logger.hpp" #include "Base/Logger.hpp"
@@ -23,30 +23,16 @@ TEST_CASE("Load zip from exe")
{ {
Logger::SetupLogger("", "tests.log"); Logger::SetupLogger("", "tests.log");
#ifdef _WIN32 #ifdef _WIN32
ExeAppendedZipLoaderWindows loader; ExeAppendedZipResourceLoaderWindows loader;
#else #else
ExeAppendedZipLoaderLinux loader; ExeAppendedZipResourceLoaderLinux loader;
#endif #endif
Array<char> zipData = loader.GetResource(loader.GetCurrentExecutablePath()); auto iconData = loader.GetResource("madvoxel_icon.ico");
REQUIRE(!zipData.Empty()); REQUIRE(!iconData.Empty());
auto files = loader.GetZipArchiveFiles(loader.GetCurrentExecutablePath()); auto txtFile = loader.GetResource("text.txt");
REQUIRE(files.size() == 2); REQUIRE(!txtFile.Empty());
int i = 0;
for (const auto& [fileDesc, fileData] : files)
{
if (i == 0)
{
REQUIRE(fileDesc.path == "madvoxel_icon.ico");
}
else if (i == 1)
{
REQUIRE(fileDesc.path == "text.txt");
std::string s(fileData.Data(), fileData.Size());
REQUIRE(s == "Hello world!");
}
i++;
}
std::string s(txtFile.Data(), txtFile.Size());
REQUIRE(s == "Hello world!");
} }