mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:27:44 +00:00
LibCore: Calculate the correct seek offset for buffered streams
This commit is contained in:
parent
caeb772894
commit
bdf991fe76
2 changed files with 74 additions and 0 deletions
|
@ -468,6 +468,76 @@ TEST_CASE(buffered_small_file_read)
|
||||||
EXPECT(!file->can_read_line().value());
|
EXPECT(!file->can_read_line().value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(buffered_file_tell_and_seek)
|
||||||
|
{
|
||||||
|
auto file = Core::Stream::File::open("/usr/Tests/LibCore/small.txt"sv, Core::Stream::OpenMode::Read).release_value();
|
||||||
|
auto buffered_file = Core::Stream::BufferedFile::create(move(file)).release_value();
|
||||||
|
|
||||||
|
// Initial state.
|
||||||
|
{
|
||||||
|
auto current_offset = buffered_file->tell().release_value();
|
||||||
|
EXPECT_EQ(current_offset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read a character.
|
||||||
|
{
|
||||||
|
auto character = buffered_file->read_value<char>().release_value();
|
||||||
|
EXPECT_EQ(character, 'W');
|
||||||
|
auto current_offset = buffered_file->tell().release_value();
|
||||||
|
EXPECT_EQ(current_offset, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read one more character.
|
||||||
|
{
|
||||||
|
auto character = buffered_file->read_value<char>().release_value();
|
||||||
|
EXPECT_EQ(character, 'e');
|
||||||
|
auto current_offset = buffered_file->tell().release_value();
|
||||||
|
EXPECT_EQ(current_offset, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seek seven characters forward.
|
||||||
|
{
|
||||||
|
auto current_offset = buffered_file->seek(7, Core::Stream::SeekMode::FromCurrentPosition).release_value();
|
||||||
|
EXPECT_EQ(current_offset, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read a character again.
|
||||||
|
{
|
||||||
|
auto character = buffered_file->read_value<char>().release_value();
|
||||||
|
EXPECT_EQ(character, 'o');
|
||||||
|
auto current_offset = buffered_file->tell().release_value();
|
||||||
|
EXPECT_EQ(current_offset, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seek five characters backwards.
|
||||||
|
{
|
||||||
|
auto current_offset = buffered_file->seek(-5, Core::Stream::SeekMode::FromCurrentPosition).release_value();
|
||||||
|
EXPECT_EQ(current_offset, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read a character.
|
||||||
|
{
|
||||||
|
auto character = buffered_file->read_value<char>().release_value();
|
||||||
|
EXPECT_EQ(character, 'h');
|
||||||
|
auto current_offset = buffered_file->tell().release_value();
|
||||||
|
EXPECT_EQ(current_offset, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seek back to the beginning.
|
||||||
|
{
|
||||||
|
auto current_offset = buffered_file->seek(0, Core::Stream::SeekMode::SetPosition).release_value();
|
||||||
|
EXPECT_EQ(current_offset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the first character.
|
||||||
|
{
|
||||||
|
auto character = buffered_file->read_value<char>().release_value();
|
||||||
|
EXPECT_EQ(character, 'W');
|
||||||
|
auto current_offset = buffered_file->tell().release_value();
|
||||||
|
EXPECT_EQ(current_offset, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constexpr auto buffered_sent_data = "Well hello friends!\n:^)\nThis shouldn't be present. :^("sv;
|
constexpr auto buffered_sent_data = "Well hello friends!\n:^)\nThis shouldn't be present. :^("sv;
|
||||||
constexpr auto first_line = "Well hello friends!"sv;
|
constexpr auto first_line = "Well hello friends!"sv;
|
||||||
constexpr auto second_line = ":^)"sv;
|
constexpr auto second_line = ":^)"sv;
|
||||||
|
|
|
@ -875,8 +875,12 @@ public:
|
||||||
virtual void close() override { m_helper.stream().close(); }
|
virtual void close() override { m_helper.stream().close(); }
|
||||||
virtual ErrorOr<off_t> seek(i64 offset, SeekMode mode) override
|
virtual ErrorOr<off_t> seek(i64 offset, SeekMode mode) override
|
||||||
{
|
{
|
||||||
|
if (mode == SeekMode::FromCurrentPosition)
|
||||||
|
offset = offset - m_helper.buffered_data_size();
|
||||||
|
|
||||||
auto result = TRY(m_helper.stream().seek(offset, mode));
|
auto result = TRY(m_helper.stream().seek(offset, mode));
|
||||||
m_helper.clear_buffer();
|
m_helper.clear_buffer();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
virtual ErrorOr<void> truncate(off_t length) override
|
virtual ErrorOr<void> truncate(off_t length) override
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue