aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kapi/kapi/filesystem.hpp4
-rw-r--r--kapi/kapi/filesystem/seek.hpp8
-rw-r--r--kernel/kapi/filesystem.cpp5
-rw-r--r--kernel/kapi/filesystem.tests.cpp6
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.cpp53
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.hpp4
-rw-r--r--libs/kstd/kstd/units.hpp46
7 files changed, 72 insertions, 54 deletions
diff --git a/kapi/kapi/filesystem.hpp b/kapi/kapi/filesystem.hpp
index 78845a00..6a0cd6c2 100644
--- a/kapi/kapi/filesystem.hpp
+++ b/kapi/kapi/filesystem.hpp
@@ -71,11 +71,9 @@ namespace kapi::filesystem
//!
//! @param file_descriptor The file descriptor to seek.
//! @param offset The offset to seek to, relative to the origin.
- //! @param direction The direction to seek towards, relative to the origin.
//! @param origin The origing to seek relatively to.
//! @return The new position in the file on success, an error code otherwise.
- auto seek(size_t file_descriptor, kstd::bytes offset, seek_direction direction, seek_origin origin)
- -> kstd::result<kstd::bytes>;
+ auto seek(size_t file_descriptor, kstd::offset offset, seek_origin origin) -> kstd::result<kstd::bytes>;
//! Create a new directory at the specified path.
//!
diff --git a/kapi/kapi/filesystem/seek.hpp b/kapi/kapi/filesystem/seek.hpp
index f1006f31..42bee22d 100644
--- a/kapi/kapi/filesystem/seek.hpp
+++ b/kapi/kapi/filesystem/seek.hpp
@@ -17,14 +17,6 @@ namespace kapi::filesystem
end,
};
- enum struct seek_direction
- {
- //! seek forward from the origin.
- forward,
- //! seek backward from the origin.
- backward,
- };
-
} // namespace kapi::filesystem
#endif \ No newline at end of file
diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp
index 419c3234..3708c15d 100644
--- a/kernel/kapi/filesystem.cpp
+++ b/kernel/kapi/filesystem.cpp
@@ -57,11 +57,10 @@ namespace kapi::filesystem
});
}
- auto seek(size_t file_descriptor, kstd::bytes offset, seek_direction direction, seek_origin origin)
- -> kstd::result<kstd::bytes>
+ auto seek(size_t file_descriptor, kstd::offset offset, seek_origin origin) -> kstd::result<kstd::bytes>
{
return kernel::filesystem::open_file_table::get().file(file_descriptor).and_then([=](auto file) {
- return file->seek(offset, direction, origin);
+ return file->seek(offset, origin);
});
}
diff --git a/kernel/kapi/filesystem.tests.cpp b/kernel/kapi/filesystem.tests.cpp
index 2f975bf8..2e623272 100644
--- a/kernel/kapi/filesystem.tests.cpp
+++ b/kernel/kapi/filesystem.tests.cpp
@@ -150,14 +150,12 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap
THEN("seeking forward from the beginning succeeds")
{
- REQUIRE(kapi::filesystem::seek(*file, 100_B, kapi::filesystem::seek_direction::forward,
- kapi::filesystem::seek_origin::beginning) == 100_B);
+ REQUIRE(kapi::filesystem::seek(*file, 100_B_off, kapi::filesystem::seek_origin::beginning) == 100_B);
}
THEN("seeking backward from the beginning fails")
{
- REQUIRE_FALSE(kapi::filesystem::seek(*file, 100_B, kapi::filesystem::seek_direction::backward,
- kapi::filesystem::seek_origin::beginning));
+ REQUIRE_FALSE(kapi::filesystem::seek(*file, 100_B_off, kapi::filesystem::seek_origin::beginning));
}
}
diff --git a/kernel/kernel/filesystem/open_file_descriptor.cpp b/kernel/kernel/filesystem/open_file_descriptor.cpp
index a6d97b8e..98520aa8 100644
--- a/kernel/kernel/filesystem/open_file_descriptor.cpp
+++ b/kernel/kernel/filesystem/open_file_descriptor.cpp
@@ -1,7 +1,6 @@
#include <kernel/filesystem/open_file_descriptor.hpp>
#include <kernel/filesystem/dentry.hpp>
-#include <kernel/filesystem/error.hpp>
#include <kapi/filesystem.hpp>
@@ -53,47 +52,37 @@ namespace kernel::filesystem
}
}
- auto open_file_descriptor::seek(kstd::bytes offset, kapi::filesystem::seek_direction direction,
- kapi::filesystem::seek_origin origin) -> kstd::result<kstd::bytes>
+ auto open_file_descriptor::seek(kstd::offset offset, kapi::filesystem::seek_origin origin)
+ -> kstd::result<kstd::bytes>
{
- switch (origin)
- {
- case kapi::filesystem::seek_origin::beginning:
+ auto const base = [&] {
+ switch (origin)
{
- if (direction == kapi::filesystem::seek_direction::backward)
+ case kapi::filesystem::seek_origin::beginning:
{
- return kstd::failure(vfs_errc::invalid_argument);
+ return kstd::bytes{0};
}
- return m_offset = offset;
- }
- case kapi::filesystem::seek_origin::current_position:
- {
- if (direction == kapi::filesystem::seek_direction::backward)
+ case kapi::filesystem::seek_origin::current_position:
{
- if (offset > m_offset)
- {
- return kstd::failure(vfs_errc::invalid_argument);
- }
- return m_offset -= offset;
+ return m_offset;
}
- return m_offset += offset;
- }
- case kapi::filesystem::seek_origin::end:
- {
- auto base = m_dentry->get_inode()->status()->size;
- if (direction == kapi::filesystem::seek_direction::backward)
+ case kapi::filesystem::seek_origin::end:
{
- if (offset > base)
- {
- return kstd::failure(vfs_errc::invalid_argument);
- }
- return m_offset = base - offset;
+ return m_dentry->get_inode()->status()->size;
+ }
+ default:
+ {
+ return kstd::bytes{0};
}
- return m_offset = base + offset;
}
- }
+ }();
- return kstd::failure(vfs_errc::invalid_argument);
+ auto new_offset = base + offset;
+ if (new_offset)
+ {
+ m_offset = *new_offset;
+ }
+ return new_offset;
}
auto open_file_descriptor::offset() const -> kstd::bytes
diff --git a/kernel/kernel/filesystem/open_file_descriptor.hpp b/kernel/kernel/filesystem/open_file_descriptor.hpp
index 25dbf719..a9d043bf 100644
--- a/kernel/kernel/filesystem/open_file_descriptor.hpp
+++ b/kernel/kernel/filesystem/open_file_descriptor.hpp
@@ -52,11 +52,9 @@ namespace kernel::filesystem
//! Move the read/write offset of the file.
//!
//! @param offset The offset to apply relative to the given origin.
- //! @param offset The direction to seek in, relative to the given origin.
//! @param origin The origin of the offset.
//! @return the new offset on success, an error otherwise.
- auto seek(kstd::bytes offset, kapi::filesystem::seek_direction direction, kapi::filesystem::seek_origin origin)
- -> kstd::result<kstd::bytes>;
+ auto seek(kstd::offset offset, kapi::filesystem::seek_origin origin) -> kstd::result<kstd::bytes>;
/**
@brief Returns the current file offset for this open file descriptor.
diff --git a/libs/kstd/kstd/units.hpp b/libs/kstd/kstd/units.hpp
index e3868aa7..61224336 100644
--- a/libs/kstd/kstd/units.hpp
+++ b/libs/kstd/kstd/units.hpp
@@ -2,6 +2,8 @@
#define KSTD_UNITS_HPP
#include <kstd/bits/basic_unit.hpp>
+#include <kstd/result.hpp>
+#include <kstd/system_error.hpp>
#include <concepts>
#include <cstddef>
@@ -11,6 +13,8 @@ namespace kstd
using bytes = basic_unit<std::size_t, struct bytes_tag>;
+ using offset = basic_unit<std::ptrdiff_t, struct byte_offset_tag>;
+
// NOLINTNEXTLINE(readability-identifier-naming)
constexpr auto KiB(std::unsigned_integral auto value) noexcept -> bytes
{
@@ -30,11 +34,31 @@ namespace kstd
}
template<typename ValueType>
- constexpr auto operator+(ValueType * pointer, bytes offset) -> ValueType *
+ constexpr auto operator+(ValueType * pointer, bytes offset) noexcept -> ValueType *
{
return pointer + offset.value;
}
+ constexpr auto operator+(bytes value, offset offset) noexcept -> result<bytes>
+ {
+ if (offset.value < 0 && value.value < static_cast<bytes::value_type>(-offset.value))
+ {
+ return failure(make_error_code(errc::argument_out_of_domain));
+ }
+ value.value += offset.value;
+ return value;
+ }
+
+ constexpr auto operator-(bytes value, offset offset) noexcept -> result<bytes>
+ {
+ if (offset.value > 0 && value.value < static_cast<bytes::value_type>(offset.value))
+ {
+ return failure(make_error_code(errc::argument_out_of_domain));
+ }
+ value.value -= offset.value;
+ return value;
+ }
+
inline namespace literals
{
inline namespace units_literals
@@ -59,6 +83,26 @@ namespace kstd
return GiB(value);
}
+ constexpr auto operator""_B_off(unsigned long long value) noexcept -> offset
+ {
+ return offset{static_cast<offset::value_type>(value)};
+ }
+
+ constexpr auto operator""_KiB_off(unsigned long long value) noexcept -> offset
+ {
+ return offset{static_cast<offset::value_type>(value * 1024)};
+ }
+
+ constexpr auto operator""_MiB_off(unsigned long long value) noexcept -> offset
+ {
+ return offset{static_cast<offset::value_type>(value * 1024 * 1024)};
+ }
+
+ constexpr auto operator""_GiB_off(unsigned long long value) noexcept -> offset
+ {
+ return offset{static_cast<offset::value_type>(value * 1024 * 1024 * 1024)};
+ }
+
} // namespace units_literals
} // namespace literals