Compare commits
12 Commits
4bb34781fe
...
e204889e28
Author | SHA1 | Date | |
---|---|---|---|
e204889e28 | |||
1d9fe59118 | |||
620b5733c9 | |||
5910ed3dae | |||
272d9a1502 | |||
92c0e4dabd | |||
643486b2c4 | |||
82bb90f66d | |||
c20575fdcf | |||
07ad8a55d3 | |||
17ebd56ed4 | |||
0ea1cb544e |
@@ -1,6 +1,6 @@
|
|||||||
if(PROJECT_ENABLE_LIBSODIUM)
|
if(PROJECT_ENABLE_LIBSODIUM)
|
||||||
if(PROJECT_BUILD)
|
if(PROJECT_BUILD)
|
||||||
pkg_check_modules(SODIUM libsodium=${LIBSODIUM_VERSION} REQUIRED)
|
pkg_check_modules(SODIUM libsodium>=${LIBSODIUM_VERSION} REQUIRED)
|
||||||
|
|
||||||
add_definitions(-DPROJECT_ENABLE_LIBSODIUM)
|
add_definitions(-DPROJECT_ENABLE_LIBSODIUM)
|
||||||
|
|
||||||
|
@@ -542,10 +542,9 @@ auto app_config::load() -> bool {
|
|||||||
static_cast<const char *>(__FUNCTION__),
|
static_cast<const char *>(__FUNCTION__),
|
||||||
};
|
};
|
||||||
|
|
||||||
auto ret = false;
|
auto ret{false};
|
||||||
|
|
||||||
const auto config_file_path = get_config_file_path();
|
const auto config_file_path = get_config_file_path();
|
||||||
std::cout << config_file_path << std::endl;
|
|
||||||
recur_mutex_lock lock(read_write_mutex_);
|
recur_mutex_lock lock(read_write_mutex_);
|
||||||
if (utils::file::file(config_file_path).exists()) {
|
if (utils::file::file(config_file_path).exists()) {
|
||||||
try {
|
try {
|
||||||
|
@@ -52,12 +52,16 @@ auto eviction::check_minimum_requirements(const std::string &file_path)
|
|||||||
|
|
||||||
auto reference_time = utils::file::file{file_path}.get_time(
|
auto reference_time = utils::file::file{file_path}.get_time(
|
||||||
config_.get_eviction_uses_accessed_time()
|
config_.get_eviction_uses_accessed_time()
|
||||||
? utils::file::file::time_types::access
|
? utils::file::time_type::accessed
|
||||||
: utils::file::file::time_types::modified);
|
: utils::file::time_type::modified);
|
||||||
|
|
||||||
|
if (not reference_time.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto delay = (config_.get_eviction_delay_mins() * 60UL) *
|
auto delay = (config_.get_eviction_delay_mins() * 60UL) *
|
||||||
utils::time::NANOS_PER_SECOND;
|
utils::time::NANOS_PER_SECOND;
|
||||||
return ((reference_time + static_cast<std::uint64_t>(delay)) <=
|
return ((reference_time.value() + static_cast<std::uint64_t>(delay)) <=
|
||||||
utils::time::get_time_now());
|
utils::time::get_time_now());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -92,14 +92,14 @@ void remote_server::populate_stat(const char *path, bool directory,
|
|||||||
directory ? 2 + drive_.get_directory_item_count(
|
directory ? 2 + drive_.get_directory_item_count(
|
||||||
utils::path::create_api_path(path))
|
utils::path::create_api_path(path))
|
||||||
: 1);
|
: 1);
|
||||||
r_stat.st_atimespec = utils::time::windows_time_to_unix_time(
|
r_stat.st_atimespec =
|
||||||
static_cast<std::uint64_t>(unix_st.st_atime));
|
utils::time::windows_time_t_to_unix_time(unix_st.st_atime);
|
||||||
r_stat.st_birthtimespec = utils::time::windows_time_to_unix_time(
|
r_stat.st_birthtimespec =
|
||||||
static_cast<std::uint64_t>(unix_st.st_ctime));
|
utils::time::windows_time_t_to_unix_time(unix_st.st_ctime);
|
||||||
r_stat.st_ctimespec = utils::time::windows_time_to_unix_time(
|
r_stat.st_ctimespec =
|
||||||
static_cast<std::uint64_t>(unix_st.st_ctime));
|
utils::time::windows_time_t_to_unix_time(unix_st.st_ctime);
|
||||||
r_stat.st_mtimespec = utils::time::windows_time_to_unix_time(
|
r_stat.st_mtimespec =
|
||||||
static_cast<std::uint64_t>(unix_st.st_mtime));
|
utils::time::windows_time_t_to_unix_time(unix_st.st_mtime);
|
||||||
r_stat.st_size = static_cast<remote::file_size>(unix_st.st_size);
|
r_stat.st_size = static_cast<remote::file_size>(unix_st.st_size);
|
||||||
r_stat.st_mode = unix_st.st_mode;
|
r_stat.st_mode = unix_st.st_mode;
|
||||||
}
|
}
|
||||||
|
@@ -931,10 +931,9 @@ auto winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
|
|||||||
api_path, {utils::string::to_utf8(marker)})));
|
api_path, {utils::string::to_utf8(marker)})));
|
||||||
while ((error = iterator.get_directory_item(
|
while ((error = iterator.get_directory_item(
|
||||||
offset++, dir_item)) == api_error::success) {
|
offset++, dir_item)) == api_error::success) {
|
||||||
// if (utils::path::is_ads_file_path(dir_item.api_path) ||
|
if (dir_item.api_path == "." || dir_item.api_path == "..") {
|
||||||
// dir_item.api_path == "." || dir_item.api_path == "..") {
|
continue;
|
||||||
// continue;
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
if (dir_item.meta.empty()) {
|
if (dir_item.meta.empty()) {
|
||||||
utils::error::raise_api_path_error(
|
utils::error::raise_api_path_error(
|
||||||
|
@@ -72,58 +72,20 @@ encrypt_provider::encrypt_provider(app_config &config) : config_(config) {}
|
|||||||
auto encrypt_provider::create_api_file(
|
auto encrypt_provider::create_api_file(
|
||||||
const std::string &api_path, bool directory,
|
const std::string &api_path, bool directory,
|
||||||
const std::string &source_path) -> api_file {
|
const std::string &source_path) -> api_file {
|
||||||
#if defined(_WIN32)
|
auto times = utils::file::get_times(source_path);
|
||||||
struct _stat64 buf {};
|
if (not times.has_value()) {
|
||||||
_stat64(source_path.c_str(), &buf);
|
throw std::runtime_error("failed to get file times");
|
||||||
#else
|
}
|
||||||
struct stat buf {};
|
|
||||||
stat(source_path.c_str(), &buf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
api_file file{};
|
api_file file{};
|
||||||
|
file.accessed_date = times->get(utils::file::time_type::accessed);
|
||||||
file.api_path = api_path;
|
file.api_path = api_path;
|
||||||
file.api_parent = utils::path::get_parent_api_path(api_path);
|
file.api_parent = utils::path::get_parent_api_path(api_path);
|
||||||
file.file_size =
|
file.changed_date = times->get(utils::file::time_type::modified);
|
||||||
directory
|
file.creation_date = times->get(utils::file::time_type::created);
|
||||||
? 0U
|
file.file_size = directory ? 0U : utils::encryption::encrypting_reader::calculate_encrypted_size( source_path);
|
||||||
: utils::encryption::encrypting_reader::calculate_encrypted_size(
|
file.modified_date = times->get(utils::file::time_type::written);
|
||||||
source_path);
|
|
||||||
file.source_path = source_path;
|
file.source_path = source_path;
|
||||||
#if defined(__APPLE__)
|
|
||||||
file.changed_date = buf.st_ctimespec.tv_nsec +
|
|
||||||
(buf.st_ctimespec.tv_sec * utils::time::NANOS_PER_SECOND);
|
|
||||||
file.accessed_date =
|
|
||||||
buf.st_atimespec.tv_nsec +
|
|
||||||
(buf.st_atimespec.tv_sec * utils::time::NANOS_PER_SECOND);
|
|
||||||
file.creation_date =
|
|
||||||
buf.st_birthtimespec.tv_nsec +
|
|
||||||
(buf.st_birthtimespec.tv_sec * utils::time::NANOS_PER_SECOND);
|
|
||||||
file.modified_date =
|
|
||||||
buf.st_mtimespec.tv_nsec +
|
|
||||||
(buf.st_mtimespec.tv_sec * utils::time::NANOS_PER_SECOND);
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
file.accessed_date = utils::time::windows_time_to_unix_time(
|
|
||||||
static_cast<std::uint64_t>(buf.st_atime));
|
|
||||||
file.changed_date = utils::time::windows_time_to_unix_time(
|
|
||||||
static_cast<std::uint64_t>(buf.st_mtime));
|
|
||||||
file.creation_date = utils::time::windows_time_to_unix_time(
|
|
||||||
static_cast<std::uint64_t>(buf.st_ctime));
|
|
||||||
file.modified_date = utils::time::windows_time_to_unix_time(
|
|
||||||
static_cast<std::uint64_t>(buf.st_mtime));
|
|
||||||
#else // !defined(_WIN32) && !defined(__APPLE__)
|
|
||||||
file.changed_date = static_cast<std::uint64_t>(
|
|
||||||
buf.st_mtim.tv_nsec +
|
|
||||||
(buf.st_mtim.tv_sec * utils::time::NANOS_PER_SECOND));
|
|
||||||
file.accessed_date = static_cast<std::uint64_t>(
|
|
||||||
buf.st_atim.tv_nsec +
|
|
||||||
(buf.st_atim.tv_sec * utils::time::NANOS_PER_SECOND));
|
|
||||||
file.creation_date = static_cast<std::uint64_t>(
|
|
||||||
buf.st_ctim.tv_nsec +
|
|
||||||
(buf.st_ctim.tv_sec * utils::time::NANOS_PER_SECOND));
|
|
||||||
file.modified_date = static_cast<std::uint64_t>(
|
|
||||||
buf.st_mtim.tv_nsec +
|
|
||||||
(buf.st_mtim.tv_sec * utils::time::NANOS_PER_SECOND));
|
|
||||||
#endif // defined(__APPLE__)
|
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
@@ -133,25 +95,18 @@ void encrypt_provider::create_item_meta(api_meta_map &meta, bool directory,
|
|||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
struct _stat64 buf {};
|
struct _stat64 buf {};
|
||||||
_stat64(file.source_path.c_str(), &buf);
|
_stat64(file.source_path.c_str(), &buf);
|
||||||
#else
|
#else // !defined(_WIN32)
|
||||||
struct stat buf {};
|
struct stat buf {};
|
||||||
stat(file.source_path.c_str(), &buf);
|
stat(file.source_path.c_str(), &buf);
|
||||||
#endif
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
meta[META_ACCESSED] = std::to_string(file.accessed_date);
|
meta[META_ACCESSED] = std::to_string(file.accessed_date);
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
meta[META_ATTRIBUTES] = std::to_string(
|
meta[META_ATTRIBUTES] =
|
||||||
::GetFileAttributesA(file.source_path.c_str()) &
|
std::to_string(::GetFileAttributesA(file.source_path.c_str()) &
|
||||||
~(FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_COMPRESSED |
|
~static_cast<DWORD>(FILE_ATTRIBUTE_REPARSE_POINT));
|
||||||
FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_TEMPORARY |
|
|
||||||
FILE_ATTRIBUTE_SPARSE_FILE | FILE_ATTRIBUTE_OFFLINE |
|
|
||||||
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_ATTRIBUTE_ENCRYPTED |
|
|
||||||
FILE_ATTRIBUTE_INTEGRITY_STREAM | FILE_ATTRIBUTE_VIRTUAL |
|
|
||||||
FILE_ATTRIBUTE_NO_SCRUB_DATA | FILE_ATTRIBUTE_EA |
|
|
||||||
FILE_ATTRIBUTE_PINNED | FILE_ATTRIBUTE_UNPINNED |
|
|
||||||
FILE_ATTRIBUTE_RECALL_ON_OPEN | FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS));
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
|
#endif // defined(_WIN32)
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
meta[META_BACKUP];
|
meta[META_BACKUP];
|
||||||
#endif // defined(__APPLE__)
|
#endif // defined(__APPLE__)
|
||||||
@@ -444,6 +399,8 @@ auto encrypt_provider::get_file_list(api_file_list &list) const -> api_error {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const auto cfg = config_.get_encrypt_config();
|
const auto cfg = config_.get_encrypt_config();
|
||||||
|
event_system::instance().raise<debug_log>(std::string{function_name},
|
||||||
|
cfg.path, "");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (auto &&dir_entry : utils::file::directory{cfg.path}.get_items()) {
|
for (auto &&dir_entry : utils::file::directory{cfg.path}.get_items()) {
|
||||||
@@ -597,6 +554,10 @@ auto encrypt_provider::get_pinned_files() const -> std::vector<std::string> {
|
|||||||
|
|
||||||
auto encrypt_provider::get_item_meta(const std::string &api_path,
|
auto encrypt_provider::get_item_meta(const std::string &api_path,
|
||||||
api_meta_map &meta) const -> api_error {
|
api_meta_map &meta) const -> api_error {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
auto result = db::db_select{*db_, source_table}
|
auto result = db::db_select{*db_, source_table}
|
||||||
.column("source_path")
|
.column("source_path")
|
||||||
.where("api_path")
|
.where("api_path")
|
||||||
|
@@ -232,7 +232,7 @@ auto get_directory_files(std::string path, bool oldest_first,
|
|||||||
|
|
||||||
auto is_modified_date_older_than(std::string_view path,
|
auto is_modified_date_older_than(std::string_view path,
|
||||||
const std::chrono::hours &hours) -> bool {
|
const std::chrono::hours &hours) -> bool {
|
||||||
auto modified = file{path}.get_time(file::time_types::modified);
|
auto modified = file{path}.get_time(time_type::modified);
|
||||||
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(hours);
|
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(hours);
|
||||||
return (modified + static_cast<std::uint64_t>(seconds.count()) *
|
return (modified + static_cast<std::uint64_t>(seconds.count()) *
|
||||||
utils::time::NANOS_PER_SECOND) <
|
utils::time::NANOS_PER_SECOND) <
|
||||||
|
@@ -27,6 +27,35 @@
|
|||||||
#include "utils/path.hpp"
|
#include "utils/path.hpp"
|
||||||
|
|
||||||
namespace repertory::utils::file {
|
namespace repertory::utils::file {
|
||||||
|
enum class time_type {
|
||||||
|
accessed,
|
||||||
|
created,
|
||||||
|
modified,
|
||||||
|
written,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct file_times final {
|
||||||
|
std::uint64_t accessed{};
|
||||||
|
std::uint64_t created{};
|
||||||
|
std::uint64_t modified{};
|
||||||
|
std::uint64_t written{};
|
||||||
|
|
||||||
|
[[nodiscard]] auto get(time_type type) const -> std::uint64_t {
|
||||||
|
switch (type) {
|
||||||
|
case time_type::accessed:
|
||||||
|
return accessed;
|
||||||
|
case time_type::created:
|
||||||
|
return created;
|
||||||
|
case time_type::modified:
|
||||||
|
return modified;
|
||||||
|
case time_type::written:
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("type_type not supported");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
[[nodiscard]] inline auto
|
[[nodiscard]] inline auto
|
||||||
directory_exists_in_path(std::string_view path,
|
directory_exists_in_path(std::string_view path,
|
||||||
std::string_view sub_directory) -> bool;
|
std::string_view sub_directory) -> bool;
|
||||||
@@ -42,6 +71,18 @@ file_exists_in_path(std::string_view path, std::string_view file_name) -> bool;
|
|||||||
file_exists_in_path(std::wstring_view path,
|
file_exists_in_path(std::wstring_view path,
|
||||||
std::wstring_view file_name) -> bool;
|
std::wstring_view file_name) -> bool;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_time(std::string_view path,
|
||||||
|
time_type type) -> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_time(std::wstring_view path,
|
||||||
|
time_type type) -> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
get_times(std::string_view path) -> std::optional<file_times>;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
get_times(std::wstring_view path) -> std::optional<file_times>;
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_LIBDSM)
|
#if defined(PROJECT_ENABLE_LIBDSM)
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto
|
||||||
smb_create_and_validate_relative_path(std::string_view smb_path,
|
smb_create_and_validate_relative_path(std::string_view smb_path,
|
||||||
@@ -77,13 +118,6 @@ smb_get_parent_path(std::string_view smb_path) -> std::string;
|
|||||||
struct i_fs_item {
|
struct i_fs_item {
|
||||||
using fs_item_t = std::unique_ptr<i_fs_item>;
|
using fs_item_t = std::unique_ptr<i_fs_item>;
|
||||||
|
|
||||||
enum class time_types {
|
|
||||||
access,
|
|
||||||
creation,
|
|
||||||
modified,
|
|
||||||
write,
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~i_fs_item() = default;
|
virtual ~i_fs_item() = default;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto copy_to(std::string_view to_path,
|
[[nodiscard]] virtual auto copy_to(std::string_view to_path,
|
||||||
@@ -98,7 +132,8 @@ struct i_fs_item {
|
|||||||
|
|
||||||
[[nodiscard]] virtual auto get_path() const -> std::string = 0;
|
[[nodiscard]] virtual auto get_path() const -> std::string = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_time(time_types type) const -> std::uint64_t;
|
[[nodiscard]] virtual auto
|
||||||
|
get_time(time_type type) const -> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto is_directory_item() const -> bool = 0;
|
[[nodiscard]] virtual auto is_directory_item() const -> bool = 0;
|
||||||
|
|
||||||
@@ -237,13 +272,7 @@ public:
|
|||||||
file(file &&move_file) noexcept
|
file(file &&move_file) noexcept
|
||||||
: file_(std::move(move_file.file_)),
|
: file_(std::move(move_file.file_)),
|
||||||
path_(std::move(move_file.path_)),
|
path_(std::move(move_file.path_)),
|
||||||
read_only_(move_file.read_only_)
|
read_only_(move_file.read_only_) {}
|
||||||
#if defined(_WIN32)
|
|
||||||
,
|
|
||||||
mtx_(std::move(move_file.mtx_))
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~file() override { close(); }
|
~file() override { close(); }
|
||||||
|
|
||||||
@@ -251,11 +280,6 @@ private:
|
|||||||
file_t file_;
|
file_t file_;
|
||||||
std::string path_;
|
std::string path_;
|
||||||
bool read_only_{false};
|
bool read_only_{false};
|
||||||
#if defined(_WIN32)
|
|
||||||
mutable std::unique_ptr<std::recursive_mutex> mtx_{
|
|
||||||
new std::recursive_mutex(),
|
|
||||||
};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::atomic_uint32_t read_buffer_size{65536U};
|
std::atomic_uint32_t read_buffer_size{65536U};
|
||||||
@@ -281,8 +305,6 @@ public:
|
|||||||
return read_buffer_size;
|
return read_buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] auto get_time(time_types type) const -> std::uint64_t override;
|
|
||||||
|
|
||||||
[[nodiscard]] auto is_read_only() const -> bool override {
|
[[nodiscard]] auto is_read_only() const -> bool override {
|
||||||
return read_only_;
|
return read_only_;
|
||||||
}
|
}
|
||||||
@@ -322,9 +344,6 @@ public:
|
|||||||
file_ = std::move(move_file.file_);
|
file_ = std::move(move_file.file_);
|
||||||
path_ = std::move(move_file.path_);
|
path_ = std::move(move_file.path_);
|
||||||
read_only_ = move_file.read_only_;
|
read_only_ = move_file.read_only_;
|
||||||
#if defined(_WIN32)
|
|
||||||
mtx_ = std::move(move_file.mtx_);
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@@ -376,7 +395,8 @@ public:
|
|||||||
return file_->get_read_buffer_size();
|
return file_->get_read_buffer_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] auto get_time(time_types type) const -> std::uint64_t override {
|
[[nodiscard]] auto
|
||||||
|
get_time(time_type type) const -> std::optional<std::uint64_t> override {
|
||||||
return file_->get_time(type);
|
return file_->get_time(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,7 +515,8 @@ public:
|
|||||||
return file_->get_read_buffer_size();
|
return file_->get_read_buffer_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] auto get_time(time_types type) const -> std::uint64_t override {
|
[[nodiscard]] auto
|
||||||
|
get_time(time_type type) const -> std::optional<std::uint64_t> override {
|
||||||
return file_->get_time(type);
|
return file_->get_time(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,11 +739,12 @@ public:
|
|||||||
return read_buffer_size;
|
return read_buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static auto get_time(smb_session *session, smb_tid tid,
|
[[nodiscard]] static auto
|
||||||
std::string path,
|
get_time(smb_session *session, smb_tid tid, std::string path,
|
||||||
time_types type) -> std::uint64_t;
|
time_type type) -> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
[[nodiscard]] auto get_time(time_types type) const -> std::uint64_t override {
|
[[nodiscard]] auto
|
||||||
|
get_time(time_type type) const -> std::optional<std::uint64_t> override {
|
||||||
return get_time(session_.get(), tid_, path_, type);
|
return get_time(session_.get(), tid_, path_, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -854,7 +876,8 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] auto get_path() const -> std::string override { return path_; }
|
[[nodiscard]] auto get_path() const -> std::string override { return path_; }
|
||||||
|
|
||||||
[[nodiscard]] auto get_time(time_types type) const -> std::uint64_t override {
|
[[nodiscard]] auto
|
||||||
|
get_time(time_type type) const -> std::optional<std::uint64_t> override {
|
||||||
return smb_file::get_time(session_.get(), tid_, path_, type);
|
return smb_file::get_time(session_.get(), tid_, path_, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,11 +36,6 @@ inline constexpr const auto WIN32_TIME_NANOS_PER_TICK{100ULL};
|
|||||||
}
|
}
|
||||||
#endif // defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT)
|
#endif // defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT)
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
[[nodiscard]] auto
|
|
||||||
filetime_to_unix_time(const FILETIME &file_time) -> std::uint64_t;
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT)
|
#if defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT)
|
||||||
[[nodiscard]] inline auto get_current_time_utc() -> std::time_t {
|
[[nodiscard]] inline auto get_current_time_utc() -> std::time_t {
|
||||||
auto calendar_time = fmt::gmtime(std::time(nullptr));
|
auto calendar_time = fmt::gmtime(std::time(nullptr));
|
||||||
@@ -55,9 +50,10 @@ void get_local_time_now(struct tm &local_time);
|
|||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
auto strptime(const char *s, const char *f, struct tm *tm) -> const char *;
|
auto strptime(const char *s, const char *f, struct tm *tm) -> const char *;
|
||||||
|
|
||||||
[[nodiscard]] auto time64_to_unix_time(const __time64_t &time) -> std::uint64_t;
|
|
||||||
|
|
||||||
[[nodiscard]] auto unix_time_to_filetime(std::uint64_t unix_time) -> FILETIME;
|
[[nodiscard]] auto unix_time_to_filetime(std::uint64_t unix_time) -> FILETIME;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
windows_time_t_to_unix_time(__time64_t win_time) -> std::uint64_t;
|
||||||
#endif // defined(_WIN32)
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto
|
||||||
|
@@ -28,6 +28,84 @@
|
|||||||
#include "utils/time.hpp"
|
#include "utils/time.hpp"
|
||||||
|
|
||||||
namespace repertory::utils::file {
|
namespace repertory::utils::file {
|
||||||
|
auto get_time(std::string_view path,
|
||||||
|
time_type type) -> std::optional<std::uint64_t> {
|
||||||
|
auto times = get_times(path);
|
||||||
|
if (times.has_value()) {
|
||||||
|
return times->get(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto get_time(std::wstring_view path,
|
||||||
|
time_type type) -> std::optional<std::uint64_t> {
|
||||||
|
return get_time(utils::string::to_utf8(path), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto get_times(std::string_view path) -> std::optional<file_times> {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
#if defined(_WIN32)
|
||||||
|
struct _stat64 st {};
|
||||||
|
auto res = _stat64(std::string{path}.c_str(), &st);
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
struct stat st {};
|
||||||
|
auto res = stat(std::string{path}.c_str(), &st);
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
if (res != 0) {
|
||||||
|
throw std::runtime_error("failed to get file times|" + std::string{path} +
|
||||||
|
'|' + std::to_string(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
file_times ret{};
|
||||||
|
#if defined(_WIN32)
|
||||||
|
ret.accessed = utils::time::windows_time_t_to_unix_time(st.st_atime);
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
ret.accessed = static_cast<std::uint64_t>(
|
||||||
|
st.st_atim.tv_nsec + st.st_atim.tv_sec * utils::time::NANOS_PER_SECOND);
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
ret.created = utils::time::windows_time_t_to_unix_time(st.st_ctime);
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
ret.created = static_cast<std::uint64_t>(
|
||||||
|
st.st_ctim.tv_nsec + st.st_ctim.tv_sec * utils::time::NANOS_PER_SECOND);
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
ret.modified = utils::time::windows_time_t_to_unix_time(st.st_mtime);
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
ret.modified = static_cast<std::uint64_t>(
|
||||||
|
st.st_mtim.tv_nsec + st.st_mtim.tv_sec * utils::time::NANOS_PER_SECOND);
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
ret.written = utils::time::windows_time_t_to_unix_time(st.st_mtime);
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
ret.written = static_cast<std::uint64_t>(
|
||||||
|
st.st_mtim.tv_nsec + st.st_mtim.tv_sec * utils::time::NANOS_PER_SECOND);
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto get_times(std::wstring_view path) -> std::optional<file_times> {
|
||||||
|
return get_times(utils::string::to_utf8(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto i_fs_item::get_time(time_type type) const -> std::optional<std::uint64_t> {
|
||||||
|
return utils::file::get_time(get_path(), type);
|
||||||
|
}
|
||||||
|
|
||||||
auto i_file::read_all(data_buffer &data, std::uint64_t offset,
|
auto i_file::read_all(data_buffer &data, std::uint64_t offset,
|
||||||
std::size_t *total_read) -> bool {
|
std::size_t *total_read) -> bool {
|
||||||
data_buffer buffer;
|
data_buffer buffer;
|
||||||
@@ -58,70 +136,6 @@ auto i_file::read_all(data_buffer &data, std::uint64_t offset,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto i_fs_item::get_time(time_types type) const -> std::uint64_t {
|
|
||||||
static constexpr const std::string_view function_name{
|
|
||||||
static_cast<const char *>(__FUNCTION__),
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
#if defined(_WIN32)
|
|
||||||
struct _stat64 st {};
|
|
||||||
_stat64(get_path().c_str(), &st);
|
|
||||||
#else // !defined(_WIN32)
|
|
||||||
struct stat st {};
|
|
||||||
stat(get_path().c_str(), &st);
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case time_types::access:
|
|
||||||
#if defined(_WIN32)
|
|
||||||
return utils::time::windows_time_to_unix_time(
|
|
||||||
static_cast<std::uint64_t>(st.st_atime));
|
|
||||||
#else // !defined(_WIN32)
|
|
||||||
return static_cast<std::uint64_t>(st.st_atim.tv_nsec +
|
|
||||||
st.st_atim.tv_sec *
|
|
||||||
utils::time::NANOS_PER_SECOND);
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
case time_types::creation:
|
|
||||||
#if defined(_WIN32)
|
|
||||||
return utils::time::windows_time_to_unix_time(
|
|
||||||
static_cast<std::uint64_t>(st.st_ctime));
|
|
||||||
#else // !defined(_WIN32)
|
|
||||||
return static_cast<std::uint64_t>(st.st_ctim.tv_nsec +
|
|
||||||
st.st_ctim.tv_sec *
|
|
||||||
utils::time::NANOS_PER_SECOND);
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
case time_types::modified:
|
|
||||||
#if defined(_WIN32)
|
|
||||||
return utils::time::windows_time_to_unix_time(
|
|
||||||
static_cast<std::uint64_t>(st.st_mtime));
|
|
||||||
#else // !defined(_WIN32)
|
|
||||||
return static_cast<std::uint64_t>(st.st_mtim.tv_nsec +
|
|
||||||
st.st_mtim.tv_sec *
|
|
||||||
utils::time::NANOS_PER_SECOND);
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
case time_types::write:
|
|
||||||
#if defined(_WIN32)
|
|
||||||
return utils::time::windows_time_to_unix_time(
|
|
||||||
static_cast<std::uint64_t>(st.st_mtime));
|
|
||||||
#else // !defined(_WIN32)
|
|
||||||
return static_cast<std::uint64_t>(st.st_mtim.tv_nsec +
|
|
||||||
st.st_mtim.tv_sec *
|
|
||||||
utils::time::NANOS_PER_SECOND);
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
}
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
utils::error::handle_exception(function_name, e);
|
|
||||||
} catch (...) {
|
|
||||||
utils::error::handle_exception(function_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_JSON)
|
#if defined(PROJECT_ENABLE_JSON)
|
||||||
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
|
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
|
||||||
auto read_json_file(std::string_view path, nlohmann::json &data,
|
auto read_json_file(std::string_view path, nlohmann::json &data,
|
||||||
|
@@ -65,10 +65,11 @@ auto traverse_directory(
|
|||||||
std::to_string(repertory::utils::get_last_error_code()));
|
std::to_string(repertory::utils::get_last_error_code()));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dirent *de{};
|
struct dirent *de{nullptr};
|
||||||
while (res && (de = readdir(root))) {
|
while (res && (de = readdir(root))) {
|
||||||
if (de->d_type == DT_DIR) {
|
if (de->d_type == DT_DIR) {
|
||||||
if ((strcmp(de->d_name, ".") != 0) && (strcmp(de->d_name, "..") != 0)) {
|
if ((std::string_view(de->d_name) != ".") &&
|
||||||
|
(std::string_view(de->d_name) != "..")) {
|
||||||
res = directory_action(repertory::utils::file::directory(
|
res = directory_action(repertory::utils::file::directory(
|
||||||
repertory::utils::path::combine(path, {de->d_name})));
|
repertory::utils::path::combine(path, {de->d_name})));
|
||||||
}
|
}
|
||||||
|
@@ -179,13 +179,7 @@ auto file::open_or_create_file(std::string_view path,
|
|||||||
return open_file(abs_path, read_only);
|
return open_file(abs_path, read_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
void file::close() {
|
void file::close() { file_.reset(); }
|
||||||
#if defined(_WIN32)
|
|
||||||
recur_mutex_lock lock{*mtx_};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
file_.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto file::copy_to(std::string_view new_path, bool overwrite) const -> bool {
|
auto file::copy_to(std::string_view new_path, bool overwrite) const -> bool {
|
||||||
static constexpr const std::string_view function_name{
|
static constexpr const std::string_view function_name{
|
||||||
@@ -216,29 +210,15 @@ auto file::copy_to(std::string_view new_path, bool overwrite) const -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto file::exists() const -> bool {
|
auto file::exists() const -> bool { return is_file(path_); }
|
||||||
#if defined(_WIN32)
|
|
||||||
recur_mutex_lock lock{*mtx_};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
return is_file(path_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void file::flush() const {
|
void file::flush() const {
|
||||||
#if defined(_WIN32)
|
|
||||||
recur_mutex_lock lock{*mtx_};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
if (file_) {
|
if (file_) {
|
||||||
fflush(file_.get());
|
fflush(file_.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto file::get_handle() const -> native_handle {
|
auto file::get_handle() const -> native_handle {
|
||||||
#if defined(_WIN32)
|
|
||||||
recur_mutex_lock lock{*mtx_};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
if (file_) {
|
if (file_) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
return reinterpret_cast<native_handle>(
|
return reinterpret_cast<native_handle>(
|
||||||
@@ -251,14 +231,6 @@ auto file::get_handle() const -> native_handle {
|
|||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto file::get_time(time_types type) const -> std::uint64_t {
|
|
||||||
#if defined(_WIN32)
|
|
||||||
recur_mutex_lock lock{*mtx_};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
return i_fs_item::get_time(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto file::is_symlink() const -> bool {
|
auto file::is_symlink() const -> bool {
|
||||||
static constexpr const std::string_view function_name{
|
static constexpr const std::string_view function_name{
|
||||||
static_cast<const char *>(__FUNCTION__),
|
static_cast<const char *>(__FUNCTION__),
|
||||||
@@ -280,10 +252,6 @@ auto file::move_to(std::string_view path) -> bool {
|
|||||||
static_cast<const char *>(__FUNCTION__),
|
static_cast<const char *>(__FUNCTION__),
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
recur_mutex_lock lock{*mtx_};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
auto abs_path = utils::path::absolute(path);
|
auto abs_path = utils::path::absolute(path);
|
||||||
|
|
||||||
auto reopen{false};
|
auto reopen{false};
|
||||||
@@ -326,10 +294,6 @@ auto file::read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
|
|||||||
static_cast<const char *>(__FUNCTION__),
|
static_cast<const char *>(__FUNCTION__),
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
recur_mutex_lock lock{*mtx_};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
if (total_read != nullptr) {
|
if (total_read != nullptr) {
|
||||||
(*total_read) = 0U;
|
(*total_read) = 0U;
|
||||||
}
|
}
|
||||||
@@ -441,10 +405,6 @@ auto file::sha256() -> std::optional<std::string> {
|
|||||||
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
|
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
|
||||||
|
|
||||||
auto file::remove() -> bool {
|
auto file::remove() -> bool {
|
||||||
#if defined(_WIN32)
|
|
||||||
recur_mutex_lock lock{*mtx_};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
if (not exists()) {
|
if (not exists()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -466,10 +426,6 @@ auto file::truncate(std::size_t size) -> bool {
|
|||||||
static_cast<const char *>(__FUNCTION__),
|
static_cast<const char *>(__FUNCTION__),
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
recur_mutex_lock lock{*mtx_};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
auto reopen{false};
|
auto reopen{false};
|
||||||
if (file_) {
|
if (file_) {
|
||||||
reopen = true;
|
reopen = true;
|
||||||
@@ -502,10 +458,6 @@ auto file::write(const unsigned char *data, std::size_t to_write,
|
|||||||
static_cast<const char *>(__FUNCTION__),
|
static_cast<const char *>(__FUNCTION__),
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
recur_mutex_lock lock{*mtx_};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
if (total_written != nullptr) {
|
if (total_written != nullptr) {
|
||||||
(*total_written) = 0U;
|
(*total_written) = 0U;
|
||||||
}
|
}
|
||||||
@@ -556,10 +508,6 @@ auto file::size() const -> std::optional<std::uint64_t> {
|
|||||||
static_cast<const char *>(__FUNCTION__),
|
static_cast<const char *>(__FUNCTION__),
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
recur_mutex_lock lock{*mtx_};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file_) {
|
if (file_) {
|
||||||
if (fseeko(file_.get(), 0, SEEK_END) == -1) {
|
if (fseeko(file_.get(), 0, SEEK_END) == -1) {
|
||||||
|
@@ -101,7 +101,7 @@ void smb_file::flush() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto smb_file::get_time(smb_session *session, smb_tid tid, std::string path,
|
auto smb_file::get_time(smb_session *session, smb_tid tid, std::string path,
|
||||||
time_types type) -> std::uint64_t {
|
time_type type) -> std::optional<std::uint64_t> {
|
||||||
static constexpr const std::string_view function_name{
|
static constexpr const std::string_view function_name{
|
||||||
static_cast<const char *>(__FUNCTION__),
|
static_cast<const char *>(__FUNCTION__),
|
||||||
};
|
};
|
||||||
@@ -118,16 +118,16 @@ auto smb_file::get_time(smb_session *session, smb_tid tid, std::string path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case time_types::access:
|
case time_type::access:
|
||||||
return smb_stat_get(st.get(), SMB_STAT_ATIME);
|
return smb_stat_get(st.get(), SMB_STAT_ATIME);
|
||||||
|
|
||||||
case time_types::creation:
|
case time_type::creation:
|
||||||
return smb_stat_get(st.get(), SMB_STAT_CTIME);
|
return smb_stat_get(st.get(), SMB_STAT_CTIME);
|
||||||
|
|
||||||
case time_types::modified:
|
case time_type::modified:
|
||||||
return smb_stat_get(st.get(), SMB_STAT_MTIME);
|
return smb_stat_get(st.get(), SMB_STAT_MTIME);
|
||||||
|
|
||||||
case time_types::write:
|
case time_type::write:
|
||||||
return smb_stat_get(st.get(), SMB_STAT_WTIME);
|
return smb_stat_get(st.get(), SMB_STAT_WTIME);
|
||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
@@ -136,7 +136,7 @@ auto smb_file::get_time(smb_session *session, smb_tid tid, std::string path,
|
|||||||
utils::error::handle_exception(function_name);
|
utils::error::handle_exception(function_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0U;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto smb_file::is_symlink() const -> bool {
|
auto smb_file::is_symlink() const -> bool {
|
||||||
|
@@ -22,18 +22,6 @@
|
|||||||
#include "utils/time.hpp"
|
#include "utils/time.hpp"
|
||||||
|
|
||||||
namespace repertory::utils::time {
|
namespace repertory::utils::time {
|
||||||
#if defined(_WIN32)
|
|
||||||
// https://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/
|
|
||||||
auto filetime_to_unix_time(const FILETIME &file_time) -> std::uint64_t {
|
|
||||||
LARGE_INTEGER date{};
|
|
||||||
date.HighPart = static_cast<LONG>(file_time.dwHighDateTime);
|
|
||||||
date.LowPart = file_time.dwLowDateTime;
|
|
||||||
date.QuadPart -= WIN32_TIME_CONVERSION;
|
|
||||||
|
|
||||||
return static_cast<std::uint64_t>(date.QuadPart) * WIN32_TIME_NANOS_PER_TICK;
|
|
||||||
}
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
void get_local_time_now(struct tm &local_time) {
|
void get_local_time_now(struct tm &local_time) {
|
||||||
std::memset(&local_time, 0, sizeof(local_time));
|
std::memset(&local_time, 0, sizeof(local_time));
|
||||||
|
|
||||||
@@ -66,19 +54,22 @@ auto strptime(const char *s, const char *f, struct tm *tm) -> const char * {
|
|||||||
return reinterpret_cast<const char *>(s + input.tellg());
|
return reinterpret_cast<const char *>(s + input.tellg());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto time64_to_unix_time(const __time64_t &time) -> std::uint64_t {
|
|
||||||
return static_cast<std::uint64_t>(time * NANOS_PER_SECOND);
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/
|
// https://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/
|
||||||
auto unix_time_to_filetime(std::uint64_t unix_time) -> FILETIME {
|
auto unix_time_to_filetime(std::uint64_t unix_time) -> FILETIME {
|
||||||
auto win_time =
|
auto win_time = unix_time_to_windows_time(unix_time);
|
||||||
(unix_time / WIN32_TIME_NANOS_PER_TICK) + WIN32_TIME_CONVERSION;
|
|
||||||
FILETIME file_time{};
|
FILETIME file_time{};
|
||||||
file_time.dwHighDateTime = static_cast<DWORD>(win_time >> 32U);
|
file_time.dwHighDateTime = static_cast<DWORD>(win_time >> 32U);
|
||||||
file_time.dwLowDateTime = win_time & 0xFFFFFFFF;
|
file_time.dwLowDateTime = win_time & 0xFFFFFFFF;
|
||||||
return file_time;
|
return file_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto windows_time_t_to_unix_time(__time64_t win_time) -> std::uint64_t {
|
||||||
|
return static_cast<std::uint64_t>(
|
||||||
|
std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||||
|
std::chrono::system_clock::from_time_t(win_time).time_since_epoch())
|
||||||
|
.count());
|
||||||
|
}
|
||||||
#endif // defined(_WIN32)
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
auto unix_time_to_windows_time(std::uint64_t unix_time) -> std::uint64_t {
|
auto unix_time_to_windows_time(std::uint64_t unix_time) -> std::uint64_t {
|
||||||
@@ -86,6 +77,6 @@ auto unix_time_to_windows_time(std::uint64_t unix_time) -> std::uint64_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto windows_time_to_unix_time(std::uint64_t win_time) -> std::uint64_t {
|
auto windows_time_to_unix_time(std::uint64_t win_time) -> std::uint64_t {
|
||||||
return (win_time - WIN32_TIME_CONVERSION) * WIN32_TIME_NANOS_PER_TICK;
|
return (win_time * WIN32_TIME_NANOS_PER_TICK) - WIN32_TIME_CONVERSION;
|
||||||
}
|
}
|
||||||
} // namespace repertory::utils::time
|
} // namespace repertory::utils::time
|
||||||
|
Reference in New Issue
Block a user