implement appended zip loader for executable
This commit is contained in:
56
openVulkanoCpp/Host/ExeAppendedZipLoader.cpp
Normal file
56
openVulkanoCpp/Host/ExeAppendedZipLoader.cpp
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ExeAppendedZipLoader.hpp"
|
||||||
|
#include "Base/Logger.hpp"
|
||||||
|
#include "IO/Archive/ArchiveReader.hpp"
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
namespace OpenVulkano
|
||||||
|
{
|
||||||
|
std::string ExeAppendedZipLoader::GetResourcePath(const std::string& resourceName)
|
||||||
|
{
|
||||||
|
return GetCurrentExecutablePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<char> ExeAppendedZipLoader::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>>> ExeAppendedZipLoader::GetZipArchiveFiles(const std::string& exePath)
|
||||||
|
{
|
||||||
|
Array<char> zipData = GetResource(exePath);
|
||||||
|
ArchiveReader reader(zipData.Data(), zipData.Size(), nullptr, ArchiveType::ZIP);
|
||||||
|
std::vector<std::pair<FileDescription, Array<char>>> filesFromZip;
|
||||||
|
while (reader.HasNext())
|
||||||
|
{
|
||||||
|
filesFromZip.push_back(*reader.GetNextFile());
|
||||||
|
}
|
||||||
|
return filesFromZip;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
24
openVulkanoCpp/Host/ExeAppendedZipLoader.hpp
Normal file
24
openVulkanoCpp/Host/ExeAppendedZipLoader.hpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Host/ResourceLoader.hpp"
|
||||||
|
#include "IO/FileDescription.hpp"
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace OpenVulkano
|
||||||
|
{
|
||||||
|
class ExeAppendedZipLoader : public ResourceLoader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string GetResourcePath(const std::string& resourceName) override;
|
||||||
|
Array<char> GetResource(const std::string& exePath) override;
|
||||||
|
std::vector<std::pair<FileDescription, Array<char>>> GetZipArchiveFiles(const std::string& exePath);
|
||||||
|
virtual std::string GetCurrentExecutablePath() const = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
30
openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.cpp
Normal file
30
openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.cpp
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ExeAppendedZipLoaderLinux.hpp"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
|
namespace OpenVulkano
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique<ExeAppendedZipLoaderLinux>());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string OpenVulkano::ExeAppendedZipLoaderLinux::GetCurrentExecutablePath() const
|
||||||
|
{
|
||||||
|
char dest[PATH_MAX];
|
||||||
|
memset(dest, 0, sizeof(dest)); // readlink does not null terminate!
|
||||||
|
size_t sz = 0;
|
||||||
|
if ((sz = readlink("/proc/self/exe", dest, PATH_MAX)) != -1)
|
||||||
|
{
|
||||||
|
return std::string(dest, sz);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
18
openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.hpp
Normal file
18
openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.hpp
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Host/ExeAppendedZipLoader.hpp"
|
||||||
|
|
||||||
|
namespace OpenVulkano
|
||||||
|
{
|
||||||
|
class ExeAppendedZipLoaderLinux final : public ExeAppendedZipLoader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string GetCurrentExecutablePath() const override;
|
||||||
|
};
|
||||||
|
}
|
||||||
24
openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.cpp
Normal file
24
openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.cpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ExeAppendedZipLoaderWindows.hpp"
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
namespace OpenVulkano
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique<ExeAppendedZipLoaderWindows>());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string OpenVulkano::ExeAppendedZipLoaderWindows::GetCurrentExecutablePath() const
|
||||||
|
{
|
||||||
|
CHAR nameBuf[MAX_PATH] = {};
|
||||||
|
DWORD len = GetModuleFileNameA(NULL, nameBuf, MAX_PATH);
|
||||||
|
return std::string(nameBuf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
18
openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.hpp
Normal file
18
openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.hpp
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Host/ExeAppendedZipLoader.hpp"
|
||||||
|
|
||||||
|
namespace OpenVulkano
|
||||||
|
{
|
||||||
|
class ExeAppendedZipLoaderWindows final : public ExeAppendedZipLoader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string GetCurrentExecutablePath() const override;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -10,11 +10,22 @@ FilterPlatformPaths(SOURCES)
|
|||||||
if (NOT ENABLE_CURL)
|
if (NOT ENABLE_CURL)
|
||||||
list(FILTER SOURCES EXCLUDE REGEX "WebResourceLoader")
|
list(FILTER SOURCES EXCLUDE REGEX "WebResourceLoader")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
list(FILTER SOURCES EXCLUDE REGEX "ExeAppendedZipLoader")
|
||||||
|
endif()
|
||||||
|
|
||||||
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SOURCES})
|
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SOURCES})
|
||||||
file(GLOB_RECURSE RESOURCES "${ROOT_FOLDER}/resources/*.rc" "${ROOT_FOLDER}/resources/*.h")
|
file(GLOB_RECURSE RESOURCES "${ROOT_FOLDER}/resources/*.rc" "${ROOT_FOLDER}/resources/*.h")
|
||||||
list(APPEND SOURCES ${RESOURCES})
|
list(APPEND SOURCES ${RESOURCES})
|
||||||
add_executable(OpenVulkano_Tests ${SOURCES})
|
add_executable(OpenVulkano_Tests ${SOURCES})
|
||||||
|
|
||||||
|
# append zip file at the end of executable file
|
||||||
|
if (WIN32 OR (LINUX AND NOT APPLE))
|
||||||
|
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>)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_include_directories(OpenVulkano_Tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
target_include_directories(OpenVulkano_Tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
target_include_directories(OpenVulkano_Tests PRIVATE openVulkanoCpp)
|
target_include_directories(OpenVulkano_Tests PRIVATE openVulkanoCpp)
|
||||||
|
|||||||
52
tests/Host/ExeAppendedZipLoaderTests.cpp
Normal file
52
tests/Host/ExeAppendedZipLoaderTests.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <catch2/catch_all.hpp>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "Host/Windows/ExeAppendedZipLoaderWindows.hpp"
|
||||||
|
#else
|
||||||
|
#include "Host/Linux/ExeAppendedZipLoaderLinux.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Base/Logger.hpp"
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
using namespace OpenVulkano;
|
||||||
|
|
||||||
|
TEST_CASE("Load zip from exe")
|
||||||
|
{
|
||||||
|
Logger::SetupLogger("", "tests.log");
|
||||||
|
#ifdef _WIN32
|
||||||
|
ExeAppendedZipLoaderWindows loader;
|
||||||
|
#else
|
||||||
|
ExeAppendedZipLoaderLinux loader;
|
||||||
|
#endif
|
||||||
|
Array<char> zipData = loader.GetResource(loader.GetCurrentExecutablePath());
|
||||||
|
REQUIRE(!zipData.Empty());
|
||||||
|
|
||||||
|
auto files = loader.GetZipArchiveFiles(loader.GetCurrentExecutablePath());
|
||||||
|
REQUIRE(files.size() == 2);
|
||||||
|
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user