From b41664ac616894686e072ede61c609b422d79ed4 Mon Sep 17 00:00:00 2001 From: Vinicius Rangel Date: Wed, 20 Nov 2024 13:31:44 -0300 Subject: [PATCH] savedata: fix dir name search with wildcard (#1552) * savedata: fix dir name search with wildcard * psf: replace filesystem clock by system clock (utc) * savedatadialog_ui: macOS zoned_time formatting Signed-off-by: Vinicius Rangel --------- Signed-off-by: Vinicius Rangel Co-authored-by: squidbus <175574877+squidbus@users.noreply.github.com> --- src/core/file_format/psf.cpp | 9 ++++- src/core/file_format/psf.h | 5 ++- .../save_data/dialog/savedatadialog_ui.cpp | 37 ++++++++++++++++--- .../save_data/dialog/savedatadialog_ui.h | 2 +- src/core/libraries/save_data/savedata.cpp | 10 +++-- 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/core/file_format/psf.cpp b/src/core/file_format/psf.cpp index 0502f29d..7e0ffc9a 100644 --- a/src/core/file_format/psf.cpp +++ b/src/core/file_format/psf.cpp @@ -21,8 +21,13 @@ static inline u32 get_max_size(std::string_view key, u32 default_value) { } bool PSF::Open(const std::filesystem::path& filepath) { + using namespace std::chrono; if (std::filesystem::exists(filepath)) { - last_write = std::filesystem::last_write_time(filepath); + const auto t = std::filesystem::last_write_time(filepath); + const auto rel = + duration_cast(t - std::filesystem::file_time_type::clock::now()).count(); + const auto tp = system_clock::to_time_t(system_clock::now() + seconds{rel}); + last_write = system_clock::from_time_t(tp); } Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read); @@ -99,7 +104,7 @@ bool PSF::Encode(const std::filesystem::path& filepath) const { return false; } - last_write = std::filesystem::file_time_type::clock::now(); + last_write = std::chrono::system_clock::now(); const auto psf_buffer = Encode(); const size_t written = file.Write(psf_buffer); diff --git a/src/core/file_format/psf.h b/src/core/file_format/psf.h index 6f35fa69..0f662131 100644 --- a/src/core/file_format/psf.h +++ b/src/core/file_format/psf.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include #include @@ -71,7 +72,7 @@ public: void AddString(std::string key, std::string value, bool update = false); void AddInteger(std::string key, s32 value, bool update = false); - [[nodiscard]] std::filesystem::file_time_type GetLastWrite() const { + [[nodiscard]] std::chrono::system_clock::time_point GetLastWrite() const { return last_write; } @@ -80,7 +81,7 @@ public: } private: - mutable std::filesystem::file_time_type last_write; + mutable std::chrono::system_clock::time_point last_write; std::vector entry_list; diff --git a/src/core/libraries/save_data/dialog/savedatadialog_ui.cpp b/src/core/libraries/save_data/dialog/savedatadialog_ui.cpp index 01e56f8b..52abe910 100644 --- a/src/core/libraries/save_data/dialog/savedatadialog_ui.cpp +++ b/src/core/libraries/save_data/dialog/savedatadialog_ui.cpp @@ -13,6 +13,33 @@ #include "imgui/imgui_std.h" #include "savedatadialog_ui.h" +#ifdef __APPLE__ +#include + +// Need to make a copy of the formatter for std::chrono::local_time for use with date::local_time +template +struct fmt::formatter, Char> : formatter { + FMT_CONSTEXPR formatter() { + this->format_str_ = fmt::detail::string_literal(); + } + + template + auto format(date::local_time val, FormatContext& ctx) const -> decltype(ctx.out()) { + using period = typename Duration::period; + if (period::num == 1 && period::den == 1 && + !std::is_floating_point::value) { + return formatter::format( + localtime(fmt::detail::to_time_t(date::current_zone()->to_sys(val))), ctx); + } + auto epoch = val.time_since_epoch(); + auto subsecs = fmt::detail::duration_cast( + epoch - fmt::detail::duration_cast(epoch)); + return formatter::do_format( + localtime(fmt::detail::to_time_t(date::current_zone()->to_sys(val))), ctx, &subsecs); + } +}; +#endif + using namespace ImGui; using namespace Libraries::CommonDialog; using Common::ElfInfo; @@ -98,12 +125,12 @@ SaveDialogState::SaveDialogState(const OrbisSaveDataDialogParam& param) { param_sfo.Open(param_sfo_path); auto last_write = param_sfo.GetLastWrite(); -#if defined(_WIN32) && !defined(__GNUC__) && !defined(__MINGW32__) && !defined(__MINGW64__) - auto utc_time = std::chrono::file_clock::to_utc(last_write); +#ifdef __APPLE__ + auto t = date::zoned_time{date::current_zone(), last_write}; #else - auto utc_time = std::chrono::file_clock::to_sys(last_write); + auto t = std::chrono::zoned_time{std::chrono::current_zone(), last_write}; #endif - std::string date_str = fmt::format("{:%d %b, %Y %R}", utc_time); + std::string date_str = fmt::format("{:%d %b, %Y %R}", t.get_local_time()); size_t size = Common::FS::GetDirectorySize(dir_path); std::string size_str = SpaceSizeToString(size); @@ -592,7 +619,7 @@ void SaveDialogUi::DrawList() { int idx = 0; int max_idx = 0; bool is_min = pos == FocusPos::DATAOLDEST; - std::filesystem::file_time_type max_write{}; + std::chrono::system_clock::time_point max_write{}; if (state->new_item.has_value()) { idx++; } diff --git a/src/core/libraries/save_data/dialog/savedatadialog_ui.h b/src/core/libraries/save_data/dialog/savedatadialog_ui.h index 3f414470..aa67e1f5 100644 --- a/src/core/libraries/save_data/dialog/savedatadialog_ui.h +++ b/src/core/libraries/save_data/dialog/savedatadialog_ui.h @@ -248,7 +248,7 @@ public: std::string date{}; std::string size{}; - std::filesystem::file_time_type last_write{}; + std::chrono::system_clock::time_point last_write{}; PSF pfo{}; bool is_corrupted{}; }; diff --git a/src/core/libraries/save_data/savedata.cpp b/src/core/libraries/save_data/savedata.cpp index 93b3c20a..c515ebcb 100644 --- a/src/core/libraries/save_data/savedata.cpp +++ b/src/core/libraries/save_data/savedata.cpp @@ -149,7 +149,7 @@ struct OrbisSaveDataIcon { size_t dataSize; std::array _reserved; - Error LoadIcon(const std::filesystem::path& icon_path) { + Error LoadIcon(const fs::path& icon_path) { try { const Common::FS::IOFile file(icon_path, Common::FS::FileAccessMode::Read); dataSize = file.GetSize(); @@ -345,7 +345,9 @@ static bool match(std::string_view str, std::string_view pattern) { if (*pat_it == '_') { // 1 character wildcard ++str_it; ++pat_it; - } else if (*pat_it != *str_it) { + continue; + } + if (*pat_it != *str_it) { return false; } ++str_it; @@ -1230,7 +1232,7 @@ Error PS4_SYSV_ABI sceSaveDataLoadIcon(const OrbisSaveDataMountPoint* mountPoint return Error::PARAMETER; } LOG_DEBUG(Lib_SaveData, "called"); - std::filesystem::path path; + fs::path path; const std::string_view mount_point_str{mountPoint->data}; for (const auto& instance : g_mount_slots) { if (instance.has_value() && instance->GetMountPoint() == mount_point_str) { @@ -1375,7 +1377,7 @@ Error PS4_SYSV_ABI sceSaveDataSaveIcon(const OrbisSaveDataMountPoint* mountPoint return Error::PARAMETER; } LOG_DEBUG(Lib_SaveData, "called"); - std::filesystem::path path; + fs::path path; const std::string_view mount_point_str{mountPoint->data}; for (const auto& instance : g_mount_slots) { if (instance.has_value() && instance->GetMountPoint() == mount_point_str) {