Use unique_ptr to store istream

pull/3226/head
elsid 2 years ago
parent c94d8be7bf
commit 94c1d0cced
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40

@ -44,7 +44,7 @@ void VideoWidget::playVideo(const std::string &video)
return;
}
mPlayer->playVideo(videoStream, video);
mPlayer->playVideo(std::move(videoStream), video);
osg::ref_ptr<osg::Texture2D> texture = mPlayer->getVideoTexture();
if (!texture)

@ -23,7 +23,7 @@ namespace
Files::IStreamPtr open() override
{
return std::make_shared<std::stringstream>(mContent, std::ios_base::in);
return std::make_unique<std::stringstream>(mContent, std::ios_base::in);
}
private:

@ -370,7 +370,7 @@ Files::IStreamPtr CompressedBSAFile::getFile(const FileRecord& fileRecord)
fileStream->read(reinterpret_cast<char*>(&uncompressedSize), sizeof(uint32_t));
size -= sizeof(uint32_t);
}
std::shared_ptr<Bsa::MemoryInputStream> memoryStreamPtr = std::make_shared<MemoryInputStream>(uncompressedSize);
auto memoryStreamPtr = std::make_unique<MemoryInputStream>(uncompressedSize);
if (compressed)
{
@ -403,7 +403,7 @@ Files::IStreamPtr CompressedBSAFile::getFile(const FileRecord& fileRecord)
fileStream->read(memoryStreamPtr->getRawData(), size);
}
return std::shared_ptr<std::istream>(memoryStreamPtr, (std::istream*)memoryStreamPtr.get());
return std::make_unique<Files::StreamWithBuffer<MemoryInputStream>>(std::move(memoryStreamPtr));
}
BsaVersion CompressedBSAFile::detectVersion(const std::string& filePath)

@ -26,7 +26,7 @@ namespace ESM
if (modVer == ESM4::REC_TES4)
{
return new ESM4::Reader(esmStream, filename);
return new ESM4::Reader(std::move(esmStream), filename);
}
else
{
@ -38,15 +38,15 @@ namespace ESM
}
bool Reader::getStringImpl(std::string& str, std::size_t size,
Files::IStreamPtr filestream, ToUTF8::StatelessUtf8Encoder* encoder, bool hasNull)
std::istream& stream, ToUTF8::StatelessUtf8Encoder* encoder, bool hasNull)
{
std::size_t newSize = size;
if (encoder)
{
std::string input(size, '\0');
filestream->read(input.data(), size);
if (filestream->gcount() == static_cast<std::streamsize>(size))
stream.read(input.data(), size);
if (stream.gcount() == static_cast<std::streamsize>(size))
{
encoder->getUtf8(input, ToUTF8::BufferAllocationPolicy::FitToRequiredSize, str);
return true;
@ -58,13 +58,13 @@ namespace ESM
newSize -= 1; // don't read the null terminator yet
str.resize(newSize); // assumed C++11
filestream->read(&str[0], newSize);
if ((std::size_t)filestream->gcount() == newSize)
stream.read(&str[0], newSize);
if (static_cast<std::size_t>(stream.gcount()) == newSize)
{
if (hasNull)
{
char ch;
filestream->read(&ch, 1); // read the null terminator
stream.read(&ch, 1); // read the null terminator
assert (ch == '\0'
&& "ESM4::Reader::getString string is not terminated with a null");
}

@ -53,7 +53,7 @@ namespace ESM
protected:
bool getStringImpl(std::string& str, std::size_t size,
Files::IStreamPtr filestream, ToUTF8::StatelessUtf8Encoder* encoder, bool hasNull = false);
std::istream& stream, ToUTF8::StatelessUtf8Encoder* encoder, bool hasNull = false);
};
}

@ -64,8 +64,8 @@ ReaderContext::ReaderContext() : modIndex(0), recHeaderSize(sizeof(RecordHeader)
currCellGrid.grid.y = 0;
}
Reader::Reader(Files::IStreamPtr esmStream, const std::string& filename)
: mEncoder(nullptr), mFileSize(0), mStream(esmStream)
Reader::Reader(Files::IStreamPtr&& esmStream, const std::string& filename)
: mEncoder(nullptr), mFileSize(0), mStream(std::move(esmStream))
{
// used by ESMReader only?
mCtx.filename = filename;
@ -130,8 +130,7 @@ bool Reader::restoreContext(const ReaderContext& ctx)
{
if (mSavedStream) // TODO: doesn't seem to ever happen
{
mStream = mSavedStream;
mSavedStream.reset();
mStream = std::move(mSavedStream);
}
mCtx.groupStack.clear(); // probably not necessary since it will be overwritten
@ -148,11 +147,11 @@ void Reader::close()
//mHeader.blank();
}
void Reader::openRaw(Files::IStreamPtr esmStream, const std::string& filename)
void Reader::openRaw(Files::IStreamPtr&& stream, const std::string& filename)
{
close();
mStream = esmStream;
mStream = std::move(stream);
mCtx.filename = filename;
mCtx.fileRead = 0;
mStream->seekg(0, mStream->end);
@ -161,9 +160,9 @@ void Reader::openRaw(Files::IStreamPtr esmStream, const std::string& filename)
}
void Reader::open(Files::IStreamPtr esmStream, const std::string &filename)
void Reader::open(Files::IStreamPtr&& stream, const std::string &filename)
{
openRaw(esmStream, filename);
openRaw(std::move(stream), filename);
// should at least have the size of ESM3 record header (20 or 24 bytes for ESM4)
assert (mFileSize >= 16);
@ -210,32 +209,33 @@ void Reader::buildLStringIndex(const std::string& stringFile, LocalizedStringTyp
sp.type = stringType;
// TODO: possibly check if the resource exists?
Files::IStreamPtr filestream = Files::IStreamPtr(Files::openConstrainedFileStream(stringFile));
Files::IStreamPtr filestream = Files::openConstrainedFileStream(stringFile);
filestream->seekg(0, std::ios::end);
std::size_t fileSize = filestream->tellg();
filestream->seekg(0, std::ios::beg);
std::istream* stream = filestream.get();
switch (stringType)
{
case Type_Strings: mStrings = filestream; break;
case Type_ILStrings: mILStrings = filestream; break;
case Type_DLStrings: mDLStrings = filestream; break;
case Type_Strings: mStrings = std::move(filestream); break;
case Type_ILStrings: mILStrings = std::move(filestream); break;
case Type_DLStrings: mDLStrings = std::move(filestream); break;
default:
throw std::runtime_error("ESM4::Reader::unknown localised string type");
}
filestream->read((char*)&numEntries, sizeof(numEntries));
filestream->read((char*)&dataSize, sizeof(dataSize));
stream->read((char*)&numEntries, sizeof(numEntries));
stream->read((char*)&dataSize, sizeof(dataSize));
std::size_t dataStart = fileSize - dataSize;
for (unsigned int i = 0; i < numEntries; ++i)
{
filestream->read((char*)&stringId, sizeof(stringId));
filestream->read((char*)&sp.offset, sizeof(sp.offset));
stream->read((char*)&stringId, sizeof(stringId));
stream->read((char*)&sp.offset, sizeof(sp.offset));
sp.offset += (std::uint32_t)dataStart;
mLStringIndex[stringId] = sp;
}
//assert (dataStart - filestream->tell() == 0 && "String file start of data section mismatch");
//assert (dataStart - stream->tell() == 0 && "String file start of data section mismatch");
}
void Reader::getLocalizedString(std::string& str)
@ -256,13 +256,13 @@ void Reader::getLocalizedStringImpl(const FormId stringId, std::string& str)
if (it != mLStringIndex.end())
{
Files::IStreamPtr filestream;
std::istream* filestream = nullptr;
switch (it->second.type)
{
case Type_Strings: // no string size provided
{
filestream = mStrings;
filestream = mStrings.get();
filestream->seekg(it->second.offset);
char ch;
@ -275,8 +275,8 @@ void Reader::getLocalizedStringImpl(const FormId stringId, std::string& str)
str = std::string(data.data());
return;
}
case Type_ILStrings: filestream = mILStrings; break;
case Type_DLStrings: filestream = mDLStrings; break;
case Type_ILStrings: filestream = mILStrings.get(); break;
case Type_DLStrings: filestream = mDLStrings.get(); break;
default:
throw std::runtime_error("ESM4::Reader::getLocalizedString unknown string type");
}
@ -285,7 +285,7 @@ void Reader::getLocalizedStringImpl(const FormId stringId, std::string& str)
filestream->seekg(it->second.offset);
std::uint32_t size = 0;
filestream->read((char*)&size, sizeof(size));
getStringImpl(str, size, filestream, mEncoder, true); // expect null terminated string
getStringImpl(str, size, *filestream, mEncoder, true); // expect null terminated string
}
else
throw std::runtime_error("ESM4::Reader::getLocalizedString localized string not found");
@ -296,8 +296,7 @@ bool Reader::getRecordHeader()
// FIXME: this seems very hacky but we may have skipped subrecords from within an inflated data block
if (/*mStream->eof() && */mSavedStream)
{
mStream = mSavedStream;
mSavedStream.reset();
mStream = std::move(mSavedStream);
}
mStream->read((char*)&mCtx.recordHeader, mCtx.recHeaderSize);
@ -336,12 +335,11 @@ void Reader::getRecordData(bool dump)
Bsa::MemoryInputStream compressedRecord(recordSize);
mStream->read(compressedRecord.getRawData(), recordSize);
std::istream *fileStream = (std::istream*)&compressedRecord;
mSavedStream = mStream;
mSavedStream = std::move(mStream);
mCtx.recordHeader.record.dataSize = uncompressedSize - sizeof(uncompressedSize);
std::shared_ptr<Bsa::MemoryInputStream> memoryStreamPtr
= std::make_shared<Bsa::MemoryInputStream>(uncompressedSize);
auto memoryStreamPtr = std::make_unique<Bsa::MemoryInputStream>(uncompressedSize);
boost::iostreams::filtering_streambuf<boost::iostreams::input> inputStreamBuf;
inputStreamBuf.push(boost::iostreams::zlib_decompressor());
@ -370,7 +368,7 @@ if (dump)
std::cout << ss.str() << std::endl;
}
//#endif
mStream = std::shared_ptr<std::istream>(memoryStreamPtr, (std::istream*)memoryStreamPtr.get());
mStream = std::make_unique<Files::StreamWithBuffer<Bsa::MemoryInputStream>>(std::move(memoryStreamPtr));
}
}

@ -114,17 +114,17 @@ namespace ESM4 {
//void close();
// Raw opening. Opens the file and sets everything up but doesn't parse the header.
void openRaw(Files::IStreamPtr esmStream, const std::string& filename);
void openRaw(Files::IStreamPtr&& stream, const std::string& filename);
// Load ES file from a new stream, parses the header.
// Closes the currently open file first, if any.
void open(Files::IStreamPtr esmStream, const std::string& filename);
void open(Files::IStreamPtr&& stream, const std::string& filename);
Reader() = default;
public:
Reader(Files::IStreamPtr esmStream, const std::string& filename);
Reader(Files::IStreamPtr&& esmStream, const std::string& filename);
~Reader();
// FIXME: should be private but ESMTool uses it
@ -280,10 +280,10 @@ namespace ESM4 {
// Note: uses the string size from the subrecord header rather than checking null termination
bool getZString(std::string& str) {
return getStringImpl(str, mCtx.subRecordHeader.dataSize, mStream, mEncoder, true);
return getStringImpl(str, mCtx.subRecordHeader.dataSize, *mStream, mEncoder, true);
}
bool getString(std::string& str) {
return getStringImpl(str, mCtx.subRecordHeader.dataSize, mStream, mEncoder);
return getStringImpl(str, mCtx.subRecordHeader.dataSize, *mStream, mEncoder);
}
void enterGroup();

@ -4,6 +4,6 @@ namespace Files
{
IStreamPtr openConstrainedFileStream(const std::string& filename, std::size_t start, std::size_t length)
{
return std::make_shared<ConstrainedFileStream>(std::make_unique<ConstrainedFileStreamBuf>(filename, start, length));
return std::make_unique<ConstrainedFileStream>(std::make_unique<ConstrainedFileStreamBuf>(filename, start, length));
}
}

@ -15,7 +15,7 @@ namespace Files
/// A file stream constrained to a specific region in the file, specified by the 'start' and 'length' parameters.
using ConstrainedFileStream = StreamWithBuffer<ConstrainedFileStreamBuf>;
typedef std::shared_ptr<std::istream> IStreamPtr;
typedef std::unique_ptr<std::istream> IStreamPtr;
IStreamPtr openConstrainedFileStream(const std::string& filename, std::size_t start = 0,
std::size_t length = std::numeric_limits<std::size_t>::max());

@ -137,12 +137,12 @@ namespace
}
}
[[noreturn]] void fail (Files::IStreamPtr file, const std::string& fileName, const std::string& message)
[[noreturn]] void fail(std::istream& stream, const std::string& fileName, const std::string& message)
{
std::stringstream error;
error << "Font loading error: " << message;
error << "\n File: " << fileName;
error << "\n Offset: 0x" << std::hex << file->tellg();
error << "\n Offset: 0x" << std::hex << stream.tellg();
throw std::runtime_error(error.str());
}
@ -252,33 +252,33 @@ namespace Gui
float fontSize;
file->read((char*)&fontSize, sizeof(fontSize));
if (!file->good())
fail(file, fileName, "File too small to be a valid font");
fail(*file, fileName, "File too small to be a valid font");
int one;
file->read((char*)&one, sizeof(one));
if (!file->good())
fail(file, fileName, "File too small to be a valid font");
fail(*file, fileName, "File too small to be a valid font");
if (one != 1)
fail(file, fileName, "Unexpected value");
fail(*file, fileName, "Unexpected value");
file->read((char*)&one, sizeof(one));
if (!file->good())
fail(file, fileName, "File too small to be a valid font");
fail(*file, fileName, "File too small to be a valid font");
if (one != 1)
fail(file, fileName, "Unexpected value");
fail(*file, fileName, "Unexpected value");
char name_[284];
file->read(name_, sizeof(name_));
if (!file->good())
fail(file, fileName, "File too small to be a valid font");
fail(*file, fileName, "File too small to be a valid font");
std::string name(name_);
GlyphInfo data[256];
file->read((char*)data, sizeof(data));
if (!file->good())
fail(file, fileName, "File too small to be a valid font");
fail(*file, fileName, "File too small to be a valid font");
file.reset();
@ -292,16 +292,16 @@ namespace Gui
bitmapFile->read((char*)&height, sizeof(int));
if (!bitmapFile->good())
fail(bitmapFile, bitmapFilename, "File too small to be a valid bitmap");
fail(*bitmapFile, bitmapFilename, "File too small to be a valid bitmap");
if (width <= 0 || height <= 0)
fail(bitmapFile, bitmapFilename, "Width and height must be positive");
fail(*bitmapFile, bitmapFilename, "Width and height must be positive");
std::vector<char> textureData;
textureData.resize(width*height*4);
bitmapFile->read(&textureData[0], width*height*4);
if (!bitmapFile->good())
fail(bitmapFile, bitmapFilename, "File too small to be a valid bitmap");
fail(*bitmapFile, bitmapFilename, "File too small to be a valid bitmap");
bitmapFile.reset();
std::string resourceName;

@ -12,10 +12,10 @@ namespace Nif
{
/// Open a NIF stream. The name is used for error messages.
NIFFile::NIFFile(Files::IStreamPtr stream, const std::string &name)
NIFFile::NIFFile(Files::IStreamPtr&& stream, const std::string &name)
: filename(name)
{
parse(stream);
parse(std::move(stream));
}
template <typename NodeType, RecordType recordType>
@ -170,12 +170,12 @@ std::string NIFFile::printVersion(unsigned int version)
return stream.str();
}
void NIFFile::parse(Files::IStreamPtr stream)
void NIFFile::parse(Files::IStreamPtr&& stream)
{
const std::array<std::uint64_t, 2> fileHash = Files::getHash(filename, *stream);
hash.append(reinterpret_cast<const char*>(fileHash.data()), fileHash.size() * sizeof(std::uint64_t));
NIFStream nif (this, stream);
NIFStream nif (this, std::move(stream));
// Check the header string
std::string head = nif.getVersionString();

@ -69,7 +69,7 @@ class NIFFile final : public File
static std::atomic_bool sLoadUnsupportedFiles;
/// Parse the file
void parse(Files::IStreamPtr stream);
void parse(Files::IStreamPtr&& stream);
/// Get the file's version in a human readable form
///\returns A string containing a human readable NIF version number
@ -107,7 +107,7 @@ public:
}
/// Open a NIF stream. The name is used for error messages.
NIFFile(Files::IStreamPtr stream, const std::string &name);
NIFFile(Files::IStreamPtr&& stream, const std::string &name);
/// Get a given record
Record *getRecord(size_t index) const override

@ -62,7 +62,7 @@ public:
NIFFile * const file;
NIFStream (NIFFile * file, Files::IStreamPtr inp): inp (inp), file (file) {}
NIFStream (NIFFile * file, Files::IStreamPtr&& inp): inp (std::move(inp)), file (file) {}
void skip(size_t size) { inp->ignore(size); }

@ -27,7 +27,7 @@ void VideoPlayer::setAudioFactory(MovieAudioFactory *factory)
mAudioFactory.reset(factory);
}
void VideoPlayer::playVideo(std::shared_ptr<std::istream> inputstream, const std::string& name)
void VideoPlayer::playVideo(std::unique_ptr<std::istream>&& inputstream, const std::string& name)
{
if(mState)
close();
@ -35,7 +35,7 @@ void VideoPlayer::playVideo(std::shared_ptr<std::istream> inputstream, const std
try {
mState = new VideoState;
mState->setAudioFactory(mAudioFactory.get());
mState->init(inputstream, name);
mState->init(std::move(inputstream), name);
// wait until we have the first picture
while (mState->video_st && !mState->mTexture.get())

@ -42,7 +42,7 @@ namespace Video
/// Play the given video. If a video is already playing, the old video is closed first.
/// @note The video will be unpaused by default. Use the pause() and play() methods to control pausing.
/// @param name A name for the video stream - only used for logging purposes.
void playVideo (std::shared_ptr<std::istream> inputstream, const std::string& name);
void playVideo(std::unique_ptr<std::istream>&& inputstream, const std::string& name);
/// Get the current playback time position in the video, in seconds
double getCurrentTime();

@ -714,7 +714,7 @@ int VideoState::stream_open(int stream_index, AVFormatContext *pFormatCtx)
return 0;
}
void VideoState::init(std::shared_ptr<std::istream> inputstream, const std::string &name)
void VideoState::init(std::unique_ptr<std::istream>&& inputstream, const std::string &name)
{
int video_index = -1;
int audio_index = -1;

@ -128,7 +128,7 @@ struct VideoState {
void setAudioFactory(MovieAudioFactory* factory);
void init(std::shared_ptr<std::istream> inputstream, const std::string& name);
void init(std::unique_ptr<std::istream>&& inputstream, const std::string& name);
void deinit();
void setPaused(bool isPaused);
@ -165,7 +165,7 @@ struct VideoState {
ExternalClock mExternalClock;
std::shared_ptr<std::istream> stream;
std::unique_ptr<std::istream> stream;
AVFormatContext* format_ctx;
AVCodecContext* video_ctx;
AVCodecContext* audio_ctx;

Loading…
Cancel
Save