diff --git a/Userland/Libraries/LibCore/Resource.cpp b/Userland/Libraries/LibCore/Resource.cpp index f196828f433..4334b893f5b 100644 --- a/Userland/Libraries/LibCore/Resource.cpp +++ b/Userland/Libraries/LibCore/Resource.cpp @@ -11,24 +11,27 @@ namespace Core { -Resource::Resource(String path, Scheme scheme, NonnullOwnPtr file) +Resource::Resource(String path, Scheme scheme, NonnullOwnPtr file, time_t modified_time) : m_path(move(path)) , m_scheme(scheme) , m_data(move(file)) + , m_modified_time(modified_time) { } -Resource::Resource(String path, Scheme scheme, ByteBuffer buffer) +Resource::Resource(String path, Scheme scheme, ByteBuffer buffer, time_t modified_time) : m_path(move(path)) , m_scheme(scheme) , m_data(move(buffer)) + , m_modified_time(modified_time) { } -Resource::Resource(String path, Scheme scheme, DirectoryTag) +Resource::Resource(String path, Scheme scheme, DirectoryTag, time_t modified_time) : m_path(move(path)) , m_scheme(scheme) , m_data(DirectoryTag {}) + , m_modified_time(modified_time) { } @@ -66,6 +69,11 @@ String Resource::file_url() const return MUST(String::formatted("file://{}", filesystem_path())); } +Optional Resource::modified_time() const +{ + return m_modified_time; +} + String Resource::filename() const { return MUST(String::from_utf8(LexicalPath(m_path.bytes_as_string_view()).basename())); diff --git a/Userland/Libraries/LibCore/Resource.h b/Userland/Libraries/LibCore/Resource.h index c79def4a4fa..5be17e6647d 100644 --- a/Userland/Libraries/LibCore/Resource.h +++ b/Userland/Libraries/LibCore/Resource.h @@ -31,6 +31,7 @@ public: [[nodiscard]] String filename() const; [[nodiscard]] String filesystem_path() const; [[nodiscard]] String file_url() const; + [[nodiscard]] Optional modified_time() const; [[nodiscard]] ByteBuffer clone_data() const; [[nodiscard]] ByteBuffer release_data() &&; @@ -55,14 +56,15 @@ private: Resource, }; - Resource(String path, Scheme, NonnullOwnPtr); - Resource(String path, Scheme, ByteBuffer); - Resource(String path, Scheme, DirectoryTag); + Resource(String path, Scheme, NonnullOwnPtr, time_t modified_time); + Resource(String path, Scheme, ByteBuffer, time_t modified_time); + Resource(String path, Scheme, DirectoryTag, time_t modified_time); String m_path; // Relative to scheme root. File: abspath, Resource: resource root Scheme m_scheme; Variant, ByteBuffer> m_data; + time_t m_modified_time {}; }; template Callback> diff --git a/Userland/Libraries/LibCore/ResourceImplementation.cpp b/Userland/Libraries/LibCore/ResourceImplementation.cpp index 347d91d5921..7917adcc941 100644 --- a/Userland/Libraries/LibCore/ResourceImplementation.cpp +++ b/Userland/Libraries/LibCore/ResourceImplementation.cpp @@ -25,19 +25,19 @@ ResourceImplementation& ResourceImplementation::the() return *s_the; } -NonnullRefPtr ResourceImplementation::make_resource(String full_path, NonnullOwnPtr file) +NonnullRefPtr ResourceImplementation::make_resource(String full_path, NonnullOwnPtr file, time_t modified_time) { - return adopt_ref(*new Resource(move(full_path), Resource::Scheme::Resource, move(file))); + return adopt_ref(*new Resource(move(full_path), Resource::Scheme::Resource, move(file), modified_time)); } -NonnullRefPtr ResourceImplementation::make_resource(String full_path, ByteBuffer buffer) +NonnullRefPtr ResourceImplementation::make_resource(String full_path, ByteBuffer buffer, time_t modified_time) { - return adopt_ref(*new Resource(move(full_path), Resource::Scheme::Resource, move(buffer))); + return adopt_ref(*new Resource(move(full_path), Resource::Scheme::Resource, move(buffer), modified_time)); } -NonnullRefPtr ResourceImplementation::make_directory_resource(String full_path) +NonnullRefPtr ResourceImplementation::make_directory_resource(String full_path, time_t modified_time) { - return adopt_ref(*new Resource(move(full_path), Resource::Scheme::Resource, Resource::DirectoryTag {})); + return adopt_ref(*new Resource(move(full_path), Resource::Scheme::Resource, Resource::DirectoryTag {}, modified_time)); } ErrorOr> ResourceImplementation::load_from_uri(StringView uri) @@ -51,10 +51,11 @@ ErrorOr> ResourceImplementation::load_from_uri(StringVie if (uri.starts_with(file_scheme)) { auto path = uri.substring_view(file_scheme.length()); auto utf8_path = TRY(String::from_utf8(path)); - if (is_directory(path)) - return adopt_ref(*new Resource(utf8_path, Resource::Scheme::File, Resource::DirectoryTag {})); + auto st = TRY(System::stat(utf8_path)); + if (S_ISDIR(st.st_mode)) + return adopt_ref(*new Resource(utf8_path, Resource::Scheme::File, Resource::DirectoryTag {}, st.st_mtime)); auto mapped_file = TRY(MappedFile::map(path)); - return adopt_ref(*new Resource(utf8_path, Resource::Scheme::File, move(mapped_file))); + return adopt_ref(*new Resource(utf8_path, Resource::Scheme::File, move(mapped_file), st.st_mtime)); } dbgln("ResourceImplementation: Unknown scheme for {}", uri); @@ -89,14 +90,4 @@ String ResourceImplementation::filesystem_path(Resource const& resource) return resource.m_path; } -// Note: This is a copy of the impl in LibFilesystem, but we can't link that to LibCore -bool ResourceImplementation::is_directory(StringView filesystem_path) -{ - auto st_or_error = System::stat(filesystem_path); - if (st_or_error.is_error()) - return false; - auto st = st_or_error.release_value(); - return S_ISDIR(st.st_mode); -} - } diff --git a/Userland/Libraries/LibCore/ResourceImplementation.h b/Userland/Libraries/LibCore/ResourceImplementation.h index 308b5edcaab..e173720a4ff 100644 --- a/Userland/Libraries/LibCore/ResourceImplementation.h +++ b/Userland/Libraries/LibCore/ResourceImplementation.h @@ -28,11 +28,9 @@ protected: virtual Vector child_names_for_resource_scheme(Resource const&) = 0; virtual String filesystem_path_for_resource_scheme(String const&) = 0; - static bool is_directory(StringView filesystem_path); - - static NonnullRefPtr make_resource(String full_path, NonnullOwnPtr); - static NonnullRefPtr make_resource(String full_path, ByteBuffer); - static NonnullRefPtr make_directory_resource(String full_path); + static NonnullRefPtr make_resource(String full_path, NonnullOwnPtr, time_t modified_time); + static NonnullRefPtr make_resource(String full_path, ByteBuffer, time_t modified_time); + static NonnullRefPtr make_directory_resource(String full_path, time_t modified_time); }; } diff --git a/Userland/Libraries/LibCore/ResourceImplementationFile.cpp b/Userland/Libraries/LibCore/ResourceImplementationFile.cpp index 566b83e3edb..4ee4bcc2cf6 100644 --- a/Userland/Libraries/LibCore/ResourceImplementationFile.cpp +++ b/Userland/Libraries/LibCore/ResourceImplementationFile.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace Core { @@ -25,10 +26,13 @@ ErrorOr> ResourceImplementationFile::load_from_resource_ auto path = TRY(String::from_utf8(uri.substring_view(resource_scheme.length()))); auto full_path = TRY(String::from_byte_string(LexicalPath::join(m_base_directory, path).string())); - if (is_directory(full_path)) - return make_directory_resource(move(path)); - return make_resource(path, TRY(MappedFile::map(full_path))); + auto st = TRY(System::stat(full_path)); + + if (S_ISDIR(st.st_mode)) + return make_directory_resource(move(path), st.st_mtime); + + return make_resource(path, TRY(MappedFile::map(full_path)), st.st_mtime); } Vector ResourceImplementationFile::child_names_for_resource_scheme(Resource const& resource)