diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/formats/fs_cbmdos.cpp | 86 | ||||
-rw-r--r-- | src/lib/formats/fs_coco_os9.cpp | 30 | ||||
-rw-r--r-- | src/lib/formats/fs_coco_rsdos.cpp | 72 | ||||
-rw-r--r-- | src/lib/formats/fs_fat.cpp | 158 | ||||
-rw-r--r-- | src/lib/formats/fs_hp98x5.cpp | 92 | ||||
-rw-r--r-- | src/lib/formats/fs_hplif.cpp | 28 | ||||
-rw-r--r-- | src/lib/formats/fs_isis.cpp | 68 | ||||
-rw-r--r-- | src/lib/formats/fs_oric_jasmin.cpp | 92 | ||||
-rw-r--r-- | src/lib/formats/fs_prodos.cpp | 52 | ||||
-rw-r--r-- | src/lib/formats/fs_vtech.cpp | 90 | ||||
-rw-r--r-- | src/lib/formats/fsblk.cpp | 82 | ||||
-rw-r--r-- | src/lib/formats/fsblk.h | 53 | ||||
-rw-r--r-- | src/tools/floptool.cpp | 15 |
13 files changed, 482 insertions, 436 deletions
diff --git a/src/lib/formats/fs_cbmdos.cpp b/src/lib/formats/fs_cbmdos.cpp index 0654f740685..7a567b19f95 100644 --- a/src/lib/formats/fs_cbmdos.cpp +++ b/src/lib/formats/fs_cbmdos.cpp @@ -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(); } diff --git a/src/lib/formats/fs_coco_os9.cpp b/src/lib/formats/fs_coco_os9.cpp index 334bb9d5b79..e261968f69a 100644 --- a/src/lib/formats/fs_coco_os9.cpp +++ b/src/lib/formats/fs_coco_os9.cpp @@ -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(); } diff --git a/src/lib/formats/fs_coco_rsdos.cpp b/src/lib/formats/fs_coco_rsdos.cpp index e040ea9dd75..c616c8babc6 100644 --- a/src/lib/formats/fs_coco_rsdos.cpp +++ b/src/lib/formats/fs_coco_rsdos.cpp @@ -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); } diff --git a/src/lib/formats/fs_fat.cpp b/src/lib/formats/fs_fat.cpp index 885a5ea3087..3b291171035 100644 --- a/src/lib/formats/fs_fat.cpp +++ b/src/lib/formats/fs_fat.cpp @@ -250,12 +250,12 @@ public: // virtuals virtual meta_data volume_metadata() override; - virtual std::pair<err_t, meta_data> metadata(const std::vector<std::string> &path) override; - virtual std::pair<err_t, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override; - virtual std::pair<err_t, std::vector<u8>> file_read(const std::vector<std::string> &path) override; - virtual err_t file_create(const std::vector<std::string> &path, const meta_data &meta) override; - virtual err_t file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override; - virtual err_t remove(const std::vector<std::string> &path) override; + virtual std::pair<std::error_condition, meta_data> metadata(const std::vector<std::string> &path) override; + virtual std::pair<std::error_condition, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override; + virtual std::pair<std::error_condition, std::vector<u8>> file_read(const std::vector<std::string> &path) override; + virtual std::error_condition file_create(const std::vector<std::string> &path, const meta_data &meta) override; + virtual std::error_condition file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override; + virtual std::error_condition remove(const std::vector<std::string> &path) override; // methods std::vector<u32> get_sectors_from_fat(const directory_entry &dirent) const; @@ -291,13 +291,13 @@ private: std::optional<directory_entry> find_child(const directory_span ¤t_dir, std::string_view target) const; template <typename T> void iterate_directory_entries(const directory_span &dir, T &&callback) const; bool is_valid_short_filename(std::string const &filename); - err_t build_direntry_filename(std::string const &filename, std::string &fname); - err_t file_create_root(std::string &fname, u8 attributes = 0); - err_t file_create_directory(directory_entry &dirent, std::string &fname, u8 attributes = 0); - err_t file_create_sector(u32 sector, std::string &fname, u8 attributes); - err_t initialize_directory(u32 directory_cluster, u32 parent_cluster); - err_t initialize_directory_entry(fsblk_t::block_t &dirblk, u32 offset, const std::string_view &fname, u8 attributes, u32 start_cluster); - err_t free_clusters(u32 start_cluster); + std::error_condition build_direntry_filename(std::string const &filename, std::string &fname); + std::error_condition file_create_root(std::string &fname, u8 attributes = 0); + std::error_condition file_create_directory(directory_entry &dirent, std::string &fname, u8 attributes = 0); + std::error_condition file_create_sector(u32 sector, std::string &fname, u8 attributes); + std::error_condition initialize_directory(u32 directory_cluster, u32 parent_cluster); + std::error_condition initialize_directory_entry(fsblk_t::block_t &dirblk, u32 offset, std::string_view fname, u8 attributes, u32 start_cluster); + std::error_condition free_clusters(u32 start_cluster); void clear_cluster_sectors(u32 cluster, u8 fill_byte); u32 first_cluster_sector(u32 cluster); u32 get_next_cluster(u32 cluster); @@ -603,13 +603,13 @@ meta_data impl::volume_metadata() // impl::metadata //------------------------------------------------- -std::pair<err_t, meta_data> impl::metadata(const std::vector<std::string> &path) +std::pair<std::error_condition, meta_data> impl::metadata(const std::vector<std::string> &path) { std::optional<directory_entry> dirent = find_entity(path); if (!dirent) - return std::make_pair(ERR_NOT_FOUND, meta_data()); + return std::make_pair(error::not_found, meta_data()); - return std::make_pair(ERR_OK, dirent->metadata()); + return std::make_pair(std::error_condition(), dirent->metadata()); } @@ -617,11 +617,11 @@ std::pair<err_t, meta_data> impl::metadata(const std::vector<std::string> &path) // impl::directory_contents //------------------------------------------------- -std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vector<std::string> &path) +std::pair<std::error_condition, std::vector<dir_entry>> impl::directory_contents(const std::vector<std::string> &path) { directory_span::ptr dir = find_directory(path.begin(), path.end()); if (!dir) - return std::make_pair(ERR_NOT_FOUND, std::vector<dir_entry>()); + return std::make_pair(error::not_found, std::vector<dir_entry>()); std::vector<dir_entry> results; auto const callback = [&results] (const directory_entry &dirent) @@ -634,7 +634,7 @@ std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vec return false; }; iterate_directory_entries(*dir, callback); - return std::make_pair(ERR_OK, std::move(results)); + return std::make_pair(std::error_condition(), std::move(results)); } @@ -642,12 +642,14 @@ std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vec // impl::file_read //------------------------------------------------- -std::pair<err_t, std::vector<u8>> impl::file_read(const std::vector<std::string> &path) +std::pair<std::error_condition, std::vector<u8>> impl::file_read(const std::vector<std::string> &path) { // find the file std::optional<directory_entry> dirent = find_entity(path); - if (!dirent || dirent->is_subdirectory()) - return std::make_pair(ERR_NOT_FOUND, std::vector<u8>()); + if (!dirent) + return std::make_pair(error::not_found, std::vector<u8>()); + if (dirent->is_subdirectory()) + return std::make_pair(error::invalid_name, std::vector<u8>()); // get the list of sectors for this file std::vector<u32> sectors = get_sectors_from_fat(*dirent); @@ -664,7 +666,7 @@ std::pair<err_t, std::vector<u8>> impl::file_read(const std::vector<std::string> size_t length = std::min((size_t)dirent->file_size() - result.size(), (size_t)block.size()); result.insert(result.end(), data, data + length); } - return std::make_pair(ERR_OK, std::move(result)); + return std::make_pair(std::error_condition(), std::move(result)); } @@ -684,14 +686,14 @@ bool impl::is_valid_short_filename(std::string const &filename) } -err_t impl::build_direntry_filename(std::string const &filename, std::string &fname) +std::error_condition impl::build_direntry_filename(std::string const &filename, std::string &fname) { std::regex filename_regex("([A-Z0-9!#\\$%&\\(\\)\\-@^_`\\{\\}~]{0,8})(\\.([A-Z0-9!#\\$%&\\(\\)\\-@^_`\\{\\}~]{0,3}))?"); std::smatch smatch; if (!std::regex_match(filename, smatch, filename_regex)) - return ERR_INVALID; + return error::invalid_name; if (smatch.size() != 4) - return ERR_INVALID; + return error::invalid_name; fname.resize(directory_entry::FNAME_LENGTH, ' '); @@ -701,16 +703,16 @@ err_t impl::build_direntry_filename(std::string const &filename, std::string &fn for (int j = 0; j < 3 && j < smatch.str(3).size(); j++) fname[8 + j] = smatch.str(3)[j]; - return ERR_OK; + return std::error_condition(); } -err_t impl::file_create(const std::vector<std::string> &path, const meta_data &meta) +std::error_condition impl::file_create(const std::vector<std::string> &path, const meta_data &meta) { std::string filename = meta.get_string(meta_name::name, ""); std::string fname; - err_t err = build_direntry_filename(filename, fname); - if (err != ERR_OK) + std::error_condition err = build_direntry_filename(filename, fname); + if (err) return err; if (path.empty()) @@ -732,37 +734,37 @@ err_t impl::file_create(const std::vector<std::string> &path, const meta_data &m if (!dir_entry) { if (!is_valid_short_filename(path_part)) - return ERR_INVALID; + return error::invalid_name; std::string part_fname; - err_t err = build_direntry_filename(path_part, part_fname); - if (err != ERR_OK) + std::error_condition err = build_direntry_filename(path_part, part_fname); + if (err) return err; err = !parent_entry ? file_create_root(part_fname, directory_entry::ATTR_DIRECTORY) : file_create_directory(parent_entry.value(), part_fname, directory_entry::ATTR_DIRECTORY); - if (err != ERR_OK) + if (err) return err; dir_entry = find_entity(partial_path); if (!dir_entry) - return ERR_INVALID; + return error::invalid_name; err = initialize_directory(dir_entry->start_cluster(), parent_entry ? parent_entry->start_cluster() : 0); - if (err != ERR_OK) + if (err) return err; } else { if (!dir_entry->is_subdirectory()) - return ERR_INVALID; + return error::invalid_name; } parent_entry = dir_entry; } dirent = find_entity(path); if (!dirent) - return ERR_INVALID; + return error::invalid_name; } return file_create_directory(*dirent, fname); @@ -770,7 +772,7 @@ err_t impl::file_create(const std::vector<std::string> &path, const meta_data &m } -err_t impl::initialize_directory(u32 directory_cluster, u32 parent_cluster) +std::error_condition impl::initialize_directory(u32 directory_cluster, u32 parent_cluster) { clear_cluster_sectors(directory_cluster, 0x00); @@ -780,23 +782,23 @@ err_t impl::initialize_directory(u32 directory_cluster, u32 parent_cluster) std::string dir_fname; dir_fname.resize(directory_entry::FNAME_LENGTH, ' '); dir_fname[0] = '.'; - err_t err = initialize_directory_entry(dirblk, 0, dir_fname, directory_entry::ATTR_DIRECTORY, directory_cluster); - if (err != ERR_OK) + std::error_condition err = initialize_directory_entry(dirblk, 0, dir_fname, directory_entry::ATTR_DIRECTORY, directory_cluster); + if (err) return err; dir_fname[1] = '.'; err = initialize_directory_entry(dirblk, directory_entry::SIZE, dir_fname, directory_entry::ATTR_DIRECTORY, parent_cluster); - if (err != ERR_OK) + if (err) return err; - return ERR_OK; + return std::error_condition(); } -err_t impl::initialize_directory_entry(fsblk_t::block_t &dirblk, u32 offset, const std::string_view &fname, u8 attributes, u32 start_cluster) +std::error_condition impl::initialize_directory_entry(fsblk_t::block_t &dirblk, u32 offset, std::string_view fname, u8 attributes, u32 start_cluster) { if (fname.size() != directory_entry::FNAME_LENGTH) - return ERR_INVALID; + return error::invalid_name; for (int i = 0; i < directory_entry::SIZE; i += 4) dirblk.w32l(offset + i, 0); @@ -808,33 +810,33 @@ err_t impl::initialize_directory_entry(fsblk_t::block_t &dirblk, u32 offset, con dirblk.w16l(offset + directory_entry::OFFSET_START_CLUSTER_HI, u16(start_cluster >> 16)); dirblk.w16l(offset + directory_entry::OFFSET_START_CLUSTER, u16(start_cluster & 0xffff)); - return ERR_OK; + return std::error_condition(); } -err_t impl::file_create_root(std::string &fname, u8 attributes) +std::error_condition impl::file_create_root(std::string &fname, u8 attributes) { const u32 first_directory_sector = m_starting_sector + m_reserved_sector_count + ((u32)m_file_allocation_table.size() / m_bytes_per_sector); const u32 directory_sector_count = (m_root_directory_size * directory_entry::SIZE) / m_bytes_per_sector; for (u32 sector = first_directory_sector; sector < first_directory_sector + directory_sector_count; sector++) { - err_t err = file_create_sector(sector, fname, attributes); - if (err != ERR_NOT_FOUND) + std::error_condition err = file_create_sector(sector, fname, attributes); + if (err != error::not_found) return err; } - return ERR_NO_SPACE; + return error::no_space; } -err_t impl::file_create_directory(directory_entry &dirent, std::string &fname, u8 attributes) +std::error_condition impl::file_create_directory(directory_entry &dirent, std::string &fname, u8 attributes) { u32 current_cluster = dirent.start_cluster(); do { const u32 first_sector = first_cluster_sector(current_cluster); for (int i = 0; i < m_sectors_per_cluster; i++) { - err_t err = file_create_sector(first_sector + i, fname, attributes); - if (err != ERR_NOT_FOUND) + std::error_condition err = file_create_sector(first_sector + i, fname, attributes); + if (err != error::not_found) return err; } @@ -844,7 +846,7 @@ err_t impl::file_create_directory(directory_entry &dirent, std::string &fname, u { next_cluster = find_free_cluster(); if (next_cluster == 0) - return ERR_NO_SPACE; + return error::no_space; set_next_cluster(current_cluster, next_cluster); set_next_cluster(next_cluster, m_last_cluster_indicator); @@ -853,7 +855,7 @@ err_t impl::file_create_directory(directory_entry &dirent, std::string &fname, u } current_cluster = next_cluster; } while (current_cluster > FIRST_VALID_CLUSTER && current_cluster < m_last_valid_cluster); - return ERR_NO_SPACE; + return error::no_space; } @@ -878,8 +880,8 @@ void impl::clear_cluster_sectors(u32 cluster, u8 fill_byte) } -// Returns ERR_NOT_FOUND when no room could be found to create the file in the sector. -err_t impl::file_create_sector(u32 sector, std::string &fname, u8 attributes) +// Returns error::not_found when no room could be found to create the file in the sector. +std::error_condition impl::file_create_sector(u32 sector, std::string &fname, u8 attributes) { auto dirblk = m_blockdev.get(sector); for (u32 blkoffset = 0; blkoffset < m_bytes_per_sector; blkoffset += directory_entry::SIZE) @@ -889,28 +891,28 @@ err_t impl::file_create_sector(u32 sector, std::string &fname, u8 attributes) { u32 start_cluster = find_free_cluster(); if (start_cluster == 0) - return ERR_NO_SPACE; + return error::no_space; set_next_cluster(start_cluster, m_last_cluster_indicator); - err_t err = initialize_directory_entry(dirblk, blkoffset, fname, attributes, start_cluster); - if (err != ERR_OK) + std::error_condition err = initialize_directory_entry(dirblk, blkoffset, fname, attributes, start_cluster); + if (err) return err; - return ERR_OK; + return std::error_condition(); } } - return ERR_NOT_FOUND; + return error::not_found; } -err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data) +std::error_condition impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data) { std::optional<directory_entry> dirent = find_entity(path); if (!dirent) - return ERR_NOT_FOUND; + return error::not_found; if (dirent->is_subdirectory()) - return ERR_INVALID; + return error::invalid_name; u32 current_length = dirent->file_size(); const size_t data_length = data.size(); @@ -925,13 +927,13 @@ err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u do { next_cluster = get_next_cluster(current_cluster); if (next_cluster < FIRST_VALID_CLUSTER) - return ERR_INVALID; + return error::invalid_block; } while (next_cluster < m_last_valid_cluster); for (int i = current_clusters; i < required_clusters; i++) { u32 free_cluster = find_free_cluster(); if (free_cluster < FIRST_VALID_CLUSTER) - return ERR_NO_SPACE; + return error::no_space; set_next_cluster(current_cluster, free_cluster); set_next_cluster(free_cluster, m_last_cluster_indicator); @@ -948,8 +950,8 @@ err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u u32 next_cluster = get_next_cluster(current_cluster); set_next_cluster(current_cluster, m_last_cluster_indicator); - err_t err = free_clusters(next_cluster); - if (err != ERR_OK) + std::error_condition err = free_clusters(next_cluster); + if (err) return err; } @@ -969,41 +971,41 @@ err_t impl::file_write(const std::vector<std::string> &path, const std::vector<u dirent->set_raw_modified_datetime(encode_now_fat_datetime()); dirent->set_file_size(data_length); - return ERR_OK; + return std::error_condition(); } -err_t impl::remove(const std::vector<std::string> &path) +std::error_condition impl::remove(const std::vector<std::string> &path) { if (path.size() != 0) - return ERR_UNSUPPORTED; + return error::unsupported; std::optional<directory_entry> dirent = find_entity(path); if (!dirent) - return ERR_OK; + return std::error_condition(); // Removing directories is not supported yet if (dirent->is_subdirectory()) - return ERR_UNSUPPORTED; + return error::unsupported; dirent->mark_deleted(); - return ERR_OK; + return std::error_condition(); } -err_t impl::free_clusters(u32 start_cluster) +std::error_condition impl::free_clusters(u32 start_cluster) { while (start_cluster < m_last_valid_cluster) { if (start_cluster < FIRST_VALID_CLUSTER) - return ERR_INVALID; + return error::invalid_block; u32 next_cluster = get_next_cluster(start_cluster); set_next_cluster(start_cluster, 0); start_cluster = next_cluster; } - return ERR_OK; + return std::error_condition(); } //------------------------------------------------- diff --git a/src/lib/formats/fs_hp98x5.cpp b/src/lib/formats/fs_hp98x5.cpp index a8eb139ef7a..1b47fbbb459 100644 --- a/src/lib/formats/fs_hp98x5.cpp +++ b/src/lib/formats/fs_hp98x5.cpp @@ -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; } } diff --git a/src/lib/formats/fs_hplif.cpp b/src/lib/formats/fs_hplif.cpp index 09b3d31c5d0..e910ca3cb36 100644 --- a/src/lib/formats/fs_hplif.cpp +++ b/src/lib/formats/fs_hplif.cpp @@ -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(); } //------------------------------------------------- diff --git a/src/lib/formats/fs_isis.cpp b/src/lib/formats/fs_isis.cpp index 3b79851522b..e26ab9a529b 100644 --- a/src/lib/formats/fs_isis.cpp +++ b/src/lib/formats/fs_isis.cpp @@ -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 diff --git a/src/lib/formats/fs_oric_jasmin.cpp b/src/lib/formats/fs_oric_jasmin.cpp index 8cc79d917a1..2e25d5e0070 100644 --- a/src/lib/formats/fs_oric_jasmin.cpp +++ b/src/lib/formats/fs_oric_jasmin.cpp @@ -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) diff --git a/src/lib/formats/fs_prodos.cpp b/src/lib/formats/fs_prodos.cpp index 480bdf7505a..9b7a91f1615 100644 --- a/src/lib/formats/fs_prodos.cpp +++ b/src/lib/formats/fs_prodos.cpp @@ -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>()); } diff --git a/src/lib/formats/fs_vtech.cpp b/src/lib/formats/fs_vtech.cpp index 6b414518437..39e116a7ed8 100644 --- a/src/lib/formats/fs_vtech.cpp +++ b/src/lib/formats/fs_vtech.cpp @@ -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) diff --git a/src/lib/formats/fsblk.cpp b/src/lib/formats/fsblk.cpp index 0201ca29092..8dfedcc4941 100644 --- a/src/lib/formats/fsblk.cpp +++ b/src/lib/formats/fsblk.cpp @@ -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 diff --git a/src/lib/formats/fsblk.h b/src/lib/formats/fsblk.h index 63ed910a507..619ff832a95 100644 --- a/src/lib/formats/fsblk.h +++ b/src/lib/formats/fsblk.h @@ -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 diff --git a/src/tools/floptool.cpp b/src/tools/floptool.cpp index f07713eef53..9ac9c3231ae 100644 --- a/src/tools/floptool.cpp +++ b/src/tools/floptool.cpp @@ -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; } } |