mirror of
https://github.com/transmission/transmission.git
synced 2026-02-15 07:26:49 +00:00
refactor: wrap std::filesystem::space calls (#8284)
Co-authored-by: Charles Kerr <charles@charleskerr.com>
This commit is contained in:
@@ -11,7 +11,6 @@
|
||||
|
||||
#include "libtransmission/error.h"
|
||||
#include "libtransmission/file.h"
|
||||
#include "libtransmission/tr-assert.h"
|
||||
|
||||
std::string tr_sys_path_resolve(std::string_view path, tr_error* error)
|
||||
{
|
||||
@@ -65,3 +64,19 @@ std::vector<std::string> tr_sys_dir_get_files(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::filesystem::space_info> tr_sys_path_get_capacity(std::filesystem::path const& path, tr_error* error)
|
||||
{
|
||||
auto ec = std::error_code{};
|
||||
auto space = std::filesystem::space(path, ec);
|
||||
if (!ec)
|
||||
{
|
||||
return space;
|
||||
}
|
||||
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set(ec.value(), ec.message());
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -102,6 +102,28 @@ struct tr_sys_path_info
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Temporary replacement of deprecated `std::filesystem::u8path()` while we migrate
|
||||
* from char to char8_t strings.
|
||||
*
|
||||
* https://stackoverflow.com/a/57635139/11390656
|
||||
* @{
|
||||
*/
|
||||
|
||||
template<typename InputIt>
|
||||
[[nodiscard]] std::filesystem::path tr_u8path(InputIt begin, InputIt end)
|
||||
{
|
||||
auto const view = std::ranges::subrange(begin, end) | std::views::transform([](char const c) -> char8_t { return c; });
|
||||
return { view.begin(), view.end() };
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::filesystem::path tr_u8path(std::string_view path)
|
||||
{
|
||||
return tr_u8path(path.begin(), path.end());
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/**
|
||||
* @name Platform-specific wrapper functions
|
||||
*
|
||||
@@ -144,6 +166,23 @@ bool tr_sys_path_copy(std::string_view src_path, std::string_view dst_path, tr_e
|
||||
int flags = 0,
|
||||
tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Get disk capacity and free disk space (in bytes) for the specified folder.
|
||||
*
|
||||
* @param[in] path Path to directory.
|
||||
* @param[out] error Pointer to error object. Optional, pass `nullptr` if you
|
||||
* are not interested in error details.
|
||||
*/
|
||||
[[nodiscard]] std::optional<std::filesystem::space_info> tr_sys_path_get_capacity(
|
||||
std::filesystem::path const& path,
|
||||
tr_error* error = nullptr);
|
||||
[[nodiscard]] inline std::optional<std::filesystem::space_info> tr_sys_path_get_capacity(
|
||||
std::string_view path,
|
||||
tr_error* error = nullptr)
|
||||
{
|
||||
return tr_sys_path_get_capacity(tr_u8path(path), error);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `access()`.
|
||||
*
|
||||
@@ -510,25 +549,3 @@ bool tr_sys_dir_close(tr_sys_dir_t handle, tr_error* error = nullptr);
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Temporary replacement of deprecated `std::filesystem::u8path()` while we migrate
|
||||
* from char to char8_t strings.
|
||||
*
|
||||
* https://stackoverflow.com/a/57635139/11390656
|
||||
* @{
|
||||
*/
|
||||
|
||||
template<typename InputIt>
|
||||
[[nodiscard]] std::filesystem::path tr_u8path(InputIt begin, InputIt end)
|
||||
{
|
||||
auto const view = std::ranges::subrange(begin, end) | std::views::transform([](char const c) -> char8_t { return c; });
|
||||
return { view.begin(), view.end() };
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::filesystem::path tr_u8path(std::string_view path)
|
||||
{
|
||||
return tr_u8path(path.begin(), path.end());
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -2231,9 +2231,12 @@ using SessionAccessors = std::pair<SessionGetter, SessionSetter>;
|
||||
TR_KEY_download_dir_free_space,
|
||||
[](tr_session const& src) -> tr_variant
|
||||
{
|
||||
auto ec = std::error_code{};
|
||||
auto const space = std::filesystem::space(tr_u8path(src.downloadDir()), ec);
|
||||
return !ec ? space.available : tr_variant{ -1 };
|
||||
// TODO(C++23): use std::optional::transform() instead
|
||||
if (auto const space = tr_sys_path_get_capacity(std::string_view{ src.downloadDir() }))
|
||||
{
|
||||
return space->available;
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
nullptr);
|
||||
|
||||
@@ -2736,17 +2739,17 @@ using SessionAccessors = std::pair<SessionGetter, SessionSetter>;
|
||||
}
|
||||
|
||||
// get the free space
|
||||
auto ec = std::error_code{};
|
||||
auto const capacity = std::filesystem::space(tr_u8path(*path), ec);
|
||||
auto error = tr_error{};
|
||||
auto const capacity = tr_sys_path_get_capacity(*path, &error);
|
||||
|
||||
// response
|
||||
args_out.try_emplace(TR_KEY_path, *path);
|
||||
args_out.try_emplace(TR_KEY_size_bytes, !ec ? capacity.available : tr_variant{ -1 });
|
||||
args_out.try_emplace(TR_KEY_total_size, !ec ? capacity.capacity : tr_variant{ -1 });
|
||||
args_out.try_emplace(TR_KEY_size_bytes, capacity ? capacity->available : tr_variant{ -1 });
|
||||
args_out.try_emplace(TR_KEY_total_size, capacity ? capacity->capacity : tr_variant{ -1 });
|
||||
|
||||
if (ec)
|
||||
if (error)
|
||||
{
|
||||
return { Error::SYSTEM_ERROR, ec.message() };
|
||||
return { Error::SYSTEM_ERROR, std::string{ error.message() } };
|
||||
}
|
||||
return { Error::SUCCESS, {} };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user