mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-10-10 19:43:13 +02:00
streams: Add AutoFile without ser-type and ser-version
The moved parts can be reviewed with "--color-moved=dimmed-zebra". The one-char changes can be reviewed with "--word-diff-regex=.".
This commit is contained in:
@@ -465,35 +465,28 @@ 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().
|
||||||
* If you need to close the file early, use file.fclose() instead of fclose(file).
|
* If you need to close the file early, use file.fclose() instead of fclose(file).
|
||||||
*/
|
*/
|
||||||
class CAutoFile
|
class AutoFile
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
const int nType;
|
|
||||||
const int nVersion;
|
|
||||||
|
|
||||||
FILE* file;
|
FILE* file;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn)
|
explicit AutoFile(FILE* filenew) : file{filenew} {}
|
||||||
{
|
|
||||||
file = filenew;
|
|
||||||
}
|
|
||||||
|
|
||||||
~CAutoFile()
|
~AutoFile()
|
||||||
{
|
{
|
||||||
fclose();
|
fclose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disallow copies
|
// Disallow copies
|
||||||
CAutoFile(const CAutoFile&) = delete;
|
AutoFile(const AutoFile&) = delete;
|
||||||
CAutoFile& operator=(const CAutoFile&) = delete;
|
AutoFile& operator=(const AutoFile&) = delete;
|
||||||
|
|
||||||
void fclose()
|
void fclose()
|
||||||
{
|
{
|
||||||
@@ -504,14 +497,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Get wrapped FILE* with transfer of ownership.
|
/** Get wrapped FILE* with transfer of ownership.
|
||||||
* @note This will invalidate the CAutoFile object, and makes it the responsibility of the caller
|
* @note This will invalidate the AutoFile object, and makes it the responsibility of the caller
|
||||||
* of this function to clean up the returned FILE*.
|
* of this function to clean up the returned FILE*.
|
||||||
*/
|
*/
|
||||||
FILE* release() { FILE* ret = file; file = nullptr; return ret; }
|
FILE* release() { FILE* ret = file; file = nullptr; return ret; }
|
||||||
|
|
||||||
/** Get wrapped FILE* without transfer of ownership.
|
/** Get wrapped FILE* without transfer of ownership.
|
||||||
* @note Ownership of the FILE* will remain with this class. Use this only if the scope of the
|
* @note Ownership of the FILE* will remain with this class. Use this only if the scope of the
|
||||||
* CAutoFile outlives use of the passed pointer.
|
* AutoFile outlives use of the passed pointer.
|
||||||
*/
|
*/
|
||||||
FILE* Get() const { return file; }
|
FILE* Get() const { return file; }
|
||||||
|
|
||||||
@@ -522,40 +515,62 @@ public:
|
|||||||
//
|
//
|
||||||
// Stream subset
|
// Stream subset
|
||||||
//
|
//
|
||||||
int GetType() const { return nType; }
|
|
||||||
int GetVersion() const { return nVersion; }
|
|
||||||
|
|
||||||
void read(Span<std::byte> dst)
|
void read(Span<std::byte> dst)
|
||||||
{
|
{
|
||||||
if (!file)
|
if (!file) throw std::ios_base::failure("AutoFile::read: file handle is nullptr");
|
||||||
throw std::ios_base::failure("CAutoFile::read: file handle is nullptr");
|
|
||||||
if (fread(dst.data(), 1, dst.size(), file) != dst.size()) {
|
if (fread(dst.data(), 1, dst.size(), file) != dst.size()) {
|
||||||
throw std::ios_base::failure(feof(file) ? "CAutoFile::read: end of file" : "CAutoFile::read: fread failed");
|
throw std::ios_base::failure(feof(file) ? "AutoFile::read: end of file" : "AutoFile::read: fread failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ignore(size_t nSize)
|
void ignore(size_t nSize)
|
||||||
{
|
{
|
||||||
if (!file)
|
if (!file) throw std::ios_base::failure("AutoFile::ignore: file handle is nullptr");
|
||||||
throw std::ios_base::failure("CAutoFile::ignore: file handle is nullptr");
|
|
||||||
unsigned char data[4096];
|
unsigned char data[4096];
|
||||||
while (nSize > 0) {
|
while (nSize > 0) {
|
||||||
size_t nNow = std::min<size_t>(nSize, sizeof(data));
|
size_t nNow = std::min<size_t>(nSize, sizeof(data));
|
||||||
if (fread(data, 1, nNow, file) != nNow)
|
if (fread(data, 1, nNow, file) != nNow)
|
||||||
throw std::ios_base::failure(feof(file) ? "CAutoFile::ignore: end of file" : "CAutoFile::read: fread failed");
|
throw std::ios_base::failure(feof(file) ? "AutoFile::ignore: end of file" : "AutoFile::read: fread failed");
|
||||||
nSize -= nNow;
|
nSize -= nNow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(Span<const std::byte> src)
|
void write(Span<const std::byte> src)
|
||||||
{
|
{
|
||||||
if (!file)
|
if (!file) throw std::ios_base::failure("AutoFile::write: file handle is nullptr");
|
||||||
throw std::ios_base::failure("CAutoFile::write: file handle is nullptr");
|
|
||||||
if (fwrite(src.data(), 1, src.size(), file) != src.size()) {
|
if (fwrite(src.data(), 1, src.size(), file) != src.size()) {
|
||||||
throw std::ios_base::failure("CAutoFile::write: write failed");
|
throw std::ios_base::failure("AutoFile::write: write failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AutoFile& operator<<(const T& obj)
|
||||||
|
{
|
||||||
|
if (!file) throw std::ios_base::failure("AutoFile::operator<<: file handle is nullptr");
|
||||||
|
::Serialize(*this, obj);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AutoFile& operator>>(T&& obj)
|
||||||
|
{
|
||||||
|
if (!file) throw std::ios_base::failure("AutoFile::operator>>: file handle is nullptr");
|
||||||
|
::Unserialize(*this, obj);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CAutoFile : public AutoFile
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const int nType;
|
||||||
|
const int nVersion;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn) : AutoFile{filenew}, nType(nTypeIn), nVersion(nVersionIn) {}
|
||||||
|
int GetType() const { return nType; }
|
||||||
|
int GetVersion() const { return nVersion; }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
CAutoFile& operator<<(const T& obj)
|
CAutoFile& operator<<(const T& obj)
|
||||||
{
|
{
|
||||||
|
@@ -95,7 +95,7 @@ class AddrmanTest(BitcoinTestFramework):
|
|||||||
with open(peers_dat, "wb") as f:
|
with open(peers_dat, "wb") as f:
|
||||||
f.write(serialize_addrman()[:-1])
|
f.write(serialize_addrman()[:-1])
|
||||||
self.nodes[0].assert_start_raises_init_error(
|
self.nodes[0].assert_start_raises_init_error(
|
||||||
expected_msg=init_error("CAutoFile::read: end of file.*"),
|
expected_msg=init_error("AutoFile::read: end of file.*"),
|
||||||
match=ErrorMatch.FULL_REGEX,
|
match=ErrorMatch.FULL_REGEX,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user