Merge branch 'esm_ifstream' into 'master'

Use ifstream for ESMReader

See merge request OpenMW/openmw!1776
pull/3226/head
psi29a 3 years ago
commit b4503c9c0a

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

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

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

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

@ -2,9 +2,11 @@
#include <boost/filesystem/path.hpp>
#include <components/misc/stringops.hpp>
#include <components/files/openfile.hpp>
#include <stdexcept>
#include <sstream>
#include <fstream>
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();
mEsm = _esm;
mEsm = std::move(stream);
mCtx.filename = name;
mEsm->seekg(0, mEsm->end);
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)
{
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")
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)
{
open (Files::openConstrainedFileStream(file), file);
open(Files::openBinaryInputFileStream(file), file);
}
std::string ESMReader::getHNOString(NAME name)

@ -3,8 +3,8 @@
#include <cstdint>
#include <vector>
#include <components/files/constrainedfilestream.hpp>
#include <istream>
#include <memory>
#include <components/misc/stringops.hpp>
@ -61,11 +61,11 @@ public:
/// Raw opening. Opens the file and sets everything up but doesn't
/// 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
/// 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);
@ -295,7 +295,7 @@ private:
void clearCtx();
Files::IStreamPtr mEsm;
std::unique_ptr<std::istream> mEsm;
ESM_Context mCtx;

@ -188,7 +188,7 @@ namespace EsmLoader
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();
@ -198,8 +198,6 @@ namespace EsmLoader
reader.getRecHeader();
loadRecord(query, recName, reader, content);
}
return reader;
}
ShallowContent shallowLoad(const Query& query, const std::vector<std::string>& contentFiles,

@ -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;
}
}

@ -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
Loading…
Cancel
Save