Browse Source

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.
0.10
Pieter Wuille 10 years ago
parent
commit
eb0b56b190
  1. 2
      src/main.cpp
  2. 63
      src/serialize.h
  3. 2
      src/test/alert_tests.cpp

2
src/main.cpp

@ -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);

63
src/serialize.h

@ -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;
} }

2
src/test/alert_tests.cpp

@ -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;

Loading…
Cancel
Save