summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Companion.cpp27
-rw-r--r--src/archive/ZWrapper.cpp39
-rw-r--r--src/archive/ZWrapper.h2
3 files changed, 45 insertions, 23 deletions
diff --git a/src/Companion.cpp b/src/Companion.cpp
index c5c43ae..1f52ac5 100644
--- a/src/Companion.cpp
+++ b/src/Companion.cpp
@@ -184,6 +184,14 @@ static std::string GetTypeNode(YAML::Node& node) {
return type;
}
+static fs::path RelativeTo(const fs::path& path, const fs::path& base) {
+#ifdef __WINRT__
+ return path.lexically_normal().lexically_relative(base.lexically_normal());
+#else
+ return fs::relative(path, base);
+#endif
+}
+
void Companion::Init(const ExportType type) {
std::atomic<size_t> assetCount{ 0 };
@@ -553,8 +561,8 @@ void Companion::ParseCurrentFileConfig(YAML::Node node, std::atomic<size_t>& ass
std::string externalFileName =
(this->gSourceDirectory / externalFile.as<std::string>()).generic_string();
- const auto relPath = fs::path(externalFileName).lexically_relative(this->gAssetPath).string();
- const auto relCommonPath = fs::path(externalFileName).lexically_relative(this->gCommonAssetPath).string();
+ const auto relPath = RelativeTo(externalFileName, this->gAssetPath).string();
+ const auto relCommonPath = RelativeTo(externalFileName, this->gCommonAssetPath).string();
if (StringHelper::StartsWith(relPath, "../")) {
if (StringHelper::StartsWith(relCommonPath, "../"))
throw std::runtime_error("External File " + externalFileName + " Not In Asset Directory " +
@@ -575,7 +583,7 @@ void Companion::ParseCurrentFileConfig(YAML::Node node, std::atomic<size_t>& ass
this->gCurrentFile = externalFileName;
this->gCurrentDirectory =
- fs::path(externalFileName).lexically_relative(this->gAssetPath).replace_extension("");
+ RelativeTo(externalFileName, this->gAssetPath).replace_extension("");
YAML::Node root = YAML::LoadFile(externalFileName);
@@ -1225,9 +1233,9 @@ void Companion::ProcessFile(YAML::Node root, std::atomic<size_t>& assetCount) {
// directory must be resolved before the loop. Default to the file's own
// path, then honor a :config directory override (used to register a room's
// assets under its scene's directory).
- auto relPath = fs::path(this->gCurrentFile).lexically_relative(this->gAssetPath).replace_extension("");
+ auto relPath = RelativeTo(this->gCurrentFile, this->gAssetPath).replace_extension("");
if (StringHelper::StartsWith(relPath.string(), "../"))
- relPath = fs::path(this->gCurrentFile).lexically_relative(this->gCommonAssetPath).replace_extension("");
+ relPath = RelativeTo(this->gCurrentFile, this->gCommonAssetPath).replace_extension("");
this->gCurrentDirectory = relPath;
@@ -1653,16 +1661,16 @@ void Companion::Process(std::atomic<size_t>& assetCount) {
#ifdef NAUDIO_SUPPORT
AudioManager::Instance = new AudioManager();
#endif
- BinaryWrapper* wrapper = nullptr;
+ std::unique_ptr<BinaryWrapper> wrapper;
if (mShouldProcess) {
if (this->gConfig.exporterType == ExportType::Binary) {
switch (this->gConfig.otrMode) {
case ArchiveType::OTR:
- wrapper = new SWrapper(this->gConfig.outputPath);
+ wrapper.reset(new SWrapper(this->gConfig.outputPath));
break;
case ArchiveType::O2R:
- wrapper = new ZWrapper(this->gConfig.outputPath);
+ wrapper.reset(new ZWrapper(this->gConfig.outputPath));
break;
default:
throw std::runtime_error("Invalid archive type for export type Binary");
@@ -1673,7 +1681,7 @@ void Companion::Process(std::atomic<size_t>& assetCount) {
wrapper->CreateArchive();
}
- this->gCurrentWrapper = wrapper;
+ this->gCurrentWrapper = wrapper.get();
for (auto& entry : this->gCompanionFiles) {
auto output = entry.first;
@@ -1911,6 +1919,7 @@ void Companion::Process(std::atomic<size_t>& assetCount) {
this->gCurrentAssetName = "Writing archive to disk...";
wrapper->Close();
}
+ this->gCurrentWrapper = nullptr;
// Write entries hash
std::ofstream file(this->gDestinationDirectory / "torch.hash.yml", std::ios::binary);
diff --git a/src/archive/ZWrapper.cpp b/src/archive/ZWrapper.cpp
index 9d68359..335a3a9 100644
--- a/src/archive/ZWrapper.cpp
+++ b/src/archive/ZWrapper.cpp
@@ -3,6 +3,7 @@
#include <iostream>
#include <fstream>
#include <cstring>
+#include <stdexcept>
#include "spdlog/spdlog.h"
#include <Companion.h>
@@ -12,6 +13,7 @@ namespace fs = std::filesystem;
ZWrapper::ZWrapper(const std::string& path) {
this->mPath = path;
+ this->mTempPath = path + ".tmp";
}
ZWrapper::~ZWrapper() {
@@ -22,16 +24,19 @@ ZWrapper::~ZWrapper() {
delete reinterpret_cast<mz_zip_archive*>(this->mZip);
this->mZip = nullptr;
}
+ if (!this->mFinalized) {
+ std::error_code ec;
+ fs::remove(this->mTempPath, ec);
+ }
}
int32_t ZWrapper::CreateArchive(void) {
auto* zip = new mz_zip_archive;
std::memset(zip, 0, sizeof(mz_zip_archive));
- if (!mz_zip_writer_init_file(zip, this->mPath.c_str(), 0)) {
- SPDLOG_ERROR("[ZWrapper] Could not open '{}' for writing", this->mPath);
+ if (!mz_zip_writer_init_file(zip, this->mTempPath.c_str(), 0)) {
delete zip;
- return -1;
+ throw std::runtime_error("[ZWrapper] Could not open '" + this->mTempPath + "' for writing");
}
this->mZip = reinterpret_cast<mz_zip_archive_tag*>(zip);
@@ -55,17 +60,16 @@ bool ZWrapper::AddFile(const std::string& path, std::vector<char> data) {
}
if (this->mZip == nullptr || !this->mOpen) {
- SPDLOG_ERROR("[ZWrapper] Cannot add '{}': the archive is not open", path);
- return false;
+ throw std::runtime_error("[ZWrapper] Cannot add '" + path + "': the archive is not open");
}
std::lock_guard<std::mutex> guard(this->mMutex);
if (!mz_zip_writer_add_mem(reinterpret_cast<mz_zip_archive*>(this->mZip), path.c_str(), data.data(), fileSize,
- MZ_DEFAULT_COMPRESSION)) {
+ MZ_BEST_COMPRESSION)) {
// miniz's own error says nothing useful, so log which entry blew up and how big.
SPDLOG_ERROR("[ZWrapper] Failed to add '{}' ({} bytes)", path, fileSize);
- return false;
+ throw std::runtime_error("[ZWrapper] Failed to add '" + path + "'");
}
return true;
@@ -77,14 +81,21 @@ int32_t ZWrapper::Close(void) {
}
auto* zip = reinterpret_cast<mz_zip_archive*>(this->mZip);
- int32_t result = 0;
-
- if (!mz_zip_writer_finalize_archive(zip)) {
- SPDLOG_ERROR("[ZWrapper] Failed to finalize '{}'", this->mPath);
- result = -1;
- }
+ const bool finalized = mz_zip_writer_finalize_archive(zip);
mz_zip_writer_end(zip);
this->mOpen = false;
- return result;
+ if (!finalized) {
+ throw std::runtime_error("[ZWrapper] Failed to finalize '" + this->mPath + "'");
+ }
+
+ std::error_code ec;
+ fs::rename(this->mTempPath, this->mPath, ec);
+ if (ec) {
+ throw std::runtime_error("[ZWrapper] Could not move '" + this->mTempPath + "' to '" + this->mPath +
+ "': " + ec.message());
+ }
+ this->mFinalized = true;
+
+ return 0;
}
diff --git a/src/archive/ZWrapper.h b/src/archive/ZWrapper.h
index 8727939..b543082 100644
--- a/src/archive/ZWrapper.h
+++ b/src/archive/ZWrapper.h
@@ -17,5 +17,7 @@ public:
private:
struct mz_zip_archive_tag* mZip = nullptr;
+ std::string mTempPath;
bool mOpen = false;
+ bool mFinalized = false;
};