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:
ajrhacker 2025-02-22 01:02:44 -05:00 committed by GitHub
parent b977c33432
commit c4da9ca64e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 482 additions and 436 deletions

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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 &current_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();
}
//-------------------------------------------------

View File

@ -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;
}
}

View File

@ -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();
}
//-------------------------------------------------

View File

@ -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

View File

@ -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)

View File

@ -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>());
}

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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;
}
}