From 8f0ab7d09fcc8f6fe52733b435a15f4f4b5ea234 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 22 Feb 2015 14:12:05 +0100 Subject: [PATCH] ESM component no longer relies on Ogre DataStreams --- components/esm/esmreader.cpp | 44 +++++++++++++--------- components/esm/esmreader.hpp | 17 ++++----- components/esm/loadscpt.cpp | 2 + components/files/constrainedfilestream.cpp | 20 ++++++---- 4 files changed, 49 insertions(+), 34 deletions(-) diff --git a/components/esm/esmreader.cpp b/components/esm/esmreader.cpp index bbe475ff7..2762a1fc9 100644 --- a/components/esm/esmreader.cpp +++ b/components/esm/esmreader.cpp @@ -16,7 +16,7 @@ using namespace Misc; ESM_Context ESMReader::getContext() { // Update the file position before returning - mCtx.filePos = mEsm->tell(); + mCtx.filePos = mEsm->tellg(); return mCtx; } @@ -44,12 +44,12 @@ void ESMReader::restoreContext(const ESM_Context &rc) mCtx = rc; // Make sure we seek to the right place - mEsm->seek(mCtx.filePos); + mEsm->seekg(mCtx.filePos); } void ESMReader::close() { - mEsm.setNull(); + mEsm.reset(); mCtx.filename.clear(); mCtx.leftFile = 0; mCtx.leftRec = 0; @@ -59,15 +59,22 @@ void ESMReader::close() mCtx.subName.val = 0; } -void ESMReader::openRaw(Ogre::DataStreamPtr _esm, const std::string &name) +void ESMReader::openRaw(Files::IStreamPtr _esm, const std::string& name) { close(); mEsm = _esm; mCtx.filename = name; - mCtx.leftFile = mEsm->size(); + mEsm->seekg(0, mEsm->end); + mCtx.leftFile = mEsm->tellg(); + mEsm->seekg(0, mEsm->beg); } -void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name) +void ESMReader::openRaw(const std::string& filename) +{ + openRaw(Files::openConstrainedFileStream(filename.c_str()), filename); +} + +void ESMReader::open(Files::IStreamPtr _esm, const std::string &name) { openRaw(_esm, name); @@ -81,12 +88,7 @@ void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name) void ESMReader::open(const std::string &file) { - open (openConstrainedFileDataStream (file.c_str ()), file); -} - -void ESMReader::openRaw(const std::string &file) -{ - openRaw (openConstrainedFileDataStream (file.c_str ()), file); + open (Files::openConstrainedFileStream (file.c_str ()), file); } int64_t ESMReader::getHNLong(const char *name) @@ -296,9 +298,7 @@ void ESMReader::getExact(void*x, int size) { try { - int t = mEsm->read(x, size); - if (t != size) - fail("Read error"); + mEsm->read((char*)x, size); } catch (std::exception& e) { @@ -340,8 +340,8 @@ void ESMReader::fail(const std::string &msg) ss << "\n File: " << mCtx.filename; ss << "\n Record: " << mCtx.recName.toString(); ss << "\n Subrecord: " << mCtx.subName.toString(); - if (!mEsm.isNull()) - ss << "\n Offset: 0x" << hex << mEsm->tell(); + if (mEsm.get()) + ss << "\n Offset: 0x" << hex << mEsm->tellg(); throw std::runtime_error(ss.str()); } @@ -350,4 +350,14 @@ void ESMReader::setEncoder(ToUTF8::Utf8Encoder* encoder) mEncoder = encoder; } +size_t ESMReader::getFileOffset() +{ + return mEsm->tellg(); +} + +void ESMReader::skip(int bytes) +{ + mEsm->seekg(getFileOffset()+bytes); +} + } diff --git a/components/esm/esmreader.hpp b/components/esm/esmreader.hpp index ebbc935f6..31fc3e32d 100644 --- a/components/esm/esmreader.hpp +++ b/components/esm/esmreader.hpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include @@ -63,20 +63,18 @@ public: /// Raw opening. Opens the file and sets everything up but doesn't /// parse the header. - void openRaw(Ogre::DataStreamPtr _esm, const std::string &name); + void openRaw(Files::IStreamPtr _esm, const std::string &name); /// Load ES file from a new stream, parses the header. Closes the /// currently open file first, if any. - void open(Ogre::DataStreamPtr _esm, const std::string &name); + void open(Files::IStreamPtr _esm, const std::string &name); void open(const std::string &file); - void openRaw(const std::string &file); + void openRaw(const std::string &filename); - /// Get the file size. Make sure that the file has been opened! - size_t getFileSize() { return mEsm->size(); } /// Get the current position in the file. Make sure that the file has been opened! - size_t getFileOffset() { return mEsm->tell(); } + size_t getFileOffset(); // This is a quick hack for multiple esm/esp files. Each plugin introduces its own // terrain palette, but ESMReader does not pass a reference to the correct plugin @@ -252,8 +250,7 @@ public: // them from native encoding to UTF8 in the process. std::string getString(int size); - void skip(int bytes) { mEsm->seek(mEsm->tell()+bytes); } - uint64_t getOffset() { return mEsm->tell(); } + void skip(int bytes); /// Used for error handling void fail(const std::string &msg); @@ -265,7 +262,7 @@ public: unsigned int getRecordFlags() { return mRecordFlags; } private: - Ogre::DataStreamPtr mEsm; + Files::IStreamPtr mEsm; ESM_Context mCtx; diff --git a/components/esm/loadscpt.cpp b/components/esm/loadscpt.cpp index 2df8e66ce..d9eb7290c 100644 --- a/components/esm/loadscpt.cpp +++ b/components/esm/loadscpt.cpp @@ -4,6 +4,8 @@ #include "esmwriter.hpp" #include "defs.hpp" +#include + namespace ESM { diff --git a/components/files/constrainedfilestream.cpp b/components/files/constrainedfilestream.cpp index fddfa7e52..23eab2088 100644 --- a/components/files/constrainedfilestream.cpp +++ b/components/files/constrainedfilestream.cpp @@ -1,6 +1,7 @@ #include "constrainedfilestream.hpp" #include +#include #include "lowlevelfile.hpp" @@ -28,6 +29,8 @@ namespace Files if (start != 0) mFile.seek(start); + setg(0,0,0); + mOrigin = start; } @@ -35,11 +38,11 @@ namespace Files { if(gptr() == egptr()) { + size_t toRead = std::min((mOrigin+mSize)-(mFile.tell()), sBufferSize); // Read in the next chunk of data, and set the read pointers on success - size_t got = mFile.read(mBuffer, sBufferSize); // Failure will throw exception in LowLevelFile - /*if(got != -1) */ - setg(&mBuffer[0], &mBuffer[0], mBuffer+got); + size_t got = mFile.read(mBuffer, toRead); + setg(&mBuffer[0], &mBuffer[0], &mBuffer[0]+got); } if(gptr() == egptr()) return traits_type::eof(); @@ -60,7 +63,7 @@ namespace Files newPos = offset; break; case std::ios_base::cur: - newPos = (mFile.tell() - mOrigin) + offset; + newPos = (mFile.tell() - mOrigin - (egptr() - gptr())) + offset; break; case std::ios_base::end: newPos = mSize + offset; @@ -68,9 +71,11 @@ namespace Files default: return traits_type::eof(); } - mFile.seek(mOrigin+newPos); - // EOF handled by exception in LowLevelFile + if (newPos > mSize) + return traits_type::eof(); + + mFile.seek(mOrigin+newPos); // Clear read pointers so underflow() gets called on the next read attempt. setg(0, 0, 0); @@ -83,8 +88,9 @@ namespace Files if((mode&std::ios_base::out) || !(mode&std::ios_base::in)) return traits_type::eof(); - if(pos >= (int)mSize) + if ((size_t)pos > mSize) return traits_type::eof(); + mFile.seek(mOrigin + pos); // Clear read pointers so underflow() gets called on the next read attempt.