diff --git a/src/openrct2/core/File.cpp b/src/openrct2/core/File.cpp index 51d734edd7..398e5e6440 100644 --- a/src/openrct2/core/File.cpp +++ b/src/openrct2/core/File.cpp @@ -1,4 +1,4 @@ -#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +#pragma region Copyright (c) 2014-2018 OpenRCT2 Developers /***************************************************************************** * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * @@ -21,6 +21,7 @@ #include #endif +#include #include "File.h" #include "FileStream.hpp" #include "String.hpp" @@ -50,12 +51,23 @@ namespace File return platform_file_move(srcPath.c_str(), dstPath.c_str()); } - void * ReadAllBytes(const std::string &path, size_t * length) + std::vector ReadAllBytes(const std::string_view& path) { - void * result = nullptr; + std::vector result; - FileStream fs = FileStream(path, FILE_MODE_OPEN); - uint64 fsize = fs.GetLength(); +#if defined(_WIN32) && !defined(__MINGW32__) + auto pathW = String::ToUtf16(path.data()); + std::ifstream fs(pathW, std::ios::in | std::ios::binary); +#else + std::ifstream fs(path.data(), std::ios::in | std::ios::binary); +#endif + if (!fs.is_open()) + { + throw IOException("Unable to open " + std::string(path.data())); + } + + fs.seekg(0, std::ios::end); + auto fsize = (size_t)fs.tellg(); if (fsize > SIZE_MAX) { std::string message = String::StdFormat("'%s' exceeds maximum length of %lld bytes.", SIZE_MAX); @@ -63,9 +75,11 @@ namespace File } else { - result = fs.ReadArray((size_t)fsize); + result.resize(fsize); + fs.seekg(0); + fs.read((char *)result.data(), result.size()); + fs.exceptions(fs.failbit); } - *length = (size_t)fsize; return result; } @@ -78,12 +92,11 @@ namespace File std::vector ReadAllLines(const std::string &path) { std::vector lines; - size_t length; - char * data = (char *)ReadAllBytes(path, &length); - char * lineStart = data; - char * ch = data; + auto data = ReadAllBytes(path); + auto lineStart = (const char *)data.data(); + auto ch = lineStart; char lastC = 0; - for (size_t i = 0; i < length; i++) + for (size_t i = 0; i < data.size(); i++) { char c = *ch; if (c == '\n' && lastC == '\r') @@ -102,8 +115,6 @@ namespace File // Last line lines.emplace_back(lineStart, ch - lineStart); - - Memory::Free(data); return lines; } @@ -134,19 +145,6 @@ namespace File } } // namespace File -bool readentirefile(const utf8 * path, void * * outBuffer, size_t * outLength) -{ - try - { - *outBuffer = File::ReadAllBytes(String::ToStd(path), outLength); - return true; - } - catch (const std::exception &) - { - return false; - } -} - bool writeentirefile(const utf8 * path, const void * buffer, size_t length) { try diff --git a/src/openrct2/core/File.h b/src/openrct2/core/File.h index a58c460d84..40c0ad451d 100644 --- a/src/openrct2/core/File.h +++ b/src/openrct2/core/File.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include "../common.h" @@ -26,7 +27,7 @@ namespace File bool Copy(const std::string &srcPath, const std::string &dstPath, bool overwrite); bool Delete(const std::string &path); bool Move(const std::string &srcPath, const std::string &dstPath); - void * ReadAllBytes(const std::string &path, size_t * length); + std::vector ReadAllBytes(const std::string_view& path); void WriteAllBytes(const std::string &path, const void * buffer, size_t length); std::vector ReadAllLines(const std::string &path); uint64 GetLastModified(const std::string &path); diff --git a/src/openrct2/core/Zip.cpp b/src/openrct2/core/Zip.cpp index f97038b9cc..73dad5268a 100644 --- a/src/openrct2/core/Zip.cpp +++ b/src/openrct2/core/Zip.cpp @@ -1,4 +1,4 @@ -#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +#pragma region Copyright (c) 2014-2018 OpenRCT2 Developers /***************************************************************************** * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * @@ -17,26 +17,26 @@ #ifndef __ANDROID__ #include #include "IStream.hpp" -#include "MemoryStream.h" #include "Zip.h" class ZipArchive final : public IZipArchive { private: - zip_t * _zip; - ZIP_ACCESS _access; + zip_t * _zip; + ZIP_ACCESS _access; + std::vector> _writeBuffers; public: - ZipArchive(const utf8 * path, ZIP_ACCESS access) + ZipArchive(const std::string_view& path, ZIP_ACCESS access) { - sint32 zipOpenMode = ZIP_RDONLY; - if (access == ZIP_ACCESS_WRITE) + auto zipOpenMode = ZIP_RDONLY; + if (access == ZIP_ACCESS::WRITE) { zipOpenMode = ZIP_CREATE; } sint32 error; - _zip = zip_open(path, zipOpenMode, &error); + _zip = zip_open(path.data(), zipOpenMode, &error); if (_zip == nullptr) { throw IOException("Unable to open zip file."); @@ -55,10 +55,15 @@ public: return zip_get_num_files(_zip); } - const utf8 * GetFileName(size_t index) const override + std::string GetFileName(size_t index) const override { - const utf8 * name = zip_get_name(_zip, index, ZIP_FL_ENC_GUESS); - return name; + std::string result; + auto name = zip_get_name(_zip, index, ZIP_FL_ENC_GUESS); + if (name != nullptr) + { + result = name; + } + return result; } uint64 GetFileSize(size_t index) const override @@ -74,51 +79,41 @@ public: } } - void * GetFileData(const utf8 * path, size_t * outSize) const override + std::vector GetFileData(const std::string_view& path) const override { - void * data = nullptr; - - size_t index = (size_t)zip_name_locate(_zip, path, 0); - uint64 dataSize = GetFileSize(index); + std::vector result; + auto index = (size_t)zip_name_locate(_zip, path.data(), 0); + auto dataSize = GetFileSize(index); if (dataSize > 0 && dataSize < SIZE_MAX) { - zip_file_t * zipFile = zip_fopen(_zip, path, 0); + auto zipFile = zip_fopen(_zip, path.data(), 0); if (zipFile != nullptr) { - data = Memory::Allocate((size_t)dataSize); - uint64 readBytes = zip_fread(zipFile, data, dataSize); + result.resize((size_t)dataSize); + uint64 readBytes = zip_fread(zipFile, result.data(), dataSize); if (readBytes != dataSize) { - SafeFree(data); - dataSize = 0; + result.clear(); + result.shrink_to_fit(); } zip_fclose(zipFile); } } - - if (outSize != nullptr) *outSize = (size_t)dataSize; - return data; + return result; } - IStream * GetFileStream(const utf8 * path) const override + void SetFileData(const std::string_view& path, std::vector&& data) override { - IStream * stream = nullptr; - size_t dataSize; - void * data = GetFileData(path, &dataSize); - if (data != nullptr) - { - stream = new MemoryStream(data, dataSize, MEMORY_ACCESS::READ | MEMORY_ACCESS::OWNER); - } - return stream; - } + // Push buffer to an internal list as libzip requires access to it until the zip + // handle is closed. + _writeBuffers.push_back(std::move(data)); + const auto& writeBuffer = *_writeBuffers.rbegin(); - void SetFileData(const utf8 * path, void * data, size_t dataSize) override - { - zip_source_t * source = zip_source_buffer(_zip, data, dataSize, 0); - sint64 index = zip_name_locate(_zip, path, 0); + auto source = zip_source_buffer(_zip, writeBuffer.data(), writeBuffer.size(), 0); + auto index = zip_name_locate(_zip, path.data(), 0); if (index == -1) { - zip_add(_zip, path, source); + zip_add(_zip, path.data(), source); } else { @@ -126,34 +121,34 @@ public: } } - void DeleteFile(const utf8 * path) override + void DeleteFile(const std::string_view& path) override { - uint64 index = zip_name_locate(_zip, path, 0); + auto index = zip_name_locate(_zip, path.data(), 0); zip_delete(_zip, index); } - void RenameFile(const utf8 * path, const utf8 * newPath) override + void RenameFile(const std::string_view& path, const std::string_view& newPath) override { - uint64 index = zip_name_locate(_zip, path, 0); - zip_file_rename(_zip, index, newPath, ZIP_FL_ENC_GUESS); + auto index = zip_name_locate(_zip, path.data(), 0); + zip_file_rename(_zip, index, newPath.data(), ZIP_FL_ENC_GUESS); } }; namespace Zip { - IZipArchive * Open(const utf8 * path, ZIP_ACCESS access) + std::unique_ptr Open(const std::string_view& path, ZIP_ACCESS access) { - return new ZipArchive(path, access); + return std::make_unique(path, access); } - IZipArchive * TryOpen(const utf8 * path, ZIP_ACCESS access) + std::unique_ptr TryOpen(const std::string_view& path, ZIP_ACCESS access) { - IZipArchive * result = nullptr; + std::unique_ptr result; try { - result = new ZipArchive(path, access); + result = std::make_unique(path, access); } - catch (const std::exception &) + catch (const std::exception&) { } return result; diff --git a/src/openrct2/core/Zip.h b/src/openrct2/core/Zip.h index c1add665c4..9242f9afcb 100644 --- a/src/openrct2/core/Zip.h +++ b/src/openrct2/core/Zip.h @@ -1,4 +1,4 @@ -#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +#pragma region Copyright (c) 2014-2018 OpenRCT2 Developers /***************************************************************************** * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * @@ -16,10 +16,11 @@ #pragma once +#include +#include +#include #include "../common.h" -interface IStream; - /** * Represents a zip file. */ @@ -27,33 +28,30 @@ interface IZipArchive { virtual ~IZipArchive() { } - virtual size_t GetNumFiles() const abstract; - virtual const utf8 * GetFileName(size_t index) const abstract; - virtual uint64 GetFileSize(size_t index) const abstract; - virtual void * GetFileData(const utf8 * path, size_t * outSize) const abstract; - virtual IStream * GetFileStream(const utf8 * path) const abstract; + virtual size_t GetNumFiles() const abstract; + virtual std::string GetFileName(size_t index) const abstract; + virtual uint64 GetFileSize(size_t index) const abstract; + virtual std::vector GetFileData(const std::string_view& path) const abstract; /** * Creates or overwrites a file within the zip archive to the given data buffer. * @param path The path of the file within the zip. - * @param data The data to write, this buffer must not be mutated or disposed until - * the zip archive has been disposed. - * @param dataSize The size of the data in bytes. + * @param data The data to write. */ - virtual void SetFileData(const utf8 * path, void * data, size_t dataSize) abstract; + virtual void SetFileData(const std::string_view& path, std::vector&& data) abstract; - virtual void DeleteFile(const utf8 * path) abstract; - virtual void RenameFile(const utf8 * path, const utf8 * newPath) abstract; + virtual void DeleteFile(const std::string_view& path) abstract; + virtual void RenameFile(const std::string_view& path, const std::string_view& newPath) abstract; }; -enum ZIP_ACCESS +enum class ZIP_ACCESS { - ZIP_ACCESS_READ, - ZIP_ACCESS_WRITE, + READ, + WRITE, }; namespace Zip { - IZipArchive * Open(const utf8 * path, ZIP_ACCESS zipAccess); - IZipArchive * TryOpen(const utf8 * path, ZIP_ACCESS zipAccess); + std::unique_ptr Open(const std::string_view& path, ZIP_ACCESS zipAccess); + std::unique_ptr TryOpen(const std::string_view& path, ZIP_ACCESS zipAccess); } diff --git a/src/openrct2/core/ZipAndroid.cpp b/src/openrct2/core/ZipAndroid.cpp index 8722062e60..e60e5660c4 100644 --- a/src/openrct2/core/ZipAndroid.cpp +++ b/src/openrct2/core/ZipAndroid.cpp @@ -20,30 +20,31 @@ #include #include "IStream.hpp" #include "Zip.h" -#include "MemoryStream.h" -class ZipArchive final : public IZipArchive { +class ZipArchive final : public IZipArchive +{ private: jobject _zip; public: - ZipArchive(const utf8 *path, ZIP_ACCESS access) { + ZipArchive(const std::string_view& path, ZIP_ACCESS access) + { // retrieve the JNI environment. JNIEnv *env = (JNIEnv *) SDL_AndroidGetJNIEnv(); jclass jniClass = env->FindClass("website/openrct2/ZipArchive"); jmethodID constructor = env->GetMethodID(jniClass, "", "(Ljava/lang/String;)V"); - jstring jniPath = env->NewStringUTF(path); + jstring jniPath = env->NewStringUTF(path.data()); // TODO: Catch exceptions. Should probably be done on Java side, and just return null from a static method jobject zip = env->NewObject(jniClass, constructor, jniPath); _zip = env->NewGlobalRef(zip); - } - ~ZipArchive() override { + ~ZipArchive() override + { // retrieve the JNI environment. JNIEnv *env = (JNIEnv *) SDL_AndroidGetJNIEnv(); @@ -55,7 +56,8 @@ public: env->DeleteGlobalRef(_zip); } - size_t GetNumFiles() const override { + size_t GetNumFiles() const override + { // retrieve the JNI environment. JNIEnv *env = (JNIEnv *) SDL_AndroidGetJNIEnv(); @@ -65,7 +67,8 @@ public: return (size_t) env->CallIntMethod(_zip, fileCountMethod); } - const utf8 *GetFileName(size_t index) const override { + std::string GetFileName(size_t index) const override + { // retrieve the JNI environment. JNIEnv *env = (JNIEnv *) SDL_AndroidGetJNIEnv(); @@ -86,8 +89,8 @@ public: return string; } - uint64 GetFileSize(size_t index) const override { - + uint64 GetFileSize(size_t index) const override + { // retrieve the JNI environment. JNIEnv *env = (JNIEnv *) SDL_AndroidGetJNIEnv(); @@ -97,58 +100,57 @@ public: return (size_t) env->CallLongMethod(_zip, fileSizeMethod, (jint) index); } - void *GetFileData(const utf8 *path, size_t *outSize) const override { - + std::vector GetFileData(const std::string_view& path) const override + { // retrieve the JNI environment. JNIEnv *env = (JNIEnv *) SDL_AndroidGetJNIEnv(); jclass zipClass = env->GetObjectClass(_zip); - jstring javaPath = env->NewStringUTF(path); + jstring javaPath = env->NewStringUTF(path.data()); jmethodID indexMethod = env->GetMethodID(zipClass, "getFileIndex", "(Ljava/lang/String;)I"); jint index = env->CallIntMethod(_zip, indexMethod, javaPath); jmethodID fileMethod = env->GetMethodID(zipClass, "getFile", "(I)J"); jlong ptr = env->CallLongMethod(_zip, fileMethod, index); - *outSize = this->GetFileSize(index); - return reinterpret_cast(ptr); + auto dataPtr = reinterpret_cast(ptr); + auto dataSize = this->GetFileSize(index); + + return std::vector(dataPtr, dataPtr + dataSize); } - IStream *GetFileStream(const utf8 *path) const override { - IStream * stream = nullptr; - size_t dataSize; - void * data = GetFileData(path, &dataSize); - if (data != nullptr) - { - stream = new MemoryStream(data, dataSize, MEMORY_ACCESS::READ | MEMORY_ACCESS::OWNER); - } - return stream; - } - - void SetFileData(const utf8 *path, void *data, size_t dataSize) override { + void void SetFileData(const std::string_view& path, std::vector&& data) override + { STUB(); } - void DeleteFile(const utf8 *path) override { + void DeleteFile(const std::string_view&) override + { STUB(); } - void RenameFile(const utf8 *path, const utf8 *newPath) override { + void RenameFile(const std::string_view&, const std::string_view&) override + { STUB(); } }; -namespace Zip { - IZipArchive *Open(const utf8 *path, ZIP_ACCESS access) { +namespace Zip +{ + std::unique_ptr Open(const std::string_view& path, ZIP_ACCESS access) + { return new ZipArchive(path, access); } - IZipArchive *TryOpen(const utf8 *path, ZIP_ACCESS access) { - IZipArchive *result = nullptr; - try { + std::unique_ptr TryOpen(const std::string_view path, ZIP_ACCESS access) + { + std::unique_ptr result; + try + { result = new ZipArchive(path, access); } - catch (const std::exception &) { + catch (const std::exception&) + { } return result; } diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 53dd31be44..681fed9723 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -1,4 +1,4 @@ -#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +#pragma region Copyright (c) 2014-2018 OpenRCT2 Developers /***************************************************************************** * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * @@ -16,6 +16,7 @@ #include "../audio/audio.h" #include "../Cheats.h" +#include "../core/File.h" #include "../core/Math.hpp" #include "../core/String.hpp" #include "../core/Util.hpp" @@ -90,21 +91,18 @@ rct_track_td6 * track_design_open(const utf8 * path) { log_verbose("track_design_open(\"%s\")", path); - uint8 * buffer; - size_t bufferLength; - if (readentirefile(path, (void **) &buffer, &bufferLength)) + try { - if (!sawyercoding_validate_track_checksum(buffer, bufferLength)) + auto buffer = File::ReadAllBytes(path); + if (!sawyercoding_validate_track_checksum(buffer.data(), buffer.size())) { log_error("Track checksum failed. %s", path); - free(buffer); return nullptr; } // Decode the track data uint8 * decoded = (uint8 *) malloc(0x10000); - size_t decodedLength = sawyercoding_decode_td6(buffer, decoded, bufferLength); - free(buffer); + size_t decodedLength = sawyercoding_decode_td6(buffer.data(), decoded, buffer.size()); decoded = (uint8 *) realloc(decoded, decodedLength); if (decoded == nullptr) { @@ -122,6 +120,10 @@ rct_track_td6 * track_design_open(const utf8 * path) } } } + catch (const std::exception& e) + { + log_error("Unable to load track design: %s", e.what()); + } return nullptr; } diff --git a/src/openrct2/scenario/ScenarioRepository.cpp b/src/openrct2/scenario/ScenarioRepository.cpp index 0d0b2246d5..04c84c70d9 100644 --- a/src/openrct2/scenario/ScenarioRepository.cpp +++ b/src/openrct2/scenario/ScenarioRepository.cpp @@ -492,17 +492,15 @@ private: auto directory = Path::GetDirectory(dstPath); platform_ensure_directory_exists(directory.c_str()); - size_t length; - auto mpdat = (uint8 *)(File::ReadAllBytes(srcPath, &length)); + auto mpdat = File::ReadAllBytes(srcPath); // Rotate each byte of mp.dat left by 4 bits to convert - for (size_t i = 0; i < length; i++) + for (size_t i = 0; i < mpdat.size(); i++) { mpdat[i] = rol8(mpdat[i], 4); } - File::WriteAllBytes(dstPath, mpdat, length); - Memory::FreeArray(mpdat, length); + File::WriteAllBytes(dstPath, mpdat.data(), mpdat.size()); } void AddScenario(const scenario_index_entry &entry) diff --git a/src/openrct2/title/TitleSequence.cpp b/src/openrct2/title/TitleSequence.cpp index cba8cafa99..df8f54d23a 100644 --- a/src/openrct2/title/TitleSequence.cpp +++ b/src/openrct2/title/TitleSequence.cpp @@ -14,6 +14,7 @@ *****************************************************************************/ #pragma endregion +#include #include #include "../common.h" #include "../core/Collections.hpp" @@ -39,8 +40,8 @@ static std::vector GetSaves(const utf8 * path); static std::vector GetSaves(IZipArchive * zip); static std::vector LegacyScriptRead(utf8 * script, size_t scriptLength, std::vector saves); static void LegacyScriptGetLine(IStream * stream, char * parts); -static void * ReadScriptFile(const utf8 * path, size_t * outSize); -static utf8 * LegacyScriptWrite(TitleSequence * seq); +static std::vector ReadScriptFile(const utf8 * path); +static std::string LegacyScriptWrite(TitleSequence * seq); TitleSequence * CreateTitleSequence() { @@ -51,8 +52,7 @@ TitleSequence * CreateTitleSequence() TitleSequence * LoadTitleSequence(const utf8 * path) { - size_t scriptLength; - utf8 * script; + std::vector script; std::vector saves; bool isZip; @@ -61,33 +61,30 @@ TitleSequence * LoadTitleSequence(const utf8 * path) const utf8 * ext = Path::GetExtension(path); if (String::Equals(ext, TITLE_SEQUENCE_EXTENSION)) { - IZipArchive * zip = Zip::TryOpen(path, ZIP_ACCESS_READ); + auto zip = std::unique_ptr(Zip::TryOpen(path, ZIP_ACCESS::READ)); if (zip == nullptr) { Console::Error::WriteLine("Unable to open '%s'", path); return nullptr; } - script = (utf8 *)zip->GetFileData("script.txt", &scriptLength); - if (script == nullptr) + script = zip->GetFileData("script.txt"); + if (script.empty()) { Console::Error::WriteLine("Unable to open script.txt in '%s'", path); - delete zip; return nullptr; } - saves = GetSaves(zip); + saves = GetSaves(zip.get()); isZip = true; - - delete zip; } else { utf8 scriptPath[MAX_PATH]; String::Set(scriptPath, sizeof(scriptPath), path); Path::Append(scriptPath, sizeof(scriptPath), "script.txt"); - script = (utf8 *)ReadScriptFile(scriptPath, &scriptLength); - if (script == nullptr) + script = ReadScriptFile(scriptPath); + if (script.empty()) { Console::Error::WriteLine("Unable to open '%s'", scriptPath); return nullptr; @@ -97,8 +94,7 @@ TitleSequence * LoadTitleSequence(const utf8 * path) isZip = false; } - std::vector commands = LegacyScriptRead(script, scriptLength, saves); - Memory::Free(script); + auto commands = LegacyScriptRead((utf8 *)script.data(), script.size(), saves); TitleSequence * seq = CreateTitleSequence(); seq->Name = Path::GetFileNameWithoutExtension(path); @@ -135,13 +131,17 @@ TitleSequenceParkHandle * TitleSequenceGetParkHandle(TitleSequence * seq, size_t const utf8 * filename = seq->Saves[index]; if (seq->IsZip) { - IZipArchive * zip = Zip::TryOpen(seq->Path, ZIP_ACCESS_READ); + auto zip = std::unique_ptr(Zip::TryOpen(seq->Path, ZIP_ACCESS::READ)); if (zip != nullptr) { + auto data = zip->GetFileData(filename); + auto dataForMs = Memory::Allocate(data.size()); + std::copy_n(data.data(), data.size(), dataForMs); + auto ms = new MemoryStream(dataForMs, data.size(), MEMORY_ACCESS::READ | MEMORY_ACCESS::OWNER); + handle = Memory::Allocate(); - handle->Stream = zip->GetFileStream(filename); + handle->Stream = ms; handle->HintPath = String::Duplicate(filename); - delete zip; } else { Console::Error::WriteLine("Failed to open zipped path '%s' from zip '%s'", filename, seq->Path); } @@ -185,34 +185,26 @@ void TitleSequenceCloseParkHandle(TitleSequenceParkHandle * handle) bool TitleSequenceSave(TitleSequence * seq) { - bool success = false; - utf8 * script = LegacyScriptWrite(seq); - if (seq->IsZip) + try { - IZipArchive * zip = Zip::TryOpen(seq->Path, ZIP_ACCESS_WRITE); - zip->SetFileData("script.txt", script, String::SizeOf(script)); - delete zip; - success = true; + auto script = LegacyScriptWrite(seq); + if (seq->IsZip) + { + auto fdata = std::vector(script.begin(), script.end()); + auto zip = Zip::Open(seq->Path, ZIP_ACCESS::WRITE); + zip->SetFileData("script.txt", std::move(fdata)); + } + else + { + auto scriptPath = Path::Combine(seq->Path, "script.txt"); + File::WriteAllBytes(scriptPath, script.data(), script.size()); + } + return true; } - else + catch (const std::exception &) { - utf8 scriptPath[MAX_PATH]; - String::Set(scriptPath, sizeof(scriptPath), seq->Path); - Path::Append(scriptPath, sizeof(scriptPath), "script.txt"); - - try - { - auto fs = FileStream(scriptPath, FILE_MODE_WRITE); - fs.Write(script, String::SizeOf(script)); - success = true; - } - catch (const std::exception &) - { - } + return false; } - - Memory::Free(script); - return success; } bool TitleSequenceAddPark(TitleSequence * seq, const utf8 * path, const utf8 * name) @@ -240,18 +232,14 @@ bool TitleSequenceAddPark(TitleSequence * seq, const utf8 * path, const utf8 * n { try { - size_t fsize; - void * fdata = File::ReadAllBytes(path, &fsize); - - IZipArchive * zip = Zip::TryOpen(seq->Path, ZIP_ACCESS_WRITE); + auto fdata = File::ReadAllBytes(path); + auto zip = Zip::TryOpen(seq->Path, ZIP_ACCESS::WRITE); if (zip == nullptr) { Console::Error::WriteLine("Unable to open '%s'", seq->Path); return false; } - zip->SetFileData(name, fdata, fsize); - delete zip; - Memory::Free(fdata); + zip->SetFileData(name, std::move(fdata)); } catch (const std::exception &ex) { @@ -280,14 +268,13 @@ bool TitleSequenceRenamePark(TitleSequence * seq, size_t index, const utf8 * nam utf8 * oldRelativePath = seq->Saves[index]; if (seq->IsZip) { - IZipArchive * zip = Zip::TryOpen(seq->Path, ZIP_ACCESS_WRITE); + auto zip = Zip::TryOpen(seq->Path, ZIP_ACCESS::WRITE); if (zip == nullptr) { Console::Error::WriteLine("Unable to open '%s'", seq->Path); return false; } zip->RenameFile(oldRelativePath, name); - delete zip; } else { @@ -317,14 +304,13 @@ bool TitleSequenceRemovePark(TitleSequence * seq, size_t index) utf8 * relativePath = seq->Saves[index]; if (seq->IsZip) { - IZipArchive * zip = Zip::TryOpen(seq->Path, ZIP_ACCESS_WRITE); + auto zip = Zip::TryOpen(seq->Path, ZIP_ACCESS::WRITE); if (zip == nullptr) { Console::Error::WriteLine("Unable to open '%s'", seq->Path); return false; } zip->DeleteFile(relativePath); - delete zip; } else { @@ -391,8 +377,8 @@ static std::vector GetSaves(IZipArchive * zip) size_t numFiles = zip->GetNumFiles(); for (size_t i = 0; i < numFiles; i++) { - const utf8 * name = zip->GetFileName(i); - const utf8 * ext = Path::GetExtension(name); + auto name = zip->GetFileName(i); + auto ext = Path::GetExtension(name); if (String::Equals(ext, ".sv6", true) || String::Equals(ext, ".sc6", true)) { @@ -566,29 +552,25 @@ static void LegacyScriptGetLine(IStream * stream, char * parts) } } -static void * ReadScriptFile(const utf8 * path, size_t * outSize) +static std::vector ReadScriptFile(const utf8 * path) { - void * buffer = nullptr; - size_t size = 0; + std::vector result; try { auto fs = FileStream(path, FILE_MODE_OPEN); - size = (size_t)fs.GetLength(); - buffer = Memory::Allocate(size); - fs.Read(buffer, size); + auto size = (size_t)fs.GetLength(); + result.resize(size); + fs.Read(result.data(), size); } catch (const std::exception &) { - Memory::Free(buffer); - buffer = nullptr; - size = 0; + result.clear(); + result.shrink_to_fit(); } - - *outSize = size; - return buffer; + return result; } -static utf8 * LegacyScriptWrite(TitleSequence * seq) +static std::string LegacyScriptWrite(TitleSequence * seq) { utf8 buffer[128]; auto sb = StringBuilder(128); @@ -663,8 +645,7 @@ static utf8 * LegacyScriptWrite(TitleSequence * seq) sb.Append("\n"); } - utf8 * result = sb.StealString(); - return result; + return sb.GetBuffer(); } bool TitleSequenceIsLoadCommand(const TitleCommand * command) diff --git a/src/openrct2/util/Util.h b/src/openrct2/util/Util.h index a1fa71dfd2..3bc0fbe0b3 100644 --- a/src/openrct2/util/Util.h +++ b/src/openrct2/util/Util.h @@ -34,7 +34,6 @@ void path_set_extension(utf8 *path, const utf8 *newExtension, size_t size); void path_append_extension(utf8 *path, const utf8 *newExtension, size_t size); void path_remove_extension(utf8 *path); void path_end_with_separator(utf8 *path, size_t size); -bool readentirefile(const utf8 *path, void **outBuffer, size_t *outLength); bool writeentirefile(const utf8 * path, const void * buffer, size_t length); bool sse41_available();