From f268d260e39ec2ad28eb62db4ad641e2cb58e311 Mon Sep 17 00:00:00 2001 From: bugdea1er <bugdealer@icloud.com> Date: Tue, 21 Jan 2025 23:53:32 +0300 Subject: [PATCH] Add `file::size` method --- include/tmp/file | 11 +++++++++++ src/file.cpp | 32 ++++++++++++++++++++++++++++++++ tests/file.cpp | 12 ++++++++++++ 3 files changed, 55 insertions(+) diff --git a/include/tmp/file b/include/tmp/file index b5839e2..986235f 100644 --- a/include/tmp/file +++ b/include/tmp/file @@ -72,6 +72,17 @@ public: std::string_view label = "", std::string_view extension = ""); + /// Returns the size of this file + /// @returns the size of this file, in bytes + /// @throws std::filesystem::filesystem_error if cannot get a file size + std::uintmax_t size() const; + + /// Returns the size of this file + /// @param[out] ec Parameter for error reporting + /// @returns the size of this file, in bytes + /// @throws std::filesystem::filesystem_error if cannot get a file size + std::uintmax_t size(std::error_code& ec) const; + /// Reads the entire contents of this file /// @returns A string with this file contents /// @throws std::filesystem::filesystem_error if cannot read the file contents diff --git a/src/file.cpp b/src/file.cpp index d67bc4c..7ab3d17 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -19,6 +19,7 @@ #include <Windows.h> #else #include <cerrno> +#include <sys/stat.h> #include <unistd.h> #endif @@ -131,6 +132,37 @@ file file::copy(const fs::path& path, std::string_view label, return tmpfile; } +std::uintmax_t file::size() const { + std::error_code ec; + std::uintmax_t result = size(ec); + + if (ec) { + throw fs::filesystem_error("Cannot get a temporary file size", path(), ec); + } + + return result; +} + +std::uintmax_t file::size(std::error_code& ec) const { +#ifdef _WIN32 + LARGE_INTERGER size; + if (!GetFileSize(native_handle(), &size)) { + ec = std::error_code(GetLastError(), std::system_category()); + return static_cast<std::uintmax_t>(-1); + } + + return size; +#else + struct stat stat; + if (fstat(native_handle(), &stat) == -1) { + ec = std::error_code(errno, std::system_category()); + return static_cast<std::uintmax_t>(-1); + } + + return stat.st_size; +#endif +} + std::string file::read() const { std::error_code ec; std::string content = read(ec); diff --git a/tests/file.cpp b/tests/file.cpp index dc1de7d..211d863 100644 --- a/tests/file.cpp +++ b/tests/file.cpp @@ -110,6 +110,18 @@ TEST(file, copy_directory) { EXPECT_THROW(file::copy(tmpdir), fs::filesystem_error); } +/// Tests getting a file size +TEST(file, size) { + file empty = file(); + EXPECT_EQ(empty.size(), 0); + + std::string_view content = "Hello, world!"; + + file nonempty = file(); + nonempty.write(content); + EXPECT_EQ(nonempty.size(), content.size()); +} + /// Tests binary file reading TEST(file, read_binary) { file tmpfile = file();