aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2014-10-02 22:35:13 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2014-10-02 22:35:36 +0200
commit0e64566a829a2d6a59d83c7f6731f9849f6dbc90 (patch)
tree4a34019ab37c1c382fd4335a1e699c30c6ae3651
parent6faee7942671141649b74e50908cb99cabc840e5 (diff)
parent938bccebf1cb3ed6c7b8bfb8236a5172433bf890 (diff)
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)
-rw-r--r--src/main.cpp2
-rw-r--r--src/serialize.h55
2 files changed, 41 insertions, 16 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 55485c86ff..129d184868 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3085,6 +3085,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
int nLoaded = 0;
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);
uint64_t nStartByte = 0;
if (dbp) {
@@ -3141,7 +3142,6 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what());
}
}
- fclose(fileIn);
} catch(std::runtime_error &e) {
AbortNode(_("Error: system error: ") + e.what());
}
diff --git a/src/serialize.h b/src/serialize.h
index 68501facf2..ff11edc06c 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -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.
* If you're returning the file pointer, return file.release().
@@ -1166,12 +1166,13 @@ private:
// Disallow copies
CAutoFile(const CAutoFile&);
CAutoFile& operator=(const CAutoFile&);
-protected:
- FILE* file;
-public:
+
int nType;
int nVersion;
+
+ FILE* file;
+public:
CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn)
{
file = filenew;
@@ -1186,9 +1187,10 @@ public:
void fclose()
{
- if (file != NULL && file != stdin && file != stdout && file != stderr)
+ if (file) {
::fclose(file);
- file = NULL;
+ file = NULL;
+ }
}
FILE* release() { FILE* ret = file; file = NULL; return ret; }
@@ -1256,13 +1258,23 @@ public:
}
};
-/** Wrapper around a FILE* that implements a ring buffer to
- * deserialize from. It guarantees the ability to rewind
- * a given number of bytes. */
+/** Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to
+ * deserialize from. It guarantees the ability to rewind 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
{
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 nReadPos; // how many bytes have been read from this
uint64_t nReadLimit; // up to which position we're allowed to read
@@ -1289,12 +1301,25 @@ protected:
}
public:
- int nType;
- int nVersion;
-
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),
- nType(nTypeIn), nVersion(nVersionIn) {
+ nSrcPos(0), nReadPos(0), nReadLimit((uint64_t)(-1)), nRewind(nRewindIn), vchBuf(nBufSize, 0)
+ {
+ 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