mirror of https://github.com/OpenRCT2/OpenRCT2.git
Use IStream for zip streaming
This commit is contained in:
parent
2aa2a94a7e
commit
d9b8413ec4
|
@ -70,7 +70,7 @@ namespace OpenRCT2::Audio
|
|||
return AudioSource::CreateStreamFromWAV(path);
|
||||
}
|
||||
|
||||
IAudioSource* CreateStreamFromWAV(std::unique_ptr<std::istream> stream) override
|
||||
IAudioSource* CreateStreamFromWAV(std::unique_ptr<IStream> stream) override
|
||||
{
|
||||
return AudioSource::CreateStreamFromWAV(std::move(stream));
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
#include <openrct2/audio/AudioChannel.h>
|
||||
#include <openrct2/audio/AudioSource.h>
|
||||
|
@ -67,7 +66,7 @@ namespace OpenRCT2::Audio
|
|||
IAudioSource* CreateMemoryFromWAV(const std::string& path, const AudioFormat* targetFormat = nullptr);
|
||||
IAudioSource* CreateStreamFromWAV(const std::string& path);
|
||||
IAudioSource* CreateStreamFromWAV(SDL_RWops* rw);
|
||||
IAudioSource* CreateStreamFromWAV(std::unique_ptr<std::istream> stream);
|
||||
IAudioSource* CreateStreamFromWAV(std::unique_ptr<IStream> stream);
|
||||
} // namespace AudioSource
|
||||
|
||||
namespace AudioChannel
|
||||
|
|
|
@ -203,40 +203,27 @@ namespace OpenRCT2::Audio
|
|||
return source;
|
||||
}
|
||||
|
||||
IAudioSource* AudioSource::CreateStreamFromWAV(std::unique_ptr<std::istream> stream)
|
||||
IAudioSource* AudioSource::CreateStreamFromWAV(std::unique_ptr<IStream> stream)
|
||||
{
|
||||
using streamptr = std::unique_ptr<std::istream>*;
|
||||
auto data = new std::unique_ptr<std::istream>(std::move(stream));
|
||||
|
||||
auto rw = new SDL_RWops();
|
||||
*rw = {};
|
||||
rw->type = SDL_RWOPS_UNKNOWN;
|
||||
rw->hidden.unknown.data1 = data;
|
||||
rw->hidden.unknown.data1 = stream.release();
|
||||
rw->seek = [](SDL_RWops* ctx, Sint64 offset, int whence) {
|
||||
auto ptr = static_cast<streamptr>(ctx->hidden.unknown.data1);
|
||||
auto dir = std::ios_base::beg;
|
||||
if (whence == RW_SEEK_CUR)
|
||||
{
|
||||
dir = std::ios_base::cur;
|
||||
}
|
||||
else if (whence == RW_SEEK_END)
|
||||
{
|
||||
dir = std::ios_base::end;
|
||||
}
|
||||
(*ptr)->seekg(offset, dir);
|
||||
return (*ptr)->fail() ? -1 : static_cast<Sint64>((*ptr)->tellg());
|
||||
auto ptr = static_cast<IStream*>(ctx->hidden.unknown.data1);
|
||||
ptr->Seek(offset, whence);
|
||||
return static_cast<Sint64>(ptr->GetPosition());
|
||||
};
|
||||
rw->read = [](SDL_RWops* ctx, void* buf, size_t size, size_t maxnum) {
|
||||
auto ptr = static_cast<streamptr>(ctx->hidden.unknown.data1);
|
||||
(*ptr)->read(static_cast<char*>(buf), size * maxnum);
|
||||
return static_cast<size_t>((*ptr)->gcount() / size);
|
||||
auto ptr = static_cast<IStream*>(ctx->hidden.unknown.data1);
|
||||
return static_cast<size_t>(ptr->TryRead(buf, size * maxnum) / size);
|
||||
};
|
||||
rw->size = [](SDL_RWops* ctx) {
|
||||
auto ptr = static_cast<streamptr>(ctx->hidden.unknown.data1);
|
||||
return static_cast<Sint64>((*ptr)->tellg());
|
||||
auto ptr = static_cast<IStream*>(ctx->hidden.unknown.data1);
|
||||
return static_cast<Sint64>(ptr->GetLength());
|
||||
};
|
||||
rw->close = [](SDL_RWops* ctx) {
|
||||
auto ptr = static_cast<streamptr>(ctx->hidden.unknown.data1);
|
||||
auto ptr = static_cast<IStream*>(ctx->hidden.unknown.data1);
|
||||
delete ptr;
|
||||
ctx->hidden.unknown.data1 = nullptr;
|
||||
delete ctx;
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "../common.h"
|
||||
#include "../core/IStream.hpp"
|
||||
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -35,7 +35,7 @@ namespace OpenRCT2::Audio
|
|||
virtual void SetOutputDevice(const std::string& deviceName) abstract;
|
||||
|
||||
virtual IAudioSource* CreateStreamFromWAV(const std::string& path) abstract;
|
||||
virtual IAudioSource* CreateStreamFromWAV(std::unique_ptr<std::istream> stream) abstract;
|
||||
virtual IAudioSource* CreateStreamFromWAV(std::unique_ptr<IStream> stream) abstract;
|
||||
|
||||
virtual void StartTitleMusic() abstract;
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ void* Mixer_Play_Music(const char* path, int32_t loop)
|
|||
return channel;
|
||||
}
|
||||
|
||||
void* Mixer_Play_Music(std::unique_ptr<std::istream> stream, int32_t loop)
|
||||
void* Mixer_Play_Music(std::unique_ptr<IStream> stream, int32_t loop)
|
||||
{
|
||||
IAudioChannel* channel = nullptr;
|
||||
IAudioMixer* mixer = GetMixer();
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "../common.h"
|
||||
#include "../core/IStream.hpp"
|
||||
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
|
||||
#define MIXER_VOLUME_MAX 128
|
||||
|
@ -73,7 +73,7 @@ int32_t Mixer_Channel_SetOffset(void* channel, uint64_t offset);
|
|||
void Mixer_Channel_SetGroup(void* channel, OpenRCT2::Audio::MixerGroup group);
|
||||
void* Mixer_Play_Music(int32_t pathId, int32_t loop, int32_t streaming);
|
||||
void* Mixer_Play_Music(const char* path, int32_t loop);
|
||||
void* Mixer_Play_Music(std::unique_ptr<std::istream> stream, int32_t loop);
|
||||
void* Mixer_Play_Music(std::unique_ptr<OpenRCT2::IStream> stream, int32_t loop);
|
||||
void Mixer_SetVolume(float volume);
|
||||
|
||||
int32_t DStoMixerVolume(int32_t volume);
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace OpenRCT2::Audio
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
IAudioSource* CreateStreamFromWAV(std::unique_ptr<std::istream>) override
|
||||
IAudioSource* CreateStreamFromWAV(std::unique_ptr<IStream>) override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,16 @@ namespace OpenRCT2
|
|||
{
|
||||
}
|
||||
|
||||
MemoryStream::MemoryStream(std::vector<uint8_t>&& v)
|
||||
{
|
||||
_access = MEMORY_ACCESS::OWNER;
|
||||
_dataCapacity = v.size();
|
||||
_dataSize = v.size();
|
||||
_data = Memory::Allocate<void>(v.size());
|
||||
_position = _data;
|
||||
std::memcpy(_data, v.data(), v.size());
|
||||
}
|
||||
|
||||
MemoryStream::MemoryStream(MemoryStream&& mv) noexcept
|
||||
: _access(mv._access)
|
||||
, _dataCapacity(mv._dataCapacity)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "IStream.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace OpenRCT2
|
||||
{
|
||||
|
@ -42,6 +43,7 @@ namespace OpenRCT2
|
|||
explicit MemoryStream(size_t capacity);
|
||||
MemoryStream(void* data, size_t dataSize, uint8_t access = MEMORY_ACCESS::READ);
|
||||
MemoryStream(const void* data, size_t dataSize);
|
||||
MemoryStream(std::vector<uint8_t>&& v);
|
||||
virtual ~MemoryStream();
|
||||
|
||||
MemoryStream& operator=(MemoryStream&& mv) noexcept;
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
# include <zip.h>
|
||||
#endif
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
static std::string NormalisePath(std::string_view path)
|
||||
{
|
||||
std::string result;
|
||||
|
@ -148,12 +150,12 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<std::istream> GetFileStream(std::string_view path) const override
|
||||
std::unique_ptr<IStream> GetFileStream(std::string_view path) const override
|
||||
{
|
||||
auto index = GetIndexFromPath(path);
|
||||
if (index)
|
||||
{
|
||||
return std::make_unique<ifilestream>(_zip, *index);
|
||||
return std::make_unique<ZipItemStream>(_zip, *index);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -204,145 +206,165 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
class ifilestream final : public std::istream
|
||||
class ZipItemStream final : public IStream
|
||||
{
|
||||
private:
|
||||
class ifilestreambuf final : public std::streambuf
|
||||
{
|
||||
private:
|
||||
zip* _zip;
|
||||
zip_int64_t _index;
|
||||
zip_file_t* _zipFile{};
|
||||
zip_int64_t _pos{};
|
||||
zip_int64_t _maxLen{};
|
||||
|
||||
public:
|
||||
ifilestreambuf(zip* zip, zip_int64_t index)
|
||||
: _zip(zip)
|
||||
, _index(index)
|
||||
{
|
||||
}
|
||||
|
||||
ifilestreambuf(const ifilestreambuf&) = delete;
|
||||
|
||||
~ifilestreambuf() override
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
private:
|
||||
void close()
|
||||
{
|
||||
if (_zipFile != nullptr)
|
||||
{
|
||||
zip_fclose(_zipFile);
|
||||
_zipFile = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool reset()
|
||||
{
|
||||
close();
|
||||
|
||||
_pos = 0;
|
||||
_maxLen = 0;
|
||||
_zipFile = zip_fopen_index(_zip, _index, 0);
|
||||
if (_zipFile == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
zip_stat_t zipFileStat{};
|
||||
if (zip_stat_index(_zip, _index, 0, &zipFileStat) != ZIP_ER_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_maxLen = zipFileStat.size;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::streamsize xsgetn(char_type* dst, std::streamsize len) override
|
||||
{
|
||||
if (_zipFile == nullptr && !reset())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto read = zip_fread(_zipFile, dst, len);
|
||||
if (read <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
_pos += read;
|
||||
return read;
|
||||
}
|
||||
|
||||
void skip(zip_int64_t len)
|
||||
{
|
||||
if (_zipFile != nullptr || reset())
|
||||
{
|
||||
char buffer[2048]{};
|
||||
while (len > 0)
|
||||
{
|
||||
auto readLen = std::min<zip_int64_t>(len, sizeof(buffer));
|
||||
auto read = zip_fread(_zipFile, buffer, readLen);
|
||||
if (read <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
_pos += read;
|
||||
len -= read;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pos_type seekpos(pos_type pos, ios_base::openmode mode) override final
|
||||
{
|
||||
if (pos > _pos)
|
||||
{
|
||||
// Read to seek fowards
|
||||
skip(pos - _pos);
|
||||
}
|
||||
else if (pos < _pos)
|
||||
{
|
||||
// Can not seek backwards, start from the beginning
|
||||
reset();
|
||||
skip(pos);
|
||||
}
|
||||
return std::clamp<pos_type>(pos, 0, _maxLen);
|
||||
}
|
||||
|
||||
pos_type seekoff(off_type off, ios_base::seekdir dir, ios_base::openmode mode) override
|
||||
{
|
||||
if (dir == std::ios::beg)
|
||||
{
|
||||
return seekpos(off, std::ios::in);
|
||||
}
|
||||
else if (dir == std::ios::cur)
|
||||
{
|
||||
return seekpos(_pos + off, std::ios::in);
|
||||
}
|
||||
else if (dir == std::ios::end)
|
||||
{
|
||||
return seekpos(_maxLen - off, std::ios::in);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::streampos(-1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
ifilestreambuf _streambuf;
|
||||
zip* _zip;
|
||||
zip_int64_t _index;
|
||||
zip_file_t* _zipFile{};
|
||||
zip_uint64_t _len{};
|
||||
zip_uint64_t _pos{};
|
||||
|
||||
public:
|
||||
ifilestream(zip* zip, zip_int64_t index)
|
||||
: std::istream(&_streambuf)
|
||||
, _streambuf(zip, index)
|
||||
ZipItemStream(zip* zip, zip_int64_t index)
|
||||
: _zip(zip)
|
||||
, _index(index)
|
||||
{
|
||||
}
|
||||
|
||||
~ZipItemStream() override
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool CanRead() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CanWrite() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t GetLength() const override
|
||||
{
|
||||
return _len;
|
||||
}
|
||||
|
||||
uint64_t GetPosition() const override
|
||||
{
|
||||
return _pos;
|
||||
}
|
||||
|
||||
void SetPosition(uint64_t position) override
|
||||
{
|
||||
if (position > _pos)
|
||||
{
|
||||
// Read to seek forwards
|
||||
Skip(position - _pos);
|
||||
}
|
||||
else if (position < _pos)
|
||||
{
|
||||
// Can not seek backwards, start from the beginning
|
||||
Reset();
|
||||
Skip(position);
|
||||
}
|
||||
}
|
||||
|
||||
void Seek(int64_t offset, int32_t origin) override
|
||||
{
|
||||
switch (origin)
|
||||
{
|
||||
case STREAM_SEEK_BEGIN:
|
||||
SetPosition(offset);
|
||||
break;
|
||||
case STREAM_SEEK_CURRENT:
|
||||
SetPosition(_pos + offset);
|
||||
break;
|
||||
case STREAM_SEEK_END:
|
||||
SetPosition(_len - offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Read(void* buffer, uint64_t length) override
|
||||
{
|
||||
size_t readBytes = TryRead(buffer, length);
|
||||
if (readBytes != length)
|
||||
{
|
||||
throw IOException("Attempted to read past end of file.");
|
||||
}
|
||||
}
|
||||
|
||||
void Write(const void* buffer, uint64_t length) override
|
||||
{
|
||||
throw IOException("Stream is read-only.");
|
||||
}
|
||||
|
||||
uint64_t TryRead(void* buffer, uint64_t length) override
|
||||
{
|
||||
if (_zipFile == nullptr && !Reset())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto readBytes = zip_fread(_zipFile, buffer, length);
|
||||
if (readBytes < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pos += readBytes;
|
||||
return static_cast<uint64_t>(readBytes);
|
||||
}
|
||||
}
|
||||
|
||||
const void* GetData() const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
void Close()
|
||||
{
|
||||
if (_zipFile != nullptr)
|
||||
{
|
||||
zip_fclose(_zipFile);
|
||||
_zipFile = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Reset()
|
||||
{
|
||||
Close();
|
||||
|
||||
_pos = 0;
|
||||
_len = 0;
|
||||
_zipFile = zip_fopen_index(_zip, _index, 0);
|
||||
if (_zipFile == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
zip_stat_t zipFileStat{};
|
||||
if (zip_stat_index(_zip, _index, 0, &zipFileStat) != ZIP_ER_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_len = zipFileStat.size;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Skip(zip_int64_t len)
|
||||
{
|
||||
// zip_fseek can not be used on compressed data, so skip bytes by
|
||||
// reading into a temporary buffer
|
||||
char buffer[2048]{};
|
||||
while (len > 0)
|
||||
{
|
||||
auto readLen = std::min<zip_int64_t>(len, sizeof(buffer));
|
||||
auto read = zip_fread(_zipFile, buffer, readLen);
|
||||
if (read <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
_pos += read;
|
||||
len -= read;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -17,6 +17,11 @@
|
|||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace OpenRCT2
|
||||
{
|
||||
struct IStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a zip file.
|
||||
*/
|
||||
|
@ -30,7 +35,7 @@ struct IZipArchive
|
|||
virtual std::string GetFileName(size_t index) const abstract;
|
||||
virtual uint64_t GetFileSize(size_t index) const abstract;
|
||||
virtual std::vector<uint8_t> GetFileData(std::string_view path) const abstract;
|
||||
virtual std::unique_ptr<std::istream> GetFileStream(std::string_view path) const abstract;
|
||||
virtual std::unique_ptr<OpenRCT2::IStream> GetFileStream(std::string_view path) const abstract;
|
||||
|
||||
/**
|
||||
* Creates or overwrites a file within the zip archive to the given data buffer.
|
||||
|
|
|
@ -11,11 +11,14 @@
|
|||
|
||||
# include "../platform/platform.h"
|
||||
# include "IStream.hpp"
|
||||
# include "MemoryStream.h"
|
||||
# include "Zip.h"
|
||||
|
||||
# include <SDL.h>
|
||||
# include <jni.h>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
class ZipArchive final : public IZipArchive
|
||||
{
|
||||
private:
|
||||
|
@ -113,10 +116,10 @@ public:
|
|||
return std::vector<uint8_t>(dataPtr, dataPtr + dataSize);
|
||||
}
|
||||
|
||||
std::unique_ptr<std::istream> GetFileStream(std::string_view path) const override
|
||||
std::unique_ptr<IStream> GetFileStream(std::string_view path) const override
|
||||
{
|
||||
auto data = GetFileData(path);
|
||||
return std::make_unique<memstream>(std::move(data));
|
||||
return std::make_unique<MemoryStream>(std::move(data));
|
||||
}
|
||||
|
||||
void SetFileData(std::string_view path, std::vector<uint8_t>&& data) override
|
||||
|
@ -133,34 +136,6 @@ public:
|
|||
{
|
||||
STUB();
|
||||
}
|
||||
|
||||
private:
|
||||
class memstream final : public std::istream
|
||||
{
|
||||
private:
|
||||
class vector_streambuf : public std::basic_streambuf<char, std::char_traits<char>>
|
||||
{
|
||||
public:
|
||||
explicit vector_streambuf(const std::vector<uint8_t>& vec)
|
||||
{
|
||||
this->setg(
|
||||
reinterpret_cast<char*>(const_cast<unsigned char*>(vec.data())),
|
||||
reinterpret_cast<char*>(const_cast<unsigned char*>(vec.data())),
|
||||
reinterpret_cast<char*>(const_cast<unsigned char*>(vec.data() + vec.size())));
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<uint8_t> _data;
|
||||
vector_streambuf _streambuf;
|
||||
|
||||
public:
|
||||
memstream(std::vector<uint8_t>&& data)
|
||||
: std::istream(&_streambuf)
|
||||
, _data(data)
|
||||
, _streambuf(_data)
|
||||
{
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
namespace Zip
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "../Context.h"
|
||||
#include "../core/File.h"
|
||||
#include "../core/FileStream.h"
|
||||
#include "../core/Memory.hpp"
|
||||
#include "../core/String.hpp"
|
||||
#include "../core/Zip.h"
|
||||
|
@ -24,6 +25,8 @@
|
|||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
ObjectType& operator++(ObjectType& d, int)
|
||||
{
|
||||
return d = (d == ObjectType::Count) ? ObjectType::Ride : static_cast<ObjectType>(static_cast<uint8_t>(d) + 1);
|
||||
|
@ -167,19 +170,72 @@ std::optional<uint8_t> rct_object_entry::GetSceneryType() const
|
|||
}
|
||||
}
|
||||
|
||||
class zipstreamwrapper final : public std::istream
|
||||
/**
|
||||
* Couples a zip archive and a zip item stream to ensure the lifetime of the zip archive is maintained
|
||||
* for the lifetime of the stream.
|
||||
*/
|
||||
class ZipStreamWrapper final : public IStream
|
||||
{
|
||||
private:
|
||||
std::unique_ptr<IZipArchive> _zipArchive;
|
||||
std::unique_ptr<std::istream> _base;
|
||||
std::unique_ptr<IStream> _base;
|
||||
|
||||
public:
|
||||
zipstreamwrapper(std::unique_ptr<IZipArchive> zipArchive, std::unique_ptr<std::istream> base)
|
||||
: std::istream(base->rdbuf())
|
||||
, _zipArchive(std::move(zipArchive))
|
||||
ZipStreamWrapper(std::unique_ptr<IZipArchive> zipArchive, std::unique_ptr<IStream> base)
|
||||
: _zipArchive(std::move(zipArchive))
|
||||
, _base(std::move(base))
|
||||
{
|
||||
}
|
||||
|
||||
bool CanRead() const override
|
||||
{
|
||||
return _base->CanRead();
|
||||
}
|
||||
|
||||
bool CanWrite() const override
|
||||
{
|
||||
return _base->CanWrite();
|
||||
}
|
||||
|
||||
uint64_t GetLength() const override
|
||||
{
|
||||
return _base->GetLength();
|
||||
}
|
||||
|
||||
uint64_t GetPosition() const override
|
||||
{
|
||||
return _base->GetPosition();
|
||||
}
|
||||
|
||||
void SetPosition(uint64_t position) override
|
||||
{
|
||||
_base->SetPosition(position);
|
||||
}
|
||||
|
||||
void Seek(int64_t offset, int32_t origin) override
|
||||
{
|
||||
_base->Seek(offset, origin);
|
||||
}
|
||||
|
||||
void Read(void* buffer, uint64_t length) override
|
||||
{
|
||||
_base->Read(buffer, length);
|
||||
}
|
||||
|
||||
void Write(const void* buffer, uint64_t length) override
|
||||
{
|
||||
_base->Write(buffer, length);
|
||||
}
|
||||
|
||||
uint64_t TryRead(void* buffer, uint64_t length) override
|
||||
{
|
||||
return _base->TryRead(buffer, length);
|
||||
}
|
||||
|
||||
const void* GetData() const override
|
||||
{
|
||||
return _base->GetData();
|
||||
}
|
||||
};
|
||||
|
||||
bool ObjectAsset::IsAvailable() const
|
||||
|
@ -224,11 +280,11 @@ size_t ObjectAsset::GetLength() const
|
|||
return 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<std::istream> ObjectAsset::GetStream() const
|
||||
std::unique_ptr<IStream> ObjectAsset::GetStream() const
|
||||
{
|
||||
if (_zipPath.empty())
|
||||
{
|
||||
return std::make_unique<std::ifstream>(_path, std::ios::binary);
|
||||
return std::make_unique<FileStream>(_path, FILE_MODE_OPEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -238,7 +294,7 @@ std::unique_ptr<std::istream> ObjectAsset::GetStream() const
|
|||
auto stream = zipArchive->GetFileStream(_path);
|
||||
if (stream != nullptr)
|
||||
{
|
||||
return std::make_unique<zipstreamwrapper>(std::move(zipArchive), std::move(stream));
|
||||
return std::make_unique<ZipStreamWrapper>(std::move(zipArchive), std::move(stream));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
#include "ImageTable.h"
|
||||
#include "StringTable.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
|
@ -223,7 +221,7 @@ public:
|
|||
|
||||
bool IsAvailable() const;
|
||||
size_t GetLength() const;
|
||||
std::unique_ptr<std::istream> GetStream() const;
|
||||
std::unique_ptr<OpenRCT2::IStream> GetStream() const;
|
||||
};
|
||||
|
||||
struct IReadObjectContext
|
||||
|
|
Loading…
Reference in New Issue