From 8240d3e6b6163f8676de1076c03820303e84408a Mon Sep 17 00:00:00 2001 From: Amar Takhar Date: Thu, 10 Feb 2011 23:55:59 +0000 Subject: [PATCH] Add util::freespace to check for free space on a path. (with tests) Originally committed to SVN as r5346. --- aegisub/libaegisub/common/util.cpp | 26 ++++++++++++++++++-- aegisub/libaegisub/include/libaegisub/util.h | 12 +++++++++ aegisub/libaegisub/lagi_pre.h | 2 ++ aegisub/tests/libaegisub_util.cpp | 22 +++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/aegisub/libaegisub/common/util.cpp b/aegisub/libaegisub/common/util.cpp index f07fcd959..513e0ab2e 100644 --- a/aegisub/libaegisub/common/util.cpp +++ b/aegisub/libaegisub/common/util.cpp @@ -19,10 +19,12 @@ /// @ingroup libaegisub #ifndef LAGI_PRE -#include -#include +#include +#include #include +#include +#include #include #include @@ -41,6 +43,7 @@ void str_lower(std::string &str) { } } + int strtoi(std::string &str) { long l = strtol(str.c_str(), NULL, 10); @@ -50,5 +53,24 @@ int strtoi(std::string &str) { return (int)l; } + +uint64_t freespace(std::string &path, PathType type) { + struct statfs fs; + std::string check(path); + + if (type == TypeFile) + check.assign(DirName(path)); + + acs::CheckDirRead(check); + + if ((statfs(check.c_str(), &fs)) == 0) { + return fs.f_bsize * fs.f_bavail; + } else { + /// @todo We need a collective set of exceptions for ENOTDIR, EIO etc. + throw("Failed getting free space"); + } +} + + } // namespace util } // namespace agi diff --git a/aegisub/libaegisub/include/libaegisub/util.h b/aegisub/libaegisub/include/libaegisub/util.h index 0d691093a..d21b606e5 100644 --- a/aegisub/libaegisub/include/libaegisub/util.h +++ b/aegisub/libaegisub/include/libaegisub/util.h @@ -32,6 +32,13 @@ namespace agi { namespace util { + + /// Whether the path is a file or directory. + enum PathType { + TypeFile, ///< File + TypeDir ///< Directory + }; + // Calculate midpoint from a list of Integers template inline T mid(T a, T b, T c) { return std::max(a, std::min(b, c)); } @@ -56,6 +63,11 @@ namespace agi { // @param str Input string int strtoi(std::string &str); + /// Check for amount of free space on a Path. + // @param path[in] Path to check + // @param type PathType (default is TypeDir) + uint64_t freespace(std::string &path, PathType type=TypeDir); + struct delete_ptr { template void operator()(T* ptr) const { diff --git a/aegisub/libaegisub/lagi_pre.h b/aegisub/libaegisub/lagi_pre.h index a8276860e..ee51e5e7d 100644 --- a/aegisub/libaegisub/lagi_pre.h +++ b/aegisub/libaegisub/lagi_pre.h @@ -10,6 +10,8 @@ #include #include #include +#include +#include #ifdef HAVE_SYS_TIME_H # include #else diff --git a/aegisub/tests/libaegisub_util.cpp b/aegisub/tests/libaegisub_util.cpp index 0d7ab18c6..b5a455eac 100644 --- a/aegisub/tests/libaegisub_util.cpp +++ b/aegisub/tests/libaegisub_util.cpp @@ -97,6 +97,28 @@ TEST_F(lagi_util, UtilstrtoiValidString) { EXPECT_EQ(i, 24); } +TEST_F(lagi_util, UtilfreespaceFile) { + std::string path("./data/somefile"); + EXPECT_NO_THROW(util::freespace(path, util::TypeFile)); + EXPECT_ANY_THROW(util::freespace(path)); + +} + +TEST_F(lagi_util, UtilfreespaceDir) { + std::string path("./data"); + EXPECT_NO_THROW(util::freespace(path)); +} + +TEST_F(lagi_util, UtilfreespaceNoAccess) { + std::string path("./data/dir_access_denied"); + EXPECT_THROW(util::freespace(path), acs::AcsAccess); +} + +TEST_F(lagi_util, UtilfreespaceInvalid) { + std::string path("/nonexistent"); + EXPECT_ANY_THROW(util::freespace(path)); +} +