LibCore: Add modified time to Resource

For now, all Resources are implemented with a modification time, but the
public API has been left as an Optional since abstractly, not all
resources will have a modification time.
This commit is contained in:
Shannon Booth 2024-04-01 20:17:50 +02:00 committed by Andreas Kling
parent e3ef849838
commit 28307d0db6
Notes: sideshowbarker 2024-07-17 01:12:07 +09:00
5 changed files with 36 additions and 33 deletions

View file

@ -11,24 +11,27 @@
namespace Core {
Resource::Resource(String path, Scheme scheme, NonnullOwnPtr<Core::MappedFile> file)
Resource::Resource(String path, Scheme scheme, NonnullOwnPtr<Core::MappedFile> 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<time_t> 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()));

View file

@ -31,6 +31,7 @@ public:
[[nodiscard]] String filename() const;
[[nodiscard]] String filesystem_path() const;
[[nodiscard]] String file_url() const;
[[nodiscard]] Optional<time_t> modified_time() const;
[[nodiscard]] ByteBuffer clone_data() const;
[[nodiscard]] ByteBuffer release_data() &&;
@ -55,14 +56,15 @@ private:
Resource,
};
Resource(String path, Scheme, NonnullOwnPtr<Core::MappedFile>);
Resource(String path, Scheme, ByteBuffer);
Resource(String path, Scheme, DirectoryTag);
Resource(String path, Scheme, NonnullOwnPtr<Core::MappedFile>, 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<DirectoryTag, NonnullOwnPtr<Core::MappedFile>, ByteBuffer> m_data;
time_t m_modified_time {};
};
template<IteratorFunction<Resource const&> Callback>

View file

@ -25,19 +25,19 @@ ResourceImplementation& ResourceImplementation::the()
return *s_the;
}
NonnullRefPtr<Resource> ResourceImplementation::make_resource(String full_path, NonnullOwnPtr<Core::MappedFile> file)
NonnullRefPtr<Resource> ResourceImplementation::make_resource(String full_path, NonnullOwnPtr<Core::MappedFile> 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<Resource> ResourceImplementation::make_resource(String full_path, ByteBuffer buffer)
NonnullRefPtr<Resource> 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<Resource> ResourceImplementation::make_directory_resource(String full_path)
NonnullRefPtr<Resource> 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<NonnullRefPtr<Resource>> ResourceImplementation::load_from_uri(StringView uri)
@ -51,10 +51,11 @@ ErrorOr<NonnullRefPtr<Resource>> 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);
}
}

View file

@ -28,11 +28,9 @@ protected:
virtual Vector<String> 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<Resource> make_resource(String full_path, NonnullOwnPtr<Core::MappedFile>);
static NonnullRefPtr<Resource> make_resource(String full_path, ByteBuffer);
static NonnullRefPtr<Resource> make_directory_resource(String full_path);
static NonnullRefPtr<Resource> make_resource(String full_path, NonnullOwnPtr<Core::MappedFile>, time_t modified_time);
static NonnullRefPtr<Resource> make_resource(String full_path, ByteBuffer, time_t modified_time);
static NonnullRefPtr<Resource> make_directory_resource(String full_path, time_t modified_time);
};
}

View file

@ -9,6 +9,7 @@
#include <LibCore/DirIterator.h>
#include <LibCore/Resource.h>
#include <LibCore/ResourceImplementationFile.h>
#include <LibCore/System.h>
namespace Core {
@ -25,10 +26,13 @@ ErrorOr<NonnullRefPtr<Resource>> 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<String> ResourceImplementationFile::child_names_for_resource_scheme(Resource const& resource)