ESM component no longer relies on Ogre DataStreams

c++11
scrawl 10 years ago
parent 68bce7825e
commit 8f0ab7d09f

@ -16,7 +16,7 @@ using namespace Misc;
ESM_Context ESMReader::getContext() ESM_Context ESMReader::getContext()
{ {
// Update the file position before returning // Update the file position before returning
mCtx.filePos = mEsm->tell(); mCtx.filePos = mEsm->tellg();
return mCtx; return mCtx;
} }
@ -44,12 +44,12 @@ void ESMReader::restoreContext(const ESM_Context &rc)
mCtx = rc; mCtx = rc;
// Make sure we seek to the right place // Make sure we seek to the right place
mEsm->seek(mCtx.filePos); mEsm->seekg(mCtx.filePos);
} }
void ESMReader::close() void ESMReader::close()
{ {
mEsm.setNull(); mEsm.reset();
mCtx.filename.clear(); mCtx.filename.clear();
mCtx.leftFile = 0; mCtx.leftFile = 0;
mCtx.leftRec = 0; mCtx.leftRec = 0;
@ -59,15 +59,22 @@ void ESMReader::close()
mCtx.subName.val = 0; 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(); close();
mEsm = _esm; mEsm = _esm;
mCtx.filename = name; 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); openRaw(_esm, name);
@ -81,12 +88,7 @@ void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name)
void ESMReader::open(const std::string &file) void ESMReader::open(const std::string &file)
{ {
open (openConstrainedFileDataStream (file.c_str ()), file); open (Files::openConstrainedFileStream (file.c_str ()), file);
}
void ESMReader::openRaw(const std::string &file)
{
openRaw (openConstrainedFileDataStream (file.c_str ()), file);
} }
int64_t ESMReader::getHNLong(const char *name) int64_t ESMReader::getHNLong(const char *name)
@ -296,9 +298,7 @@ void ESMReader::getExact(void*x, int size)
{ {
try try
{ {
int t = mEsm->read(x, size); mEsm->read((char*)x, size);
if (t != size)
fail("Read error");
} }
catch (std::exception& e) catch (std::exception& e)
{ {
@ -340,8 +340,8 @@ void ESMReader::fail(const std::string &msg)
ss << "\n File: " << mCtx.filename; ss << "\n File: " << mCtx.filename;
ss << "\n Record: " << mCtx.recName.toString(); ss << "\n Record: " << mCtx.recName.toString();
ss << "\n Subrecord: " << mCtx.subName.toString(); ss << "\n Subrecord: " << mCtx.subName.toString();
if (!mEsm.isNull()) if (mEsm.get())
ss << "\n Offset: 0x" << hex << mEsm->tell(); ss << "\n Offset: 0x" << hex << mEsm->tellg();
throw std::runtime_error(ss.str()); throw std::runtime_error(ss.str());
} }
@ -350,4 +350,14 @@ void ESMReader::setEncoder(ToUTF8::Utf8Encoder* encoder)
mEncoder = encoder; mEncoder = encoder;
} }
size_t ESMReader::getFileOffset()
{
return mEsm->tellg();
}
void ESMReader::skip(int bytes)
{
mEsm->seekg(getFileOffset()+bytes);
}
} }

@ -7,7 +7,7 @@
#include <vector> #include <vector>
#include <sstream> #include <sstream>
#include <OgreDataStream.h> #include <components/files/constrainedfilestream.hpp>
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
@ -63,20 +63,18 @@ 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(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 /// 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(Ogre::DataStreamPtr _esm, const std::string &name); void open(Files::IStreamPtr _esm, const std::string &name);
void open(const std::string &file); 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! /// 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 // 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 // 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. // them from native encoding to UTF8 in the process.
std::string getString(int size); std::string getString(int size);
void skip(int bytes) { mEsm->seek(mEsm->tell()+bytes); } void skip(int bytes);
uint64_t getOffset() { return mEsm->tell(); }
/// Used for error handling /// Used for error handling
void fail(const std::string &msg); void fail(const std::string &msg);
@ -265,7 +262,7 @@ public:
unsigned int getRecordFlags() { return mRecordFlags; } unsigned int getRecordFlags() { return mRecordFlags; }
private: private:
Ogre::DataStreamPtr mEsm; Files::IStreamPtr mEsm;
ESM_Context mCtx; ESM_Context mCtx;

@ -4,6 +4,8 @@
#include "esmwriter.hpp" #include "esmwriter.hpp"
#include "defs.hpp" #include "defs.hpp"
#include <iostream>
namespace ESM namespace ESM
{ {

@ -1,6 +1,7 @@
#include "constrainedfilestream.hpp" #include "constrainedfilestream.hpp"
#include <streambuf> #include <streambuf>
#include <iostream>
#include "lowlevelfile.hpp" #include "lowlevelfile.hpp"
@ -28,6 +29,8 @@ namespace Files
if (start != 0) if (start != 0)
mFile.seek(start); mFile.seek(start);
setg(0,0,0);
mOrigin = start; mOrigin = start;
} }
@ -35,11 +38,11 @@ namespace Files
{ {
if(gptr() == egptr()) 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 // 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 // Failure will throw exception in LowLevelFile
/*if(got != -1) */ size_t got = mFile.read(mBuffer, toRead);
setg(&mBuffer[0], &mBuffer[0], mBuffer+got); setg(&mBuffer[0], &mBuffer[0], &mBuffer[0]+got);
} }
if(gptr() == egptr()) if(gptr() == egptr())
return traits_type::eof(); return traits_type::eof();
@ -60,7 +63,7 @@ namespace Files
newPos = offset; newPos = offset;
break; break;
case std::ios_base::cur: case std::ios_base::cur:
newPos = (mFile.tell() - mOrigin) + offset; newPos = (mFile.tell() - mOrigin - (egptr() - gptr())) + offset;
break; break;
case std::ios_base::end: case std::ios_base::end:
newPos = mSize + offset; newPos = mSize + offset;
@ -68,9 +71,11 @@ namespace Files
default: default:
return traits_type::eof(); 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. // Clear read pointers so underflow() gets called on the next read attempt.
setg(0, 0, 0); setg(0, 0, 0);
@ -83,8 +88,9 @@ namespace Files
if((mode&std::ios_base::out) || !(mode&std::ios_base::in)) if((mode&std::ios_base::out) || !(mode&std::ios_base::in))
return traits_type::eof(); return traits_type::eof();
if(pos >= (int)mSize) if ((size_t)pos > mSize)
return traits_type::eof(); return traits_type::eof();
mFile.seek(mOrigin + pos); mFile.seek(mOrigin + pos);
// Clear read pointers so underflow() gets called on the next read attempt. // Clear read pointers so underflow() gets called on the next read attempt.

Loading…
Cancel
Save