Skip to content

Commit

Permalink
Add file::size method (#145)
Browse files Browse the repository at this point in the history
Unlike `std::filesystem::file_size`, does not require existing path for
the file
  • Loading branch information
bugdea1er authored Jan 21, 2025
1 parent f36435c commit c0ab457
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 0 deletions.
1 change: 1 addition & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Checks: >
-bugprone-easily-swappable-parameters,
-cppcoreguidelines-avoid-do-while,
-cppcoreguidelines-init-variables,
-cppcoreguidelines-pro-type-member-init,
-cppcoreguidelines-pro-type-vararg,
-misc-const-correctness,
-misc-include-cleaner,
Expand Down
10 changes: 10 additions & 0 deletions include/tmp/file
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ 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
std::uintmax_t size(std::error_code& ec) const noexcept;

/// 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
Expand Down
34 changes: 34 additions & 0 deletions src/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <Windows.h>
#else
#include <cerrno>
#include <sys/stat.h>
#include <unistd.h>
#endif

Expand Down Expand Up @@ -131,6 +132,39 @@ 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 noexcept {
#ifdef _WIN32
DWORD size_upper;
DWORD size_lower = GetFileSize(native_handle(), &size_upper);
if (size_upper == INVALID_FILE_SIZE) {
ec = std::error_code(GetLastError(), std::system_category());
return static_cast<std::uintmax_t>(-1);
}

std::uintmax_t size = size_upper;
return size << sizeof(DWORD) * CHAR_BIT | size_lower;
#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);
Expand Down
12 changes: 12 additions & 0 deletions tests/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit c0ab457

Please sign in to comment.