mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 14:28:12 +00:00
Kernel: Split the ISO9660FileSystem.{cpp,h} files to smaller components
This commit is contained in:
parent
fca3b7f1f9
commit
1c91881a1d
11 changed files with 871 additions and 779 deletions
134
Kernel/FileSystem/ISO9660FS/DirectoryIterator.cpp
Normal file
134
Kernel/FileSystem/ISO9660FS/DirectoryIterator.cpp
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Copyright (c) 2021, sin-ack <sin-ack@protonmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/FileSystem/ISO9660FS/Definitions.h>
|
||||
#include <Kernel/FileSystem/ISO9660FS/DirectoryIterator.h>
|
||||
#include <Kernel/KBuffer.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
ISO9660DirectoryIterator::ISO9660DirectoryIterator(ISO9660FS& fs, ISO::DirectoryRecordHeader const& header)
|
||||
: m_fs(fs)
|
||||
, m_current_header(&header)
|
||||
{
|
||||
// FIXME: Panic or alternative method?
|
||||
(void)read_directory_contents();
|
||||
get_header();
|
||||
}
|
||||
|
||||
ErrorOr<bool> ISO9660DirectoryIterator::next()
|
||||
{
|
||||
if (done())
|
||||
return false;
|
||||
dbgln_if(ISO9660_VERY_DEBUG, "next(): Called");
|
||||
|
||||
if (has_flag(m_current_header->file_flags, ISO::FileFlags::Directory)) {
|
||||
dbgln_if(ISO9660_VERY_DEBUG, "next(): Recursing");
|
||||
{
|
||||
TRY(m_directory_stack.try_append(move(m_current_directory)));
|
||||
}
|
||||
|
||||
dbgln_if(ISO9660_VERY_DEBUG, "next(): Pushed into directory stack");
|
||||
|
||||
TRY(read_directory_contents());
|
||||
|
||||
dbgln_if(ISO9660_VERY_DEBUG, "next(): Read directory contents");
|
||||
|
||||
m_current_directory.offset = 0;
|
||||
get_header();
|
||||
if (m_current_header->length == 0) {
|
||||
// We have found an empty directory, let's continue with the
|
||||
// next one.
|
||||
if (!go_up())
|
||||
return false;
|
||||
} else {
|
||||
// We cannot skip here, as this is the first record in this
|
||||
// extent.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return skip();
|
||||
}
|
||||
|
||||
bool ISO9660DirectoryIterator::skip()
|
||||
{
|
||||
VERIFY(m_current_directory.entry);
|
||||
|
||||
if (m_current_directory.offset >= m_current_directory.entry->length) {
|
||||
dbgln_if(ISO9660_VERY_DEBUG, "skip(): Was at last item already");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_current_directory.offset += m_current_header->length;
|
||||
get_header();
|
||||
if (m_current_header->length == 0) {
|
||||
// According to ECMA 119, if a logical block contains directory
|
||||
// records, then the leftover bytes in the logical block are
|
||||
// all zeros. So if our directory header has a length of 0,
|
||||
// we're probably looking at padding.
|
||||
//
|
||||
// Of course, this doesn't mean we're done; it only means that there
|
||||
// are no more directory entries in *this* logical block. If we
|
||||
// have at least one more logical block of data length to go, we
|
||||
// need to snap to the next logical block, because directory records
|
||||
// cannot span multiple logical blocks.
|
||||
u32 remaining_bytes = m_current_directory.entry->length - m_current_directory.offset;
|
||||
if (remaining_bytes > m_fs.logical_block_size()) {
|
||||
m_current_directory.offset += remaining_bytes % m_fs.logical_block_size();
|
||||
get_header();
|
||||
|
||||
dbgln_if(ISO9660_VERY_DEBUG, "skip(): Snapped to next logical block (succeeded)");
|
||||
return true;
|
||||
}
|
||||
|
||||
dbgln_if(ISO9660_VERY_DEBUG, "skip(): Was at the last logical block, at padding now (offset {}, data length {})", m_current_directory.entry->length, m_current_directory.offset);
|
||||
return false;
|
||||
}
|
||||
|
||||
dbgln_if(ISO9660_VERY_DEBUG, "skip(): Skipped to next item");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ISO9660DirectoryIterator::go_up()
|
||||
{
|
||||
if (m_directory_stack.is_empty()) {
|
||||
dbgln_if(ISO9660_VERY_DEBUG, "go_up(): Empty directory stack");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_current_directory = m_directory_stack.take_last();
|
||||
get_header();
|
||||
|
||||
dbgln_if(ISO9660_VERY_DEBUG, "go_up(): Went up a directory");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ISO9660DirectoryIterator::done() const
|
||||
{
|
||||
VERIFY(m_current_directory.entry);
|
||||
auto result = m_directory_stack.is_empty() && m_current_directory.offset >= m_current_directory.entry->length;
|
||||
dbgln_if(ISO9660_VERY_DEBUG, "done(): {}", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
ErrorOr<void> ISO9660DirectoryIterator::read_directory_contents()
|
||||
{
|
||||
m_current_directory.entry = TRY(m_fs.directory_entry_for_record({}, m_current_header));
|
||||
return {};
|
||||
}
|
||||
|
||||
void ISO9660DirectoryIterator::get_header()
|
||||
{
|
||||
VERIFY(m_current_directory.entry);
|
||||
if (!m_current_directory.entry->blocks)
|
||||
return;
|
||||
|
||||
m_current_header = reinterpret_cast<ISO::DirectoryRecordHeader const*>(m_current_directory.entry->blocks->data() + m_current_directory.offset);
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue