mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 03:47:29 -03: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:
parent
e4e201dfd9
commit
6666803c89
2 changed files with 43 additions and 28 deletions
|
@ -465,35 +465,28 @@ public:
|
|||
};
|
||||
|
||||
|
||||
|
||||
/** 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().
|
||||
* If you need to close the file early, use file.fclose() instead of fclose(file).
|
||||
*/
|
||||
class CAutoFile
|
||||
class AutoFile
|
||||
{
|
||||
private:
|
||||
const int nType;
|
||||
const int nVersion;
|
||||
|
||||
protected:
|
||||
FILE* file;
|
||||
|
||||
public:
|
||||
CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn)
|
||||
{
|
||||
file = filenew;
|
||||
}
|
||||
explicit AutoFile(FILE* filenew) : file{filenew} {}
|
||||
|
||||
~CAutoFile()
|
||||
~AutoFile()
|
||||
{
|
||||
fclose();
|
||||
}
|
||||
|
||||
// Disallow copies
|
||||
CAutoFile(const CAutoFile&) = delete;
|
||||
CAutoFile& operator=(const CAutoFile&) = delete;
|
||||
AutoFile(const AutoFile&) = delete;
|
||||
AutoFile& operator=(const AutoFile&) = delete;
|
||||
|
||||
void fclose()
|
||||
{
|
||||
|
@ -504,14 +497,14 @@ public:
|
|||
}
|
||||
|
||||
/** 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*.
|
||||
*/
|
||||
FILE* release() { FILE* ret = file; file = nullptr; return ret; }
|
||||
|
||||
/** 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
|
||||
* CAutoFile outlives use of the passed pointer.
|
||||
* AutoFile outlives use of the passed pointer.
|
||||
*/
|
||||
FILE* Get() const { return file; }
|
||||
|
||||
|
@ -522,40 +515,62 @@ public:
|
|||
//
|
||||
// Stream subset
|
||||
//
|
||||
int GetType() const { return nType; }
|
||||
int GetVersion() const { return nVersion; }
|
||||
|
||||
void read(Span<std::byte> dst)
|
||||
{
|
||||
if (!file)
|
||||
throw std::ios_base::failure("CAutoFile::read: file handle is nullptr");
|
||||
if (!file) throw std::ios_base::failure("AutoFile::read: file handle is nullptr");
|
||||
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)
|
||||
{
|
||||
if (!file)
|
||||
throw std::ios_base::failure("CAutoFile::ignore: file handle is nullptr");
|
||||
if (!file) throw std::ios_base::failure("AutoFile::ignore: file handle is nullptr");
|
||||
unsigned char data[4096];
|
||||
while (nSize > 0) {
|
||||
size_t nNow = std::min<size_t>(nSize, sizeof(data));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void write(Span<const std::byte> src)
|
||||
{
|
||||
if (!file)
|
||||
throw std::ios_base::failure("CAutoFile::write: file handle is nullptr");
|
||||
if (!file) throw std::ios_base::failure("AutoFile::write: file handle is nullptr");
|
||||
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>
|
||||
CAutoFile& operator<<(const T& obj)
|
||||
{
|
||||
|
|
|
@ -95,7 +95,7 @@ class AddrmanTest(BitcoinTestFramework):
|
|||
with open(peers_dat, "wb") as f:
|
||||
f.write(serialize_addrman()[:-1])
|
||||
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,
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue