assetnameparser: Make Fopen return a unique_ptr

Prevents leaks from occurring (aside from obvious .release() calls).
This commit is contained in:
Lioncash 2020-05-31 07:04:00 -04:00
parent e6aed18d59
commit c369af4adf
1 changed files with 33 additions and 28 deletions

View File

@ -1,8 +1,10 @@
#include <iostream>
#include <cstdint> #include <cstdint>
#include <iostream>
#include <memory>
#include <vector> #include <vector>
#include <logvisor/logvisor.hpp>
#include "tinyxml2/tinyxml2.h" #include "tinyxml2/tinyxml2.h"
#include "logvisor/logvisor.hpp"
#ifndef _WIN32 #ifndef _WIN32
#include <cstdlib> #include <cstdlib>
@ -150,25 +152,33 @@ using SystemString = std::string;
using Sstat = struct stat; using Sstat = struct stat;
#endif #endif
FILE* Fopen(const SystemChar* path, const SystemChar* mode, FileLockType lock = FileLockType::None) { struct FILEDeleter {
void operator()(FILE* file) const { std::fclose(file); }
};
using FILEPtr = std::unique_ptr<FILE, FILEDeleter>;
FILEPtr Fopen(const SystemChar* path, const SystemChar* mode, FileLockType lock = FileLockType::None) {
#if IS_UCS2 #if IS_UCS2
FILE* fp = _wfopen(path, mode); FILEPtr fp{_wfopen(path, mode)};
if (!fp) if (!fp) {
return nullptr; return nullptr;
}
#else #else
FILE* fp = fopen(path, mode); FILEPtr fp{std::fopen(path, mode)};
if (!fp) if (!fp) {
return nullptr; return nullptr;
}
#endif #endif
if (lock != FileLockType::None) { if (lock != FileLockType::None) {
#if _WIN32 #if _WIN32
OVERLAPPED ov = {}; OVERLAPPED ov = {};
LockFileEx((HANDLE)(uintptr_t)_fileno(fp), (lock == FileLockType::Write) ? LOCKFILE_EXCLUSIVE_LOCK : 0, 0, 0, 1, LockFileEx((HANDLE)(uintptr_t)_fileno(fp.get()), (lock == FileLockType::Write) ? LOCKFILE_EXCLUSIVE_LOCK : 0, 0, 0,
&ov); 1, &ov);
#else #else
if (flock(fileno(fp), ((lock == FileLockType::Write) ? LOCK_EX : LOCK_SH) | LOCK_NB)) if (flock(fileno(fp.get()), ((lock == FileLockType::Write) ? LOCK_EX : LOCK_SH) | LOCK_NB)) {
fprintf(stderr, "flock %s: %s", path, strerror(errno)); std::fprintf(stderr, "flock %s: %s", path, strerror(errno));
}
#endif #endif
} }
@ -194,8 +204,8 @@ int main(int argc, const char* argv[])
tinyxml2::XMLDocument doc; tinyxml2::XMLDocument doc;
std::vector<SAsset> assets; std::vector<SAsset> assets;
FILE* docF = Fopen(inPath.c_str(), _SYS_STR("rb")); FILEPtr docF = Fopen(inPath.c_str(), _SYS_STR("rb"));
if (doc.LoadFile(docF) == tinyxml2::XML_SUCCESS) { if (doc.LoadFile(docF.get()) == tinyxml2::XML_SUCCESS) {
const tinyxml2::XMLElement* elm = doc.RootElement(); const tinyxml2::XMLElement* elm = doc.RootElement();
if (strcmp(elm->Name(), "AssetNameMap") != 0) { if (strcmp(elm->Name(), "AssetNameMap") != 0) {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Invalid database supplied"))); Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Invalid database supplied")));
@ -241,7 +251,7 @@ int main(int argc, const char* argv[])
elm = elm->NextSiblingElement("Asset"); elm = elm->NextSiblingElement("Asset");
} }
FILE* f = Fopen(outPath.c_str(), _SYS_STR("wb")); FILEPtr f = Fopen(outPath.c_str(), _SYS_STR("wb"));
if (f == nullptr) { if (f == nullptr) {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unable to open destination"))); Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unable to open destination")));
return 0; return 0;
@ -249,28 +259,23 @@ int main(int argc, const char* argv[])
uint32_t assetCount = SBig(uint32_t(assets.size())); uint32_t assetCount = SBig(uint32_t(assets.size()));
FourCC sentinel(SBIG('AIDM')); FourCC sentinel(SBIG('AIDM'));
fwrite(&sentinel, 1, 4, f); fwrite(&sentinel, 1, sizeof(sentinel), f.get());
fwrite(&assetCount, 1, 4, f); fwrite(&assetCount, 1, sizeof(assetCount), f.get());
for (const SAsset& asset : assets) { for (const SAsset& asset : assets) {
fwrite(&asset.type, 1, 4, f); fwrite(&asset.type, 1, sizeof(asset.type), f.get());
uint64_t id = SBig(asset.id); uint64_t id = SBig(asset.id);
fwrite(&id, 1, 8, f); fwrite(&id, 1, sizeof(id), f.get());
uint32_t tmp = SBig(uint32_t(asset.name.length())); uint32_t tmp = SBig(uint32_t(asset.name.length()));
fwrite(&tmp, 1, 4, f); fwrite(&tmp, 1, sizeof(tmp), f.get());
fwrite(asset.name.c_str(), 1, SBig(tmp), f); fwrite(asset.name.c_str(), 1, SBig(tmp), f.get());
tmp = SBig(uint32_t(asset.dir.length())); tmp = SBig(uint32_t(asset.dir.length()));
fwrite(&tmp, 1, 4, f); fwrite(&tmp, 1, sizeof(tmp), f.get());
fwrite(asset.dir.c_str(), 1, SBig(tmp), f); fwrite(asset.dir.c_str(), 1, SBig(tmp), f.get());
} }
fflush(f); fflush(f.get());
fclose(f);
fclose(docF);
return 0; return 0;
} }
if (docF)
fclose(docF);
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("failed to load"))); Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("failed to load")));
return 1; return 1;
} }