1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-15 16:39:41 +00:00

Use ifstream for ESMReader

ESMReader reads the whole file, there is no need in the ConstrainedFileStream.
This commit is contained in:
elsid 2022-04-14 22:12:59 +02:00
parent ea6b84ce1f
commit b09570692e
No known key found for this signature in database
GPG key ID: B845CB9FEE18AB40
9 changed files with 54 additions and 30 deletions

View file

@ -21,7 +21,7 @@ void EsmLoader::load(const boost::filesystem::path& filepath, int& index, Loadin
lEsm.setIndex(index); lEsm.setIndex(index);
lEsm.open(filepath.string()); lEsm.open(filepath.string());
lEsm.resolveParentFileIndices(mEsm); lEsm.resolveParentFileIndices(mEsm);
mEsm[index] = lEsm; mEsm[index] = std::move(lEsm);
mStore.load(mEsm[index], listener); mStore.load(mEsm[index], listener);
} }

View file

@ -436,7 +436,7 @@ namespace
{ {
Variant result; Variant result;
ESMReader reader; ESMReader reader;
reader.open(std::make_shared<std::istringstream>(data), ""); reader.open(std::make_unique<std::istringstream>(data), "");
result.read(reader, format); result.read(reader, format);
return result; return result;
} }

View file

@ -224,17 +224,17 @@ protected:
/// Create an ESM file in-memory containing the specified record. /// Create an ESM file in-memory containing the specified record.
/// @param deleted Write record with deleted flag? /// @param deleted Write record with deleted flag?
template <typename T> template <typename T>
Files::IStreamPtr getEsmFile(T record, bool deleted) std::unique_ptr<std::istream> getEsmFile(T record, bool deleted)
{ {
ESM::ESMWriter writer; ESM::ESMWriter writer;
auto* stream = new std::stringstream; auto stream = std::make_unique<std::stringstream>();
writer.setFormat(0); writer.setFormat(0);
writer.save(*stream); writer.save(*stream);
writer.startRecord(T::sRecordId); writer.startRecord(T::sRecordId);
record.save(writer, deleted); record.save(writer, deleted);
writer.endRecord(T::sRecordId); writer.endRecord(T::sRecordId);
return Files::IStreamPtr(stream); return stream;
} }
/// Tests deletion of records. /// Tests deletion of records.
@ -251,16 +251,14 @@ TEST_F(StoreTest, delete_test)
ESM::ESMReader reader; ESM::ESMReader reader;
// master file inserts a record // master file inserts a record
Files::IStreamPtr file = getEsmFile(record, false); reader.open(getEsmFile(record, false), "filename");
reader.open(file, "filename");
mEsmStore.load(reader, &dummyListener); mEsmStore.load(reader, &dummyListener);
mEsmStore.setUp(); mEsmStore.setUp();
ASSERT_TRUE (mEsmStore.get<RecordType>().getSize() == 1); ASSERT_TRUE (mEsmStore.get<RecordType>().getSize() == 1);
// now a plugin deletes it // now a plugin deletes it
file = getEsmFile(record, true); reader.open(getEsmFile(record, true), "filename");
reader.open(file, "filename");
mEsmStore.load(reader, &dummyListener); mEsmStore.load(reader, &dummyListener);
mEsmStore.setUp(); mEsmStore.setUp();
@ -268,8 +266,7 @@ TEST_F(StoreTest, delete_test)
// now another plugin inserts it again // now another plugin inserts it again
// expected behaviour is the record to reappear rather than staying deleted // expected behaviour is the record to reappear rather than staying deleted
file = getEsmFile(record, false); reader.open(getEsmFile(record, false), "filename");
reader.open(file, "filename");
mEsmStore.load(reader, &dummyListener); mEsmStore.load(reader, &dummyListener);
mEsmStore.setUp(); mEsmStore.setUp();
@ -291,16 +288,14 @@ TEST_F(StoreTest, overwrite_test)
ESM::ESMReader reader; ESM::ESMReader reader;
// master file inserts a record // master file inserts a record
Files::IStreamPtr file = getEsmFile(record, false); reader.open(getEsmFile(record, false), "filename");
reader.open(file, "filename");
mEsmStore.load(reader, &dummyListener); mEsmStore.load(reader, &dummyListener);
mEsmStore.setUp(); mEsmStore.setUp();
// now a plugin overwrites it with changed data // now a plugin overwrites it with changed data
record.mId = recordIdUpper; // change id to uppercase, to test case smashing while we're at it record.mId = recordIdUpper; // change id to uppercase, to test case smashing while we're at it
record.mModel = "the_new_model"; record.mModel = "the_new_model";
file = getEsmFile(record, false); reader.open(getEsmFile(record, false), "filename");
reader.open(file, "filename");
mEsmStore.load(reader, &dummyListener); mEsmStore.load(reader, &dummyListener);
mEsmStore.setUp(); mEsmStore.setUp();

View file

@ -206,7 +206,7 @@ IF(NOT WIN32 AND NOT APPLE)
ENDIF() ENDIF()
add_component_dir (files add_component_dir (files
linuxpath androidpath windowspath macospath fixedpath multidircollection collections configurationmanager linuxpath androidpath windowspath macospath fixedpath multidircollection collections configurationmanager
lowlevelfile constrainedfilestream memorystream hash configfileparser lowlevelfile constrainedfilestream memorystream hash configfileparser openfile
) )
add_component_dir (compiler add_component_dir (compiler

View file

@ -2,9 +2,11 @@
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
#include <components/files/openfile.hpp>
#include <stdexcept> #include <stdexcept>
#include <sstream> #include <sstream>
#include <fstream>
namespace ESM namespace ESM
{ {
@ -82,10 +84,10 @@ void ESMReader::resolveParentFileIndices(const std::vector<ESMReader>& allPlugin
} }
} }
void ESMReader::openRaw(Files::IStreamPtr _esm, const std::string& name) void ESMReader::openRaw(std::unique_ptr<std::istream>&& stream, const std::string& name)
{ {
close(); close();
mEsm = _esm; mEsm = std::move(stream);
mCtx.filename = name; mCtx.filename = name;
mEsm->seekg(0, mEsm->end); mEsm->seekg(0, mEsm->end);
mCtx.leftFile = mFileSize = mEsm->tellg(); mCtx.leftFile = mFileSize = mEsm->tellg();
@ -94,12 +96,12 @@ void ESMReader::openRaw(Files::IStreamPtr _esm, const std::string& name)
void ESMReader::openRaw(const std::string& filename) void ESMReader::openRaw(const std::string& filename)
{ {
openRaw(Files::openConstrainedFileStream(filename), filename); openRaw(Files::openBinaryInputFileStream(filename), filename);
} }
void ESMReader::open(Files::IStreamPtr _esm, const std::string &name) void ESMReader::open(std::unique_ptr<std::istream>&& stream, const std::string &name)
{ {
openRaw(_esm, name); openRaw(std::move(stream), name);
if (getRecName() != "TES3") if (getRecName() != "TES3")
fail("Not a valid Morrowind file"); fail("Not a valid Morrowind file");
@ -111,7 +113,7 @@ void ESMReader::open(Files::IStreamPtr _esm, const std::string &name)
void ESMReader::open(const std::string &file) void ESMReader::open(const std::string &file)
{ {
open (Files::openConstrainedFileStream(file), file); open(Files::openBinaryInputFileStream(file), file);
} }
std::string ESMReader::getHNOString(NAME name) std::string ESMReader::getHNOString(NAME name)

View file

@ -3,8 +3,8 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
#include <istream>
#include <components/files/constrainedfilestream.hpp> #include <memory>
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
@ -61,11 +61,11 @@ public:
/// Raw opening. Opens the file and sets everything up but doesn't /// Raw opening. Opens the file and sets everything up but doesn't
/// parse the header. /// parse the header.
void openRaw(Files::IStreamPtr _esm, const std::string &name); void openRaw(std::unique_ptr<std::istream>&& stream, const std::string &name);
/// Load ES file from a new stream, parses the header. Closes the /// Load ES file from a new stream, parses the header. Closes the
/// currently open file first, if any. /// currently open file first, if any.
void open(Files::IStreamPtr _esm, const std::string &name); void open(std::unique_ptr<std::istream>&& stream, const std::string &name);
void open(const std::string &file); void open(const std::string &file);
@ -295,7 +295,7 @@ private:
void clearCtx(); void clearCtx();
Files::IStreamPtr mEsm; std::unique_ptr<std::istream> mEsm;
ESM_Context mCtx; ESM_Context mCtx;

View file

@ -188,7 +188,7 @@ namespace EsmLoader
reader.skipRecord(); reader.skipRecord();
} }
ESM::ESMReader loadEsm(const Query& query, ESM::ESMReader& reader, ShallowContent& content) void loadEsm(const Query& query, ESM::ESMReader& reader, ShallowContent& content)
{ {
Log(Debug::Info) << "Loading ESM file " << reader.getName(); Log(Debug::Info) << "Loading ESM file " << reader.getName();
@ -198,8 +198,6 @@ namespace EsmLoader
reader.getRecHeader(); reader.getRecHeader();
loadRecord(query, recName, reader, content); loadRecord(query, recName, reader, content);
} }
return reader;
} }
ShallowContent shallowLoad(const Query& query, const std::vector<std::string>& contentFiles, ShallowContent shallowLoad(const Query& query, const std::vector<std::string>& contentFiles,

View file

@ -0,0 +1,16 @@
#include "openfile.hpp"
#include <cstring>
#include <fstream>
namespace Files
{
std::unique_ptr<std::ifstream> openBinaryInputFileStream(const std::string& path)
{
auto stream = std::make_unique<std::ifstream>(path, std::ios::binary);
if (!stream->is_open())
throw std::runtime_error("Failed to open '" + path + "' for reading: " + std::strerror(errno));
stream->exceptions(std::ios::badbit);
return stream;
}
}

View file

@ -0,0 +1,13 @@
#ifndef OPENMW_COMPONENTS_FILES_OPENFILE_H
#define OPENMW_COMPONENTS_FILES_OPENFILE_H
#include <iosfwd>
#include <memory>
#include <string>
namespace Files
{
std::unique_ptr<std::ifstream> openBinaryInputFileStream(const std::string& path);
}
#endif