Simplify serialize.h's exception handling

Remove the 'state' and 'exceptmask' from serialize.h's stream implementations,
as well as related methods.

As exceptmask always included 'failbit', and setstate was always called with
bits = failbit, all it did was immediately raise an exception. Get rid of
those variables, and replace the setstate with direct exception throwing
(which also removes some dead code).

As a result, good() is never reached after a failure (there are only 2
calls, one of which is in tests), and can just be replaced by !eof().

fail(), clear(n) and exceptions() are just never called. Delete them.
This commit is contained in:
Pieter Wuille 2014-08-01 22:57:55 +02:00
parent de89257fc5
commit eb0b56b190
3 changed files with 8 additions and 59 deletions

View file

@ -3228,7 +3228,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
} }
} }
uint64_t nRewind = blkdat.GetPos(); uint64_t nRewind = blkdat.GetPos();
while (blkdat.good() && !blkdat.eof()) { while (!blkdat.eof()) {
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
blkdat.SetPos(nRewind); blkdat.SetPos(nRewind);

View file

@ -870,8 +870,6 @@ protected:
typedef CSerializeData vector_type; typedef CSerializeData vector_type;
vector_type vch; vector_type vch;
unsigned int nReadPos; unsigned int nReadPos;
short state;
short exceptmask;
public: public:
int nType; int nType;
int nVersion; int nVersion;
@ -923,8 +921,6 @@ public:
nReadPos = 0; nReadPos = 0;
nType = nTypeIn; nType = nTypeIn;
nVersion = nVersionIn; nVersion = nVersionIn;
state = 0;
exceptmask = std::ios::badbit | std::ios::failbit;
} }
CDataStream& operator+=(const CDataStream& b) CDataStream& operator+=(const CDataStream& b)
@ -1047,19 +1043,7 @@ public:
// //
// Stream subset // Stream subset
// //
void setstate(short bits, const char* psz)
{
state |= bits;
if (state & exceptmask)
throw std::ios_base::failure(psz);
}
bool eof() const { return size() == 0; } bool eof() const { return size() == 0; }
bool fail() const { return state & (std::ios::badbit | std::ios::failbit); }
bool good() const { return !eof() && (state == 0); }
void clear(short n) { state = n; } // name conflict with vector clear()
short exceptions() { return exceptmask; }
short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; }
CDataStream* rdbuf() { return this; } CDataStream* rdbuf() { return this; }
int in_avail() { return size(); } int in_avail() { return size(); }
@ -1079,9 +1063,7 @@ public:
{ {
if (nReadPosNext > vch.size()) if (nReadPosNext > vch.size())
{ {
setstate(std::ios::failbit, "CDataStream::read() : end of data"); throw std::ios_base::failure("CDataStream::read() : end of data");
memset(pch, 0, nSize);
nSize = vch.size() - nReadPos;
} }
memcpy(pch, &vch[nReadPos], nSize); memcpy(pch, &vch[nReadPos], nSize);
nReadPos = 0; nReadPos = 0;
@ -1101,7 +1083,7 @@ public:
if (nReadPosNext >= vch.size()) if (nReadPosNext >= vch.size())
{ {
if (nReadPosNext > vch.size()) if (nReadPosNext > vch.size())
setstate(std::ios::failbit, "CDataStream::ignore() : end of data"); throw std::ios_base::failure("CDataStream::ignore() : end of data");
nReadPos = 0; nReadPos = 0;
vch.clear(); vch.clear();
return (*this); return (*this);
@ -1174,8 +1156,6 @@ class CAutoFile
{ {
protected: protected:
FILE* file; FILE* file;
short state;
short exceptmask;
public: public:
int nType; int nType;
int nVersion; int nVersion;
@ -1185,8 +1165,6 @@ public:
file = filenew; file = filenew;
nType = nTypeIn; nType = nTypeIn;
nVersion = nVersionIn; nVersion = nVersionIn;
state = 0;
exceptmask = std::ios::badbit | std::ios::failbit;
} }
~CAutoFile() ~CAutoFile()
@ -1213,19 +1191,6 @@ public:
// //
// Stream subset // Stream subset
// //
void setstate(short bits, const char* psz)
{
state |= bits;
if (state & exceptmask)
throw std::ios_base::failure(psz);
}
bool fail() const { return state & (std::ios::badbit | std::ios::failbit); }
bool good() const { return state == 0; }
void clear(short n = 0) { state = n; }
short exceptions() { return exceptmask; }
short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; }
void SetType(int n) { nType = n; } void SetType(int n) { nType = n; }
int GetType() { return nType; } int GetType() { return nType; }
void SetVersion(int n) { nVersion = n; } void SetVersion(int n) { nVersion = n; }
@ -1238,7 +1203,7 @@ public:
if (!file) if (!file)
throw std::ios_base::failure("CAutoFile::read : file handle is NULL"); throw std::ios_base::failure("CAutoFile::read : file handle is NULL");
if (fread(pch, 1, nSize, file) != nSize) if (fread(pch, 1, nSize, file) != nSize)
setstate(std::ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed"); throw std::ios_base::failure(feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");
return (*this); return (*this);
} }
@ -1247,7 +1212,7 @@ public:
if (!file) if (!file)
throw std::ios_base::failure("CAutoFile::write : file handle is NULL"); throw std::ios_base::failure("CAutoFile::write : file handle is NULL");
if (fwrite(pch, 1, nSize, file) != nSize) if (fwrite(pch, 1, nSize, file) != nSize)
setstate(std::ios::failbit, "CAutoFile::write : write failed"); throw std::ios_base::failure("CAutoFile::write : write failed");
return (*this); return (*this);
} }
@ -1292,16 +1257,7 @@ private:
uint64_t nRewind; // how many bytes we guarantee to rewind uint64_t nRewind; // how many bytes we guarantee to rewind
std::vector<char> vchBuf; // the buffer std::vector<char> vchBuf; // the buffer
short state;
short exceptmask;
protected: protected:
void setstate(short bits, const char *psz) {
state |= bits;
if (state & exceptmask)
throw std::ios_base::failure(psz);
}
// read data from the source to fill the buffer // read data from the source to fill the buffer
bool Fill() { bool Fill() {
unsigned int pos = nSrcPos % vchBuf.size(); unsigned int pos = nSrcPos % vchBuf.size();
@ -1313,8 +1269,7 @@ protected:
return false; return false;
size_t read = fread((void*)&vchBuf[pos], 1, readNow, src); size_t read = fread((void*)&vchBuf[pos], 1, readNow, src);
if (read == 0) { if (read == 0) {
setstate(std::ios_base::failbit, feof(src) ? "CBufferedFile::Fill : end of file" : "CBufferedFile::Fill : fread failed"); throw std::ios_base::failure(feof(src) ? "CBufferedFile::Fill : end of file" : "CBufferedFile::Fill : fread failed");
return false;
} else { } else {
nSrcPos += read; nSrcPos += read;
return true; return true;
@ -1327,12 +1282,7 @@ public:
CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) : CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) :
src(fileIn), nSrcPos(0), nReadPos(0), nReadLimit((uint64_t)(-1)), nRewind(nRewindIn), vchBuf(nBufSize, 0), src(fileIn), nSrcPos(0), nReadPos(0), nReadLimit((uint64_t)(-1)), nRewind(nRewindIn), vchBuf(nBufSize, 0),
state(0), exceptmask(std::ios_base::badbit | std::ios_base::failbit), nType(nTypeIn), nVersion(nVersionIn) { nType(nTypeIn), nVersion(nVersionIn) {
}
// check whether no error occurred
bool good() const {
return state == 0;
} }
// check whether we're at the end of the source file // check whether we're at the end of the source file
@ -1391,7 +1341,6 @@ public:
nLongPos = ftell(src); nLongPos = ftell(src);
nSrcPos = nLongPos; nSrcPos = nLongPos;
nReadPos = nLongPos; nReadPos = nLongPos;
state = 0;
return true; return true;
} }

View file

@ -83,7 +83,7 @@ struct ReadAlerts
std::vector<unsigned char> vch(alert_tests::alertTests, alert_tests::alertTests + sizeof(alert_tests::alertTests)); std::vector<unsigned char> vch(alert_tests::alertTests, alert_tests::alertTests + sizeof(alert_tests::alertTests));
CDataStream stream(vch, SER_DISK, CLIENT_VERSION); CDataStream stream(vch, SER_DISK, CLIENT_VERSION);
try { try {
while (stream.good()) while (!stream.eof())
{ {
CAlert alert; CAlert alert;
stream >> alert; stream >> alert;