Skip to content

Commit f82ca5d

Browse files
committed
formats/fsblk.cpp: Internal API change
- Raw pointer accessors (data, rodata) are no longer provided for fsblk_t::block_t. Other accessors used to be based on these methods, but now require their own internal overrides. This entails more copying of data in many cases, but will allow more flexible subclassing opportunities in the future. - To compensate for the removal of raw pointer accessors, add methods to fsblk_t::block_t for checking whether a portion of a block is equal to a memory range or a string (eqmem, eqstr). The resulting changed behavior in formats/fs_oric_jasmin.cpp actually fixes a bug in the directory search routine.
1 parent c3258de commit f82ca5d

File tree

14 files changed

+288
-221
lines changed

14 files changed

+288
-221
lines changed

src/lib/formats/fs_cbmdos.cpp

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Current limitations:
2121
#include "fsblk.h"
2222

2323
#include "corestr.h"
24-
#include "multibyte.h"
24+
#include "coretmpl.h"
2525
#include "strformat.h"
2626

2727
#include <array>
@@ -65,8 +65,8 @@ class impl : public filesystem_t {
6565
public:
6666
block_iterator(const impl &fs, u8 first_track, u8 first_sector);
6767
bool next();
68-
const void *data() const;
69-
const std::array<cbmdos_dirent, SECTOR_DIRECTORY_COUNT> &dirent_data() const;
68+
void append_data(std::vector<u8> &vec) const;
69+
cbmdos_dirent get_dirent(int file_index) const;
7070
u8 size() const;
7171
u8 track() const { return m_track; }
7272
u8 sector() const { return m_sector; }
@@ -305,7 +305,7 @@ impl::impl(fsblk_t &blockdev)
305305
meta_data impl::volume_metadata()
306306
{
307307
auto bam_block = read_sector(DIRECTORY_TRACK, BAM_SECTOR);
308-
std::string_view disk_name = bam_block->rstr(0x90, 16);
308+
std::string disk_name = bam_block->rstr(0x90, 16);
309309

310310
meta_data results;
311311
results.set(meta_name::name, strtrimright_cbm(disk_name));
@@ -359,7 +359,7 @@ std::pair<std::error_condition, std::vector<u8>> impl::file_read(const std::vect
359359
std::vector<u8> result;
360360
block_iterator iter(*this, dirent->m_file_first_track, dirent->m_file_first_sector);
361361
while (iter.next())
362-
result.insert(result.end(), (const u8 *)iter.data(), (const u8 *)iter.data() + iter.size());
362+
iter.append_data(result);
363363

364364
return std::make_pair(std::error_condition(), std::move(result));
365365
}
@@ -670,13 +670,12 @@ void impl::iterate_directory_entries(const std::function<bool(u8 track, u8 secto
670670
block_iterator iter(*this, DIRECTORY_TRACK, FIRST_DIRECTORY_SECTOR);
671671
while (iter.next())
672672
{
673-
auto entries = iter.dirent_data();
674-
675673
for (int file_index = 0; file_index < SECTOR_DIRECTORY_COUNT; file_index++)
676674
{
677-
if (entries[file_index].m_file_type != 0x00)
675+
cbmdos_dirent entry = iter.get_dirent(file_index);
676+
if (entry.m_file_type != 0x00)
678677
{
679-
if (callback(iter.track(), iter.sector(), file_index, entries[file_index]))
678+
if (callback(iter.track(), iter.sector(), file_index, entry))
680679
return;
681680
}
682681
}
@@ -688,11 +687,10 @@ void impl::iterate_all_directory_entries(const std::function<bool(u8 track, u8 s
688687
block_iterator iter(*this, DIRECTORY_TRACK, FIRST_DIRECTORY_SECTOR);
689688
while (iter.next())
690689
{
691-
auto entries = iter.dirent_data();
692-
693690
for (int file_index = 0; file_index < SECTOR_DIRECTORY_COUNT; file_index++)
694691
{
695-
if (callback(iter.track(), iter.sector(), file_index, entries[file_index]))
692+
cbmdos_dirent entry = iter.get_dirent(file_index);
693+
if (callback(iter.track(), iter.sector(), file_index, entry))
696694
return;
697695
}
698696
}
@@ -790,22 +788,26 @@ bool impl::block_iterator::next()
790788

791789

792790
//-------------------------------------------------
793-
// impl::block_iterator::data
791+
// impl::block_iterator::append_data
794792
//-------------------------------------------------
795793

796-
const void *impl::block_iterator::data() const
794+
void impl::block_iterator::append_data(std::vector<u8> &vec) const
797795
{
798-
return m_block->rodata() + 2;
796+
const u8 size = this->size();
797+
vec.resize(vec.size() + size);
798+
m_block->read(2, &*(vec.end() - size), size);
799799
}
800800

801801

802802
//-------------------------------------------------
803-
// impl::block_iterator::dirent_data
803+
// impl::block_iterator::get_dirent
804804
//-------------------------------------------------
805805

806-
const std::array<impl::cbmdos_dirent, impl::SECTOR_DIRECTORY_COUNT> &impl::block_iterator::dirent_data() const
806+
impl::cbmdos_dirent impl::block_iterator::get_dirent(int file_index) const
807807
{
808-
return *reinterpret_cast<const std::array<impl::cbmdos_dirent, SECTOR_DIRECTORY_COUNT> *>(m_block->rodata());
808+
cbmdos_dirent entry;
809+
m_block->read(sizeof(cbmdos_dirent) * file_index, reinterpret_cast<u8 *>(&entry), sizeof(cbmdos_dirent));
810+
return entry;
809811
}
810812

811813

src/lib/formats/fs_coco_os9.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -555,8 +555,8 @@ std::vector<u8> coco_os9_impl::read_file_data(const file_header &header) const
555555
{
556556
auto block = m_blockdev.get(lsn);
557557
size_t block_size = std::min(std::min(u32(m_volume_header.sector_size()), block->size()), header.file_size() - u32(data.size()));
558-
for (auto i = 0; i < block_size; i++)
559-
data.push_back(block->rodata()[i]);
558+
data.resize(data.size() + block_size);
559+
block->read(0, &*(data.end() - block_size), block_size);
560560
}
561561
}
562562
return data;
@@ -676,7 +676,7 @@ coco_os9_impl::volume_header::volume_header(fsblk_t::block_t::ptr &&block)
676676

677677
std::string coco_os9_impl::volume_header::name() const
678678
{
679-
std::string_view raw_name(m_block->rstr(31, 32));
679+
std::string raw_name(m_block->rstr(31, 32));
680680
return pick_os9_string(raw_name);
681681
}
682682

src/lib/formats/fs_coco_rsdos.cpp

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ class coco_rsdos_impl : public filesystem_t
3434
coco_rsdos_impl(fsblk_t &blockdev);
3535
virtual ~coco_rsdos_impl() = default;
3636

37-
static constexpr int SECTOR_DIRECTORY_ENTRY_COUNT = 8;
38-
3937
struct rsdos_dirent
4038
{
4139
char m_filename[11];
@@ -46,15 +44,6 @@ class coco_rsdos_impl : public filesystem_t
4644
u8 m_last_sector_bytes_lsb;
4745
};
4846

49-
struct rsdos_dirent_sector
50-
{
51-
struct
52-
{
53-
rsdos_dirent m_dirent;
54-
u8 m_unused[16];
55-
} m_entries[SECTOR_DIRECTORY_ENTRY_COUNT];
56-
};
57-
5847
class granule_iterator
5948
{
6049
public:
@@ -79,6 +68,7 @@ class coco_rsdos_impl : public filesystem_t
7968
static bool validate_filename(std::string_view name);
8069

8170
private:
71+
static constexpr int SECTOR_DIRECTORY_ENTRY_COUNT = 8;
8272
static constexpr u8 TRACK_GRANULE_COUNT = 2;
8373
static constexpr u8 GRANULE_SECTOR_COUNT = 9;
8474
static constexpr u8 TRACK_SECTOR_COUNT = TRACK_GRANULE_COUNT * GRANULE_SECTOR_COUNT;
@@ -99,6 +89,7 @@ class coco_rsdos_impl : public filesystem_t
9989
fsblk_t::block_t::ptr read_sector(int track, int sector) const;
10090
fsblk_t::block_t::ptr read_granule_sector(u8 granule, u8 sector) const;
10191
u8 maximum_granules() const;
92+
static rsdos_dirent get_dirent(const fsblk_t::block_t &dir_block, int file_index);
10293
std::optional<rsdos_dirent> dirent_from_path(const std::vector<std::string> &path);
10394
template <typename T>
10495
void iterate_directory_entries(T &&callback);
@@ -596,6 +587,18 @@ std::optional<coco_rsdos_impl::rsdos_dirent> coco_rsdos_impl::dirent_from_path(c
596587
}
597588

598589

590+
//-------------------------------------------------
591+
// coco_rsdos_impl::get_dirent
592+
//-------------------------------------------------
593+
594+
coco_rsdos_impl::rsdos_dirent coco_rsdos_impl::get_dirent(const fsblk_t::block_t &dir_block, int file_index)
595+
{
596+
rsdos_dirent result;
597+
dir_block.read(file_index * DIRECTORY_ENTRY_SIZE, reinterpret_cast<u8 *>(&result), sizeof(rsdos_dirent));
598+
return result;
599+
}
600+
601+
599602
//-------------------------------------------------
600603
// coco_rsdos_impl::iterate_directory_entries
601604
//-------------------------------------------------
@@ -608,21 +611,21 @@ void coco_rsdos_impl::iterate_directory_entries(T &&callback)
608611
{
609612
// read this directory sector
610613
auto dir_block = read_sector(DIRECTORY_TRACK, dir_sector);
611-
const rsdos_dirent_sector &sector = *reinterpret_cast<const rsdos_dirent_sector *>(dir_block->rodata());
612614

613615
// and loop through all entries
614616
for (int file_index = 0; file_index < 8; file_index++)
615617
{
616618
// 0xFF marks the end of the directory
617-
if (sector.m_entries[file_index].m_dirent.m_filename[0] == '\xFF')
619+
rsdos_dirent entry = get_dirent(*dir_block, file_index);
620+
if (entry.m_filename[0] == '\xFF')
618621
{
619622
done = true;
620623
}
621624
else
622625
{
623626
// 0x00 marks a deleted file
624-
if (sector.m_entries[file_index].m_dirent.m_filename[0] != '\0')
625-
done = callback(dir_sector, 0, sector.m_entries[file_index].m_dirent);
627+
if (entry.m_filename[0] != '\0')
628+
done = callback(dir_sector, 0, entry);
626629
}
627630

628631
if (done)
@@ -708,27 +711,27 @@ bool coco_rsdos_impl::granule_iterator::next(u8 &granule, u16 &byte_count)
708711
if (m_current_granule)
709712
{
710713
std::optional<u8> next_granule;
711-
const u8 *granule_map_data = m_granule_map->rodata();
712-
if (granule_map_data[*m_current_granule] < m_maximum_granules)
714+
const u8 cur_granule = m_granule_map->r8(*m_current_granule);
715+
if (cur_granule < m_maximum_granules)
713716
{
714717
// this entry points to the next granule
715718
success = true;
716719
granule = *m_current_granule;
717720
byte_count = GRANULE_SECTOR_COUNT * SECTOR_SIZE;
718-
next_granule = granule_map_data[*m_current_granule];
721+
next_granule = cur_granule;
719722

720723
// check for cycles, which should only happen if the disk is corrupt (or not in RS-DOS format)
721724
if (m_visited_granules[*next_granule])
722725
next_granule = std::nullopt; // this is corrupt!
723726
else
724727
m_visited_granules.set(*next_granule);
725728
}
726-
else if (granule_map_data[*m_current_granule] >= FILE_LAST_GRANULE_INDICATOR && granule_map_data[*m_current_granule] <= FILE_LAST_GRANULE_INDICATOR + GRANULE_SECTOR_COUNT)
729+
else if (cur_granule >= FILE_LAST_GRANULE_INDICATOR && cur_granule <= FILE_LAST_GRANULE_INDICATOR + GRANULE_SECTOR_COUNT)
727730
{
728731
// this is the last granule in the file
729732
success = true;
730733
granule = *m_current_granule;
731-
u16 sector_count = std::max(granule_map_data[*m_current_granule], u8(0xC1)) - 0xC1;
734+
u16 sector_count = std::max(cur_granule, u8(0xC1)) - 0xC1;
732735
byte_count = sector_count * SECTOR_SIZE + m_last_sector_bytes;
733736
next_granule = std::nullopt;
734737
}

src/lib/formats/fs_fat.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,8 @@ class directory_entry
191191
{
192192
}
193193

194-
std::string_view raw_stem() const { return m_block->rstr(m_offset + OFFSET_FNAME, 8); }
195-
std::string_view raw_ext() const { return m_block->rstr(m_offset + OFFSET_FNAME + 8, 3); }
194+
std::string raw_stem() const { return m_block->rstr(m_offset + OFFSET_FNAME, 8); }
195+
std::string raw_ext() const { return m_block->rstr(m_offset + OFFSET_FNAME + 8, 3); }
196196
u8 attributes() const { return m_block->r8(m_offset + OFFSET_ATTRIBUTES); }
197197
u32 raw_create_datetime() const { return m_block->r32l(m_offset + OFFSET_CREATE_DATETIME); }
198198
u32 raw_modified_datetime() const { return m_block->r32l(m_offset + OFFSET_MODIFIED_DATETIME); }
@@ -506,7 +506,8 @@ std::unique_ptr<filesystem_t> fs::fat_image::mount_partition(fsblk_t &blockdev,
506506
for (auto i = 0; i < fat_count * sectors_per_fat; i++)
507507
{
508508
fsblk_t::block_t::ptr fatblk = blockdev.get(starting_sector + reserved_sector_count + i);
509-
file_allocation_table.insert(file_allocation_table.end(), fatblk->rodata(), fatblk->rodata() + bytes_per_sector);
509+
file_allocation_table.resize(file_allocation_table.size() + bytes_per_sector);
510+
fatblk->read(0, &*(file_allocation_table.end() - bytes_per_sector), bytes_per_sector);
510511
}
511512

512513
// and return the implementation
@@ -521,8 +522,8 @@ std::unique_ptr<filesystem_t> fs::fat_image::mount_partition(fsblk_t &blockdev,
521522

522523
std::string directory_entry::name() const
523524
{
524-
std::string_view stem = filesystem_t::trim_end_spaces(raw_stem());
525-
std::string_view ext = filesystem_t::trim_end_spaces(raw_ext());
525+
std::string stem(filesystem_t::trim_end_spaces(raw_stem()));
526+
std::string ext(filesystem_t::trim_end_spaces(raw_ext()));
526527
return !ext.empty()
527528
? util::string_format("%s.%s", stem, ext)
528529
: std::string(stem);
@@ -662,9 +663,9 @@ std::pair<std::error_condition, std::vector<u8>> impl::file_read(const std::vect
662663
for (u32 sector : sectors)
663664
{
664665
fsblk_t::block_t::ptr block = m_blockdev.get(sector);
665-
const u8 *data = block->rodata();
666666
size_t length = std::min((size_t)dirent->file_size() - result.size(), (size_t)block->size());
667-
result.insert(result.end(), data, data + length);
667+
result.resize(result.size() + length);
668+
block->read(0, &*(result.end() - length), length);
668669
}
669670
return std::make_pair(std::error_condition(), std::move(result));
670671
}
@@ -1234,8 +1235,8 @@ void impl::iterate_directory_entries(const directory_span &dir, T &&callback) co
12341235
if (dirent.raw_stem()[0] != 0x00 && !dirent.is_deleted() && !dirent.is_long_file_name())
12351236
{
12361237
// get the filename
1237-
std::string_view stem = trim_end_spaces(dirent.raw_stem());
1238-
std::string_view ext = trim_end_spaces(dirent.raw_ext());
1238+
std::string stem(trim_end_spaces(dirent.raw_stem()));
1239+
std::string ext(trim_end_spaces(dirent.raw_ext()));
12391240
if (ext.empty() && (stem == "." || stem == ".."))
12401241
continue;
12411242

src/lib/formats/fs_hp98x5.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666

6767
#include <bitset>
6868
#include <map>
69+
#include <stdexcept>
6970

7071
using namespace fs;
7172
using namespace std::literals;

0 commit comments

Comments
 (0)