mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-25 12:41:01 +00:00
Merge branch 'rm_base_esm_reader' into 'master'
Remove ESM::Reader base class See merge request OpenMW/openmw!2388
This commit is contained in:
commit
25fa8c3656
@ -9,6 +9,7 @@
|
||||
#include <components/esm/esmcommon.hpp>
|
||||
#include <components/esm4/reader.hpp>
|
||||
#include <components/esm4/records.hpp>
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
|
||||
namespace EsmTool
|
||||
{
|
||||
|
@ -80,7 +80,7 @@ add_component_dir (to_utf8
|
||||
to_utf8
|
||||
)
|
||||
|
||||
add_component_dir(esm attr common defs esmcommon reader records util luascripts format)
|
||||
add_component_dir(esm attr common defs esmcommon records util luascripts format)
|
||||
|
||||
add_component_dir(fx pass technique lexer widgets stateupdater)
|
||||
|
||||
|
@ -1,86 +0,0 @@
|
||||
#include "reader.hpp"
|
||||
|
||||
//#ifdef NDEBUG
|
||||
//#undef NDEBUG
|
||||
//#endif
|
||||
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <components/files/constrainedfilestream.hpp>
|
||||
|
||||
#include "components/esm3/esmreader.hpp"
|
||||
#include "components/esm4/reader.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
Reader* Reader::getReader(const std::string &filename)
|
||||
{
|
||||
Files::IStreamPtr esmStream(Files::openConstrainedFileStream(filename));
|
||||
|
||||
std::uint32_t modVer = 0; // get the first 4 bytes of the record header only
|
||||
esmStream->read((char*)&modVer, sizeof(modVer));
|
||||
if (esmStream->gcount() == sizeof(modVer))
|
||||
{
|
||||
esmStream->seekg(0);
|
||||
|
||||
if (modVer == ESM4::REC_TES4)
|
||||
{
|
||||
return new ESM4::Reader(std::move(esmStream), filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
//return new ESM3::ESMReader(esmStream, filename);
|
||||
}
|
||||
}
|
||||
|
||||
throw std::runtime_error("Unknown file format");
|
||||
}
|
||||
|
||||
bool Reader::getStringImpl(std::string& str, std::size_t size,
|
||||
std::istream& stream, const ToUTF8::StatelessUtf8Encoder* encoder, bool hasNull)
|
||||
{
|
||||
std::size_t newSize = size;
|
||||
|
||||
if (encoder)
|
||||
{
|
||||
std::string input(size, '\0');
|
||||
stream.read(input.data(), size);
|
||||
if (stream.gcount() == static_cast<std::streamsize>(size))
|
||||
{
|
||||
encoder->getUtf8(input, ToUTF8::BufferAllocationPolicy::FitToRequiredSize, str);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasNull)
|
||||
newSize -= 1; // don't read the null terminator yet
|
||||
|
||||
str.resize(newSize); // assumed C++11
|
||||
stream.read(str.data(), newSize);
|
||||
if (static_cast<std::size_t>(stream.gcount()) == newSize)
|
||||
{
|
||||
if (hasNull)
|
||||
{
|
||||
char ch;
|
||||
stream.read(&ch, 1); // read the null terminator
|
||||
assert (ch == '\0'
|
||||
&& "ESM4::Reader::getString string is not terminated with a null");
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
{
|
||||
// NOTE: normal ESMs don't but omwsave has locals or spells with null terminator
|
||||
assert (str[newSize - 1] != '\0'
|
||||
&& "ESM4::Reader::getString string is unexpectedly terminated with a null");
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
str.clear();
|
||||
return false; // FIXME: throw instead?
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
#ifndef COMPONENT_ESM_READER_H
|
||||
#define COMPONENT_ESM_READER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
|
||||
#include "common.hpp" // MasterData
|
||||
|
||||
namespace ToUTF8
|
||||
{
|
||||
class Utf8Encoder;
|
||||
}
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class Reader
|
||||
{
|
||||
std::vector<Reader*>* mGlobalReaderList;
|
||||
|
||||
public:
|
||||
virtual ~Reader() {}
|
||||
|
||||
static Reader* getReader(const std::string& filename);
|
||||
|
||||
void setGlobalReaderList(std::vector<Reader*> *list) {mGlobalReaderList = list;}
|
||||
std::vector<Reader*> *getGlobalReaderList() {return mGlobalReaderList;}
|
||||
|
||||
virtual inline bool isEsm4() const = 0;
|
||||
|
||||
virtual inline bool hasMoreRecs() const = 0;
|
||||
|
||||
virtual inline void setEncoder(const ToUTF8::StatelessUtf8Encoder* encoder) = 0;
|
||||
|
||||
// used to check for dependencies e.g. CS::Editor::run()
|
||||
virtual inline const std::vector<ESM::MasterData>& getGameFiles() const = 0;
|
||||
|
||||
// used by ContentSelector::ContentModel::addFiles()
|
||||
virtual inline const std::string getAuthor() const = 0;
|
||||
virtual inline const std::string getDesc() const = 0;
|
||||
virtual inline int getFormat() const = 0;
|
||||
|
||||
virtual inline std::string getFileName() const = 0;
|
||||
|
||||
// used by CSMWorld::Data::startLoading() and getTotalRecords() for loading progress bar
|
||||
virtual inline int getRecordCount() const = 0;
|
||||
|
||||
virtual void setModIndex(std::uint32_t index) = 0;
|
||||
|
||||
// used by CSMWorld::Data::getTotalRecords()
|
||||
virtual void close() = 0;
|
||||
|
||||
protected:
|
||||
bool getStringImpl(std::string& str, std::size_t size,
|
||||
std::istream& stream, const ToUTF8::StatelessUtf8Encoder* encoder, bool hasNull = false);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // COMPONENT_ESM_READER_H
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream> // FIXME: testing only
|
||||
#include <cstring>
|
||||
|
||||
#include "reader.hpp"
|
||||
//#include "writer.hpp"
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include <components/bsa/memorystream.hpp>
|
||||
#include <components/misc/strings/lower.hpp>
|
||||
#include <components/files/constrainedfilestream.hpp>
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
|
||||
#include "formid.hpp"
|
||||
|
||||
@ -646,4 +647,51 @@ void Reader::adjustGRUPFormId()
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
bool Reader::getStringImpl(std::string& str, std::size_t size,
|
||||
std::istream& stream, const ToUTF8::StatelessUtf8Encoder* encoder, bool hasNull)
|
||||
{
|
||||
std::size_t newSize = size;
|
||||
|
||||
if (encoder)
|
||||
{
|
||||
std::string input(size, '\0');
|
||||
stream.read(input.data(), size);
|
||||
if (stream.gcount() == static_cast<std::streamsize>(size))
|
||||
{
|
||||
encoder->getUtf8(input, ToUTF8::BufferAllocationPolicy::FitToRequiredSize, str);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasNull)
|
||||
newSize -= 1; // don't read the null terminator yet
|
||||
|
||||
str.resize(newSize); // assumed C++11
|
||||
stream.read(str.data(), newSize);
|
||||
if (static_cast<std::size_t>(stream.gcount()) == newSize)
|
||||
{
|
||||
if (hasNull)
|
||||
{
|
||||
char ch;
|
||||
stream.read(&ch, 1); // read the null terminator
|
||||
assert (ch == '\0'
|
||||
&& "ESM4::Reader::getString string is not terminated with a null");
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
{
|
||||
// NOTE: normal ESMs don't but omwsave has locals or spells with null terminator
|
||||
assert (str[newSize - 1] != '\0'
|
||||
&& "ESM4::Reader::getString string is unexpectedly terminated with a null");
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
str.clear();
|
||||
return false; // FIXME: throw instead?
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,10 +30,14 @@
|
||||
|
||||
#include "common.hpp"
|
||||
#include "loadtes4.hpp"
|
||||
#include "../esm/reader.hpp"
|
||||
|
||||
#include <components/files/istreamptr.hpp>
|
||||
|
||||
namespace ToUTF8
|
||||
{
|
||||
class StatelessUtf8Encoder;
|
||||
}
|
||||
|
||||
namespace ESM4 {
|
||||
// bytes read from group, updated by
|
||||
// getRecordHeader() in advance
|
||||
@ -75,7 +79,7 @@ namespace ESM4 {
|
||||
ReaderContext();
|
||||
};
|
||||
|
||||
class Reader : public ESM::Reader
|
||||
class Reader
|
||||
{
|
||||
Header mHeader; // ESM4 header
|
||||
|
||||
@ -107,6 +111,8 @@ namespace ESM4 {
|
||||
|
||||
std::map<FormId, LStringOffset> mLStringIndex;
|
||||
|
||||
std::vector<Reader*>* mGlobalReaderList = nullptr;
|
||||
|
||||
void buildLStringIndex(const std::string& stringFile, LocalizedStringType stringType);
|
||||
|
||||
inline bool hasLocalizedStrings() const { return (mHeader.mFlags & Rec_Localized) != 0; }
|
||||
@ -126,6 +132,9 @@ namespace ESM4 {
|
||||
|
||||
Reader() = default;
|
||||
|
||||
bool getStringImpl(std::string& str, std::size_t size,
|
||||
std::istream& stream, const ToUTF8::StatelessUtf8Encoder* encoder, bool hasNull = false);
|
||||
|
||||
public:
|
||||
|
||||
Reader(Files::IStreamPtr&& esmStream, const std::string& filename);
|
||||
@ -136,22 +145,22 @@ namespace ESM4 {
|
||||
|
||||
void open(const std::string& filename);
|
||||
|
||||
void close() final;
|
||||
void close();
|
||||
|
||||
inline bool isEsm4() const final { return true; }
|
||||
inline bool isEsm4() const { return true; }
|
||||
|
||||
inline void setEncoder(const ToUTF8::StatelessUtf8Encoder* encoder) final { mEncoder = encoder; };
|
||||
inline void setEncoder(const ToUTF8::StatelessUtf8Encoder* encoder) { mEncoder = encoder; };
|
||||
|
||||
const std::vector<ESM::MasterData>& getGameFiles() const final { return mHeader.mMaster; }
|
||||
const std::vector<ESM::MasterData>& getGameFiles() const { return mHeader.mMaster; }
|
||||
|
||||
inline int getRecordCount() const final { return mHeader.mData.records; }
|
||||
inline const std::string getAuthor() const final { return mHeader.mAuthor; }
|
||||
inline int getFormat() const final { return 0; }; // prob. not relevant for ESM4
|
||||
inline const std::string getDesc() const final { return mHeader.mDesc; }
|
||||
inline int getRecordCount() const { return mHeader.mData.records; }
|
||||
inline const std::string getAuthor() const { return mHeader.mAuthor; }
|
||||
inline int getFormat() const { return 0; }; // prob. not relevant for ESM4
|
||||
inline const std::string getDesc() const { return mHeader.mDesc; }
|
||||
|
||||
inline std::string getFileName() const final { return mCtx.filename; }; // not used
|
||||
inline std::string getFileName() const { return mCtx.filename; }; // not used
|
||||
|
||||
inline bool hasMoreRecs() const final { return (mFileSize - mCtx.fileRead) > 0; }
|
||||
inline bool hasMoreRecs() const { return (mFileSize - mCtx.fileRead) > 0; }
|
||||
|
||||
// Methods added for updating loading progress bars
|
||||
inline std::size_t getFileSize() const { return mFileSize; }
|
||||
@ -195,7 +204,7 @@ namespace ESM4 {
|
||||
|
||||
// The object setting up this reader needs to supply the file's load order index
|
||||
// so that the formId's in this file can be adjusted with the file (i.e. mod) index.
|
||||
void setModIndex(std::uint32_t index) final { mCtx.modIndex = (index << 24) & 0xff000000; }
|
||||
void setModIndex(std::uint32_t index) { mCtx.modIndex = (index << 24) & 0xff000000; }
|
||||
void updateModIndices(const std::vector<std::string>& files);
|
||||
|
||||
// Maybe should throw an exception if called when not valid?
|
||||
@ -292,6 +301,10 @@ namespace ESM4 {
|
||||
|
||||
// Used for error handling
|
||||
[[noreturn]] void fail(const std::string& msg);
|
||||
|
||||
void setGlobalReaderList(std::vector<Reader*> *list) { mGlobalReaderList = list; }
|
||||
|
||||
std::vector<Reader*> *getGlobalReaderList() { return mGlobalReaderList; }
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user