More ESM cleanup

pull/3094/head
Dobrohotov Alexei 4 years ago
parent 3944648f0b
commit e68a454fd8

@ -119,13 +119,13 @@ std::string ESMReader::getHString()
// them. For some reason, they break the rules, and contain a byte // them. For some reason, they break the rules, and contain a byte
// (value 0) even if the header says there is no data. If // (value 0) even if the header says there is no data. If
// Morrowind accepts it, so should we. // Morrowind accepts it, so should we.
if (mCtx.leftSub == 0 && !mEsm->peek()) if (mCtx.leftSub == 0 && hasMoreSubs() && !mEsm->peek())
{ {
// Skip the following zero byte // Skip the following zero byte
mCtx.leftRec--; mCtx.leftRec--;
char c; char c;
getExact(&c, 1); getT(c);
return ""; return std::string();
} }
return getString(mCtx.leftSub); return getString(mCtx.leftSub);
@ -155,14 +155,12 @@ void ESMReader::getSubNameIs(const char* name)
{ {
getSubName(); getSubName();
if (mCtx.subName != name) if (mCtx.subName != name)
fail( fail("Expected subrecord " + std::string(name) + " but got " + mCtx.subName.toString());
"Expected subrecord " + std::string(name) + " but got "
+ mCtx.subName.toString());
} }
bool ESMReader::isNextSub(const char* name) bool ESMReader::isNextSub(const char* name)
{ {
if (!mCtx.leftRec) if (!hasMoreSubs())
return false; return false;
getSubName(); getSubName();
@ -177,7 +175,7 @@ bool ESMReader::isNextSub(const char* name)
bool ESMReader::peekNextSub(const char *name) bool ESMReader::peekNextSub(const char *name)
{ {
if (!mCtx.leftRec) if (!hasMoreSubs())
return false; return false;
getSubName(); getSubName();
@ -234,21 +232,17 @@ void ESMReader::skipHSubUntil(const char *name)
void ESMReader::getSubHeader() void ESMReader::getSubHeader()
{ {
if (mCtx.leftRec < 4) if (mCtx.leftRec < sizeof(mCtx.leftSub))
fail("End of record while reading sub-record header"); fail("End of record while reading sub-record header");
// Get subrecord size // Get subrecord size
getT(mCtx.leftSub); getT(mCtx.leftSub);
mCtx.leftRec -= sizeof(mCtx.leftSub);
// Adjust number of record bytes left // Adjust number of record bytes left
mCtx.leftRec -= mCtx.leftSub + 4; if (mCtx.leftRec < mCtx.leftSub)
} fail("Record size is larger than rest of file");
mCtx.leftRec -= mCtx.leftSub;
void ESMReader::getSubHeaderIs(int size)
{
getSubHeader();
if (size != static_cast<int> (mCtx.leftSub))
fail("getSubHeaderIs(): Sub header mismatch");
} }
NAME ESMReader::getRecName() NAME ESMReader::getRecName()
@ -276,7 +270,7 @@ void ESMReader::skipRecord()
void ESMReader::getRecHeader(uint32_t &flags) void ESMReader::getRecHeader(uint32_t &flags)
{ {
// General error checking // General error checking
if (mCtx.leftFile < 12) if (mCtx.leftFile < 3 * sizeof(uint32_t))
fail("End of file while reading record header"); fail("End of file while reading record header");
if (mCtx.leftRec) if (mCtx.leftRec)
fail("Previous record contains unread bytes"); fail("Previous record contains unread bytes");
@ -284,7 +278,7 @@ void ESMReader::getRecHeader(uint32_t &flags)
getUint(mCtx.leftRec); getUint(mCtx.leftRec);
getUint(flags);// This header entry is always zero getUint(flags);// This header entry is always zero
getUint(flags); getUint(flags);
mCtx.leftFile -= 12; mCtx.leftFile -= 3 * sizeof(uint32_t);
// Check that sizes add up // Check that sizes add up
if (mCtx.leftFile < mCtx.leftRec) if (mCtx.leftFile < mCtx.leftRec)

@ -206,10 +206,6 @@ public:
*/ */
void getSubHeader(); void getSubHeader();
/** Get sub header and check the size
*/
void getSubHeaderIs(int size);
/************************************************************************* /*************************************************************************
* *
* Low level record methods * Low level record methods

@ -50,7 +50,9 @@ namespace ESM
switch (esm.retSubName().intval) switch (esm.retSubName().intval)
{ {
case ESM::FourCC<'I','N','T','V'>::value: case ESM::FourCC<'I','N','T','V'>::value:
esm.getSubHeaderIs(8); esm.getSubHeader();
if (esm.getSubSize() != 8)
esm.fail("Subrecord size is not equal to 8");
esm.getT<int>(mX); esm.getT<int>(mX);
esm.getT<int>(mY); esm.getT<int>(mY);
hasLocation = true; hasLocation = true;

@ -39,7 +39,7 @@ namespace ESM
// May include the additional two bytes (but not necessarily) // May include the additional two bytes (but not necessarily)
if (esm.getSubSize() == sizeof(mData)) if (esm.getSubSize() == sizeof(mData))
{ {
esm.getExact(&mData, sizeof(mData)); esm.getT(mData);
} }
else else
{ {

Loading…
Cancel
Save