diff options
author | 2022-06-27 10:26:36 +0200 | |
---|---|---|
committer | 2022-06-28 23:08:45 +0200 | |
commit | 43d01755e61da415cc12b3215688d23d912fe185 (patch) | |
tree | 1b2dc49bc4fbab36cc5fe73724e47c9fc85069e9 /src/lib/formats/fs_coco_os9.cpp | |
parent | 735bd1f62632c853f5401051e1c47b54aa746174 (diff) |
fs: new API, blk_t is probably going to change too
Diffstat (limited to 'src/lib/formats/fs_coco_os9.cpp')
-rw-r--r-- | src/lib/formats/fs_coco_os9.cpp | 689 |
1 files changed, 33 insertions, 656 deletions
diff --git a/src/lib/formats/fs_coco_os9.cpp b/src/lib/formats/fs_coco_os9.cpp index 3813255482c..c4fcd14ea16 100644 --- a/src/lib/formats/fs_coco_os9.cpp +++ b/src/lib/formats/fs_coco_os9.cpp @@ -18,147 +18,22 @@ #include "strformat.h" -//************************************************************************** -// TYPE DECLARATIONS -//************************************************************************** - -namespace { - using namespace fs; -// methods -std::string pick_os9_string(std::string_view raw_string); -std::string to_os9_string(std::string_view s, size_t length); -util::arbitrary_datetime from_os9_date(u32 os9_date, u16 os9_time = 0); -std::tuple<u32, u16> to_os9_date(const util::arbitrary_datetime &datetime); -u32 pick_integer_be(const u8 *data, int length); -bool validate_filename(std::string_view name); -bool is_ignored_filename(std::string_view name); -std::vector<meta_description> entity_meta_description(); +namespace fs { const coco_os9_image COCO_OS9; } +namespace { -// ======================> volume_header - -class volume_header -{ +class coco_os9_impl : public filesystem_t { public: - volume_header(fsblk_t::block_t &&block); - - u32 total_sectors() const { return m_block.r24b(0); } - u8 track_size_in_sectors() const { return m_block.r8(3); } - u16 allocation_bitmap_bytes() const { return m_block.r16b(4); } - u16 cluster_size() const { return m_block.r16b(6); } - u32 root_dir_lsn() const { return m_block.r24b(8); } - u16 owner_id() const { return m_block.r16b(11); } - u16 disk_id() const { return m_block.r16b(14); } - u8 format_flags() const { return m_block.r8(16); } - u16 sectors_per_track() const { return m_block.r16b(17); } - u32 bootstrap_lsn() const { return m_block.r24b(21); } - u16 bootstrap_size() const { return m_block.r16b(24); } - util::arbitrary_datetime creation_date() const { return from_os9_date(m_block.r24b(26), m_block.r16b(29)); } - u16 sector_size() const { u16 result = m_block.r16b(104); return result != 0 ? result : 256; } - u8 sides() const { return (format_flags() & 0x01) ? 2 : 1; } - bool double_density() const { return (format_flags() & 0x02) != 0; } - bool double_track() const { return (format_flags() & 0x04) != 0; } - bool quad_track_density() const { return (format_flags() & 0x08) != 0; } - bool octal_track_density() const { return (format_flags() & 0x10) != 0; } - - std::string name() const; - -private: - fsblk_t::block_t m_block; -}; + coco_os9_impl(fsblk_t &blockdev); + virtual ~coco_os9_impl() = default; - -// ======================> file_header - -class file_header -{ -public: - file_header(fsblk_t::block_t &&block); - - u8 attributes() const { return m_block.r8(0); } - u16 owner_id() const { return m_block.r16b(1); } - u8 link_count() const { return m_block.r8(8); } - u32 file_size() const { return m_block.r32b(9); } - util::arbitrary_datetime creation_date() const; - bool is_directory() const { return (attributes() & 0x80) != 0; } - bool is_non_sharable() const { return (attributes() & 0x40) != 0; } - bool is_public_execute() const { return (attributes() & 0x20) != 0; } - bool is_public_write() const { return (attributes() & 0x10) != 0; } - bool is_public_read() const { return (attributes() & 0x08) != 0; } - bool is_user_execute() const { return (attributes() & 0x04) != 0; } - bool is_user_write() const { return (attributes() & 0x02) != 0; } - bool is_user_read() const { return (attributes() & 0x01) != 0; } - - meta_data metadata() const; - int get_sector_map_entry_count() const; - void get_sector_map_entry(int entry_number, u32 &start_lsn, u16 &count) const; - -private: - fsblk_t::block_t m_block; + static bool is_ignored_filename(std::string_view name); + static bool validate_filename(std::string_view name); }; - - -// ======================> impl - -class impl : public filesystem_t { -public: - class file : public ifile_t { - public: - file(impl &fs, file_header &&file_header); - virtual ~file() = default; - - virtual void drop_weak_references() override; - - virtual meta_data metadata() override; - virtual std::vector<u8> read_all() override; - - private: - impl &m_fs; - file_header m_file_header; - }; - - class directory : public idir_t { - public: - directory(impl &i, file_header &&file_header); - virtual ~directory() = default; - - virtual void drop_weak_references() override; - virtual meta_data metadata() override; - virtual std::vector<dir_entry> contents() override; - virtual file_t file_get(u64 key) override; - virtual dir_t dir_get(u64 key) override; - - private: - impl &m_fs; - file_header m_file_header; - }; - - impl(fsblk_t &blockdev, volume_header &&header); - virtual ~impl() = default; - - virtual meta_data metadata() override; - virtual dir_t root() override; - virtual void format(const meta_data &meta) override; - -private: - volume_header m_volume_header; - dir_t m_root; - - directory *open_directory(u32 lsn); - std::vector<u8> read_file_data(const file_header &header) const; -}; - } -namespace fs { - -const coco_os9_image COCO_OS9; - -}; - - //************************************************************************** // IMPLEMENTATION //************************************************************************** @@ -167,7 +42,7 @@ const coco_os9_image COCO_OS9; // name //------------------------------------------------- -const char *fs::coco_os9_image::name() const +const char *coco_os9_image::name() const { return "coco_os9"; } @@ -177,7 +52,7 @@ const char *fs::coco_os9_image::name() const // description //------------------------------------------------- -const char *fs::coco_os9_image::description() const +const char *coco_os9_image::description() const { return "CoCo OS-9"; } @@ -187,7 +62,7 @@ const char *fs::coco_os9_image::description() const // enumerate_f //------------------------------------------------- -void fs::coco_os9_image::enumerate_f(floppy_enumerator &fe, u32 form_factor, const std::vector<u32> &variants) const +void coco_os9_image::enumerate_f(floppy_enumerator &fe, u32 form_factor, const std::vector<u32> &variants) const { if (has(form_factor, variants, floppy_image::FF_525, floppy_image::SSDD)) { @@ -201,7 +76,7 @@ void fs::coco_os9_image::enumerate_f(floppy_enumerator &fe, u32 form_factor, con // can_format //------------------------------------------------- -bool fs::coco_os9_image::can_format() const +bool coco_os9_image::can_format() const { return true; } @@ -211,7 +86,7 @@ bool fs::coco_os9_image::can_format() const // can_read //------------------------------------------------- -bool fs::coco_os9_image::can_read() const +bool coco_os9_image::can_read() const { return true; } @@ -221,7 +96,7 @@ bool fs::coco_os9_image::can_read() const // can_write //------------------------------------------------- -bool fs::coco_os9_image::can_write() const +bool coco_os9_image::can_write() const { return false; } @@ -231,7 +106,7 @@ bool fs::coco_os9_image::can_write() const // has_rsrc //------------------------------------------------- -bool fs::coco_os9_image::has_rsrc() const +bool coco_os9_image::has_rsrc() const { return false; } @@ -241,7 +116,7 @@ bool fs::coco_os9_image::has_rsrc() const // directory_separator //------------------------------------------------- -char fs::coco_os9_image::directory_separator() const +char coco_os9_image::directory_separator() const { return '/'; } @@ -251,7 +126,7 @@ char fs::coco_os9_image::directory_separator() const // volume_meta_description //------------------------------------------------- -std::vector<meta_description> fs::coco_os9_image::volume_meta_description() const +std::vector<meta_description> coco_os9_image::volume_meta_description() const { std::vector<meta_description> results; results.emplace_back(meta_description(meta_name::name, "UNTITLED", false, [](const meta_value &m) { return m.as_string().size() <= 32; }, "Volume name, up to 32 characters")); @@ -264,51 +139,10 @@ std::vector<meta_description> fs::coco_os9_image::volume_meta_description() cons // file_meta_description //------------------------------------------------- -std::vector<meta_description> fs::coco_os9_image::file_meta_description() const -{ - return entity_meta_description(); -} - - -//------------------------------------------------- -// directory_meta_description -//------------------------------------------------- - -std::vector<meta_description> fs::coco_os9_image::directory_meta_description() const -{ - return entity_meta_description(); -} - - -//------------------------------------------------- -// mount -//------------------------------------------------- - -std::unique_ptr<filesystem_t> fs::coco_os9_image::mount(fsblk_t &blockdev) const -{ - // read the header block - blockdev.set_block_size(256); - volume_header header(blockdev.get(0)); - - // sanity checks - if (header.sectors_per_track() != header.track_size_in_sectors()) - return { }; - - // create the implementation - return std::make_unique<impl>(blockdev, std::move(header)); -} - - -//------------------------------------------------- -// entity_meta_description -//------------------------------------------------- - -namespace { - -std::vector<meta_description> entity_meta_description() +std::vector<meta_description> coco_os9_image::file_meta_description() const { std::vector<meta_description> results; - results.emplace_back(meta_description(meta_name::name, "", false, [](const meta_value &m) { return validate_filename(m.as_string()); }, "File name")); + results.emplace_back(meta_description(meta_name::name, "", false, [](const meta_value &m) { return coco_os9_impl::validate_filename(m.as_string()); }, "File name")); results.emplace_back(meta_description(meta_name::creation_date, util::arbitrary_datetime::now(), false, nullptr, "Creation time")); results.emplace_back(meta_description(meta_name::owner_id, 0, true, nullptr, "Owner ID")); results.emplace_back(meta_description(meta_name::attributes, "", true, nullptr, "File attributes")); @@ -318,107 +152,38 @@ std::vector<meta_description> entity_meta_description() //------------------------------------------------- -// pick_os9_string -//------------------------------------------------- - -std::string pick_os9_string(std::string_view raw_string) -{ - // find the last NUL or high bit character - auto iter = std::find_if(raw_string.begin(), raw_string.end(), [](char ch) - { - return ch == '\0' || ch & 0x80; - }); - - // get the preliminary result - std::string result(raw_string.begin(), iter); - - // and add the final character if we have to - if (iter < raw_string.end() && *iter & 0x80) - result.append(1, *iter & 0x7F); - return result; - -} - - -//------------------------------------------------- -// to_os9_string -//------------------------------------------------- - -std::string to_os9_string(std::string_view s, size_t length) -{ - std::string result(length, '\0'); - for (auto i = 0; i < std::min(length, s.size()); i++) - { - result[i] = (s[i] & 0x7F) - | (i == s.size() ? 0x80 : 0x00); - } - return result; -} - - -//------------------------------------------------- -// pick_integer_be -//------------------------------------------------- - -u32 pick_integer_be(const u8 *data, int length) -{ - u32 result = 0; - for (int i = 0; i < length; i++) - result |= u32(data[length - i - 1]) << i * 8; - return result; -} - - -//------------------------------------------------- -// from_os9_date +// directory_meta_description //------------------------------------------------- -util::arbitrary_datetime from_os9_date(u32 os9_date, u16 os9_time) +std::vector<meta_description> coco_os9_image::directory_meta_description() const { - util::arbitrary_datetime dt; - memset(&dt, 0, sizeof(dt)); - dt.year = ((os9_date >> 16) & 0xFF) + 1900; - dt.month = (os9_date >> 8) & 0xFF; - dt.day_of_month = (os9_date >> 0) & 0xFF; - dt.hour = (os9_time >> 8) & 0xFF; - dt.minute = (os9_time >> 0) & 0xFF; - return dt; + return file_meta_description(); } - //------------------------------------------------- -// to_os9_date +// mount //------------------------------------------------- -std::tuple<u32, u16> to_os9_date(const util::arbitrary_datetime &datetime) +std::unique_ptr<filesystem_t> coco_os9_image::mount(fsblk_t &blockdev) const { - u32 os9_date = ((datetime.year - 1900) & 0xFF) << 16 - | (datetime.month & 0xFF) << 8 - | (datetime.day_of_month & 0xFF) << 0; - u16 os9_time = (datetime.hour & 0xFF) << 8 - | (datetime.minute & 0xFF) << 0; - return std::make_tuple(os9_date, os9_time); + return std::make_unique<coco_os9_impl>(blockdev); } - //------------------------------------------------- -// validate_filename +// impl ctor //------------------------------------------------- -bool validate_filename(std::string_view name) +coco_os9_impl::coco_os9_impl(fsblk_t &blockdev) + : filesystem_t(blockdev, 256) { - return !is_ignored_filename(name) - && name.size() <= 29 - && std::find_if(name.begin(), name.end(), [](const char ch) { return ch == '\0' || ch == '/' || ch >= 0x80; }) == name.end(); } - //------------------------------------------------- // is_ignored_filename - should this file name be // ignored if it is in the file system? //------------------------------------------------- -bool is_ignored_filename(std::string_view name) +bool coco_os9_impl::is_ignored_filename(std::string_view name) { return name.empty() || name[0] == '\0' @@ -426,401 +191,13 @@ bool is_ignored_filename(std::string_view name) || name == ".."; } - -//------------------------------------------------- -// volume_header ctor -//------------------------------------------------- - -volume_header::volume_header(fsblk_t::block_t &&block) - : m_block(std::move(block)) -{ -} - - -//------------------------------------------------- -// volume_header::name -//------------------------------------------------- - -std::string volume_header::name() const -{ - std::string_view raw_name((const char *)&m_block.rodata()[31], 32); - return pick_os9_string(raw_name); -} - - -//------------------------------------------------- -// file_header ctor -//------------------------------------------------- - -file_header::file_header(fsblk_t::block_t &&block) - : m_block(std::move(block)) -{ -} - - -//------------------------------------------------- -// file_header::creation_date -//------------------------------------------------- - -util::arbitrary_datetime file_header::creation_date() const -{ - return from_os9_date(m_block.r24b(13)); -} - - -//------------------------------------------------- -// file_header::metadata -//------------------------------------------------- - -meta_data file_header::metadata() const -{ - // format the attributes - std::string attributes = util::string_format("%c%c%c%c%c%c%c%c", - is_directory() ? 'd' : '-', - is_non_sharable() ? 's' : '-', - is_public_execute() ? 'x' : '-', - is_public_write() ? 'w' : '-', - is_public_read() ? 'r' : '-', - is_user_execute() ? 'x' : '-', - is_user_write() ? 'w' : '-', - is_user_read() ? 'r' : '-'); - - meta_data result; - result.set(meta_name::creation_date, creation_date()); - result.set(meta_name::owner_id, owner_id()); - result.set(meta_name::attributes, std::move(attributes)); - result.set(meta_name::length, file_size()); - return result; -} - - -//------------------------------------------------- -// file_header::get_sector_map_entry_count -//------------------------------------------------- - -int file_header::get_sector_map_entry_count() const -{ - return (m_block.size() - 16) / 5; -} - - -//------------------------------------------------- -// file_header::get_sector_map_entry -//------------------------------------------------- - -void file_header::get_sector_map_entry(int entry_number, u32 &start_lsn, u16 &count) const -{ - start_lsn = m_block.r24b(16 + (entry_number * 5) + 0); - count = m_block.r16b(16 + (entry_number * 5) + 3); -} - - -//------------------------------------------------- -// impl ctor -//------------------------------------------------- - -impl::impl(fsblk_t &blockdev, volume_header &&header) - : filesystem_t(blockdev, 256) - , m_volume_header(std::move(header)) -{ -} - - -//------------------------------------------------- -// impl::metadata -//------------------------------------------------- - -meta_data impl::metadata() -{ - meta_data results; - results.set(meta_name::name, m_volume_header.name()); - results.set(meta_name::creation_date, m_volume_header.creation_date()); - return results; -} - - -//------------------------------------------------- -// impl::root -//------------------------------------------------- - -filesystem_t::dir_t impl::root() -{ - if (!m_root) - m_root = open_directory(m_volume_header.root_dir_lsn()); - return m_root.strong(); -} - - -//------------------------------------------------- -// impl::format -//------------------------------------------------- - -void impl::format(const meta_data &meta) -{ - // for some reason, the OS-9 world favored filling with 0xE5 - m_blockdev.fill(0xE5); - - // identify geometry info - u8 sectors = 18; // TODO - we need a definitive technique to get the floppy geometry - u8 heads = 1; // TODO - we need a definitive technique to get the floppy geometry - u16 sector_bytes = 256; // TODO - we need a definitive technique to get the floppy geometry - bool is_double_density = true; // TODO - we need a definitive technique to get the floppy geometry - u32 tracks = m_blockdev.block_count() / sectors / heads; - - // get attributes from metadata - std::string volume_title = meta.get_string(meta_name::name, "UNTITLED"); - util::arbitrary_datetime creation_datetime = meta.get_date(meta_name::creation_date); - auto [creation_os9date, creation_os9time] = to_os9_date(creation_datetime); - - u32 lsn_count = m_blockdev.block_count(); - u16 cluster_size = 1; - u16 owner_id = 1; - u16 disk_id = 1; - u8 attributes = 0; - u32 allocation_bitmap_bits = lsn_count / cluster_size; - u32 allocation_bitmap_lsns = (allocation_bitmap_bits / 8 + sector_bytes - 1) / sector_bytes; - u8 format_flags = ((heads > 1) ? 0x01 : 0x00) - | (is_double_density ? 0x02 : 0x00); - - // volume header - auto volume_header = m_blockdev.get(0); - volume_header.fill(0x00); - volume_header.w24b(0, lsn_count); // DD.TOT - total secctors - volume_header.w8(3, sectors); // DD.TKS - track size in sectors - volume_header.w16b(4, (allocation_bitmap_bits + 7) / 8); // DD.MAP - allocation bitmap in bytes - volume_header.w16b(6, cluster_size); // DD.BIT - cluster size - volume_header.w24b(8, 1 + allocation_bitmap_lsns); // DD.DIR - root directory LSN - volume_header.w16b(11, owner_id); // DD.OWN - owner ID - volume_header.w8(13, attributes); // DD.ATT - Dattributes - volume_header.w16b(14, disk_id); // DD.DSK - disk ID - volume_header.w8(16, format_flags); // DD.FMT - format flags - volume_header.w16b(17, sectors); // DD.SPT - sectors per track - volume_header.w24b(26, creation_os9date); // DD.DAT - date of creation - volume_header.w16b(29, creation_os9time); // DD.DAT - time of creation - volume_header.wstr(31, to_os9_string(volume_title, 32)); // DD.NAM - title - volume_header.w16b(103, sector_bytes / 256); // sector bytes - - // path descriptor options - volume_header.w8(0x3f + 0x00, 1); // device class - volume_header.w8(0x3f + 0x01, 1); // drive number - volume_header.w8(0x3f + 0x03, 0x20); // device type - volume_header.w8(0x3f + 0x04, 1); // density capability - volume_header.w16b(0x3f + 0x05, tracks); // number of tracks - volume_header.w8(0x3f + 0x07, heads); // number of sides - volume_header.w16b(0x3f + 0x09, sectors); // sectors per track - volume_header.w16b(0x3f + 0x0b, sectors); // sectors on track zero - volume_header.w8(0x3f + 0x0d, 3); // sector interleave factor - volume_header.w8(0x3f + 0x0e, 8); // default sectors per allocation - - // allocation bitmap - u32 total_allocated_sectors = 1 + allocation_bitmap_lsns + 1 + 8; - std::vector<u8> abblk_bytes; - abblk_bytes.resize(sector_bytes); - for (u32 i = 0; i < allocation_bitmap_lsns; i++) - { - for (u32 j = 0; j < sector_bytes; j++) - { - u32 pos = (i * sector_bytes + j) * 8; - if (pos + 8 < total_allocated_sectors) - abblk_bytes[j] = 0xFF; - else if (pos >= total_allocated_sectors) - abblk_bytes[j] = 0x00; - else - abblk_bytes[j] = ~((1 << (8 - total_allocated_sectors + pos)) - 1); - } - - auto abblk = m_blockdev.get(1 + i); - abblk.copy(0, abblk_bytes.data(), sector_bytes); - } - - // root directory header - auto roothdr_blk = m_blockdev.get(1 + allocation_bitmap_lsns); - roothdr_blk.fill(0x00); - roothdr_blk.w8(0x00, 0xBF); - roothdr_blk.w8(0x01, 0x00); - roothdr_blk.w8(0x02, 0x00); - roothdr_blk.w24b(0x03, creation_os9date); - roothdr_blk.w16b(0x06, creation_os9time); - roothdr_blk.w8(0x08, 0x01); - roothdr_blk.w8(0x09, 0x00); - roothdr_blk.w8(0x0A, 0x00); - roothdr_blk.w8(0x0B, 0x00); - roothdr_blk.w8(0x0C, 0x40); - roothdr_blk.w24b(0x0D, creation_os9date); - roothdr_blk.w24b(0x10, 1 + allocation_bitmap_lsns + 1); - roothdr_blk.w16b(0x13, 8); - - // root directory data - auto rootdata_blk = m_blockdev.get(1 + allocation_bitmap_lsns + 1); - rootdata_blk.fill(0x00); - rootdata_blk.w8(0x00, 0x2E); - rootdata_blk.w8(0x01, 0xAE); - rootdata_blk.w8(0x1F, 1 + allocation_bitmap_lsns); - rootdata_blk.w8(0x20, 0xAE); - rootdata_blk.w8(0x3F, 1 + allocation_bitmap_lsns); -} - - -//------------------------------------------------- -// impl::open_directory -//------------------------------------------------- - -impl::directory *impl::open_directory(u32 lsn) -{ - file_header header(m_blockdev.get(lsn)); - return new directory(*this, std::move(header)); -} - - -//------------------------------------------------- -// impl::read_file_data -//------------------------------------------------- - -std::vector<u8> impl::read_file_data(const file_header &header) const -{ - std::vector<u8> data; - data.reserve(header.file_size()); - int entry_count = header.get_sector_map_entry_count(); - for (int i = 0; i < entry_count; i++) - { - u32 start_lsn; - u16 count; - header.get_sector_map_entry(i, start_lsn, count); - - for (u32 lsn = start_lsn; lsn < start_lsn + count; lsn++) - { - auto block = m_blockdev.get(lsn); - size_t block_size = std::min(std::min(u32(m_volume_header.sector_size()), block.size()), header.file_size() - u32(data.size())); - for (auto i = 0; i < block_size; i++) - data.push_back(block.rodata()[i]); - } - } - return data; -} - - -//------------------------------------------------- -// file ctor -//------------------------------------------------- - -impl::file::file(impl &i, file_header &&file_header) - : m_fs(i) - , m_file_header(std::move(file_header)) -{ -} - - -//------------------------------------------------- -// file::drop_weak_references //------------------------------------------------- - -void impl::file::drop_weak_references() -{ -} - - -//------------------------------------------------- -// file::metadata -//------------------------------------------------- - -meta_data impl::file::metadata() -{ - return m_file_header.metadata(); -} - - -//------------------------------------------------- -// file::read_all -//------------------------------------------------- - -std::vector<u8> impl::file::read_all() -{ - return m_fs.read_file_data(m_file_header); -} - - -//------------------------------------------------- -// directory ctor -//------------------------------------------------- - -impl::directory::directory(impl &i, file_header &&file_header) - : m_fs(i) - , m_file_header(std::move(file_header)) -{ -} - - -//------------------------------------------------- -// directory::drop_weak_references -//------------------------------------------------- - -void impl::directory::drop_weak_references() -{ -} - - -//------------------------------------------------- -// directory::metadata -//------------------------------------------------- - -meta_data impl::directory::metadata() -{ - return m_file_header.metadata(); -} - - -//------------------------------------------------- -// directory::contents -//------------------------------------------------- - -std::vector<dir_entry> impl::directory::contents() -{ - // read the directory data - std::vector<u8> directory_data = m_fs.read_file_data(m_file_header); - - // and assemble results - std::vector<dir_entry> results; - int directory_count = directory_data.size() / 32; - for (int i = 0; i < directory_count; i++) - { - // determine the filename - std::string_view raw_filename((const char *) &directory_data[i * 32], 29); - std::string filename = pick_os9_string(raw_filename); - if (is_ignored_filename(filename)) - continue; - - // determine the entry type - u32 lsn = pick_integer_be(&directory_data[i * 32] + 29, 3); - file_header file_header(m_fs.m_blockdev.get(lsn)); - dir_entry_type entry_type = file_header.is_directory() - ? dir_entry_type::dir - : dir_entry_type::file; - - // and return the results - results.emplace_back(std::move(filename), entry_type, lsn); - } - return results; -} - - -//------------------------------------------------- -// directory::file_get -//------------------------------------------------- - -filesystem_t::file_t impl::directory::file_get(u64 key) -{ - file_header header(m_fs.m_blockdev.get(u32(key))); - return file_t(new file(m_fs, std::move(header))); -} - - -//------------------------------------------------- -// directory::dir_get +// validate_filename //------------------------------------------------- -filesystem_t::dir_t impl::directory::dir_get(u64 key) +bool coco_os9_impl::validate_filename(std::string_view name) { - return dir_t(m_fs.open_directory(u32(key))); + return !is_ignored_filename(name) + && name.size() <= 29 + && std::find_if(name.begin(), name.end(), [](const char ch) { return ch == '\0' || ch == '/' || ch >= 0x80; }) == name.end(); } - -}; |