mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
formats/fsblk.cpp: Replaced fs::err_t enum with a standard error condition category. (#13128)
Also replace "invalid" error with more specific values.
This commit is contained in:
parent
b977c33432
commit
c4da9ca64e
@ -85,11 +85,11 @@ public:
|
||||
virtual ~impl() = default;
|
||||
|
||||
virtual meta_data volume_metadata() override;
|
||||
virtual std::pair<err_t, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<err_t, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<err_t, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual err_t file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
virtual err_t file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
virtual std::pair<std::error_condition, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual std::error_condition file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
virtual std::error_condition file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
|
||||
private:
|
||||
static constexpr u32 BLOCK_SIZE = 256;
|
||||
@ -130,9 +130,9 @@ private:
|
||||
void iterate_all_directory_entries(const std::function<bool(u8 track, u8 sector, u8 file_index, const cbmdos_dirent &dirent)> &callback) const;
|
||||
meta_data metadata_from_dirent(const cbmdos_dirent &dirent) const;
|
||||
bool is_valid_filename(const std::string &filename) const;
|
||||
std::pair<err_t, u8> claim_track_sector(u8 track) const;
|
||||
std::tuple<err_t, u8, u8> claim_sector() const;
|
||||
err_t free_sector(u8 track, u8 sector) const;
|
||||
std::pair<std::error_condition, u8> claim_track_sector(u8 track) const;
|
||||
std::tuple<std::error_condition, u8, u8> claim_sector() const;
|
||||
std::error_condition free_sector(u8 track, u8 sector) const;
|
||||
u8 determine_file_type(const std::vector<u8> &data) const;
|
||||
};
|
||||
|
||||
@ -317,13 +317,13 @@ meta_data impl::volume_metadata()
|
||||
// impl::metadata
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, meta_data> impl::metadata(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, meta_data> impl::metadata(const std::vector<std::string> &path)
|
||||
{
|
||||
std::optional<cbmdos_dirent> dirent = dirent_from_path(path);
|
||||
if (!dirent)
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data());
|
||||
return std::make_pair(error::not_found, meta_data());
|
||||
|
||||
return std::make_pair(ERR_OK, metadata_from_dirent(*dirent));
|
||||
return std::make_pair(std::error_condition(), metadata_from_dirent(*dirent));
|
||||
}
|
||||
|
||||
|
||||
@ -331,7 +331,7 @@ std::pair<err_t, meta_data> impl::metadata(const std::vector<std::string> &path)
|
||||
// impl::directory_contents
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<dir_entry>> impl::directory_contents(const std::vector<std::string> &path)
|
||||
{
|
||||
std::vector<dir_entry> results;
|
||||
auto callback = [this, &results](u8 track, u8 sector, u8 file_index, const cbmdos_dirent &ent)
|
||||
@ -340,7 +340,7 @@ std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vec
|
||||
return false;
|
||||
};
|
||||
iterate_directory_entries(callback);
|
||||
return std::make_pair(ERR_OK, std::move(results));
|
||||
return std::make_pair(std::error_condition(), std::move(results));
|
||||
}
|
||||
|
||||
|
||||
@ -348,12 +348,12 @@ std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vec
|
||||
// impl::file_read
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, std::vector<u8>> impl::file_read(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<u8>> impl::file_read(const std::vector<std::string> &path)
|
||||
{
|
||||
// find the file
|
||||
std::optional<cbmdos_dirent> dirent = dirent_from_path(path);
|
||||
if (!dirent)
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<u8>());
|
||||
return std::make_pair(error::not_found, std::vector<u8>());
|
||||
|
||||
// and get the data
|
||||
std::vector<u8> result;
|
||||
@ -361,15 +361,15 @@ std::pair<err_t, std::vector<u8>> impl::file_read(const std::vector<std::string>
|
||||
while (iter.next())
|
||||
result.insert(result.end(), (const u8 *)iter.data(), (const u8 *)iter.data() + iter.size());
|
||||
|
||||
return std::make_pair(ERR_OK, std::move(result));
|
||||
return std::make_pair(std::error_condition(), std::move(result));
|
||||
}
|
||||
|
||||
|
||||
err_t impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
std::error_condition impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
{
|
||||
std::string filename = meta.get_string(meta_name::name, "");
|
||||
if (!is_valid_filename(filename))
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
|
||||
std::optional<cbmdos_dirent> result;
|
||||
u8 track = 0;
|
||||
@ -393,7 +393,7 @@ err_t impl::file_create(const std::vector<std::string> &path, const meta_data &m
|
||||
{
|
||||
// Claim a next directory sector
|
||||
auto const [err, new_sector] = claim_track_sector(DIRECTORY_TRACK);
|
||||
if (err != ERR_OK)
|
||||
if (err)
|
||||
return err;
|
||||
auto new_block = read_sector(DIRECTORY_TRACK, new_sector);
|
||||
for (int i = 2; i < BLOCK_SIZE; i++)
|
||||
@ -412,7 +412,7 @@ err_t impl::file_create(const std::vector<std::string> &path, const meta_data &m
|
||||
}
|
||||
|
||||
auto const [err, file_track, file_sector] = claim_sector();
|
||||
if (err != ERR_OK)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
// Create the file
|
||||
@ -429,14 +429,14 @@ err_t impl::file_create(const std::vector<std::string> &path, const meta_data &m
|
||||
// TODO set rel file record length
|
||||
// sector count will be set while writing the data
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
|
||||
err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
std::error_condition impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
{
|
||||
if (path.size() != 1)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
std::string_view path_part = path[0];
|
||||
|
||||
std::optional<cbmdos_dirent> result;
|
||||
@ -458,7 +458,7 @@ err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u
|
||||
iterate_directory_entries(callback);
|
||||
|
||||
if (!result)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
u8 data_track = result->m_file_first_track;
|
||||
u8 data_sector = result->m_file_first_sector;
|
||||
@ -478,7 +478,7 @@ err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u
|
||||
if (offset < data_length)
|
||||
{
|
||||
auto [err, next_track, next_sector] = claim_sector();
|
||||
if (err != ERR_OK)
|
||||
if (err)
|
||||
return err;
|
||||
datablk.w8(OFFSET_CHAIN_TRACK, next_track);
|
||||
datablk.w8(OFFSET_CHAIN_SECTOR, next_sector);
|
||||
@ -501,8 +501,8 @@ err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u
|
||||
|
||||
while (track_to_free != CHAIN_END)
|
||||
{
|
||||
err_t const err = free_sector(track_to_free, sector_to_free);
|
||||
if (err != ERR_OK)
|
||||
std::error_condition const err = free_sector(track_to_free, sector_to_free);
|
||||
if (err)
|
||||
return err;
|
||||
datablk = read_sector(track_to_free, sector_to_free);
|
||||
track_to_free = datablk.r8(OFFSET_CHAIN_TRACK);
|
||||
@ -525,8 +525,8 @@ err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u
|
||||
// Free sector, update first file sector to 00
|
||||
u8 file_track = dirblk.r8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_FIRST_TRACK);
|
||||
u8 file_sector = dirblk.r8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_FIRST_SECTOR);
|
||||
err_t err = free_sector(file_track, file_sector);
|
||||
if (err != ERR_OK)
|
||||
std::error_condition err = free_sector(file_track, file_sector);
|
||||
if (err)
|
||||
return err;
|
||||
dirblk.w8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_FIRST_TRACK, 0);
|
||||
dirblk.w8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_FIRST_SECTOR, 0);
|
||||
@ -535,7 +535,7 @@ err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u
|
||||
dirblk.w8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_TYPE, file_type);
|
||||
dirblk.w16l(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_SECTOR_COUNT, sector_count);
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
|
||||
@ -557,15 +557,15 @@ bool impl::is_valid_filename(const std::string &filename) const
|
||||
}
|
||||
|
||||
|
||||
std::pair<err_t, u8> impl::claim_track_sector(u8 track) const
|
||||
std::pair<std::error_condition, u8> impl::claim_track_sector(u8 track) const
|
||||
{
|
||||
if (track == 0 || track > m_max_track)
|
||||
return std::make_pair(ERR_INVALID, 0);
|
||||
return std::make_pair(error::invalid_block, 0);
|
||||
|
||||
u8 map_index;
|
||||
for (map_index = 0; map_index < TRACK_VARIANTS && !(s_track_sector_map[map_index].first_track <= track && track <= s_track_sector_map[map_index].last_track) ; map_index++);
|
||||
if (map_index >= TRACK_VARIANTS)
|
||||
return std::make_pair(ERR_INVALID, 0);
|
||||
return std::make_pair(error::invalid_block, 0);
|
||||
|
||||
auto bamblk = read_sector(DIRECTORY_TRACK, BAM_SECTOR);
|
||||
u8 free_count = bamblk.r8(4 * track);
|
||||
@ -584,31 +584,31 @@ std::pair<err_t, u8> impl::claim_track_sector(u8 track) const
|
||||
auto claimedlk = read_sector(track, sector);
|
||||
claimedlk.w8(OFFSET_CHAIN_TRACK, CHAIN_END);
|
||||
claimedlk.w8(OFFSET_CHAIN_SECTOR, 0xff);
|
||||
return std::make_pair(ERR_OK, sector);
|
||||
return std::make_pair(std::error_condition(), sector);
|
||||
}
|
||||
}
|
||||
return std::make_pair(ERR_NO_SPACE, 0);
|
||||
return std::make_pair(error::no_space, 0);
|
||||
}
|
||||
|
||||
|
||||
std::tuple<err_t, u8, u8> impl::claim_sector() const
|
||||
std::tuple<std::error_condition, u8, u8> impl::claim_sector() const
|
||||
{
|
||||
for (int track = 0; track < m_max_track - 1; track++)
|
||||
{
|
||||
auto const [err, sector] = claim_track_sector(s_data_track_order[track]);
|
||||
if (err == ERR_OK)
|
||||
return std::make_tuple(ERR_OK, s_data_track_order[track], sector);
|
||||
if (err != ERR_NO_SPACE)
|
||||
if (!err)
|
||||
return std::make_tuple(std::error_condition(), s_data_track_order[track], sector);
|
||||
if (err != error::no_space)
|
||||
return std::make_tuple(err, 0, 0);
|
||||
}
|
||||
return std::make_tuple(ERR_NO_SPACE, 0, 0);
|
||||
return std::make_tuple(error::no_space, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
err_t impl::free_sector(u8 track, u8 sector) const
|
||||
std::error_condition impl::free_sector(u8 track, u8 sector) const
|
||||
{
|
||||
if (track == 0 || track > m_max_track)
|
||||
return ERR_INVALID;
|
||||
return error::invalid_block;
|
||||
|
||||
auto bamblk = read_sector(DIRECTORY_TRACK, BAM_SECTOR);
|
||||
u8 free_count = bamblk.r8(4 * track);
|
||||
@ -617,7 +617,7 @@ err_t impl::free_sector(u8 track, u8 sector) const
|
||||
free_count++;
|
||||
bamblk.w8(4 * track, free_count);
|
||||
bamblk.w24l(4 * track + 1, free_bitmap);
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
|
||||
|
@ -109,10 +109,10 @@ public:
|
||||
virtual ~coco_os9_impl() = default;
|
||||
|
||||
virtual meta_data volume_metadata() override;
|
||||
virtual std::pair<err_t, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<err_t, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<err_t, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual err_t format(const meta_data &meta) override;
|
||||
virtual std::pair<std::error_condition, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual std::error_condition format(const meta_data &meta) override;
|
||||
|
||||
std::optional<file_header> find(const std::vector<std::string> &path, std::optional<dir_entry_type> expected_entry_type) const;
|
||||
void iterate_directory_entries(const file_header &header, const std::function<bool(std::string &&, u32)> callback) const;
|
||||
@ -301,14 +301,14 @@ meta_data coco_os9_impl::volume_metadata()
|
||||
// coco_os9_impl::metadata
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, meta_data> coco_os9_impl::metadata(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, meta_data> coco_os9_impl::metadata(const std::vector<std::string> &path)
|
||||
{
|
||||
// look up the path
|
||||
std::optional<file_header> header = find(path, { });
|
||||
if (!header)
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data());
|
||||
return std::make_pair(error::not_found, meta_data());
|
||||
|
||||
return std::make_pair(ERR_OK, header->metadata());
|
||||
return std::make_pair(std::error_condition(), header->metadata());
|
||||
}
|
||||
|
||||
|
||||
@ -316,12 +316,12 @@ std::pair<err_t, meta_data> coco_os9_impl::metadata(const std::vector<std::strin
|
||||
// coco_os9_impl::directory_contents
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, std::vector<dir_entry>> coco_os9_impl::directory_contents(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<dir_entry>> coco_os9_impl::directory_contents(const std::vector<std::string> &path)
|
||||
{
|
||||
// look up the path
|
||||
std::optional<file_header> header = find(path, dir_entry_type::dir);
|
||||
if (!header)
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<dir_entry>());
|
||||
return std::make_pair(error::not_found, std::vector<dir_entry>());
|
||||
|
||||
// iterate through the directory
|
||||
std::vector<dir_entry> results;
|
||||
@ -337,7 +337,7 @@ std::pair<err_t, std::vector<dir_entry>> coco_os9_impl::directory_contents(const
|
||||
iterate_directory_entries(*header, callback);
|
||||
|
||||
// and we're done
|
||||
return std::make_pair(ERR_OK, std::move(results));
|
||||
return std::make_pair(std::error_condition(), std::move(results));
|
||||
}
|
||||
|
||||
|
||||
@ -345,15 +345,15 @@ std::pair<err_t, std::vector<dir_entry>> coco_os9_impl::directory_contents(const
|
||||
// coco_os9_impl::file_read
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, std::vector<u8>> coco_os9_impl::file_read(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<u8>> coco_os9_impl::file_read(const std::vector<std::string> &path)
|
||||
{
|
||||
// look up the path
|
||||
std::optional<file_header> header = find(path, dir_entry_type::file);
|
||||
if (!header)
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<u8>());
|
||||
return std::make_pair(error::not_found, std::vector<u8>());
|
||||
|
||||
std::vector<u8> data = read_file_data(*header);
|
||||
return std::make_pair(ERR_OK, std::move(data));
|
||||
return std::make_pair(std::error_condition(), std::move(data));
|
||||
}
|
||||
|
||||
|
||||
@ -361,7 +361,7 @@ std::pair<err_t, std::vector<u8>> coco_os9_impl::file_read(const std::vector<std
|
||||
// coco_os9_impl::format
|
||||
//-------------------------------------------------
|
||||
|
||||
err_t coco_os9_impl::format(const meta_data &meta)
|
||||
std::error_condition coco_os9_impl::format(const meta_data &meta)
|
||||
{
|
||||
// for some reason, the OS-9 world favored filling with 0xE5
|
||||
m_blockdev.fill(0xe5);
|
||||
@ -464,7 +464,7 @@ err_t coco_os9_impl::format(const meta_data &meta)
|
||||
rootdata_blk.w8(0x1f, 1 + allocation_bitmap_lsns);
|
||||
rootdata_blk.w8(0x20, 0xae);
|
||||
rootdata_blk.w8(0x3f, 1 + allocation_bitmap_lsns);
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
|
||||
|
@ -69,12 +69,12 @@ public:
|
||||
std::bitset<256> m_visited_granules;
|
||||
};
|
||||
|
||||
virtual std::pair<err_t, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<err_t, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<err_t, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual err_t format(const meta_data &meta) override;
|
||||
virtual err_t file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
virtual err_t file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
virtual std::pair<std::error_condition, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual std::error_condition format(const meta_data &meta) override;
|
||||
virtual std::error_condition file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
virtual std::error_condition file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
|
||||
static bool validate_filename(std::string_view name);
|
||||
|
||||
@ -104,8 +104,8 @@ private:
|
||||
void iterate_directory_entries(T &&callback);
|
||||
meta_data get_metadata_from_dirent(const rsdos_dirent &dirent);
|
||||
static std::string get_filename_from_dirent(const rsdos_dirent &dirent);
|
||||
std::pair<err_t, std::string> build_direntry_filename(const std::string &filename);
|
||||
std::pair<err_t, u8> claim_granule();
|
||||
std::pair<std::error_condition, std::string> build_direntry_filename(const std::string &filename);
|
||||
std::pair<std::error_condition, u8> claim_granule();
|
||||
void write_granule_map(u8 granule, u8 map_data);
|
||||
u8 read_granule_map(u8 granule) const;
|
||||
bool is_ascii(const std::vector<u8> &data) const;
|
||||
@ -239,14 +239,14 @@ coco_rsdos_impl::coco_rsdos_impl(fsblk_t &blockdev)
|
||||
// coco_rsdos_impl::metadata
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, meta_data> coco_rsdos_impl::metadata(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, meta_data> coco_rsdos_impl::metadata(const std::vector<std::string> &path)
|
||||
{
|
||||
// attempt to find the file
|
||||
const std::optional<rsdos_dirent> dirent = dirent_from_path(path);
|
||||
if (!dirent)
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data());
|
||||
return std::make_pair(error::not_found, meta_data());
|
||||
|
||||
return std::make_pair(ERR_OK, get_metadata_from_dirent(*dirent));
|
||||
return std::make_pair(std::error_condition(), get_metadata_from_dirent(*dirent));
|
||||
}
|
||||
|
||||
|
||||
@ -254,7 +254,7 @@ std::pair<err_t, meta_data> coco_rsdos_impl::metadata(const std::vector<std::str
|
||||
// coco_rsdos_impl::directory_contents
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, std::vector<dir_entry>> coco_rsdos_impl::directory_contents(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<dir_entry>> coco_rsdos_impl::directory_contents(const std::vector<std::string> &path)
|
||||
{
|
||||
std::vector<dir_entry> results;
|
||||
auto const callback = [this, &results](u8 s, u8 i, const rsdos_dirent &dirent)
|
||||
@ -263,7 +263,7 @@ std::pair<err_t, std::vector<dir_entry>> coco_rsdos_impl::directory_contents(con
|
||||
return false;
|
||||
};
|
||||
iterate_directory_entries(callback);
|
||||
return std::make_pair(ERR_OK, std::move(results));
|
||||
return std::make_pair(std::error_condition(), std::move(results));
|
||||
}
|
||||
|
||||
|
||||
@ -271,12 +271,12 @@ std::pair<err_t, std::vector<dir_entry>> coco_rsdos_impl::directory_contents(con
|
||||
// coco_rsdos_impl::file_read
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, std::vector<u8>> coco_rsdos_impl::file_read(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<u8>> coco_rsdos_impl::file_read(const std::vector<std::string> &path)
|
||||
{
|
||||
// attempt to find the file
|
||||
const std::optional<rsdos_dirent> dirent = dirent_from_path(path);
|
||||
if (!dirent)
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<u8>());
|
||||
return std::make_pair(error::not_found, std::vector<u8>());
|
||||
|
||||
std::vector<u8> result;
|
||||
u8 granule;
|
||||
@ -309,7 +309,7 @@ std::pair<err_t, std::vector<u8>> coco_rsdos_impl::file_read(const std::vector<s
|
||||
sector++;
|
||||
}
|
||||
}
|
||||
return std::make_pair(ERR_OK, std::move(result));
|
||||
return std::make_pair(std::error_condition(), std::move(result));
|
||||
}
|
||||
|
||||
|
||||
@ -317,23 +317,23 @@ std::pair<err_t, std::vector<u8>> coco_rsdos_impl::file_read(const std::vector<s
|
||||
// coco_rsdos_impl::format
|
||||
//-------------------------------------------------
|
||||
|
||||
err_t coco_rsdos_impl::format(const meta_data &meta)
|
||||
std::error_condition coco_rsdos_impl::format(const meta_data &meta)
|
||||
{
|
||||
// formatting RS-DOS is easy - just fill everything with 0xFF
|
||||
m_blockdev.fill(0xFF);
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
|
||||
std::pair<err_t, std::string> coco_rsdos_impl::build_direntry_filename(const std::string &filename)
|
||||
std::pair<std::error_condition, std::string> coco_rsdos_impl::build_direntry_filename(const std::string &filename)
|
||||
{
|
||||
// The manual does not say anything about valid characters for a file name.
|
||||
const std::regex filename_regex("([^.]{0,8})(\\.([^.]{0,3}))?");
|
||||
std::smatch smatch;
|
||||
if (!std::regex_match(filename, smatch, filename_regex))
|
||||
return std::make_pair(ERR_INVALID, std::string());
|
||||
return std::make_pair(error::invalid_name, std::string());
|
||||
if (smatch.size() != 4)
|
||||
return std::make_pair(ERR_INVALID, std::string());
|
||||
return std::make_pair(error::invalid_name, std::string());
|
||||
|
||||
std::string fname;
|
||||
fname.resize(FNAME_LENGTH, ' ');
|
||||
@ -344,18 +344,18 @@ std::pair<err_t, std::string> coco_rsdos_impl::build_direntry_filename(const std
|
||||
for (int j = 0; j < 3 && j < smatch.str(3).size(); j++)
|
||||
fname[8 + j] = smatch.str(3)[j];
|
||||
|
||||
return std::make_pair(ERR_OK, std::move(fname));
|
||||
return std::make_pair(std::error_condition(), std::move(fname));
|
||||
}
|
||||
|
||||
|
||||
err_t coco_rsdos_impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
std::error_condition coco_rsdos_impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
{
|
||||
if (!path.empty())
|
||||
return ERR_UNSUPPORTED;
|
||||
return error::unsupported;
|
||||
|
||||
const std::string filename = meta.get_string(meta_name::name, "");
|
||||
auto [err, fname] = build_direntry_filename(filename);
|
||||
if (err != ERR_OK)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
bool found_entry = false;
|
||||
@ -376,7 +376,7 @@ err_t coco_rsdos_impl::file_create(const std::vector<std::string> &path, const m
|
||||
dir_block.w8(file_index * DIRECTORY_ENTRY_SIZE + i, 0);
|
||||
|
||||
auto [cerr, granule] = claim_granule();
|
||||
if (cerr != ERR_OK)
|
||||
if (cerr != std::error_condition())
|
||||
return cerr;
|
||||
|
||||
dir_block.wstr(file_index * DIRECTORY_ENTRY_SIZE + 0, fname);
|
||||
@ -386,16 +386,16 @@ err_t coco_rsdos_impl::file_create(const std::vector<std::string> &path, const m
|
||||
}
|
||||
}
|
||||
if (!found_entry)
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
|
||||
err_t coco_rsdos_impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
std::error_condition coco_rsdos_impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
{
|
||||
if (path.size() != 1)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
const std::string &target = path[0];
|
||||
|
||||
std::optional<rsdos_dirent> result;
|
||||
@ -415,7 +415,7 @@ err_t coco_rsdos_impl::file_write(const std::vector<std::string> &path, const st
|
||||
iterate_directory_entries(callback);
|
||||
|
||||
if (!result)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
const size_t data_length = data.size();
|
||||
const u8 max_granule = maximum_granules();
|
||||
@ -446,7 +446,7 @@ err_t coco_rsdos_impl::file_write(const std::vector<std::string> &path, const st
|
||||
else
|
||||
{
|
||||
auto [err, next_granule] = claim_granule();
|
||||
if (err != ERR_OK)
|
||||
if (err)
|
||||
return err;
|
||||
write_granule_map(granule, next_granule);
|
||||
granule = next_granule;
|
||||
@ -470,7 +470,7 @@ err_t coco_rsdos_impl::file_write(const std::vector<std::string> &path, const st
|
||||
dir_block.w8(dir_file_index * DIRECTORY_ENTRY_SIZE + OFFSET_ASCII_FLAG, is_ascii(data) ? 0xff : 0x00);
|
||||
dir_block.w16b(dir_file_index * DIRECTORY_ENTRY_SIZE + OFFSET_LAST_SECTOR_BYTES, bytes_in_last_sector);
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
|
||||
@ -510,7 +510,7 @@ u8 coco_rsdos_impl::determine_file_type(const std::vector<u8> &data) const
|
||||
}
|
||||
|
||||
|
||||
std::pair<err_t, u8> coco_rsdos_impl::claim_granule()
|
||||
std::pair<std::error_condition, u8> coco_rsdos_impl::claim_granule()
|
||||
{
|
||||
// Granules are likely not assigned in this order on hardware.
|
||||
auto granule_block = read_sector(DIRECTORY_TRACK, 2);
|
||||
@ -519,10 +519,10 @@ std::pair<err_t, u8> coco_rsdos_impl::claim_granule()
|
||||
if (granule_block.r8(g) == 0xff)
|
||||
{
|
||||
granule_block.w8(g, FILE_LAST_GRANULE_INDICATOR);
|
||||
return std::make_pair(ERR_OK, g);
|
||||
return std::make_pair(std::error_condition(), g);
|
||||
}
|
||||
}
|
||||
return std::make_pair(ERR_NO_SPACE, 0);
|
||||
return std::make_pair(error::no_space, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -250,12 +250,12 @@ public:
|
||||
|
||||
// virtuals
|
||||
virtual meta_data volume_metadata() override;
|
||||
virtual std::pair<err_t, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<err_t, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<err_t, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual err_t file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
virtual err_t file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
virtual err_t remove(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual std::error_condition file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
virtual std::error_condition file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
virtual std::error_condition remove(const std::vector<std::string> &path) override;
|
||||
|
||||
// methods
|
||||
std::vector<u32> get_sectors_from_fat(const directory_entry &dirent) const;
|
||||
@ -291,13 +291,13 @@ private:
|
||||
std::optional<directory_entry> find_child(const directory_span ¤t_dir, std::string_view target) const;
|
||||
template <typename T> void iterate_directory_entries(const directory_span &dir, T &&callback) const;
|
||||
bool is_valid_short_filename(std::string const &filename);
|
||||
err_t build_direntry_filename(std::string const &filename, std::string &fname);
|
||||
err_t file_create_root(std::string &fname, u8 attributes = 0);
|
||||
err_t file_create_directory(directory_entry &dirent, std::string &fname, u8 attributes = 0);
|
||||
err_t file_create_sector(u32 sector, std::string &fname, u8 attributes);
|
||||
err_t initialize_directory(u32 directory_cluster, u32 parent_cluster);
|
||||
err_t initialize_directory_entry(fsblk_t::block_t &dirblk, u32 offset, const std::string_view &fname, u8 attributes, u32 start_cluster);
|
||||
err_t free_clusters(u32 start_cluster);
|
||||
std::error_condition build_direntry_filename(std::string const &filename, std::string &fname);
|
||||
std::error_condition file_create_root(std::string &fname, u8 attributes = 0);
|
||||
std::error_condition file_create_directory(directory_entry &dirent, std::string &fname, u8 attributes = 0);
|
||||
std::error_condition file_create_sector(u32 sector, std::string &fname, u8 attributes);
|
||||
std::error_condition initialize_directory(u32 directory_cluster, u32 parent_cluster);
|
||||
std::error_condition initialize_directory_entry(fsblk_t::block_t &dirblk, u32 offset, std::string_view fname, u8 attributes, u32 start_cluster);
|
||||
std::error_condition free_clusters(u32 start_cluster);
|
||||
void clear_cluster_sectors(u32 cluster, u8 fill_byte);
|
||||
u32 first_cluster_sector(u32 cluster);
|
||||
u32 get_next_cluster(u32 cluster);
|
||||
@ -603,13 +603,13 @@ meta_data impl::volume_metadata()
|
||||
// impl::metadata
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, meta_data> impl::metadata(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, meta_data> impl::metadata(const std::vector<std::string> &path)
|
||||
{
|
||||
std::optional<directory_entry> dirent = find_entity(path);
|
||||
if (!dirent)
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data());
|
||||
return std::make_pair(error::not_found, meta_data());
|
||||
|
||||
return std::make_pair(ERR_OK, dirent->metadata());
|
||||
return std::make_pair(std::error_condition(), dirent->metadata());
|
||||
}
|
||||
|
||||
|
||||
@ -617,11 +617,11 @@ std::pair<err_t, meta_data> impl::metadata(const std::vector<std::string> &path)
|
||||
// impl::directory_contents
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<dir_entry>> impl::directory_contents(const std::vector<std::string> &path)
|
||||
{
|
||||
directory_span::ptr dir = find_directory(path.begin(), path.end());
|
||||
if (!dir)
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<dir_entry>());
|
||||
return std::make_pair(error::not_found, std::vector<dir_entry>());
|
||||
|
||||
std::vector<dir_entry> results;
|
||||
auto const callback = [&results] (const directory_entry &dirent)
|
||||
@ -634,7 +634,7 @@ std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vec
|
||||
return false;
|
||||
};
|
||||
iterate_directory_entries(*dir, callback);
|
||||
return std::make_pair(ERR_OK, std::move(results));
|
||||
return std::make_pair(std::error_condition(), std::move(results));
|
||||
}
|
||||
|
||||
|
||||
@ -642,12 +642,14 @@ std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vec
|
||||
// impl::file_read
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, std::vector<u8>> impl::file_read(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<u8>> impl::file_read(const std::vector<std::string> &path)
|
||||
{
|
||||
// find the file
|
||||
std::optional<directory_entry> dirent = find_entity(path);
|
||||
if (!dirent || dirent->is_subdirectory())
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<u8>());
|
||||
if (!dirent)
|
||||
return std::make_pair(error::not_found, std::vector<u8>());
|
||||
if (dirent->is_subdirectory())
|
||||
return std::make_pair(error::invalid_name, std::vector<u8>());
|
||||
|
||||
// get the list of sectors for this file
|
||||
std::vector<u32> sectors = get_sectors_from_fat(*dirent);
|
||||
@ -664,7 +666,7 @@ std::pair<err_t, std::vector<u8>> impl::file_read(const std::vector<std::string>
|
||||
size_t length = std::min((size_t)dirent->file_size() - result.size(), (size_t)block.size());
|
||||
result.insert(result.end(), data, data + length);
|
||||
}
|
||||
return std::make_pair(ERR_OK, std::move(result));
|
||||
return std::make_pair(std::error_condition(), std::move(result));
|
||||
}
|
||||
|
||||
|
||||
@ -684,14 +686,14 @@ bool impl::is_valid_short_filename(std::string const &filename)
|
||||
}
|
||||
|
||||
|
||||
err_t impl::build_direntry_filename(std::string const &filename, std::string &fname)
|
||||
std::error_condition impl::build_direntry_filename(std::string const &filename, std::string &fname)
|
||||
{
|
||||
std::regex filename_regex("([A-Z0-9!#\\$%&\\(\\)\\-@^_`\\{\\}~]{0,8})(\\.([A-Z0-9!#\\$%&\\(\\)\\-@^_`\\{\\}~]{0,3}))?");
|
||||
std::smatch smatch;
|
||||
if (!std::regex_match(filename, smatch, filename_regex))
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
if (smatch.size() != 4)
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
|
||||
fname.resize(directory_entry::FNAME_LENGTH, ' ');
|
||||
|
||||
@ -701,16 +703,16 @@ err_t impl::build_direntry_filename(std::string const &filename, std::string &fn
|
||||
for (int j = 0; j < 3 && j < smatch.str(3).size(); j++)
|
||||
fname[8 + j] = smatch.str(3)[j];
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
|
||||
err_t impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
std::error_condition impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
{
|
||||
std::string filename = meta.get_string(meta_name::name, "");
|
||||
std::string fname;
|
||||
err_t err = build_direntry_filename(filename, fname);
|
||||
if (err != ERR_OK)
|
||||
std::error_condition err = build_direntry_filename(filename, fname);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (path.empty())
|
||||
@ -732,37 +734,37 @@ err_t impl::file_create(const std::vector<std::string> &path, const meta_data &m
|
||||
if (!dir_entry)
|
||||
{
|
||||
if (!is_valid_short_filename(path_part))
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
|
||||
std::string part_fname;
|
||||
err_t err = build_direntry_filename(path_part, part_fname);
|
||||
if (err != ERR_OK)
|
||||
std::error_condition err = build_direntry_filename(path_part, part_fname);
|
||||
if (err)
|
||||
return err;
|
||||
err = !parent_entry ?
|
||||
file_create_root(part_fname, directory_entry::ATTR_DIRECTORY) :
|
||||
file_create_directory(parent_entry.value(), part_fname, directory_entry::ATTR_DIRECTORY);
|
||||
if (err != ERR_OK)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dir_entry = find_entity(partial_path);
|
||||
if (!dir_entry)
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
|
||||
err = initialize_directory(dir_entry->start_cluster(), parent_entry ? parent_entry->start_cluster() : 0);
|
||||
if (err != ERR_OK)
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!dir_entry->is_subdirectory())
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
}
|
||||
parent_entry = dir_entry;
|
||||
}
|
||||
|
||||
dirent = find_entity(path);
|
||||
if (!dirent)
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
}
|
||||
|
||||
return file_create_directory(*dirent, fname);
|
||||
@ -770,7 +772,7 @@ err_t impl::file_create(const std::vector<std::string> &path, const meta_data &m
|
||||
}
|
||||
|
||||
|
||||
err_t impl::initialize_directory(u32 directory_cluster, u32 parent_cluster)
|
||||
std::error_condition impl::initialize_directory(u32 directory_cluster, u32 parent_cluster)
|
||||
{
|
||||
clear_cluster_sectors(directory_cluster, 0x00);
|
||||
|
||||
@ -780,23 +782,23 @@ err_t impl::initialize_directory(u32 directory_cluster, u32 parent_cluster)
|
||||
std::string dir_fname;
|
||||
dir_fname.resize(directory_entry::FNAME_LENGTH, ' ');
|
||||
dir_fname[0] = '.';
|
||||
err_t err = initialize_directory_entry(dirblk, 0, dir_fname, directory_entry::ATTR_DIRECTORY, directory_cluster);
|
||||
if (err != ERR_OK)
|
||||
std::error_condition err = initialize_directory_entry(dirblk, 0, dir_fname, directory_entry::ATTR_DIRECTORY, directory_cluster);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dir_fname[1] = '.';
|
||||
err = initialize_directory_entry(dirblk, directory_entry::SIZE, dir_fname, directory_entry::ATTR_DIRECTORY, parent_cluster);
|
||||
if (err != ERR_OK)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
|
||||
err_t impl::initialize_directory_entry(fsblk_t::block_t &dirblk, u32 offset, const std::string_view &fname, u8 attributes, u32 start_cluster)
|
||||
std::error_condition impl::initialize_directory_entry(fsblk_t::block_t &dirblk, u32 offset, std::string_view fname, u8 attributes, u32 start_cluster)
|
||||
{
|
||||
if (fname.size() != directory_entry::FNAME_LENGTH)
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
|
||||
for (int i = 0; i < directory_entry::SIZE; i += 4)
|
||||
dirblk.w32l(offset + i, 0);
|
||||
@ -808,33 +810,33 @@ err_t impl::initialize_directory_entry(fsblk_t::block_t &dirblk, u32 offset, con
|
||||
dirblk.w16l(offset + directory_entry::OFFSET_START_CLUSTER_HI, u16(start_cluster >> 16));
|
||||
dirblk.w16l(offset + directory_entry::OFFSET_START_CLUSTER, u16(start_cluster & 0xffff));
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
|
||||
err_t impl::file_create_root(std::string &fname, u8 attributes)
|
||||
std::error_condition impl::file_create_root(std::string &fname, u8 attributes)
|
||||
{
|
||||
const u32 first_directory_sector = m_starting_sector + m_reserved_sector_count + ((u32)m_file_allocation_table.size() / m_bytes_per_sector);
|
||||
const u32 directory_sector_count = (m_root_directory_size * directory_entry::SIZE) / m_bytes_per_sector;
|
||||
for (u32 sector = first_directory_sector; sector < first_directory_sector + directory_sector_count; sector++)
|
||||
{
|
||||
err_t err = file_create_sector(sector, fname, attributes);
|
||||
if (err != ERR_NOT_FOUND)
|
||||
std::error_condition err = file_create_sector(sector, fname, attributes);
|
||||
if (err != error::not_found)
|
||||
return err;
|
||||
}
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
}
|
||||
|
||||
|
||||
err_t impl::file_create_directory(directory_entry &dirent, std::string &fname, u8 attributes)
|
||||
std::error_condition impl::file_create_directory(directory_entry &dirent, std::string &fname, u8 attributes)
|
||||
{
|
||||
u32 current_cluster = dirent.start_cluster();
|
||||
do {
|
||||
const u32 first_sector = first_cluster_sector(current_cluster);
|
||||
for (int i = 0; i < m_sectors_per_cluster; i++)
|
||||
{
|
||||
err_t err = file_create_sector(first_sector + i, fname, attributes);
|
||||
if (err != ERR_NOT_FOUND)
|
||||
std::error_condition err = file_create_sector(first_sector + i, fname, attributes);
|
||||
if (err != error::not_found)
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -844,7 +846,7 @@ err_t impl::file_create_directory(directory_entry &dirent, std::string &fname, u
|
||||
{
|
||||
next_cluster = find_free_cluster();
|
||||
if (next_cluster == 0)
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
|
||||
set_next_cluster(current_cluster, next_cluster);
|
||||
set_next_cluster(next_cluster, m_last_cluster_indicator);
|
||||
@ -853,7 +855,7 @@ err_t impl::file_create_directory(directory_entry &dirent, std::string &fname, u
|
||||
}
|
||||
current_cluster = next_cluster;
|
||||
} while (current_cluster > FIRST_VALID_CLUSTER && current_cluster < m_last_valid_cluster);
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
}
|
||||
|
||||
|
||||
@ -878,8 +880,8 @@ void impl::clear_cluster_sectors(u32 cluster, u8 fill_byte)
|
||||
}
|
||||
|
||||
|
||||
// Returns ERR_NOT_FOUND when no room could be found to create the file in the sector.
|
||||
err_t impl::file_create_sector(u32 sector, std::string &fname, u8 attributes)
|
||||
// Returns error::not_found when no room could be found to create the file in the sector.
|
||||
std::error_condition impl::file_create_sector(u32 sector, std::string &fname, u8 attributes)
|
||||
{
|
||||
auto dirblk = m_blockdev.get(sector);
|
||||
for (u32 blkoffset = 0; blkoffset < m_bytes_per_sector; blkoffset += directory_entry::SIZE)
|
||||
@ -889,28 +891,28 @@ err_t impl::file_create_sector(u32 sector, std::string &fname, u8 attributes)
|
||||
{
|
||||
u32 start_cluster = find_free_cluster();
|
||||
if (start_cluster == 0)
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
set_next_cluster(start_cluster, m_last_cluster_indicator);
|
||||
|
||||
err_t err = initialize_directory_entry(dirblk, blkoffset, fname, attributes, start_cluster);
|
||||
if (err != ERR_OK)
|
||||
std::error_condition err = initialize_directory_entry(dirblk, blkoffset, fname, attributes, start_cluster);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
}
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
}
|
||||
|
||||
|
||||
err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
std::error_condition impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
{
|
||||
std::optional<directory_entry> dirent = find_entity(path);
|
||||
if (!dirent)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
if (dirent->is_subdirectory())
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
|
||||
u32 current_length = dirent->file_size();
|
||||
const size_t data_length = data.size();
|
||||
@ -925,13 +927,13 @@ err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u
|
||||
do {
|
||||
next_cluster = get_next_cluster(current_cluster);
|
||||
if (next_cluster < FIRST_VALID_CLUSTER)
|
||||
return ERR_INVALID;
|
||||
return error::invalid_block;
|
||||
} while (next_cluster < m_last_valid_cluster);
|
||||
for (int i = current_clusters; i < required_clusters; i++)
|
||||
{
|
||||
u32 free_cluster = find_free_cluster();
|
||||
if (free_cluster < FIRST_VALID_CLUSTER)
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
|
||||
set_next_cluster(current_cluster, free_cluster);
|
||||
set_next_cluster(free_cluster, m_last_cluster_indicator);
|
||||
@ -948,8 +950,8 @@ err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u
|
||||
u32 next_cluster = get_next_cluster(current_cluster);
|
||||
set_next_cluster(current_cluster, m_last_cluster_indicator);
|
||||
|
||||
err_t err = free_clusters(next_cluster);
|
||||
if (err != ERR_OK)
|
||||
std::error_condition err = free_clusters(next_cluster);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -969,41 +971,41 @@ err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u
|
||||
dirent->set_raw_modified_datetime(encode_now_fat_datetime());
|
||||
dirent->set_file_size(data_length);
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
|
||||
err_t impl::remove(const std::vector<std::string> &path)
|
||||
std::error_condition impl::remove(const std::vector<std::string> &path)
|
||||
{
|
||||
if (path.size() != 0)
|
||||
return ERR_UNSUPPORTED;
|
||||
return error::unsupported;
|
||||
|
||||
std::optional<directory_entry> dirent = find_entity(path);
|
||||
if (!dirent)
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
|
||||
// Removing directories is not supported yet
|
||||
if (dirent->is_subdirectory())
|
||||
return ERR_UNSUPPORTED;
|
||||
return error::unsupported;
|
||||
|
||||
dirent->mark_deleted();
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
|
||||
err_t impl::free_clusters(u32 start_cluster)
|
||||
std::error_condition impl::free_clusters(u32 start_cluster)
|
||||
{
|
||||
while (start_cluster < m_last_valid_cluster)
|
||||
{
|
||||
if (start_cluster < FIRST_VALID_CLUSTER)
|
||||
return ERR_INVALID;
|
||||
return error::invalid_block;
|
||||
|
||||
u32 next_cluster = get_next_cluster(start_cluster);
|
||||
set_next_cluster(start_cluster, 0);
|
||||
start_cluster = next_cluster;
|
||||
}
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
|
@ -107,17 +107,17 @@ namespace {
|
||||
|
||||
virtual meta_data volume_metadata() override;
|
||||
|
||||
virtual std::pair<err_t, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
|
||||
virtual std::pair<err_t, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
|
||||
virtual err_t file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
virtual std::error_condition file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
|
||||
virtual std::pair<err_t, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
|
||||
virtual err_t file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
virtual std::error_condition file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
|
||||
virtual err_t format(const meta_data &meta) override;
|
||||
virtual std::error_condition format(const meta_data &meta) override;
|
||||
|
||||
private:
|
||||
// Map of used/free sectors
|
||||
@ -202,7 +202,7 @@ namespace {
|
||||
|
||||
using dir_t = std::vector<entry>;
|
||||
|
||||
err_t parse_filename(const std::string& name, std::string& basename, int& bpr, u8& file_type) const;
|
||||
std::error_condition parse_filename(const std::string& name, std::string& basename, int& bpr, u8& file_type) const;
|
||||
bool validate_filename(const std::string& s) const;
|
||||
void ensure_dir_loaded();
|
||||
std::pair<dir_t, sect_map> decode_dir() const;
|
||||
@ -323,10 +323,10 @@ meta_data hp98x5_impl::volume_metadata()
|
||||
return res;
|
||||
}
|
||||
|
||||
std::pair<err_t, meta_data> hp98x5_impl::metadata(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, meta_data> hp98x5_impl::metadata(const std::vector<std::string> &path)
|
||||
{
|
||||
if (path.size() != 1) {
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data{});
|
||||
return std::make_pair(error::not_found, meta_data{});
|
||||
}
|
||||
|
||||
std::string basename;
|
||||
@ -334,21 +334,21 @@ std::pair<err_t, meta_data> hp98x5_impl::metadata(const std::vector<std::string>
|
||||
u8 file_type;
|
||||
|
||||
auto err = parse_filename(path.front(), basename, bpr, file_type);
|
||||
if (err != ERR_OK) {
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data{});
|
||||
if (err) {
|
||||
return std::make_pair(error::not_found, meta_data{});
|
||||
}
|
||||
|
||||
ensure_dir_loaded();
|
||||
auto it = scan_dir(m_dir, basename);
|
||||
if (it == m_dir.end()) {
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data{});
|
||||
return std::make_pair(error::not_found, meta_data{});
|
||||
}
|
||||
|
||||
auto meta = get_metadata(*it);
|
||||
return std::make_pair(ERR_OK, std::move(meta));
|
||||
return std::make_pair(std::error_condition(), std::move(meta));
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<dir_entry>> hp98x5_impl::directory_contents(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<dir_entry>> hp98x5_impl::directory_contents(const std::vector<std::string> &path)
|
||||
{
|
||||
if (path.empty()) {
|
||||
ensure_dir_loaded();
|
||||
@ -360,16 +360,16 @@ std::pair<err_t, std::vector<dir_entry>> hp98x5_impl::directory_contents(const s
|
||||
dir_entries.emplace_back(dir_entry_type::file, std::move(meta));
|
||||
}
|
||||
}
|
||||
return std::make_pair(ERR_OK, dir_entries);
|
||||
return std::make_pair(std::error_condition(), dir_entries);
|
||||
} else {
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<dir_entry>{});
|
||||
return std::make_pair(error::not_found, std::vector<dir_entry>{});
|
||||
}
|
||||
}
|
||||
|
||||
err_t hp98x5_impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
std::error_condition hp98x5_impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
{
|
||||
if (!path.empty()) {
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
}
|
||||
|
||||
auto name = meta.get_string(meta_name::name);
|
||||
@ -381,9 +381,13 @@ err_t hp98x5_impl::file_create(const std::vector<std::string> &path, const meta_
|
||||
// Parse & validate filename
|
||||
// Extension must be specified
|
||||
auto err = parse_filename(name, basename, bpr, file_type);
|
||||
if (err != ERR_OK || file_type == NO_FILE_TYPE) {
|
||||
return ERR_INVALID;
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
if (file_type == NO_FILE_TYPE) {
|
||||
return error::invalid_name;
|
||||
}
|
||||
|
||||
if (bpr < 0) {
|
||||
// Use default bpr when not specified
|
||||
bpr = DEF_BPR;
|
||||
@ -393,7 +397,7 @@ err_t hp98x5_impl::file_create(const std::vector<std::string> &path, const meta_
|
||||
ensure_dir_loaded();
|
||||
auto it = scan_dir(m_dir, basename);
|
||||
if (it != m_dir.end()) {
|
||||
return ERR_INVALID;
|
||||
return error::already_exists;
|
||||
}
|
||||
|
||||
// Find a free entry in directory
|
||||
@ -404,7 +408,7 @@ err_t hp98x5_impl::file_create(const std::vector<std::string> &path, const meta_
|
||||
m_dir.emplace_back(entry());
|
||||
it2 = m_dir.end() - 1;
|
||||
} else {
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
}
|
||||
}
|
||||
|
||||
@ -421,13 +425,13 @@ err_t hp98x5_impl::file_create(const std::vector<std::string> &path, const meta_
|
||||
|
||||
store_dir_map();
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<u8>> hp98x5_impl::file_read(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<u8>> hp98x5_impl::file_read(const std::vector<std::string> &path)
|
||||
{
|
||||
if (path.size() != 1) {
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<u8>{});
|
||||
return std::make_pair(error::not_found, std::vector<u8>{});
|
||||
}
|
||||
std::string basename;
|
||||
int bpr;
|
||||
@ -435,10 +439,10 @@ std::pair<err_t, std::vector<u8>> hp98x5_impl::file_read(const std::vector<std::
|
||||
|
||||
auto err = parse_filename(path.front(), basename, bpr, file_type);
|
||||
|
||||
if (err == ERR_OK) {
|
||||
if (!err) {
|
||||
auto it = find_file(basename, bpr, file_type);
|
||||
if (it == m_dir.end()) {
|
||||
err = ERR_NOT_FOUND;
|
||||
err = error::not_found;
|
||||
} else {
|
||||
auto file_data = get_sector_range(it->m_1st_sect, it->m_sectors);
|
||||
if (file_type == TEXT_TYPE) {
|
||||
@ -446,16 +450,16 @@ std::pair<err_t, std::vector<u8>> hp98x5_impl::file_read(const std::vector<std::
|
||||
} else {
|
||||
file_data.resize(it->m_size);
|
||||
}
|
||||
return std::make_pair(ERR_OK, std::move(file_data));
|
||||
return std::make_pair(std::error_condition(), std::move(file_data));
|
||||
}
|
||||
}
|
||||
return std::make_pair(err, std::vector<u8>{});
|
||||
}
|
||||
|
||||
err_t hp98x5_impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
std::error_condition hp98x5_impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
{
|
||||
if (path.size() != 1) {
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
}
|
||||
|
||||
std::string basename;
|
||||
@ -463,13 +467,13 @@ err_t hp98x5_impl::file_write(const std::vector<std::string> &path, const std::v
|
||||
u8 file_type;
|
||||
|
||||
auto err = parse_filename(path.front(), basename, bpr, file_type);
|
||||
if (err != ERR_OK) {
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
// Check that file already exists
|
||||
auto it = find_file(basename, bpr, file_type);
|
||||
if (it == m_dir.end()) {
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
}
|
||||
|
||||
// De-allocate current blocks
|
||||
@ -488,7 +492,7 @@ err_t hp98x5_impl::file_write(const std::vector<std::string> &path, const std::v
|
||||
// Allocate space
|
||||
it->m_sectors = (data_ptr->size() + SECTOR_SIZE - 1) / SECTOR_SIZE;
|
||||
if (!allocate(it->m_sectors, it->m_1st_sect)) {
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
}
|
||||
|
||||
// Store file content
|
||||
@ -498,10 +502,10 @@ err_t hp98x5_impl::file_write(const std::vector<std::string> &path, const std::v
|
||||
// Update directory & map
|
||||
store_dir_map();
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
err_t hp98x5_impl::format(const meta_data &meta)
|
||||
std::error_condition hp98x5_impl::format(const meta_data &meta)
|
||||
{
|
||||
bool is_ds = m_blockdev.block_count() == DS_SECTORS;
|
||||
|
||||
@ -553,10 +557,10 @@ err_t hp98x5_impl::format(const meta_data &meta)
|
||||
|
||||
store_dir_map();
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
err_t hp98x5_impl::parse_filename(const std::string& name, std::string& basename, int& bpr, u8& file_type) const
|
||||
std::error_condition hp98x5_impl::parse_filename(const std::string& name, std::string& basename, int& bpr, u8& file_type) const
|
||||
{
|
||||
// General form of filenames:
|
||||
// basename[[.&bpr].ext]
|
||||
@ -579,18 +583,18 @@ err_t hp98x5_impl::parse_filename(const std::string& name, std::string& basename
|
||||
if (p2 != std::string::npos) {
|
||||
// [p1+1 p2) should have "&bpr"
|
||||
if (name[ p1 + 1 ] != '&') {
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
}
|
||||
if (!std::all_of(name.cbegin() + p1 + 2, name.cbegin() + p2, [](char c) { return c >= '0' && c <= '9'; })) {
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
}
|
||||
try {
|
||||
bpr = std::stoul(std::string{name, p1 + 2, p2 - p1 - 2});
|
||||
} catch (...) {
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
}
|
||||
if (bpr < 4 || bpr > 32767 || (bpr & 1) != 0) {
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
}
|
||||
} else {
|
||||
p2 = p1;
|
||||
@ -607,7 +611,7 @@ err_t hp98x5_impl::parse_filename(const std::string& name, std::string& basename
|
||||
}
|
||||
}
|
||||
if (file_type == NO_FILE_TYPE) {
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -615,9 +619,9 @@ err_t hp98x5_impl::parse_filename(const std::string& name, std::string& basename
|
||||
// [0 p1) has "basename"
|
||||
basename = std::string(name, 0, p1);
|
||||
if (validate_filename(basename)) {
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
} else {
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,9 +74,9 @@ public:
|
||||
virtual ~impl() = default;
|
||||
|
||||
virtual meta_data volume_metadata() override;
|
||||
virtual std::pair<err_t, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<err_t, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<err_t, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
|
||||
private:
|
||||
fsblk_t::block_t read_sector(u32 starting_sector) const;
|
||||
@ -84,7 +84,7 @@ private:
|
||||
void iterate_directory_entries(const std::function<bool(const hplif_dirent &dirent)> &callback) const;
|
||||
util::arbitrary_datetime decode_datetime(const hplif_time *time) const;
|
||||
meta_data metadata_from_dirent(const hplif_dirent &dirent) const;
|
||||
err_t format(const meta_data &meta) override;
|
||||
std::error_condition format(const meta_data &meta) override;
|
||||
};
|
||||
|
||||
// methods
|
||||
@ -265,13 +265,13 @@ meta_data impl::volume_metadata()
|
||||
// impl::metadata
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, meta_data> impl::metadata(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, meta_data> impl::metadata(const std::vector<std::string> &path)
|
||||
{
|
||||
std::optional<hplif_dirent> dirent = dirent_from_path(path);
|
||||
if (!dirent)
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data());
|
||||
return std::make_pair(error::not_found, meta_data());
|
||||
|
||||
return std::make_pair(ERR_OK, metadata_from_dirent(*dirent));
|
||||
return std::make_pair(std::error_condition(), metadata_from_dirent(*dirent));
|
||||
}
|
||||
|
||||
|
||||
@ -279,7 +279,7 @@ std::pair<err_t, meta_data> impl::metadata(const std::vector<std::string> &path)
|
||||
// impl::directory_contents
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<dir_entry>> impl::directory_contents(const std::vector<std::string> &path)
|
||||
{
|
||||
std::vector<dir_entry> results;
|
||||
auto callback = [this, &results](const hplif_dirent &ent)
|
||||
@ -288,7 +288,7 @@ std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vec
|
||||
return false;
|
||||
};
|
||||
iterate_directory_entries(callback);
|
||||
return std::make_pair(ERR_OK, std::move(results));
|
||||
return std::make_pair(std::error_condition(), std::move(results));
|
||||
}
|
||||
|
||||
|
||||
@ -296,12 +296,12 @@ std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vec
|
||||
// impl::file_read
|
||||
//-------------------------------------------------
|
||||
|
||||
std::pair<err_t, std::vector<u8>> impl::file_read(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<u8>> impl::file_read(const std::vector<std::string> &path)
|
||||
{
|
||||
// find the file
|
||||
std::optional<hplif_dirent> dirent = dirent_from_path(path);
|
||||
if (!dirent)
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<u8>());
|
||||
return std::make_pair(error::not_found, std::vector<u8>());
|
||||
|
||||
// and get the data
|
||||
u32 sector_count = big_endianize_int32(dirent->m_sector_count);
|
||||
@ -316,7 +316,7 @@ std::pair<err_t, std::vector<u8>> impl::file_read(const std::vector<std::string>
|
||||
while (iter.next())
|
||||
result.insert(result.end(), (const u8 *)iter.data(), (const u8 *)iter.data() + 256);
|
||||
|
||||
return std::make_pair(ERR_OK, std::move(result));
|
||||
return std::make_pair(std::error_condition(), std::move(result));
|
||||
}
|
||||
|
||||
|
||||
@ -468,7 +468,7 @@ const void *impl::block_iterator::data() const
|
||||
// impl::format
|
||||
//-------------------------------------------------
|
||||
|
||||
err_t impl::format(const meta_data &meta)
|
||||
std::error_condition impl::format(const meta_data &meta)
|
||||
{
|
||||
std::string volume_name = meta.get_string(meta_name::name, "B9826 ");
|
||||
fsblk_t::block_t block = m_blockdev.get(0);
|
||||
@ -484,7 +484,7 @@ err_t impl::format(const meta_data &meta)
|
||||
block.w16b(12, 0x1000); // LIF identifier
|
||||
block.w32b(16, 14); // directory size
|
||||
block.w16b(20, 1); // LIF version
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
|
@ -45,17 +45,17 @@ namespace {
|
||||
|
||||
virtual meta_data volume_metadata() override;
|
||||
|
||||
virtual std::pair<err_t, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
|
||||
virtual std::pair<err_t, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
|
||||
virtual err_t file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
virtual std::error_condition file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
|
||||
virtual std::pair<err_t, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
|
||||
virtual err_t file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
virtual std::error_condition file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
|
||||
virtual err_t format(const meta_data &meta) override;
|
||||
virtual std::error_condition format(const meta_data &meta) override;
|
||||
|
||||
private:
|
||||
using sect_map = std::bitset<DD_SECTORS>;
|
||||
@ -225,24 +225,24 @@ meta_data isis_impl::volume_metadata()
|
||||
return res;
|
||||
}
|
||||
|
||||
std::pair<err_t, meta_data> isis_impl::metadata(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, meta_data> isis_impl::metadata(const std::vector<std::string> &path)
|
||||
{
|
||||
if (path.size() != 1) {
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data{});
|
||||
return std::make_pair(error::not_found, meta_data{});
|
||||
}
|
||||
|
||||
ensure_dir_loaded();
|
||||
|
||||
auto it = scan_dir(path.front());
|
||||
if (it == m_dir.end()) {
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data{});
|
||||
return std::make_pair(error::not_found, meta_data{});
|
||||
}
|
||||
|
||||
auto meta = get_metadata(*it);
|
||||
return std::make_pair(ERR_OK, std::move(meta));
|
||||
return std::make_pair(std::error_condition(), std::move(meta));
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<dir_entry>> isis_impl::directory_contents(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<dir_entry>> isis_impl::directory_contents(const std::vector<std::string> &path)
|
||||
{
|
||||
if (path.empty()) {
|
||||
ensure_dir_loaded();
|
||||
@ -254,16 +254,16 @@ std::pair<err_t, std::vector<dir_entry>> isis_impl::directory_contents(const std
|
||||
dir_entries.emplace_back(dir_entry_type::file, std::move(meta));
|
||||
}
|
||||
}
|
||||
return std::make_pair(ERR_OK, dir_entries);
|
||||
return std::make_pair(std::error_condition(), dir_entries);
|
||||
} else {
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<dir_entry>{});
|
||||
return std::make_pair(error::not_found, std::vector<dir_entry>{});
|
||||
}
|
||||
}
|
||||
|
||||
err_t isis_impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
std::error_condition isis_impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
{
|
||||
if (!path.empty()) {
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
}
|
||||
|
||||
auto name = meta.get_string(meta_name::name);
|
||||
@ -274,13 +274,13 @@ err_t isis_impl::file_create(const std::vector<std::string> &path, const meta_da
|
||||
std::string filename = name.substr(0, pt_pos);
|
||||
|
||||
if (filename.size() < 1 || filename.size() > 6 || !validate_filename(filename)) {
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
}
|
||||
|
||||
if (pt_pos != std::string::npos) {
|
||||
auto ext = name.substr(pt_pos + 1);
|
||||
if (ext.size() < 1 || ext.size() > 3 || !validate_filename(ext)) {
|
||||
return ERR_INVALID;
|
||||
return error::invalid_name;
|
||||
}
|
||||
filename.push_back('.');
|
||||
filename += ext;
|
||||
@ -288,14 +288,14 @@ err_t isis_impl::file_create(const std::vector<std::string> &path, const meta_da
|
||||
|
||||
// Check that file can be created by user
|
||||
if (!user_can_create(filename)) {
|
||||
return ERR_INVALID;
|
||||
return error::unsupported;
|
||||
}
|
||||
|
||||
// Check that file doesn't exist
|
||||
ensure_dir_loaded();
|
||||
auto it = scan_dir(filename);
|
||||
if (it != m_dir.end()) {
|
||||
return ERR_INVALID;
|
||||
return error::already_exists;
|
||||
}
|
||||
|
||||
// Find a free entry in directory
|
||||
@ -305,13 +305,13 @@ err_t isis_impl::file_create(const std::vector<std::string> &path, const meta_da
|
||||
}
|
||||
}
|
||||
if (it == m_dir.end()) {
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
}
|
||||
|
||||
// Allocate space
|
||||
lba_list lbas;
|
||||
if (!allocate(0, lbas)) {
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
}
|
||||
|
||||
// Fill dir entry
|
||||
@ -326,42 +326,42 @@ err_t isis_impl::file_create(const std::vector<std::string> &path, const meta_da
|
||||
// Update directory & map
|
||||
store_dir_map();
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<u8>> isis_impl::file_read(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<u8>> isis_impl::file_read(const std::vector<std::string> &path)
|
||||
{
|
||||
const auto& [ lbas, size ] = find_file(path);
|
||||
if (lbas != nullptr) {
|
||||
auto file_data = get_file_content(*lbas, size);
|
||||
return std::make_pair(ERR_OK, std::move(file_data));
|
||||
return std::make_pair(std::error_condition(), std::move(file_data));
|
||||
}
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<u8>{});
|
||||
return std::make_pair(error::not_found, std::vector<u8>{});
|
||||
}
|
||||
|
||||
err_t isis_impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
std::error_condition isis_impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
{
|
||||
if (path.size() != 1) {
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
}
|
||||
|
||||
// Check that file is user-writeable
|
||||
const auto& filename = path.front();
|
||||
if (!user_can_write(filename)) {
|
||||
return ERR_INVALID;
|
||||
return error::unsupported;
|
||||
}
|
||||
|
||||
// ISIS.T0 can only be 2944 bytes long
|
||||
bool is_t0 = filename == ISIS_T0;
|
||||
if (is_t0 && data.size() != ISIS_T0_SIZE) {
|
||||
return ERR_INVALID;
|
||||
return error::incorrect_size;
|
||||
}
|
||||
|
||||
// Check that file already exists
|
||||
ensure_dir_loaded();
|
||||
auto it = scan_dir(filename);
|
||||
if (it == m_dir.end()) {
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
}
|
||||
|
||||
// De-allocate current blocks
|
||||
@ -372,7 +372,7 @@ err_t isis_impl::file_write(const std::vector<std::string> &path, const std::vec
|
||||
if (is_t0) {
|
||||
allocate_t0(lbas);
|
||||
} else if (!allocate(data.size(), lbas)) {
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
}
|
||||
|
||||
// Update dir entry
|
||||
@ -386,10 +386,10 @@ err_t isis_impl::file_write(const std::vector<std::string> &path, const std::vec
|
||||
// Update directory & map
|
||||
store_dir_map();
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
err_t isis_impl::format(const meta_data &meta)
|
||||
std::error_condition isis_impl::format(const meta_data &meta)
|
||||
{
|
||||
entry dir_e;
|
||||
dir_e.m_alloc_state = DIR_IN_USE;
|
||||
@ -442,7 +442,7 @@ err_t isis_impl::format(const meta_data &meta)
|
||||
}
|
||||
|
||||
store_dir_map();
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
isis_impl::lba_t isis_impl::ts_2_lba(const track_sect &ts) const
|
||||
|
@ -56,20 +56,20 @@ public:
|
||||
virtual ~oric_jasmin_impl() = default;
|
||||
|
||||
virtual meta_data volume_metadata() override;
|
||||
virtual err_t volume_metadata_change(const meta_data &info) override;
|
||||
virtual std::pair<err_t, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual err_t metadata_change(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
virtual std::error_condition volume_metadata_change(const meta_data &info) override;
|
||||
virtual std::pair<std::error_condition, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::error_condition metadata_change(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
|
||||
virtual std::pair<err_t, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual err_t rename(const std::vector<std::string> &opath, const std::vector<std::string> &npath) override;
|
||||
virtual err_t remove(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::error_condition rename(const std::vector<std::string> &opath, const std::vector<std::string> &npath) override;
|
||||
virtual std::error_condition remove(const std::vector<std::string> &path) override;
|
||||
|
||||
virtual err_t file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
virtual std::error_condition file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
|
||||
virtual std::pair<err_t, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual err_t file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
virtual std::pair<std::error_condition, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual std::error_condition file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
|
||||
virtual err_t format(const meta_data &meta) override;
|
||||
virtual std::error_condition format(const meta_data &meta) override;
|
||||
|
||||
static bool validate_filename(std::string name);
|
||||
|
||||
@ -196,7 +196,7 @@ bool oric_jasmin_impl::validate_filename(std::string name)
|
||||
return name.size() > 0 && name.size() <= 8;
|
||||
}
|
||||
|
||||
err_t oric_jasmin_impl::format(const meta_data &meta)
|
||||
std::error_condition oric_jasmin_impl::format(const meta_data &meta)
|
||||
{
|
||||
std::string volume_name = meta.get_string(meta_name::name, "UNTITLED");
|
||||
u32 blocks = m_blockdev.block_count();
|
||||
@ -229,7 +229,7 @@ err_t oric_jasmin_impl::format(const meta_data &meta)
|
||||
bdir.w16l(0, 0x0000);
|
||||
bdir.w16l(2, 0x0000);
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
meta_data oric_jasmin_impl::volume_metadata()
|
||||
@ -244,14 +244,14 @@ meta_data oric_jasmin_impl::volume_metadata()
|
||||
return res;
|
||||
}
|
||||
|
||||
err_t oric_jasmin_impl::volume_metadata_change(const meta_data &meta)
|
||||
std::error_condition oric_jasmin_impl::volume_metadata_change(const meta_data &meta)
|
||||
{
|
||||
if(meta.has(meta_name::name)) {
|
||||
std::string volume_name = meta.get_string(meta_name::name);
|
||||
volume_name.resize(8, ' ');
|
||||
m_blockdev.get(20*17).wstr(0xf8, volume_name);
|
||||
}
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
std::string oric_jasmin_impl::file_name_prepare(std::string fname)
|
||||
@ -344,27 +344,27 @@ std::tuple<fsblk_t::block_t, u32, bool> oric_jasmin_impl::file_find(std::string
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<err_t, meta_data> oric_jasmin_impl::metadata(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, meta_data> oric_jasmin_impl::metadata(const std::vector<std::string> &path)
|
||||
{
|
||||
if(path.size() != 1)
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data());
|
||||
return std::make_pair(error::not_found, meta_data());
|
||||
|
||||
auto [bdir, off, sys] = file_find(path[0]);
|
||||
std::ignore = sys;
|
||||
if(!off)
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data());
|
||||
return std::make_pair(error::not_found, meta_data());
|
||||
|
||||
return std::make_pair(ERR_OK, file_metadata(bdir.rodata() + off));
|
||||
return std::make_pair(std::error_condition(), file_metadata(bdir.rodata() + off));
|
||||
}
|
||||
|
||||
err_t oric_jasmin_impl::metadata_change(const std::vector<std::string> &path, const meta_data &meta)
|
||||
std::error_condition oric_jasmin_impl::metadata_change(const std::vector<std::string> &path, const meta_data &meta)
|
||||
{
|
||||
if(path.size() != 1)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
auto [bdir, off, sys] = file_find(path[0]);
|
||||
if(!off)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
u8 *entry = bdir.data() + off;
|
||||
if(meta.has(meta_name::locked))
|
||||
@ -376,19 +376,19 @@ err_t oric_jasmin_impl::metadata_change(const std::vector<std::string> &path, co
|
||||
if(!sys && meta.has(meta_name::loading_address))
|
||||
m_blockdev.get(cs_to_block(get_u16be(entry))).w16l(2, meta.get_number(meta_name::loading_address));
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<dir_entry>> oric_jasmin_impl::directory_contents(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<dir_entry>> oric_jasmin_impl::directory_contents(const std::vector<std::string> &path)
|
||||
{
|
||||
std::pair<err_t, std::vector<dir_entry>> res;
|
||||
std::pair<std::error_condition, std::vector<dir_entry>> res;
|
||||
|
||||
if(path.size() != 0) {
|
||||
res.first = ERR_NOT_FOUND;
|
||||
res.first = error::not_found;
|
||||
return res;
|
||||
}
|
||||
|
||||
res.first = ERR_OK;
|
||||
res.first = std::error_condition();
|
||||
|
||||
auto bdir = m_blockdev.get(20*17+1);
|
||||
for(;;) {
|
||||
@ -408,30 +408,30 @@ std::pair<err_t, std::vector<dir_entry>> oric_jasmin_impl::directory_contents(co
|
||||
return res;
|
||||
}
|
||||
|
||||
err_t oric_jasmin_impl::rename(const std::vector<std::string> &opath, const std::vector<std::string> &npath)
|
||||
std::error_condition oric_jasmin_impl::rename(const std::vector<std::string> &opath, const std::vector<std::string> &npath)
|
||||
{
|
||||
if(opath.size() != 1 || npath.size() != 1)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
auto [bdir, off, sys] = file_find(opath[0]);
|
||||
std::ignore = sys;
|
||||
if(!off)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
wstr(bdir.data() + off + 0x03, file_name_prepare(npath[0]));
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
err_t oric_jasmin_impl::remove(const std::vector<std::string> &path)
|
||||
std::error_condition oric_jasmin_impl::remove(const std::vector<std::string> &path)
|
||||
{
|
||||
return ERR_UNSUPPORTED;
|
||||
return error::unsupported;
|
||||
}
|
||||
|
||||
err_t oric_jasmin_impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
std::error_condition oric_jasmin_impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
{
|
||||
if(path.size() != 0)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
// One block of sector list, one block of data
|
||||
u32 nb = 2;
|
||||
@ -457,7 +457,7 @@ err_t oric_jasmin_impl::file_create(const std::vector<std::string> &path, const
|
||||
found:
|
||||
auto block = allocate_blocks(nb);
|
||||
if(block.empty())
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
|
||||
auto sblk = m_blockdev.get(cs_to_block(block[0]));
|
||||
sblk.w16b(0, 0xff00); // Next sector
|
||||
@ -480,19 +480,19 @@ err_t oric_jasmin_impl::file_create(const std::vector<std::string> &path, const
|
||||
bdir.w8 (off+0x0f, meta.get_flag(meta_name::sequential, true) ? 'S' : 'D');
|
||||
bdir.w16l(off+0x10, 2); // 2 sectors for an empty file
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<u8>> oric_jasmin_impl::file_read(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<u8>> oric_jasmin_impl::file_read(const std::vector<std::string> &path)
|
||||
{
|
||||
std::vector<u8> data;
|
||||
|
||||
if(path.size() != 1)
|
||||
return std::make_pair(ERR_NOT_FOUND, data);
|
||||
return std::make_pair(error::not_found, data);
|
||||
|
||||
auto [bdir, off, sys] = file_find(path[0]);
|
||||
if(!off)
|
||||
return std::make_pair(ERR_NOT_FOUND, data);
|
||||
return std::make_pair(error::not_found, data);
|
||||
|
||||
if(sys) {
|
||||
data.resize(0x3e00);
|
||||
@ -527,21 +527,21 @@ std::pair<err_t, std::vector<u8>> oric_jasmin_impl::file_read(const std::vector<
|
||||
data.resize(length);
|
||||
}
|
||||
|
||||
return std::make_pair(ERR_OK, data);
|
||||
return std::make_pair(std::error_condition(), data);
|
||||
}
|
||||
|
||||
err_t oric_jasmin_impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
std::error_condition oric_jasmin_impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
{
|
||||
if(path.size() != 1)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
auto [bdir, off, sys] = file_find(path[0]);
|
||||
if(!off)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
if(sys) {
|
||||
if(data.size() != 0x3e00)
|
||||
return ERR_INVALID;
|
||||
return error::incorrect_size;
|
||||
|
||||
for(u32 i=0; i != 0x3e; i++)
|
||||
m_blockdev.get(i).copy(0, data.data() + i * 256, 256);
|
||||
@ -558,7 +558,7 @@ err_t oric_jasmin_impl::file_write(const std::vector<std::string> &path, const s
|
||||
|
||||
// Enough space?
|
||||
if(cur_ns < need_ns && free_block_count() < need_ns - cur_ns)
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
|
||||
u16 load_address = 0;
|
||||
std::vector<u16> tofree;
|
||||
@ -603,7 +603,7 @@ err_t oric_jasmin_impl::file_write(const std::vector<std::string> &path, const s
|
||||
put_u16le(entry + 0x10, need_ns);
|
||||
put_u16be(entry + 0x00, blocks[0]);
|
||||
}
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
std::vector<u16> oric_jasmin_impl::allocate_blocks(u32 count)
|
||||
|
@ -26,14 +26,14 @@ public:
|
||||
virtual ~prodos_impl() = default;
|
||||
|
||||
virtual meta_data volume_metadata() override;
|
||||
virtual std::pair<err_t, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
|
||||
virtual std::pair<err_t, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
|
||||
virtual std::pair<err_t, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<err_t, std::vector<u8>> file_rsrc_read(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<u8>> file_rsrc_read(const std::vector<std::string> &path) override;
|
||||
|
||||
virtual err_t format(const meta_data &meta) override;
|
||||
virtual std::error_condition format(const meta_data &meta) override;
|
||||
|
||||
private:
|
||||
static const u8 boot[512];
|
||||
@ -41,7 +41,7 @@ private:
|
||||
|
||||
std::tuple<fsblk_t::block_t, u32> path_find_step(const std::string &name, u16 block);
|
||||
std::tuple<fsblk_t::block_t, u32, bool> path_find(const std::vector<std::string> &path);
|
||||
std::pair<err_t, std::vector<u8>> any_read(u8 type, u16 block, u32 length);
|
||||
std::pair<std::error_condition, std::vector<u8>> any_read(u8 type, u16 block, u32 length);
|
||||
};
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ std::vector<meta_description> prodos_image::directory_meta_description() const
|
||||
return res;
|
||||
}
|
||||
|
||||
err_t prodos_impl::format(const meta_data &meta)
|
||||
std::error_condition prodos_impl::format(const meta_data &meta)
|
||||
{
|
||||
std::string volume_name = meta.get_string(meta_name::name, "UNTITLED");
|
||||
u32 blocks = m_blockdev.block_count();
|
||||
@ -274,7 +274,7 @@ err_t prodos_impl::format(const meta_data &meta)
|
||||
memset(fdata+sb, 0xff, eb-sb-1);
|
||||
}
|
||||
}
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
prodos_impl::prodos_impl(fsblk_t &blockdev) : filesystem_t(blockdev, 512)
|
||||
@ -309,7 +309,7 @@ meta_data prodos_impl::volume_metadata()
|
||||
return res;
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<dir_entry>> prodos_impl::directory_contents(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<dir_entry>> prodos_impl::directory_contents(const std::vector<std::string> &path)
|
||||
{
|
||||
u16 block;
|
||||
if(path.empty())
|
||||
@ -318,7 +318,7 @@ std::pair<err_t, std::vector<dir_entry>> prodos_impl::directory_contents(const s
|
||||
else {
|
||||
auto [blk, off, dir] = path_find(path);
|
||||
if(!off || !dir)
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<dir_entry>());
|
||||
return std::make_pair(error::not_found, std::vector<dir_entry>());
|
||||
block = blk.r16l(off+0x11);
|
||||
}
|
||||
|
||||
@ -356,7 +356,7 @@ std::pair<err_t, std::vector<dir_entry>> prodos_impl::directory_contents(const s
|
||||
if(block >= m_blockdev.block_count())
|
||||
break;
|
||||
} while(block);
|
||||
return std::make_pair(ERR_OK, res);
|
||||
return std::make_pair(std::error_condition(), res);
|
||||
}
|
||||
|
||||
std::tuple<fsblk_t::block_t, u32> prodos_impl::path_find_step(const std::string &name, u16 block)
|
||||
@ -396,15 +396,15 @@ std::tuple<fsblk_t::block_t, u32, bool> prodos_impl::path_find(const std::vector
|
||||
}
|
||||
|
||||
|
||||
std::pair<err_t, meta_data> prodos_impl::metadata(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, meta_data> prodos_impl::metadata(const std::vector<std::string> &path)
|
||||
{
|
||||
if(path.size() == 0)
|
||||
return std::make_pair(ERR_OK, meta_data());
|
||||
return std::make_pair(std::error_condition(), meta_data());
|
||||
|
||||
auto [blk, off, dir] = path_find(path);
|
||||
|
||||
if(!off)
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data());
|
||||
return std::make_pair(error::not_found, meta_data());
|
||||
|
||||
const u8 *entry = blk.rodata() + off;
|
||||
|
||||
@ -427,16 +427,16 @@ std::pair<err_t, meta_data> prodos_impl::metadata(const std::vector<std::string>
|
||||
res.set(meta_name::length, get_u24le(entry + 0x15));
|
||||
|
||||
else
|
||||
return std::make_pair(ERR_UNSUPPORTED, meta_data());
|
||||
return std::make_pair(error::unsupported, meta_data());
|
||||
}
|
||||
|
||||
return std::make_pair(ERR_OK, res);
|
||||
return std::make_pair(std::error_condition(), res);
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<u8>> prodos_impl::any_read(u8 type, u16 block, u32 length)
|
||||
std::pair<std::error_condition, std::vector<u8>> prodos_impl::any_read(u8 type, u16 block, u32 length)
|
||||
{
|
||||
std::pair<err_t, std::vector<u8>> data;
|
||||
data.first = ERR_OK;
|
||||
std::pair<std::error_condition, std::vector<u8>> data;
|
||||
data.first = std::error_condition();
|
||||
data.second.resize((length + 511) & ~511);
|
||||
u32 nb = data.second.size()/512;
|
||||
if(!nb)
|
||||
@ -475,7 +475,7 @@ std::pair<err_t, std::vector<u8>> prodos_impl::any_read(u8 type, u16 block, u32
|
||||
}
|
||||
|
||||
default:
|
||||
data.first = ERR_UNSUPPORTED;
|
||||
data.first = error::unsupported;
|
||||
data.second.clear();
|
||||
return data;
|
||||
}
|
||||
@ -484,11 +484,11 @@ std::pair<err_t, std::vector<u8>> prodos_impl::any_read(u8 type, u16 block, u32
|
||||
return data;
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<u8>> prodos_impl::file_read(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<u8>> prodos_impl::file_read(const std::vector<std::string> &path)
|
||||
{
|
||||
auto [blk, off, dir] = path_find(path);
|
||||
if(!off || dir)
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<u8>());
|
||||
return std::make_pair(error::not_found, std::vector<u8>());
|
||||
|
||||
const u8 *entry = blk.rodata() + off;
|
||||
u8 type = entry[0] >> 4;
|
||||
@ -501,14 +501,14 @@ std::pair<err_t, std::vector<u8>> prodos_impl::file_read(const std::vector<std::
|
||||
return any_read(kblk.r8(0x000), kblk.r16l(0x001), kblk.r24l(0x005));
|
||||
|
||||
} else
|
||||
return std::make_pair(ERR_UNSUPPORTED, std::vector<u8>());
|
||||
return std::make_pair(error::unsupported, std::vector<u8>());
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<u8>> prodos_impl::file_rsrc_read(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<u8>> prodos_impl::file_rsrc_read(const std::vector<std::string> &path)
|
||||
{
|
||||
auto [blk, off, dir] = path_find(path);
|
||||
if(!off || dir)
|
||||
return std::make_pair(ERR_NOT_FOUND, std::vector<u8>());
|
||||
return std::make_pair(error::not_found, std::vector<u8>());
|
||||
|
||||
const u8 *entry = blk.rodata() + off;
|
||||
u8 type = entry[0] >> 4;
|
||||
@ -518,5 +518,5 @@ std::pair<err_t, std::vector<u8>> prodos_impl::file_rsrc_read(const std::vector<
|
||||
return any_read(kblk.r8(0x100), kblk.r16l(0x101), kblk.r24l(0x105));
|
||||
|
||||
} else
|
||||
return std::make_pair(ERR_UNSUPPORTED, std::vector<u8>());
|
||||
return std::make_pair(error::unsupported, std::vector<u8>());
|
||||
}
|
||||
|
@ -38,20 +38,20 @@ public:
|
||||
virtual ~vtech_impl() = default;
|
||||
|
||||
virtual meta_data volume_metadata() override;
|
||||
virtual err_t volume_metadata_change(const meta_data &info) override;
|
||||
virtual std::pair<err_t, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual err_t metadata_change(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
virtual std::error_condition volume_metadata_change(const meta_data &info) override;
|
||||
virtual std::pair<std::error_condition, meta_data> metadata(const std::vector<std::string> &path) override;
|
||||
virtual std::error_condition metadata_change(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
|
||||
virtual std::pair<err_t, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual err_t rename(const std::vector<std::string> &opath, const std::vector<std::string> &npath) override;
|
||||
virtual err_t remove(const std::vector<std::string> &path) override;
|
||||
virtual std::pair<std::error_condition, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override;
|
||||
virtual std::error_condition rename(const std::vector<std::string> &opath, const std::vector<std::string> &npath) override;
|
||||
virtual std::error_condition remove(const std::vector<std::string> &path) override;
|
||||
|
||||
virtual err_t file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
virtual std::error_condition file_create(const std::vector<std::string> &path, const meta_data &meta) override;
|
||||
|
||||
virtual std::pair<err_t, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual err_t file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
virtual std::pair<std::error_condition, std::vector<u8>> file_read(const std::vector<std::string> &path) override;
|
||||
virtual std::error_condition file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override;
|
||||
|
||||
virtual err_t format(const meta_data &meta) override;
|
||||
virtual std::error_condition format(const meta_data &meta) override;
|
||||
|
||||
private:
|
||||
meta_data file_metadata(const u8 *entry);
|
||||
@ -124,10 +124,10 @@ vtech_impl::vtech_impl(fsblk_t &blockdev) : filesystem_t(blockdev, 128)
|
||||
{
|
||||
}
|
||||
|
||||
err_t vtech_impl::format(const meta_data &meta)
|
||||
std::error_condition vtech_impl::format(const meta_data &meta)
|
||||
{
|
||||
m_blockdev.fill(0);
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
meta_data vtech_impl::volume_metadata()
|
||||
@ -135,9 +135,9 @@ meta_data vtech_impl::volume_metadata()
|
||||
return meta_data();
|
||||
}
|
||||
|
||||
err_t vtech_impl::volume_metadata_change(const meta_data &meta)
|
||||
std::error_condition vtech_impl::volume_metadata_change(const meta_data &meta)
|
||||
{
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
meta_data vtech_impl::file_metadata(const u8 *entry)
|
||||
@ -171,26 +171,26 @@ std::tuple<fsblk_t::block_t, u32> vtech_impl::file_find(std::string_view name)
|
||||
return std::make_tuple(fsblk_t::block_t(), 0xffffffff);
|
||||
}
|
||||
|
||||
std::pair<err_t, meta_data> vtech_impl::metadata(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, meta_data> vtech_impl::metadata(const std::vector<std::string> &path)
|
||||
{
|
||||
if(path.size() != 1)
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data());
|
||||
return std::make_pair(error::not_found, meta_data());
|
||||
|
||||
auto [bdir, off] = file_find(path[0]);
|
||||
if(off == 0xffffffff)
|
||||
return std::make_pair(ERR_NOT_FOUND, meta_data());
|
||||
return std::make_pair(error::not_found, meta_data());
|
||||
|
||||
return std::make_pair(ERR_OK, file_metadata(bdir.rodata() + off));
|
||||
return std::make_pair(std::error_condition(), file_metadata(bdir.rodata() + off));
|
||||
}
|
||||
|
||||
err_t vtech_impl::metadata_change(const std::vector<std::string> &path, const meta_data &meta)
|
||||
std::error_condition vtech_impl::metadata_change(const std::vector<std::string> &path, const meta_data &meta)
|
||||
{
|
||||
if(path.size() != 1)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
auto [bdir, off] = file_find(path[0]);
|
||||
if(off == 0xffffffff)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
u8 *entry = bdir.data() + off;
|
||||
if(meta.has(meta_name::file_type))
|
||||
@ -207,19 +207,19 @@ err_t vtech_impl::metadata_change(const std::vector<std::string> &path, const me
|
||||
put_u16le(entry + 0xe, new_end);
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<dir_entry>> vtech_impl::directory_contents(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<dir_entry>> vtech_impl::directory_contents(const std::vector<std::string> &path)
|
||||
{
|
||||
std::pair<err_t, std::vector<dir_entry>> res;
|
||||
std::pair<std::error_condition, std::vector<dir_entry>> res;
|
||||
|
||||
if(path.size() != 0) {
|
||||
res.first = ERR_NOT_FOUND;
|
||||
res.first = error::not_found;
|
||||
return res;
|
||||
}
|
||||
|
||||
res.first = ERR_OK;
|
||||
res.first = std::error_condition();
|
||||
|
||||
for(int sect = 0; sect != 14; sect++) {
|
||||
auto bdir = m_blockdev.get(sect);
|
||||
@ -237,32 +237,32 @@ std::pair<err_t, std::vector<dir_entry>> vtech_impl::directory_contents(const st
|
||||
return res;
|
||||
}
|
||||
|
||||
err_t vtech_impl::rename(const std::vector<std::string> &opath, const std::vector<std::string> &npath)
|
||||
std::error_condition vtech_impl::rename(const std::vector<std::string> &opath, const std::vector<std::string> &npath)
|
||||
{
|
||||
if(opath.size() != 1 || npath.size() != 1)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
auto [bdir, off] = file_find(opath[0]);
|
||||
if(off == 0xffffffff)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
std::string name = npath[0];
|
||||
name.resize(8, ' ');
|
||||
wstr(bdir.data() + off + 2, name);
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
err_t vtech_impl::remove(const std::vector<std::string> &path)
|
||||
std::error_condition vtech_impl::remove(const std::vector<std::string> &path)
|
||||
{
|
||||
return ERR_NOT_FOUND;
|
||||
return error::unsupported;
|
||||
}
|
||||
|
||||
|
||||
err_t vtech_impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
std::error_condition vtech_impl::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
{
|
||||
if(path.size() != 0)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
// Find the key for the next unused entry
|
||||
for(int sect = 0; sect != 14; sect++) {
|
||||
@ -281,23 +281,23 @@ err_t vtech_impl::file_create(const std::vector<std::string> &path, const meta_d
|
||||
bdir.w8 (off+0xb, 0x00);
|
||||
bdir.w16l(off+0xc, meta.get_number(meta_name::loading_address, 0x7ae9));
|
||||
bdir.w16l(off+0xe, bdir.r16l(off+0xc)); // Size 0 initially
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<u8>> vtech_impl::file_read(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<u8>> vtech_impl::file_read(const std::vector<std::string> &path)
|
||||
{
|
||||
std::vector<u8> data;
|
||||
|
||||
if(path.size() != 1)
|
||||
return std::make_pair(ERR_NOT_FOUND, data);
|
||||
return std::make_pair(error::not_found, data);
|
||||
|
||||
auto [bdir, off] = file_find(path[0]);
|
||||
if(off == 0xffffffff)
|
||||
return std::make_pair(ERR_NOT_FOUND, data);
|
||||
return std::make_pair(error::not_found, data);
|
||||
|
||||
const u8 *entry = bdir.rodata() + off;
|
||||
|
||||
@ -319,17 +319,17 @@ std::pair<err_t, std::vector<u8>> vtech_impl::file_read(const std::vector<std::s
|
||||
track = dblk.r8(126);
|
||||
sector = dblk.r8(127);
|
||||
}
|
||||
return std::make_pair(ERR_OK, data);
|
||||
return std::make_pair(std::error_condition(), data);
|
||||
}
|
||||
|
||||
err_t vtech_impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
std::error_condition vtech_impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
{
|
||||
if(path.size() != 1)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
auto [bdir, off] = file_find(path[0]);
|
||||
if(off == 0xffffffff)
|
||||
return ERR_NOT_FOUND;
|
||||
return error::not_found;
|
||||
|
||||
u8 *entry = bdir.data() + off;
|
||||
|
||||
@ -342,7 +342,7 @@ err_t vtech_impl::file_write(const std::vector<std::string> &path, const std::ve
|
||||
|
||||
// Enough space?
|
||||
if(cur_ns < need_ns && free_block_count() < need_ns - cur_ns)
|
||||
return ERR_NO_SPACE;
|
||||
return error::no_space;
|
||||
|
||||
u8 track = entry[0xa];
|
||||
u8 sector = entry[0xb];
|
||||
@ -380,7 +380,7 @@ err_t vtech_impl::file_write(const std::vector<std::string> &path, const std::ve
|
||||
} else
|
||||
put_u16le(entry + 0xa, 0);
|
||||
|
||||
return ERR_OK;
|
||||
return std::error_condition();
|
||||
}
|
||||
|
||||
std::vector<std::pair<u8, u8>> vtech_impl::allocate_blocks(u32 count)
|
||||
|
@ -186,69 +186,99 @@ meta_data filesystem_t::volume_metadata()
|
||||
return meta_data();
|
||||
}
|
||||
|
||||
err_t filesystem_t::volume_metadata_change(const meta_data &meta)
|
||||
std::error_condition filesystem_t::volume_metadata_change(const meta_data &meta)
|
||||
{
|
||||
return ERR_UNSUPPORTED;
|
||||
return error::unsupported;
|
||||
}
|
||||
|
||||
std::pair<err_t, meta_data> filesystem_t::metadata(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, meta_data> filesystem_t::metadata(const std::vector<std::string> &path)
|
||||
{
|
||||
return std::make_pair(ERR_UNSUPPORTED, meta_data());
|
||||
return std::make_pair(error::unsupported, meta_data());
|
||||
}
|
||||
|
||||
err_t filesystem_t::metadata_change(const std::vector<std::string> &path, const meta_data &meta)
|
||||
std::error_condition filesystem_t::metadata_change(const std::vector<std::string> &path, const meta_data &meta)
|
||||
{
|
||||
return ERR_UNSUPPORTED;
|
||||
return error::unsupported;
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<dir_entry>> filesystem_t::directory_contents(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<dir_entry>> filesystem_t::directory_contents(const std::vector<std::string> &path)
|
||||
{
|
||||
return std::make_pair(ERR_UNSUPPORTED, std::vector<dir_entry>());
|
||||
return std::make_pair(error::unsupported, std::vector<dir_entry>());
|
||||
}
|
||||
|
||||
err_t filesystem_t::rename(const std::vector<std::string> &opath, const std::vector<std::string> &npath)
|
||||
std::error_condition filesystem_t::rename(const std::vector<std::string> &opath, const std::vector<std::string> &npath)
|
||||
{
|
||||
return ERR_UNSUPPORTED;
|
||||
return error::unsupported;
|
||||
}
|
||||
|
||||
err_t filesystem_t::remove(const std::vector<std::string> &path)
|
||||
std::error_condition filesystem_t::remove(const std::vector<std::string> &path)
|
||||
{
|
||||
return ERR_UNSUPPORTED;
|
||||
return error::unsupported;
|
||||
}
|
||||
|
||||
err_t filesystem_t::dir_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
std::error_condition filesystem_t::dir_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
{
|
||||
return ERR_UNSUPPORTED;
|
||||
return error::unsupported;
|
||||
}
|
||||
|
||||
err_t filesystem_t::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
std::error_condition filesystem_t::file_create(const std::vector<std::string> &path, const meta_data &meta)
|
||||
{
|
||||
return ERR_UNSUPPORTED;
|
||||
return error::unsupported;
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<u8>> filesystem_t::file_read(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<u8>> filesystem_t::file_read(const std::vector<std::string> &path)
|
||||
{
|
||||
return std::make_pair(ERR_UNSUPPORTED, std::vector<u8>());
|
||||
return std::make_pair(error::unsupported, std::vector<u8>());
|
||||
}
|
||||
|
||||
err_t filesystem_t::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
std::error_condition filesystem_t::file_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
{
|
||||
return ERR_UNSUPPORTED;
|
||||
return error::unsupported;
|
||||
}
|
||||
|
||||
std::pair<err_t, std::vector<u8>> filesystem_t::file_rsrc_read(const std::vector<std::string> &path)
|
||||
std::pair<std::error_condition, std::vector<u8>> filesystem_t::file_rsrc_read(const std::vector<std::string> &path)
|
||||
{
|
||||
return std::make_pair(ERR_UNSUPPORTED, std::vector<u8>());
|
||||
return std::make_pair(error::unsupported, std::vector<u8>());
|
||||
}
|
||||
|
||||
err_t filesystem_t::file_rsrc_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
std::error_condition filesystem_t::file_rsrc_write(const std::vector<std::string> &path, const std::vector<u8> &data)
|
||||
{
|
||||
return ERR_UNSUPPORTED;
|
||||
return error::unsupported;
|
||||
}
|
||||
|
||||
err_t filesystem_t::format(const meta_data &meta)
|
||||
std::error_condition filesystem_t::format(const meta_data &meta)
|
||||
{
|
||||
return ERR_UNSUPPORTED;
|
||||
return error::unsupported;
|
||||
}
|
||||
|
||||
std::error_category const &fs_category() noexcept
|
||||
{
|
||||
class fs_category_impl : public std::error_category
|
||||
{
|
||||
public:
|
||||
virtual char const *name() const noexcept override { return "fs"; }
|
||||
|
||||
virtual std::string message(int condition) const override
|
||||
{
|
||||
using namespace std::literals;
|
||||
static std::string_view const s_messages[] = {
|
||||
"No error"sv,
|
||||
"Unsupported operation"sv,
|
||||
"File or directory not found"sv,
|
||||
"No space on volume"sv,
|
||||
"Invalid block number"sv,
|
||||
"Invalid filename or path"sv,
|
||||
"Incorrect file size"sv,
|
||||
"File already exists"sv,
|
||||
};
|
||||
if ((0 <= condition) && (std::size(s_messages) > condition))
|
||||
return std::string(s_messages[condition]);
|
||||
else
|
||||
return "Unknown error"s;
|
||||
}
|
||||
};
|
||||
static fs_category_impl const s_fs_category_instance;
|
||||
return s_fs_category_instance;
|
||||
}
|
||||
|
||||
} // namespace fs
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <system_error>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -22,13 +23,14 @@ using u16 = uint16_t;
|
||||
using u32 = uint32_t;
|
||||
using u64 = uint64_t;
|
||||
|
||||
enum err_t {
|
||||
ERR_OK = 0,
|
||||
ERR_UNSUPPORTED,
|
||||
ERR_INVALID,
|
||||
ERR_NOT_FOUND,
|
||||
ERR_NOT_EMPTY,
|
||||
ERR_NO_SPACE,
|
||||
enum class error : int {
|
||||
unsupported = 1,
|
||||
not_found,
|
||||
no_space,
|
||||
invalid_block,
|
||||
invalid_name,
|
||||
incorrect_size,
|
||||
already_exists,
|
||||
};
|
||||
|
||||
template<typename T> class refcounted_outer {
|
||||
@ -218,44 +220,44 @@ public:
|
||||
virtual meta_data volume_metadata();
|
||||
|
||||
// Change the metadata for the volume
|
||||
virtual err_t volume_metadata_change(const meta_data &meta);
|
||||
virtual std::error_condition volume_metadata_change(const meta_data &meta);
|
||||
|
||||
// Get the metadata for a file or a directory. Empty path targets the root directory
|
||||
virtual std::pair<err_t, meta_data> metadata(const std::vector<std::string> &path);
|
||||
virtual std::pair<std::error_condition, meta_data> metadata(const std::vector<std::string> &path);
|
||||
|
||||
// Change the metadata for a file or a directory. Empty path targets the root directory
|
||||
virtual err_t metadata_change(const std::vector<std::string> &path, const meta_data &meta);
|
||||
virtual std::error_condition metadata_change(const std::vector<std::string> &path, const meta_data &meta);
|
||||
|
||||
// Get the contents of a directory, empty path targets the root directory
|
||||
virtual std::pair<err_t, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path);
|
||||
virtual std::pair<std::error_condition, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path);
|
||||
|
||||
// Rename a file or a directory. In contrast to metadata_change, this can move the object
|
||||
// between directories
|
||||
virtual err_t rename(const std::vector<std::string> &opath, const std::vector<std::string> &npath);
|
||||
virtual std::error_condition rename(const std::vector<std::string> &opath, const std::vector<std::string> &npath);
|
||||
|
||||
// Remove a file or a directory. Directories must be empty (e.g. it's not recursive)
|
||||
virtual err_t remove(const std::vector<std::string> &path);
|
||||
virtual std::error_condition remove(const std::vector<std::string> &path);
|
||||
|
||||
// Create a directory, path designates where the directory must be, directory name is in meta
|
||||
virtual err_t dir_create(const std::vector<std::string> &path, const meta_data &meta);
|
||||
virtual std::error_condition dir_create(const std::vector<std::string> &path, const meta_data &meta);
|
||||
|
||||
// Create an empty file, path designates where the file must be, file name is in meta
|
||||
virtual err_t file_create(const std::vector<std::string> &path, const meta_data &meta);
|
||||
virtual std::error_condition file_create(const std::vector<std::string> &path, const meta_data &meta);
|
||||
|
||||
// Read the contents of a file
|
||||
virtual std::pair<err_t, std::vector<u8>> file_read(const std::vector<std::string> &path);
|
||||
virtual std::pair<std::error_condition, std::vector<u8>> file_read(const std::vector<std::string> &path);
|
||||
|
||||
// Replace the contents of a file, the file must already exist
|
||||
virtual err_t file_write(const std::vector<std::string> &path, const std::vector<u8> &data);
|
||||
virtual std::error_condition file_write(const std::vector<std::string> &path, const std::vector<u8> &data);
|
||||
|
||||
// Read the resource fork of a file on systems that handle those
|
||||
virtual std::pair<err_t, std::vector<u8>> file_rsrc_read(const std::vector<std::string> &path);
|
||||
virtual std::pair<std::error_condition, std::vector<u8>> file_rsrc_read(const std::vector<std::string> &path);
|
||||
|
||||
// Replace the resource fork of a file, the file must already exist
|
||||
virtual err_t file_rsrc_write(const std::vector<std::string> &path, const std::vector<u8> &data);
|
||||
virtual std::error_condition file_rsrc_write(const std::vector<std::string> &path, const std::vector<u8> &data);
|
||||
|
||||
// Format an image, provide the volume metadata
|
||||
virtual err_t format(const meta_data &meta);
|
||||
virtual std::error_condition format(const meta_data &meta);
|
||||
|
||||
static void wstr(u8 *p, std::string_view str);
|
||||
|
||||
@ -271,6 +273,17 @@ protected:
|
||||
fsblk_t &m_blockdev;
|
||||
};
|
||||
|
||||
// error category for filesystem errors
|
||||
std::error_category const &fs_category() noexcept;
|
||||
inline std::error_condition make_error_condition(error err) noexcept { return std::error_condition(int(err), fs_category()); }
|
||||
|
||||
} // namespace fs
|
||||
|
||||
|
||||
namespace std {
|
||||
|
||||
template <> struct is_error_condition_enum<fs::error> : public std::true_type { };
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
@ -302,7 +302,7 @@ static void dir_scan(fs::filesystem_t *fs, u32 depth, const std::vector<std::str
|
||||
head += " ";
|
||||
auto [err, contents] = fs->directory_contents(path);
|
||||
if(err)
|
||||
return;
|
||||
return; // FIXME: don't swallow errors
|
||||
for(const auto &c : contents) {
|
||||
size_t id = entries.size();
|
||||
entries.resize(id+1);
|
||||
@ -472,10 +472,7 @@ static int generic_read(image_handler &ih, const char *srcpath, const char *dstp
|
||||
std::vector<std::string> path = ih.path_split(srcpath);
|
||||
auto [err, dfork] = fs->file_read(path);
|
||||
if(err) {
|
||||
if(err == fs::ERR_NOT_FOUND)
|
||||
fprintf(stderr, "File not found.\n");
|
||||
else
|
||||
fprintf(stderr, "Unknown error (%d).\n", err);
|
||||
fprintf(stderr, "File reading failed: %s\n", err.message().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -568,14 +565,14 @@ static int generic_write(image_handler &ih, const char *srcpath, const char *dst
|
||||
auto [err, meta] = fs->metadata(path);
|
||||
std::ignore = meta;
|
||||
|
||||
if(err) {
|
||||
if(err == fs::error::not_found) {
|
||||
fs::meta_data meta;
|
||||
meta.set(fs::meta_name::name, path.back());
|
||||
auto dpath = path;
|
||||
dpath.pop_back();
|
||||
err = fs->file_create(dpath, meta);
|
||||
if(err) {
|
||||
fprintf(stderr, "File creation failure.\n");
|
||||
fprintf(stderr, "File creation failed: %s\n", err.message().c_str());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -583,7 +580,7 @@ static int generic_write(image_handler &ih, const char *srcpath, const char *dst
|
||||
auto dfork = image_handler::fload(srcpath);
|
||||
err = fs->file_write(path, dfork);
|
||||
if(err) {
|
||||
fprintf(stderr, "File writing failure.\n");
|
||||
fprintf(stderr, "File writing failed: %s\n", err.message().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -594,7 +591,7 @@ static int generic_write(image_handler &ih, const char *srcpath, const char *dst
|
||||
auto rfork = image_handler::fload_rsrc(rpath);
|
||||
if(!rfork.empty()) {
|
||||
err = fs->file_rsrc_write(path, rfork);
|
||||
fprintf(stderr, "File resource fork writing failure.\n");
|
||||
fprintf(stderr, "File resource fork writing failed: %s\n", err.message().c_str());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user