mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 15:15:31 +00:00
ConstrainedDataStream: print the name of the file in exceptions
This commit is contained in:
parent
51e451e249
commit
2abc033655
1 changed files with 52 additions and 42 deletions
|
@ -15,6 +15,7 @@ public:
|
||||||
static const size_t sBufferThreshold = 1024; // reads larger than this bypass buffering as cost of memcpy outweighs cost of system call
|
static const size_t sBufferThreshold = 1024; // reads larger than this bypass buffering as cost of memcpy outweighs cost of system call
|
||||||
|
|
||||||
ConstrainedDataStream(const Ogre::String &fname, size_t start, size_t length)
|
ConstrainedDataStream(const Ogre::String &fname, size_t start, size_t length)
|
||||||
|
: Ogre::DataStream(fname)
|
||||||
{
|
{
|
||||||
mFile.open (fname.c_str ());
|
mFile.open (fname.c_str ());
|
||||||
mSize = length != 0xFFFFFFFF ? length : mFile.size () - start;
|
mSize = length != 0xFFFFFFFF ? length : mFile.size () - start;
|
||||||
|
@ -30,63 +31,72 @@ public:
|
||||||
|
|
||||||
size_t read(void* buf, size_t count)
|
size_t read(void* buf, size_t count)
|
||||||
{
|
{
|
||||||
assert (mPos <= mSize);
|
try
|
||||||
|
|
||||||
uint8_t * out = reinterpret_cast <uint8_t *> (buf);
|
|
||||||
|
|
||||||
size_t posBeg = mOrigin + mPos;
|
|
||||||
size_t posEnd = posBeg + count;
|
|
||||||
|
|
||||||
if (posEnd > mExtent)
|
|
||||||
posEnd = mExtent;
|
|
||||||
|
|
||||||
size_t posCur = posBeg;
|
|
||||||
|
|
||||||
while (posCur != posEnd)
|
|
||||||
{
|
{
|
||||||
size_t readLeft = posEnd - posCur;
|
assert (mPos <= mSize);
|
||||||
|
|
||||||
if (posCur < mBufferOrigin || posCur >= mBufferExtent)
|
uint8_t * out = reinterpret_cast <uint8_t *> (buf);
|
||||||
|
|
||||||
|
size_t posBeg = mOrigin + mPos;
|
||||||
|
size_t posEnd = posBeg + count;
|
||||||
|
|
||||||
|
if (posEnd > mExtent)
|
||||||
|
posEnd = mExtent;
|
||||||
|
|
||||||
|
size_t posCur = posBeg;
|
||||||
|
|
||||||
|
while (posCur != posEnd)
|
||||||
{
|
{
|
||||||
if (readLeft >= sBufferThreshold || (posCur == mOrigin && posEnd == mExtent))
|
size_t readLeft = posEnd - posCur;
|
||||||
|
|
||||||
|
if (posCur < mBufferOrigin || posCur >= mBufferExtent)
|
||||||
{
|
{
|
||||||
assert (mFile.tell () == mBufferExtent);
|
if (readLeft >= sBufferThreshold || (posCur == mOrigin && posEnd == mExtent))
|
||||||
|
{
|
||||||
|
assert (mFile.tell () == mBufferExtent);
|
||||||
|
|
||||||
if (posCur != mBufferExtent)
|
if (posCur != mBufferExtent)
|
||||||
mFile.seek (posCur);
|
mFile.seek (posCur);
|
||||||
|
|
||||||
posCur += mFile.read (out, readLeft);
|
posCur += mFile.read (out, readLeft);
|
||||||
|
|
||||||
mBufferOrigin = mBufferExtent = posCur;
|
mBufferOrigin = mBufferExtent = posCur;
|
||||||
|
|
||||||
mPos = posCur - mOrigin;
|
mPos = posCur - mOrigin;
|
||||||
|
|
||||||
return posCur - posBeg;
|
return posCur - posBeg;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t newBufferOrigin;
|
|
||||||
|
|
||||||
if ((posCur < mBufferOrigin) && (mBufferOrigin - posCur < sBufferSize))
|
|
||||||
newBufferOrigin = std::max (mOrigin, mBufferOrigin > sBufferSize ? mBufferOrigin - sBufferSize : 0);
|
|
||||||
else
|
else
|
||||||
newBufferOrigin = posCur;
|
{
|
||||||
|
size_t newBufferOrigin;
|
||||||
|
|
||||||
fill (newBufferOrigin);
|
if ((posCur < mBufferOrigin) && (mBufferOrigin - posCur < sBufferSize))
|
||||||
|
newBufferOrigin = std::max (mOrigin, mBufferOrigin > sBufferSize ? mBufferOrigin - sBufferSize : 0);
|
||||||
|
else
|
||||||
|
newBufferOrigin = posCur;
|
||||||
|
|
||||||
|
fill (newBufferOrigin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t xfer = std::min (readLeft, mBufferExtent - posCur);
|
||||||
|
|
||||||
|
memcpy (out, mBuffer + (posCur - mBufferOrigin), xfer);
|
||||||
|
|
||||||
|
posCur += xfer;
|
||||||
|
out += xfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t xfer = std::min (readLeft, mBufferExtent - posCur);
|
count = posEnd - posBeg;
|
||||||
|
mPos += count;
|
||||||
memcpy (out, mBuffer + (posCur - mBufferOrigin), xfer);
|
return count;
|
||||||
|
}
|
||||||
posCur += xfer;
|
catch (std::exception& e)
|
||||||
out += xfer;
|
{
|
||||||
|
std::stringstream error;
|
||||||
|
error << "Failed to read '" << mName << "': " << e.what();
|
||||||
|
throw std::runtime_error(error.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
count = posEnd - posBeg;
|
|
||||||
mPos += count;
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void skip(long count)
|
void skip(long count)
|
||||||
|
|
Loading…
Reference in a new issue