Merge pull request #4978

938bcce CAutoFile: make file private (Philip Kaufmann)
0c35486 CBufferedFile: add explicit close function (Philip Kaufmann)
c9fb27d CBufferedFile: convert into a non-refcounted RAII wrapper (Philip Kaufmann)
This commit is contained in:
Wladimir J. van der Laan 2014-10-02 22:35:13 +02:00
commit 0e64566a82
No known key found for this signature in database
GPG key ID: 74810B012346C9A6
2 changed files with 41 additions and 16 deletions

View file

@ -3085,6 +3085,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
int nLoaded = 0; int nLoaded = 0;
try { try {
// This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION); CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
uint64_t nStartByte = 0; uint64_t nStartByte = 0;
if (dbp) { if (dbp) {
@ -3141,7 +3142,6 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what()); LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what());
} }
} }
fclose(fileIn);
} catch(std::runtime_error &e) { } catch(std::runtime_error &e) {
AbortNode(_("Error: system error: ") + e.what()); AbortNode(_("Error: system error: ") + e.what());
} }

View file

@ -1154,7 +1154,7 @@ public:
/** Non-refcounted RAII wrapper for FILE*. /** Non-refcounted RAII wrapper for FILE*
* *
* Will automatically close the file when it goes out of scope if not null. * Will automatically close the file when it goes out of scope if not null.
* If you're returning the file pointer, return file.release(). * If you're returning the file pointer, return file.release().
@ -1166,12 +1166,13 @@ private:
// Disallow copies // Disallow copies
CAutoFile(const CAutoFile&); CAutoFile(const CAutoFile&);
CAutoFile& operator=(const CAutoFile&); CAutoFile& operator=(const CAutoFile&);
protected:
FILE* file;
public:
int nType; int nType;
int nVersion; int nVersion;
FILE* file;
public:
CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn) CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn)
{ {
file = filenew; file = filenew;
@ -1186,9 +1187,10 @@ public:
void fclose() void fclose()
{ {
if (file != NULL && file != stdin && file != stdout && file != stderr) if (file) {
::fclose(file); ::fclose(file);
file = NULL; file = NULL;
}
} }
FILE* release() { FILE* ret = file; file = NULL; return ret; } FILE* release() { FILE* ret = file; file = NULL; return ret; }
@ -1256,13 +1258,23 @@ public:
} }
}; };
/** Wrapper around a FILE* that implements a ring buffer to /** Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to
* deserialize from. It guarantees the ability to rewind * deserialize from. It guarantees the ability to rewind a given number of bytes.
* a given number of bytes. */ *
* Will automatically close the file when it goes out of scope if not null.
* If you need to close the file early, use file.fclose() instead of fclose(file).
*/
class CBufferedFile class CBufferedFile
{ {
private: private:
FILE *src; // source file // Disallow copies
CBufferedFile(const CBufferedFile&);
CBufferedFile& operator=(const CBufferedFile&);
int nType;
int nVersion;
FILE *src; // source file
uint64_t nSrcPos; // how many bytes have been read from source uint64_t nSrcPos; // how many bytes have been read from source
uint64_t nReadPos; // how many bytes have been read from this uint64_t nReadPos; // how many bytes have been read from this
uint64_t nReadLimit; // up to which position we're allowed to read uint64_t nReadLimit; // up to which position we're allowed to read
@ -1289,12 +1301,25 @@ protected:
} }
public: public:
int nType;
int nVersion;
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), nSrcPos(0), nReadPos(0), nReadLimit((uint64_t)(-1)), nRewind(nRewindIn), vchBuf(nBufSize, 0)
nType(nTypeIn), nVersion(nVersionIn) { {
src = fileIn;
nType = nTypeIn;
nVersion = nVersionIn;
}
~CBufferedFile()
{
fclose();
}
void fclose()
{
if (src) {
::fclose(src);
src = NULL;
}
} }
// check whether we're at the end of the source file // check whether we're at the end of the source file