From b7af960eb82f5e3af530014a4f59c48faa3a4109 Mon Sep 17 00:00:00 2001 From: Fabian Jahr Date: Thu, 19 Sep 2024 17:36:19 +0200 Subject: [PATCH] refactor: Add AutoFile::size --- src/streams.cpp | 14 ++++++++++++++ src/streams.h | 3 +++ src/test/streams_tests.cpp | 5 +++++ src/util/asmap.cpp | 5 +---- src/wallet/migrate.cpp | 3 +-- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/streams.cpp b/src/streams.cpp index 0364c2134f4..e38b9592942 100644 --- a/src/streams.cpp +++ b/src/streams.cpp @@ -57,6 +57,20 @@ int64_t AutoFile::tell() return *m_position; } +int64_t AutoFile::size() +{ + if (IsNull()) { + throw std::ios_base::failure("AutoFile::size: file handle is nullptr"); + } + // Temporarily save the current position + int64_t current_pos = tell(); + seek(0, SEEK_END); + int64_t file_size = tell(); + // Restore the original position + seek(current_pos, SEEK_SET); + return file_size; +} + void AutoFile::read(std::span dst) { if (detail_fread(dst) != dst.size()) { diff --git a/src/streams.h b/src/streams.h index 36af8dd6159..466084e9fa0 100644 --- a/src/streams.h +++ b/src/streams.h @@ -435,6 +435,9 @@ public: /** Find position within the file. Will throw if unknown. */ int64_t tell(); + /** Return the size of the file. Will throw if unknown. */ + int64_t size(); + /** Wrapper around FileCommit(). */ bool Commit(); diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp index ce496df5a9f..6b9d2b35db9 100644 --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -122,6 +122,7 @@ BOOST_AUTO_TEST_CASE(xor_file) BOOST_CHECK_EXCEPTION(xor_file << std::byte{}, std::ios_base::failure, HasReason{"AutoFile::write: file handle is nullptr"}); BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure, HasReason{"AutoFile::read: file handle is nullptr"}); BOOST_CHECK_EXCEPTION(xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: file handle is nullptr"}); + BOOST_CHECK_EXCEPTION(xor_file.size(), std::ios_base::failure, HasReason{"AutoFile::size: file handle is nullptr"}); } { #ifdef __MINGW64__ @@ -132,6 +133,7 @@ BOOST_AUTO_TEST_CASE(xor_file) #endif AutoFile xor_file{raw_file(mode), obfuscation}; xor_file << test1 << test2; + BOOST_CHECK_EQUAL(xor_file.size(), 7); BOOST_REQUIRE_EQUAL(xor_file.fclose(), 0); } { @@ -142,6 +144,7 @@ BOOST_AUTO_TEST_CASE(xor_file) BOOST_CHECK_EQUAL(HexStr(raw), "fc01fd03fd04fa"); // Check that no padding exists BOOST_CHECK_EXCEPTION(non_xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: end of file"}); + BOOST_CHECK_EQUAL(non_xor_file.size(), 7); } { AutoFile xor_file{raw_file("rb"), obfuscation}; @@ -151,6 +154,7 @@ BOOST_AUTO_TEST_CASE(xor_file) BOOST_CHECK_EQUAL(HexStr(read2), HexStr(test2)); // Check that eof was reached BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure, HasReason{"AutoFile::read: end of file"}); + BOOST_CHECK_EQUAL(xor_file.size(), 7); } { AutoFile xor_file{raw_file("rb"), obfuscation}; @@ -162,6 +166,7 @@ BOOST_AUTO_TEST_CASE(xor_file) // Check that ignore and read fail now BOOST_CHECK_EXCEPTION(xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: end of file"}); BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure, HasReason{"AutoFile::read: end of file"}); + BOOST_CHECK_EQUAL(xor_file.size(), 7); } } diff --git a/src/util/asmap.cpp b/src/util/asmap.cpp index 7c5f6eb5d4b..4c20bd819f7 100644 --- a/src/util/asmap.cpp +++ b/src/util/asmap.cpp @@ -203,10 +203,8 @@ std::vector DecodeAsmap(fs::path path) LogWarning("Failed to open asmap file from disk"); return bits; } - file.seek(0, SEEK_END); - int length = file.tell(); + int64_t length{file.size()}; LogInfo("Opened asmap file %s (%d bytes) from disk", fs::quoted(fs::PathToString(path)), length); - file.seek(0, SEEK_SET); uint8_t cur_byte; for (int i = 0; i < length; ++i) { file >> cur_byte; @@ -220,4 +218,3 @@ std::vector DecodeAsmap(fs::path path) } return bits; } - diff --git a/src/wallet/migrate.cpp b/src/wallet/migrate.cpp index 603a0d2bab1..5e202d8df45 100644 --- a/src/wallet/migrate.cpp +++ b/src/wallet/migrate.cpp @@ -544,8 +544,7 @@ void BerkeleyRODatabase::Open() page_size = outer_meta.pagesize; // Verify the size of the file is a multiple of the page size - db_file.seek(0, SEEK_END); - int64_t size = db_file.tell(); + const int64_t size{db_file.size()}; // Since BDB stores everything in a page, the file size should be a multiple of the page size; // However, BDB doesn't actually check that this is the case, and enforcing this check results