summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author npwoods <npwoods@mess.org>2022-01-07 12:04:07 -0500
committer GitHub <noreply@github.com>2022-01-07 18:04:07 +0100
commitfd736212854673efa8e2bcf2e1b2d3420bcacdb5 (patch)
tree0ce9a5c6224cfb8f9d02f287b3122e9c67987c5d /src/lib
parent3abc1a4805412a600ae572699db6dc6b1516d15f (diff)
Created an initial file system implementation for OS-9 under the CoCo (#9096)
* Created an initial file system implementation for OS-9 under the CoCo * Minor fixes to directory entry handling * Changed to use fsblk_t::r[8|16|24|32]b() - Changed the above functions to be const
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/formats/all.cpp7
-rw-r--r--src/lib/formats/fs_coco_os9.cpp542
-rw-r--r--src/lib/formats/fs_coco_os9.h160
-rw-r--r--src/lib/formats/fsmeta.cpp2
-rw-r--r--src/lib/formats/fsmeta.h4
-rw-r--r--src/lib/formats/fsmgr.cpp16
-rw-r--r--src/lib/formats/fsmgr.h20
7 files changed, 733 insertions, 18 deletions
diff --git a/src/lib/formats/all.cpp b/src/lib/formats/all.cpp
index 692977d4d03..aa3d9ab8d70 100644
--- a/src/lib/formats/all.cpp
+++ b/src/lib/formats/all.cpp
@@ -364,6 +364,10 @@
#include "fs_coco_rsdos.h"
#endif
+#ifdef HAS_FORMATS_FS_COCO_OS9
+#include "fs_coco_os9.h"
+#endif
+
#ifdef HAS_FORMATS_JFD_DSK
#include "jfd_dsk.h"
#endif
@@ -1085,6 +1089,9 @@ void mame_formats_full_list(mame_formats_enumerator &en)
#ifdef HAS_FORMATS_FS_COCO_RSDOS
en.add(fs::COCO_RSDOS); // fs_coco_rsdos.h
#endif
+#ifdef HAS_FORMATS_FS_COCO_OS9
+ en.add(fs::COCO_OS9); // fs_coco_os9.h
+#endif
en.category("Kaypro");
#ifdef HAS_FORMATS_KAYPRO_DSK
diff --git a/src/lib/formats/fs_coco_os9.cpp b/src/lib/formats/fs_coco_os9.cpp
new file mode 100644
index 00000000000..aeacaf66d36
--- /dev/null
+++ b/src/lib/formats/fs_coco_os9.cpp
@@ -0,0 +1,542 @@
+// license:BSD-3-Clause
+// copyright-holders:Nathan Woods
+/***************************************************************************
+
+ fs_coco_os9.cpp
+
+ Management of CoCo OS-9 floppy images
+
+ OS-9 Level 2 Technical Reference, Chapter 5, Random Block File Manager,
+ page 2
+
+ http://www.colorcomputerarchive.com/coco/Documents/Manuals/Operating Systems/OS-9 Level 2 Manual (Tandy).pdf
+
+***************************************************************************/
+
+#include "fs_coco_os9.h"
+#include "coco_rawdsk.h"
+#include "strformat.h"
+
+namespace fs {
+
+const coco_os9_image COCO_OS9;
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+//-------------------------------------------------
+// name
+//-------------------------------------------------
+
+const char *coco_os9_image::name() const
+{
+ return "coco_os9";
+}
+
+
+//-------------------------------------------------
+// description
+//-------------------------------------------------
+
+const char *coco_os9_image::description() const
+{
+ return "CoCo OS-9";
+}
+
+
+//-------------------------------------------------
+// enumerate_f
+//-------------------------------------------------
+
+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))
+ {
+ fe.add(FLOPPY_COCO_RAWDSK_FORMAT, 161280, "coco_rawdsk_os9_35", "CoCo Raw Disk OS-9 single-sided 35 tracks");
+ fe.add(FLOPPY_COCO_RAWDSK_FORMAT, 184320, "coco_rawdsk_os9_40", "CoCo Raw Disk OS-9 single-sided 40 tracks");
+ }
+}
+
+
+//-------------------------------------------------
+// can_format
+//-------------------------------------------------
+
+bool coco_os9_image::can_format() const
+{
+ return false;
+}
+
+
+//-------------------------------------------------
+// can_read
+//-------------------------------------------------
+
+bool coco_os9_image::can_read() const
+{
+ return true;
+}
+
+
+//-------------------------------------------------
+// can_write
+//-------------------------------------------------
+
+bool coco_os9_image::can_write() const
+{
+ return false;
+}
+
+
+//-------------------------------------------------
+// has_rsrc
+//-------------------------------------------------
+
+bool coco_os9_image::has_rsrc() const
+{
+ return false;
+}
+
+
+//-------------------------------------------------
+// directory_separator
+//-------------------------------------------------
+
+char coco_os9_image::directory_separator() const
+{
+ return '/';
+}
+
+
+//-------------------------------------------------
+// volume_meta_description
+//-------------------------------------------------
+
+std::vector<meta_description> coco_os9_image::volume_meta_description() const
+{
+ std::vector<meta_description> results;
+ results.emplace_back(meta_description(meta_name::name, meta_type::string, "UNTITLED", false, [](const meta_value &m) { return m.as_string().size() <= 32; }, "Volume name, up to 32 characters"));
+ return results;
+}
+
+
+//-------------------------------------------------
+// file_meta_description
+//-------------------------------------------------
+
+std::vector<meta_description> coco_os9_image::file_meta_description() const
+{
+ return entity_meta_description();
+}
+
+
+//-------------------------------------------------
+// directory_meta_description
+//-------------------------------------------------
+
+std::vector<meta_description> coco_os9_image::directory_meta_description() const
+{
+ return entity_meta_description();
+}
+
+
+//-------------------------------------------------
+// entity_meta_description
+//-------------------------------------------------
+
+std::vector<meta_description> coco_os9_image::entity_meta_description() const
+{
+ std::vector<meta_description> results;
+ results.emplace_back(meta_description(meta_name::name, meta_type::string, "", false, [](const meta_value &m) { return validate_filename(m.as_string()); }, "File name"));
+ results.emplace_back(meta_description(meta_name::creation_date, meta_type::date, util::arbitrary_datetime::now(), false, nullptr, "Creation time"));
+ results.emplace_back(meta_description(meta_name::owner_id, meta_type::number, 0, true, nullptr, "Owner ID"));
+ results.emplace_back(meta_description(meta_name::attributes, meta_type::string, 0, true, nullptr, "File attributes"));
+ results.emplace_back(meta_description(meta_name::length, meta_type::number, 0, true, nullptr, "Size of the file in bytes"));
+ return results;
+}
+
+
+//-------------------------------------------------
+// mount
+//-------------------------------------------------
+
+std::unique_ptr<filesystem_t> 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));
+}
+
+
+//-------------------------------------------------
+// pick_os9_string
+//-------------------------------------------------
+
+std::string coco_os9_image::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;
+
+}
+
+
+//-------------------------------------------------
+// pick_integer_be
+//-------------------------------------------------
+
+u32 coco_os9_image::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;
+}
+
+
+//-------------------------------------------------
+// validate_filename
+//-------------------------------------------------
+
+bool coco_os9_image::validate_filename(std::string_view name)
+{
+ 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 coco_os9_image::is_ignored_filename(std::string_view name)
+{
+ return name.empty()
+ || name[0] == '\0'
+ || name == "."
+ || name == "..";
+}
+
+
+//-------------------------------------------------
+// volume_header ctor
+//-------------------------------------------------
+
+coco_os9_image::volume_header::volume_header(fsblk_t::block_t &&block)
+ : m_block(std::move(block))
+{
+}
+
+
+//-------------------------------------------------
+// volume_header::name
+//-------------------------------------------------
+
+std::string coco_os9_image::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
+//-------------------------------------------------
+
+coco_os9_image::file_header::file_header(fsblk_t::block_t &&block)
+ : m_block(std::move(block))
+{
+}
+
+
+//-------------------------------------------------
+// file_header::creation_date
+//-------------------------------------------------
+
+util::arbitrary_datetime coco_os9_image::file_header::creation_date() const
+{
+ util::arbitrary_datetime dt;
+ memset(&dt, 0, sizeof(dt));
+ dt.year = 1900 + m_block.r8(13);
+ dt.month = m_block.r8(14);
+ dt.day_of_month = m_block.r8(15);
+ return dt;
+}
+
+
+//-------------------------------------------------
+// file_header::metadata
+//-------------------------------------------------
+
+meta_data coco_os9_image::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 coco_os9_image::file_header::get_sector_map_entry_count() const
+{
+ return (m_block.size() - 16) / 5;
+}
+
+
+//-------------------------------------------------
+// file_header::get_sector_map_entry
+//-------------------------------------------------
+
+void coco_os9_image::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
+//-------------------------------------------------
+
+coco_os9_image::impl::impl(fsblk_t &blockdev, volume_header &&header)
+ : filesystem_t(blockdev, 256)
+ , m_volume_header(std::move(header))
+{
+}
+
+
+//-------------------------------------------------
+// impl::metadata
+//-------------------------------------------------
+
+meta_data coco_os9_image::impl::metadata()
+{
+ meta_data results;
+ results.set(meta_name::name, m_volume_header.name());
+ return results;
+}
+
+
+//-------------------------------------------------
+// impl::root
+//-------------------------------------------------
+
+filesystem_t::dir_t coco_os9_image::impl::root()
+{
+ if (!m_root)
+ m_root = open_directory(m_volume_header.root_dir_lsn());
+ return m_root.strong();
+}
+
+
+//-------------------------------------------------
+// impl::drop_root_ref
+//-------------------------------------------------
+
+void coco_os9_image::impl::drop_root_ref()
+{
+ m_root = nullptr;
+}
+
+
+//-------------------------------------------------
+// impl::open_directory
+//-------------------------------------------------
+
+coco_os9_image::impl::directory *coco_os9_image::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> coco_os9_image::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
+//-------------------------------------------------
+
+coco_os9_image::impl::file::file(impl &i, file_header &&file_header)
+ : m_fs(i)
+ , m_file_header(std::move(file_header))
+{
+}
+
+
+//-------------------------------------------------
+// file::drop_weak_references
+//-------------------------------------------------
+
+void coco_os9_image::impl::file::drop_weak_references()
+{
+}
+
+
+//-------------------------------------------------
+// file::metadata
+//-------------------------------------------------
+
+meta_data coco_os9_image::impl::file::metadata()
+{
+ return m_file_header.metadata();
+}
+
+
+//-------------------------------------------------
+// file::read_all
+//-------------------------------------------------
+
+std::vector<u8> coco_os9_image::impl::file::read_all()
+{
+ return m_fs.read_file_data(m_file_header);
+}
+
+
+//-------------------------------------------------
+// directory ctor
+//-------------------------------------------------
+
+coco_os9_image::impl::directory::directory(impl &i, file_header &&file_header)
+ : m_fs(i)
+ , m_file_header(std::move(file_header))
+{
+}
+
+
+//-------------------------------------------------
+// directory::drop_weak_references
+//-------------------------------------------------
+
+void coco_os9_image::impl::directory::drop_weak_references()
+{
+}
+
+
+//-------------------------------------------------
+// directory::metadata
+//-------------------------------------------------
+
+meta_data coco_os9_image::impl::directory::metadata()
+{
+ return m_file_header.metadata();
+}
+
+
+//-------------------------------------------------
+// directory::contents
+//-------------------------------------------------
+
+std::vector<dir_entry> coco_os9_image::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 coco_os9_image::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
+//-------------------------------------------------
+
+filesystem_t::dir_t coco_os9_image::impl::directory::dir_get(u64 key)
+{
+ return dir_t(m_fs.open_directory((u32) key));
+}
+
+}
diff --git a/src/lib/formats/fs_coco_os9.h b/src/lib/formats/fs_coco_os9.h
new file mode 100644
index 00000000000..dce2439694c
--- /dev/null
+++ b/src/lib/formats/fs_coco_os9.h
@@ -0,0 +1,160 @@
+// license:BSD-3-Clause
+// copyright-holders:Nathan Woods
+/***************************************************************************
+
+ fs_coco_os9.h
+
+ Management of CoCo OS-9 floppy images
+
+***************************************************************************/
+
+#ifndef MAME_FORMATS_FS_COCO_OS9_H
+#define MAME_FORMATS_FS_COCO_OS9_H
+
+#pragma once
+
+#include "fsmgr.h"
+#include <optional>
+#include <string_view>
+
+namespace fs {
+
+// ======================> coco_os9_image
+
+class coco_os9_image : public manager_t {
+public:
+ class volume_header
+ {
+ 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); }
+ 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;
+ };
+
+ 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;
+ };
+
+ coco_os9_image() : manager_t() {}
+
+ virtual const char *name() const override;
+ virtual const char *description() const override;
+
+ virtual void enumerate_f(floppy_enumerator &fe, u32 form_factor, const std::vector<u32> &variants) const override;
+ virtual std::unique_ptr<filesystem_t> mount(fsblk_t &blockdev) const override;
+
+ virtual bool can_format() const override;
+ virtual bool can_read() const override;
+ virtual bool can_write() const override;
+ virtual bool has_rsrc() const override;
+ virtual char directory_separator() const override;
+
+ virtual std::vector<meta_description> volume_meta_description() const override;
+ virtual std::vector<meta_description> file_meta_description() const override;
+ virtual std::vector<meta_description> directory_meta_description() const override;
+ std::vector<meta_description> entity_meta_description() const;
+
+private:
+ 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;
+
+ private:
+ volume_header m_volume_header;
+ dir_t m_root;
+
+ directory *open_directory(u32 lsn);
+ void drop_root_ref();
+ std::vector<u8> read_file_data(const file_header &header) const;
+ };
+
+ static std::string pick_os9_string(std::string_view raw_string);
+ static u32 pick_integer_be(const u8 *data, int length);
+ static bool validate_filename(std::string_view name);
+ static bool is_ignored_filename(std::string_view name);
+};
+
+extern const coco_os9_image COCO_OS9;
+
+} // namespace fs
+
+#endif // MAME_FORMATS_FS_COCO_OS9_H
diff --git a/src/lib/formats/fsmeta.cpp b/src/lib/formats/fsmeta.cpp
index 0159269a0d6..9ccb7e144b3 100644
--- a/src/lib/formats/fsmeta.cpp
+++ b/src/lib/formats/fsmeta.cpp
@@ -26,6 +26,8 @@ const char *meta_data::entry_name(meta_name name)
case meta_name::size_in_blocks: return "size_in_blocks";
case meta_name::file_type: return "file_type";
case meta_name::ascii_flag: return "ascii_flag";
+ case meta_name::owner_id: return "owner_id";
+ case meta_name::attributes: return "attributes";
}
return "";
}
diff --git a/src/lib/formats/fsmeta.h b/src/lib/formats/fsmeta.h
index 948df0c1f06..12ca8ef8e1a 100644
--- a/src/lib/formats/fsmeta.h
+++ b/src/lib/formats/fsmeta.h
@@ -32,7 +32,9 @@ enum class meta_name {
sequential,
size_in_blocks,
file_type,
- ascii_flag
+ ascii_flag,
+ owner_id,
+ attributes
};
enum class meta_type {
diff --git a/src/lib/formats/fsmgr.cpp b/src/lib/formats/fsmgr.cpp
index 185c08fa503..3f37c79691a 100644
--- a/src/lib/formats/fsmgr.cpp
+++ b/src/lib/formats/fsmgr.cpp
@@ -216,49 +216,49 @@ void fsblk_t::block_t::w32l(u32 offset, u32 data)
blk[3] = data >> 24;
}
-std::string fsblk_t::block_t::rstr(u32 offset, u32 size)
+std::string fsblk_t::block_t::rstr(u32 offset, u32 size) const
{
const u8 *d = m_object->rooffset("rstr", offset, size);
return std::string(d, d + size);
}
-u8 fsblk_t::block_t::r8(u32 offset)
+u8 fsblk_t::block_t::r8(u32 offset) const
{
const u8 *blk = m_object->offset("r8", offset, 1);
return blk[0];
}
-u16 fsblk_t::block_t::r16b(u32 offset)
+u16 fsblk_t::block_t::r16b(u32 offset) const
{
const u8 *blk = m_object->offset("r16b", offset, 2);
return (blk[0] << 8) | blk[1];
}
-u32 fsblk_t::block_t::r24b(u32 offset)
+u32 fsblk_t::block_t::r24b(u32 offset) const
{
const u8 *blk = m_object->offset("r24b", offset, 3);
return (blk[0] << 16) | (blk[1] << 8) | blk[2];
}
-u32 fsblk_t::block_t::r32b(u32 offset)
+u32 fsblk_t::block_t::r32b(u32 offset) const
{
const u8 *blk = m_object->offset("r32b", offset, 4);
return (blk[0] << 24) | (blk[1] << 16) | (blk[2] << 8) | blk[3];
}
-u16 fsblk_t::block_t::r16l(u32 offset)
+u16 fsblk_t::block_t::r16l(u32 offset) const
{
const u8 *blk = m_object->offset("r16l", offset, 2);
return blk[0] | (blk[1] << 8);
}
-u32 fsblk_t::block_t::r24l(u32 offset)
+u32 fsblk_t::block_t::r24l(u32 offset) const
{
const u8 *blk = m_object->offset("r24l", offset, 3);
return blk[0] | (blk[1] << 8) | (blk[2] << 16);
}
-u32 fsblk_t::block_t::r32l(u32 offset)
+u32 fsblk_t::block_t::r32l(u32 offset) const
{
const u8 *blk = m_object->offset("r32l", offset, 4);
return blk[0] | (blk[1] << 8) | (blk[2] << 16) | (blk[3] << 24);
diff --git a/src/lib/formats/fsmgr.h b/src/lib/formats/fsmgr.h
index 37ddaac2265..376f7f35fe5 100644
--- a/src/lib/formats/fsmgr.h
+++ b/src/lib/formats/fsmgr.h
@@ -158,7 +158,9 @@ public:
block_t strong() { return block_t(m_object, false); }
block_t weak() { return block_t(m_object, true); }
- const u8 *rodata() { return m_object->rodata(); }
+ u32 size() const { return m_object->size(); }
+
+ const u8 *rodata() const { return m_object->rodata(); }
u8 *data() { return m_object->data(); }
void copy(u32 offset, const u8 *src, u32 size);
@@ -173,14 +175,14 @@ public:
void w24l(u32 offset, u32 data);
void w32l(u32 offset, u32 data);
- std::string rstr(u32 offset, u32 size);
- u8 r8( u32 offset);
- u16 r16b(u32 offset);
- u32 r24b(u32 offset);
- u32 r32b(u32 offset);
- u16 r16l(u32 offset);
- u32 r24l(u32 offset);
- u32 r32l(u32 offset);
+ std::string rstr(u32 offset, u32 size) const;
+ u8 r8( u32 offset) const;
+ u16 r16b(u32 offset) const;
+ u32 r24b(u32 offset) const;
+ u32 r32b(u32 offset) const;
+ u16 r16l(u32 offset) const;
+ u32 r24l(u32 offset) const;
+ u32 r32l(u32 offset) const;
};
fsblk_t() : m_block_size(0) {}