Browse Source

assets.cpp: Switch to C FILE for UNPACKED_MPQS

Eliminates some of the (minor) overhead of fstream.
pull/5522/head
Gleb Mazovetskiy 3 years ago committed by Anders Jenbo
parent
commit
dc3908e360
  1. 2
      Source/engine/assets.cpp
  2. 37
      Source/engine/assets.hpp
  3. 16
      Source/utils/file_util.cpp
  4. 1
      Source/utils/file_util.h

2
Source/engine/assets.cpp

@ -144,7 +144,7 @@ AssetRef FindAsset(const char *filename)
AssetHandle OpenAsset(AssetRef &&ref, bool threadsafe)
{
#ifdef UNPACKED_MPQS
return AssetHandle { CreateFileStream(ref.path.c_str(), std::fstream::in | std::fstream::binary) };
return AssetHandle { OpenFile(ref.path.c_str(), "rb") };
#else
if (ref.archive != nullptr)
return AssetHandle { SDL_RWops_FromMpqFile(*ref.archive, ref.fileNumber, ref.filename, threadsafe) };

37
Source/engine/assets.hpp

@ -2,6 +2,7 @@
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <string>
#include <SDL.h>
@ -40,23 +41,47 @@ struct AssetRef {
};
struct AssetHandle {
std::optional<std::fstream> handle;
FILE *handle = nullptr;
AssetHandle() = default;
AssetHandle(FILE *handle)
: handle(handle)
{
}
AssetHandle(AssetHandle &&other) noexcept
: handle(other.handle)
{
other.handle = nullptr;
}
AssetHandle &operator=(AssetHandle &&other) noexcept
{
handle = other.handle;
other.handle = nullptr;
return *this;
}
~AssetHandle()
{
if (handle != nullptr)
std::fclose(handle);
}
[[nodiscard]] bool ok() const
{
return handle && !handle->fail();
return handle != nullptr && std::ferror(handle) == 0;
}
bool read(void *buffer, size_t len)
{
handle->read(static_cast<char *>(buffer), len);
return !handle->fail();
return std::fread(buffer, len, 1, handle) == 1;
}
bool seek(std::ios::pos_type pos)
{
handle->seekg(pos);
return !handle->fail();
return std::fseek(handle, pos, SEEK_SET) == 0;
}
[[nodiscard]] const char *error() const

16
Source/utils/file_util.cpp

@ -225,4 +225,20 @@ std::optional<std::fstream> CreateFileStream(const char *path, std::ios::openmod
#endif
}
FILE *OpenFile(const char *path, const char *mode)
{
#if (defined(_WIN64) || defined(_WIN32)) && !defined(NXDK)
std::unique_ptr<wchar_t[]> pathUtf16;
std::unique_ptr<wchar_t[]> modeUtf16;
if ((pathUtf16 = ToWideChar(path)) == nullptr
|| (modeUtf16 = ToWideChar(mode)) == nullptr) {
LogError("UTF-8 -> UTF-16 conversion error code {}", ::GetLastError());
return {};
}
return _wfopen(pathUtf16.get(), modeUtf16.get());
#else
return std::fopen(path, mode);
#endif
}
} // namespace devilution

1
Source/utils/file_util.h

@ -23,6 +23,7 @@ bool GetFileSize(const char *path, std::uintmax_t *size);
bool ResizeFile(const char *path, std::uintmax_t size);
void RemoveFile(const char *path);
std::optional<std::fstream> CreateFileStream(const char *path, std::ios::openmode mode);
FILE *OpenFile(const char *path, const char *mode);
#if (defined(_WIN64) || defined(_WIN32)) && !defined(NXDK)
std::unique_ptr<wchar_t[]> ToWideChar(string_view path);

Loading…
Cancel
Save