diff options
author | Vas Crabb <cuavas@users.noreply.github.com> | 2021-08-22 09:06:15 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-22 09:06:15 +1000 |
commit | e8bbea1fc6e94e14768509d322f6c624403ffb36 (patch) | |
tree | 74dd1606a900d83de8aecff17a6737af4113308d /src/tools | |
parent | e319bde5fc3696d7f48f62b15b6366c4377fe5d1 (diff) |
formats, osd, util: Started refactoring file I/O stuff. (#8456)
Added more modern generic I/O interfaces with implementation backed by stdio, osd_file and core_file, replacing io_generic. Also replaced core_file's build-in zlib compression with a filter.
unzip.cpp, un7z.cpp: Added option to supply abstract I/O interface rather than filename.
Converted osd_file, core_file, archive_file, chd_file and device_image_interface to use std::error_condition rather than their own error enums.
Allow mounting TI-99 RPK from inside archives.
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/castool.cpp | 15 | ||||
-rw-r--r-- | src/tools/chdman.cpp | 265 | ||||
-rw-r--r-- | src/tools/floptool.cpp | 16 | ||||
-rw-r--r-- | src/tools/image_handler.cpp | 116 | ||||
-rw-r--r-- | src/tools/image_handler.h | 22 | ||||
-rw-r--r-- | src/tools/imgtool/iflopimg.cpp | 83 | ||||
-rw-r--r-- | src/tools/imgtool/iflopimg.h | 11 | ||||
-rw-r--r-- | src/tools/imgtool/imghd.cpp | 57 | ||||
-rw-r--r-- | src/tools/imgtool/imghd.h | 3 | ||||
-rw-r--r-- | src/tools/imgtool/imgtool.cpp | 12 | ||||
-rw-r--r-- | src/tools/imgtool/library.h | 28 | ||||
-rw-r--r-- | src/tools/imgtool/main.cpp | 2 | ||||
-rw-r--r-- | src/tools/imgtool/modules/hp85_tape.cpp | 56 | ||||
-rw-r--r-- | src/tools/imgtool/modules/hp9845_tape.cpp | 57 | ||||
-rw-r--r-- | src/tools/imgtool/stream.cpp | 255 | ||||
-rw-r--r-- | src/tools/imgtool/stream.h | 141 | ||||
-rw-r--r-- | src/tools/ldresample.cpp | 55 | ||||
-rw-r--r-- | src/tools/ldverify.cpp | 29 | ||||
-rw-r--r-- | src/tools/pngcmp.cpp | 14 | ||||
-rw-r--r-- | src/tools/regrep.cpp | 16 | ||||
-rw-r--r-- | src/tools/romcmp.cpp | 743 | ||||
-rw-r--r-- | src/tools/split.cpp | 18 | ||||
-rw-r--r-- | src/tools/srcclean.cpp | 6 | ||||
-rw-r--r-- | src/tools/unidasm.cpp | 6 |
24 files changed, 997 insertions, 1029 deletions
diff --git a/src/tools/castool.cpp b/src/tools/castool.cpp index e03a15203d5..896c0bde5c2 100644 --- a/src/tools/castool.cpp +++ b/src/tools/castool.cpp @@ -53,6 +53,7 @@ #include "formats/zx81_p.h" #include "corestr.h" +#include "ioprocs.h" #include <cassert> #include <cctype> @@ -162,7 +163,6 @@ int CLIB_DECL main(int argc, char *argv[]) int found =0; const cassette_image::Format * const *selected_formats = nullptr; cassette_image::ptr cassette; - FILE *f; if (argc > 1) { @@ -188,21 +188,26 @@ int CLIB_DECL main(int argc, char *argv[]) return -1; } - f = fopen(argv[3], "rb"); + FILE *f = fopen(argv[3], "rb"); if (!f) { fprintf(stderr, "File %s not found.\n",argv[3]); return -1; } - if (cassette_image::open_choices(f, &stdio_ioprocs, get_extension(argv[3]), selected_formats, cassette_image::FLAG_READONLY, cassette) != cassette_image::error::SUCCESS) { + auto io = util::stdio_read_write(f, 0x00); + f = nullptr; + if (!io) { + fprintf(stderr, "Out of memory.\n"); + return -1; + } + + if (cassette_image::open_choices(std::move(io), get_extension(argv[3]), selected_formats, cassette_image::FLAG_READONLY, cassette) != cassette_image::error::SUCCESS) { fprintf(stderr, "Invalid format of input file.\n"); - fclose(f); return -1; } cassette->dump(argv[4]); cassette.reset(); - fclose(f); goto theend; } } diff --git a/src/tools/chdman.cpp b/src/tools/chdman.cpp index 835a87c18c3..e0243ce7277 100644 --- a/src/tools/chdman.cpp +++ b/src/tools/chdman.cpp @@ -294,8 +294,8 @@ public: return 0; if (offset + length > m_maxoffset) length = m_maxoffset - offset; - chd_error err = m_file.read_bytes(offset, dest, length); - if (err != CHDERR_NONE) + std::error_condition err = m_file.read_bytes(offset, dest, length); + if (err) throw err; // if we have TOC - detect audio sectors and swap data @@ -385,9 +385,9 @@ public: { m_file.reset(); m_lastfile = m_info.track[tracknum].fname; - osd_file::error filerr = util::core_file::open(m_lastfile, OPEN_FLAG_READ, m_file); - if (filerr != osd_file::error::NONE) - report_error(1, "Error opening input file (%s)'", m_lastfile.c_str()); + std::error_condition const filerr = util::core_file::open(m_lastfile, OPEN_FLAG_READ, m_file); + if (filerr) + report_error(1, "Error opening input file (%s): %s", m_lastfile, filerr.message()); } // iterate over frames @@ -411,9 +411,9 @@ public: { m_file.reset(); m_lastfile = m_info.track[tracknum+1].fname; - osd_file::error filerr = util::core_file::open(m_lastfile, OPEN_FLAG_READ, m_file); - if (filerr != osd_file::error::NONE) - report_error(1, "Error opening input file (%s)'", m_lastfile.c_str()); + std::error_condition const filerr = util::core_file::open(m_lastfile, OPEN_FLAG_READ, m_file); + if (filerr) + report_error(1, "Error opening input file (%s): %s", m_lastfile, filerr.message()); } if (src_frame_start < src_track_end) @@ -430,7 +430,7 @@ public: : src_frame_start, SEEK_SET); uint32_t count = m_file->read(dest, bytesperframe); if (count != bytesperframe) - report_error(1, "Error reading input file (%s)'", m_lastfile.c_str()); + report_error(1, "Error reading input file (%s)'", m_lastfile); } // swap if appropriate @@ -1035,18 +1035,18 @@ static void parse_input_chd_parameters(const parameters_map ¶ms, chd_file &i auto input_chd_parent_str = params.find(OPTION_INPUT_PARENT); if (input_chd_parent_str != params.end()) { - chd_error err = input_parent_chd.open(input_chd_parent_str->second->c_str()); - if (err != CHDERR_NONE) - report_error(1, "Error opening parent CHD file (%s): %s", input_chd_parent_str->second->c_str(), chd_file::error_string(err)); + std::error_condition err = input_parent_chd.open(*input_chd_parent_str->second); + if (err) + report_error(1, "Error opening parent CHD file (%s): %s", *input_chd_parent_str->second, err.message()); } // process input file auto input_chd_str = params.find(OPTION_INPUT); if (input_chd_str != params.end()) { - chd_error err = input_chd.open(input_chd_str->second->c_str(), writeable, input_parent_chd.opened() ? &input_parent_chd : nullptr); - if (err != CHDERR_NONE) - report_error(1, "Error opening CHD file (%s): %s", input_chd_str->second->c_str(), chd_file::error_string(err)); + std::error_condition err = input_chd.open(*input_chd_str->second, writeable, input_parent_chd.opened() ? &input_parent_chd : nullptr); + if (err) + report_error(1, "Error opening CHD file (%s): %s", *input_chd_str->second, err.message()); } } @@ -1102,8 +1102,8 @@ static void check_existing_output_file(const parameters_map ¶ms, const char if (params.find(OPTION_OUTPUT_FORCE) == params.end()) { util::core_file::ptr file; - osd_file::error filerr = util::core_file::open(filename, OPEN_FLAG_READ, file); - if (filerr == osd_file::error::NONE) + std::error_condition const filerr = util::core_file::open(filename, OPEN_FLAG_READ, file); + if (!filerr) { file.reset(); report_error(1, "Error: file already exists (%s)\nUse --force (or -f) to force overwriting", filename); @@ -1123,9 +1123,9 @@ static std::string *parse_output_chd_parameters(const parameters_map ¶ms, ch auto output_chd_parent_str = params.find(OPTION_OUTPUT_PARENT); if (output_chd_parent_str != params.end()) { - chd_error err = output_parent_chd.open(output_chd_parent_str->second->c_str()); - if (err != CHDERR_NONE) - report_error(1, "Error opening parent CHD file (%s): %s", output_chd_parent_str->second->c_str(), chd_file::error_string(err)); + std::error_condition err = output_parent_chd.open(*output_chd_parent_str->second); + if (err) + report_error(1, "Error opening parent CHD file (%s): %s", *output_chd_parent_str->second, err.message()); } // process output file @@ -1180,10 +1180,10 @@ static void parse_compression(const parameters_map ¶ms, chd_codec_type compr { std::string name(*compression_str->second, start, (end == -1) ? -1 : end - start); if (name.length() != 4) - report_error(1, "Invalid compressor '%s' specified", name.c_str()); + report_error(1, "Invalid compressor '%s' specified", name); chd_codec_type type = CHD_MAKE_TAG(name[0], name[1], name[2], name[3]); if (!chd_codec_list::codec_exists(type)) - report_error(1, "Invalid compressor '%s' specified", name.c_str()); + report_error(1, "Invalid compressor '%s' specified", name); compression[index++] = type; if (end == -1) break; @@ -1257,16 +1257,16 @@ static void compress_common(chd_file_compressor &chd) // loop until done double complete, ratio; - chd_error err; - while ((err = chd.compress_continue(complete, ratio)) == CHDERR_WALKING_PARENT || err == CHDERR_COMPRESSING) - if (err == CHDERR_WALKING_PARENT) + std::error_condition err; + while ((err = chd.compress_continue(complete, ratio)) == chd_file::error::WALKING_PARENT || err == chd_file::error::COMPRESSING) + if (err == chd_file::error::WALKING_PARENT) progress(false, "Examining parent, %.1f%% complete... \r", 100.0 * complete); else progress(false, "Compressing, %.1f%% complete... (ratio=%.1f%%) \r", 100.0 * complete, 100.0 * ratio); // handle errors - if (err != CHDERR_NONE) - report_error(1, "Error during compression: %-40s", chd_file::error_string(err)); + if (err) + report_error(1, "Error during compression: %-40s", err.message()); // final progress update progress(true, "Compression complete ... final ratio = %.1f%% \n", 100.0 * ratio); @@ -1447,15 +1447,17 @@ static void do_info(parameters_map ¶ms) // output cmpression and size information chd_codec_type compression[4] = { input_chd.compression(0), input_chd.compression(1), input_chd.compression(2), input_chd.compression(3) }; + uint64_t filesize = 0; + input_chd.file().length(filesize); printf("Logical size: %s bytes\n", big_int_string(input_chd.logical_bytes()).c_str()); printf("Hunk Size: %s bytes\n", big_int_string(input_chd.hunk_bytes()).c_str()); printf("Total Hunks: %s\n", big_int_string(input_chd.hunk_count()).c_str()); printf("Unit Size: %s bytes\n", big_int_string(input_chd.unit_bytes()).c_str()); printf("Total Units: %s\n", big_int_string(input_chd.unit_count()).c_str()); printf("Compression: %s\n", compression_string(compression).c_str()); - printf("CHD size: %s bytes\n", big_int_string(static_cast<util::core_file &>(input_chd).size()).c_str()); + printf("CHD size: %s bytes\n", big_int_string(filesize).c_str()); if (compression[0] != CHD_CODEC_NONE) - printf("Ratio: %.1f%%\n", 100.0 * double(static_cast<util::core_file &>(input_chd).size()) / double(input_chd.logical_bytes())); + printf("Ratio: %.1f%%\n", 100.0 * double(filesize) / double(input_chd.logical_bytes())); // add SHA1 output util::sha1_t overall = input_chd.sha1(); @@ -1477,8 +1479,8 @@ static void do_info(parameters_map ¶ms) // get the indexed metadata item; stop when we hit an error chd_metadata_tag metatag; uint8_t metaflags; - chd_error err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index, buffer, metatag, metaflags); - if (err != CHDERR_NONE) + std::error_condition err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index, buffer, metatag, metaflags); + if (err) break; // determine our index @@ -1523,9 +1525,9 @@ static void do_info(parameters_map ¶ms) // get info on this hunk chd_codec_type codec; uint32_t compbytes; - chd_error err = input_chd.hunk_info(hunknum, codec, compbytes); - if (err != CHDERR_NONE) - report_error(1, "Error getting info on hunk %d: %s", hunknum, chd_file::error_string(err)); + std::error_condition err = input_chd.hunk_info(hunknum, codec, compbytes); + if (err) + report_error(1, "Error getting info on hunk %d: %s", hunknum, err.message()); // decode into our data if (codec > CHD_CODEC_MINI) @@ -1603,9 +1605,9 @@ static void do_verify(parameters_map ¶ms) // determine how much to read uint32_t bytes_to_read = (std::min<uint64_t>)(buffer.size(), input_chd.logical_bytes() - offset); - chd_error err = input_chd.read_bytes(offset, &buffer[0], bytes_to_read); - if (err != CHDERR_NONE) - report_error(1, "Error reading CHD file (%s): %s", params.find(OPTION_INPUT)->second->c_str(), chd_file::error_string(err)); + std::error_condition err = input_chd.read_bytes(offset, &buffer[0], bytes_to_read); + if (err) + report_error(1, "Error reading CHD file (%s): %s", *params.find(OPTION_INPUT)->second, err.message()); // add to the checksum rawsha1.append(&buffer[0], bytes_to_read); @@ -1665,9 +1667,9 @@ static void do_create_raw(parameters_map ¶ms) auto input_file_str = params.find(OPTION_INPUT); if (input_file_str != params.end()) { - osd_file::error filerr = util::core_file::open(*input_file_str->second, OPEN_FLAG_READ, input_file); - if (filerr != osd_file::error::NONE) - report_error(1, "Unable to open file (%s)", input_file_str->second->c_str()); + std::error_condition const filerr = util::core_file::open(*input_file_str->second, OPEN_FLAG_READ, input_file); + if (filerr) + report_error(1, "Unable to open file (%s): %s", *input_file_str->second, filerr.message()); } // process output CHD @@ -1720,13 +1722,13 @@ static void do_create_raw(parameters_map ¶ms) { // create the new CHD std::unique_ptr<chd_file_compressor> chd(new chd_rawfile_compressor(*input_file, input_start, input_end)); - chd_error err; + std::error_condition err; if (output_parent.opened()) err = chd->create(output_chd_str->c_str(), input_end - input_start, hunk_size, compression, output_parent); else err = chd->create(output_chd_str->c_str(), input_end - input_start, hunk_size, unit_size, compression); - if (err != CHDERR_NONE) - report_error(1, "Error creating CHD file (%s): %s", output_chd_str->c_str(), chd_file::error_string(err)); + if (err) + report_error(1, "Error creating CHD file (%s): %s", output_chd_str, err.message()); // if we have a parent, copy forward all the metadata if (output_parent.opened()) @@ -1758,9 +1760,9 @@ static void do_create_hd(parameters_map ¶ms) auto input_file_str = params.find(OPTION_INPUT); if (input_file_str != params.end()) { - osd_file::error filerr = util::core_file::open(*input_file_str->second, OPEN_FLAG_READ, input_file); - if (filerr != osd_file::error::NONE) - report_error(1, "Unable to open file (%s)", input_file_str->second->c_str()); + std::error_condition const filerr = util::core_file::open(*input_file_str->second, OPEN_FLAG_READ, input_file); + if (filerr) + report_error(1, "Unable to open file (%s): %s", *input_file_str->second, filerr.message()); } // process output CHD @@ -1833,13 +1835,13 @@ static void do_create_hd(parameters_map ¶ms) if (ident_str != params.end()) { // load the file - osd_file::error filerr = util::core_file::load(ident_str->second->c_str(), identdata); - if (filerr != osd_file::error::NONE) - report_error(1, "Error reading ident file (%s)", ident_str->second->c_str()); + std::error_condition const filerr = util::core_file::load(*ident_str->second, identdata); + if (filerr) + report_error(1, "Error reading ident file (%s): %s", *ident_str->second, filerr.message()); // must be at least 14 bytes; extract CHS data from there if (identdata.size() < 14) - report_error(1, "Ident file '%s' is invalid (too short)", ident_str->second->c_str()); + report_error(1, "Ident file '%s' is invalid (too short)", *ident_str->second); cylinders = (identdata[3] << 8) | identdata[2]; heads = (identdata[7] << 8) | identdata[6]; sectors = (identdata[13] << 8) | identdata[12]; @@ -1870,7 +1872,7 @@ static void do_create_hd(parameters_map ¶ms) if (output_parent.opened() && cylinders == 0) { std::string metadata; - if (output_parent.read_metadata(HARD_DISK_METADATA_TAG, 0, metadata) != CHDERR_NONE) + if (output_parent.read_metadata(HARD_DISK_METADATA_TAG, 0, metadata)) report_error(1, "Unable to find hard disk metadata in parent CHD"); if (sscanf(metadata.c_str(), HARD_DISK_METADATA_FORMAT, &cylinders, &heads, §ors, §or_size) != 4) report_error(1, "Error parsing hard disk metadata in parent CHD"); @@ -1917,26 +1919,26 @@ static void do_create_hd(parameters_map ¶ms) std::unique_ptr<chd_file_compressor> chd; if (input_file) chd.reset(new chd_rawfile_compressor(*input_file, input_start, input_end)); else chd.reset(new chd_zero_compressor(input_start, input_end)); - chd_error err; + std::error_condition err; if (output_parent.opened()) err = chd->create(output_chd_str->c_str(), uint64_t(totalsectors) * uint64_t(sector_size), hunk_size, compression, output_parent); else err = chd->create(output_chd_str->c_str(), uint64_t(totalsectors) * uint64_t(sector_size), hunk_size, sector_size, compression); - if (err != CHDERR_NONE) - report_error(1, "Error creating CHD file (%s): %s", output_chd_str->c_str(), chd_file::error_string(err)); + if (err) + report_error(1, "Error creating CHD file (%s): %s", output_chd_str, err.message()); // add the standard hard disk metadata std::string metadata = string_format(HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sector_size); err = chd->write_metadata(HARD_DISK_METADATA_TAG, 0, metadata); - if (err != CHDERR_NONE) - report_error(1, "Error adding hard disk metadata: %s", chd_file::error_string(err)); + if (err) + report_error(1, "Error adding hard disk metadata: %s", err.message()); // write the ident if present if (!identdata.empty()) { err = chd->write_metadata(HARD_DISK_IDENT_METADATA_TAG, 0, identdata); - if (err != CHDERR_NONE) - report_error(1, "Error adding hard disk metadata: %s", chd_file::error_string(err)); + if (err) + report_error(1, "Error adding hard disk metadata: %s", err.message()); } // compress it generically @@ -1967,9 +1969,9 @@ static void do_create_cd(parameters_map ¶ms) auto input_file_str = params.find(OPTION_INPUT); if (input_file_str != params.end()) { - chd_error err = chdcd_parse_toc(input_file_str->second->c_str(), toc, track_info); - if (err != CHDERR_NONE) - report_error(1, "Error parsing input file (%s: %s)\n", input_file_str->second->c_str(), chd_file::error_string(err)); + std::error_condition err = chdcd_parse_toc(input_file_str->second->c_str(), toc, track_info); + if (err) + report_error(1, "Error parsing input file (%s: %s)\n", *input_file_str->second, err.message()); } // process output CHD @@ -2016,18 +2018,18 @@ static void do_create_cd(parameters_map ¶ms) { // create the new CD chd = new chd_cd_compressor(toc, track_info); - chd_error err; + std::error_condition err; if (output_parent.opened()) err = chd->create(output_chd_str->c_str(), uint64_t(totalsectors) * uint64_t(CD_FRAME_SIZE), hunk_size, compression, output_parent); else err = chd->create(output_chd_str->c_str(), uint64_t(totalsectors) * uint64_t(CD_FRAME_SIZE), hunk_size, CD_FRAME_SIZE, compression); - if (err != CHDERR_NONE) - report_error(1, "Error creating CHD file (%s): %s", output_chd_str->c_str(), chd_file::error_string(err)); + if (err) + report_error(1, "Error creating CHD file (%s): %s", *output_chd_str, err.message()); // add the standard CD metadata; we do this even if we have a parent because it might be different err = cdrom_write_metadata(chd, &toc); - if (err != CHDERR_NONE) - report_error(1, "Error adding CD metadata: %s", chd_file::error_string(err)); + if (err) + report_error(1, "Error adding CD metadata: %s", err.message()); // compress it generically compress_common(*chd); @@ -2059,7 +2061,7 @@ static void do_create_ld(parameters_map ¶ms) { avi_file::error avierr = avi_file::open(*input_file_str->second, input_file); if (avierr != avi_file::error::NONE) - report_error(1, "Error opening AVI file (%s): %s\n", input_file_str->second->c_str(), avi_file::error_string(avierr)); + report_error(1, "Error opening AVI file (%s): %s\n", *input_file_str->second, avi_file::error_string(avierr)); } const avi_file::movie_info &aviinfo = input_file->get_movie_info(); @@ -2133,19 +2135,19 @@ static void do_create_ld(parameters_map ¶ms) { // create the new CHD chd = new chd_avi_compressor(*input_file, info, input_start, input_end); - chd_error err; + std::error_condition err; if (output_parent.opened()) err = chd->create(output_chd_str->c_str(), uint64_t(input_end - input_start) * hunk_size, hunk_size, compression, output_parent); else err = chd->create(output_chd_str->c_str(), uint64_t(input_end - input_start) * hunk_size, hunk_size, info.bytes_per_frame, compression); - if (err != CHDERR_NONE) - report_error(1, "Error creating CHD file (%s): %s", output_chd_str->c_str(), chd_file::error_string(err)); + if (err) + report_error(1, "Error creating CHD file (%s): %s", *output_chd_str, err.message()); // write the core A/V metadata std::string metadata = string_format(AV_METADATA_FORMAT, info.fps_times_1million / 1000000, info.fps_times_1million % 1000000, info.width, info.height, info.interlaced, info.channels, info.rate); err = chd->write_metadata(AV_METADATA_TAG, 0, metadata); - if (err != CHDERR_NONE) - report_error(1, "Error adding AV metadata: %s\n", chd_file::error_string(err)); + if (err) + report_error(1, "Error adding AV metadata: %s\n", err.message()); // create the compressor and then run it generically compress_common(*chd); @@ -2154,8 +2156,8 @@ static void do_create_ld(parameters_map ¶ms) if (info.height == 524/2 || info.height == 624/2) { err = chd->write_metadata(AV_LD_METADATA_TAG, 0, chd->ldframedata(), 0); - if (err != CHDERR_NONE) - report_error(1, "Error adding AVLD metadata: %s\n", chd_file::error_string(err)); + if (err) + report_error(1, "Error adding AVLD metadata: %s\n", err.message()); } delete chd; } @@ -2202,15 +2204,15 @@ static void do_copy(parameters_map ¶ms) chd_codec_type compression[4]; { std::vector<uint8_t> metadata; - if (input_chd.read_metadata(HARD_DISK_METADATA_TAG, 0, metadata) == CHDERR_NONE) + if (!input_chd.read_metadata(HARD_DISK_METADATA_TAG, 0, metadata)) memcpy(compression, s_default_hd_compression, sizeof(compression)); - else if (input_chd.read_metadata(AV_METADATA_TAG, 0, metadata) == CHDERR_NONE) + else if (!input_chd.read_metadata(AV_METADATA_TAG, 0, metadata)) memcpy(compression, s_default_ld_compression, sizeof(compression)); - else if (input_chd.read_metadata(CDROM_OLD_METADATA_TAG, 0, metadata) == CHDERR_NONE || - input_chd.read_metadata(CDROM_TRACK_METADATA_TAG, 0, metadata) == CHDERR_NONE || - input_chd.read_metadata(CDROM_TRACK_METADATA2_TAG, 0, metadata) == CHDERR_NONE || - input_chd.read_metadata(GDROM_OLD_METADATA_TAG, 0, metadata) == CHDERR_NONE || - input_chd.read_metadata(GDROM_TRACK_METADATA_TAG, 0, metadata) == CHDERR_NONE) + else if (!input_chd.read_metadata(CDROM_OLD_METADATA_TAG, 0, metadata) || + !input_chd.read_metadata(CDROM_TRACK_METADATA_TAG, 0, metadata) || + !input_chd.read_metadata(CDROM_TRACK_METADATA2_TAG, 0, metadata) || + !input_chd.read_metadata(GDROM_OLD_METADATA_TAG, 0, metadata) || + !input_chd.read_metadata(GDROM_TRACK_METADATA_TAG, 0, metadata)) memcpy(compression, s_default_cd_compression, sizeof(compression)); else memcpy(compression, s_default_raw_compression, sizeof(compression)); @@ -2240,13 +2242,13 @@ static void do_copy(parameters_map ¶ms) { // create the new CHD chd = new chd_chdfile_compressor(input_chd, input_start, input_end); - chd_error err; + std::error_condition err; if (output_parent.opened()) err = chd->create(output_chd_str->c_str(), input_end - input_start, hunk_size, compression, output_parent); else err = chd->create(output_chd_str->c_str(), input_end - input_start, hunk_size, input_chd.unit_bytes(), compression); - if (err != CHDERR_NONE) - report_error(1, "Error creating CHD file (%s): %s", output_chd_str->c_str(), chd_file::error_string(err)); + if (err) + report_error(1, "Error creating CHD file (%s): %s", *output_chd_str, err.message()); // clone all the metadata, upgrading where appropriate std::vector<uint8_t> metadata; @@ -2255,7 +2257,7 @@ static void do_copy(parameters_map ¶ms) uint32_t index = 0; bool redo_cd = false; bool cdda_swap = false; - for (err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index++, metadata, metatag, metaflags); err == CHDERR_NONE; err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index++, metadata, metatag, metaflags)) + for (err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index++, metadata, metatag, metaflags); !err; err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index++, metadata, metatag, metaflags)) { // if this is an old CD-CHD tag, note that we want to re-do it if (metatag == CDROM_OLD_METADATA_TAG || metatag == CDROM_TRACK_METADATA_TAG) @@ -2272,8 +2274,8 @@ static void do_copy(parameters_map ¶ms) // otherwise, clone it err = chd->write_metadata(metatag, CHDMETAINDEX_APPEND, metadata, metaflags); - if (err != CHDERR_NONE) - report_error(1, "Error writing cloned metadata: %s", chd_file::error_string(err)); + if (err) + report_error(1, "Error writing cloned metadata: %s", err.message()); } // if we need to re-do the CD metadata, do it now @@ -2284,8 +2286,8 @@ static void do_copy(parameters_map ¶ms) report_error(1, "Error upgrading CD metadata"); const cdrom_toc *toc = cdrom_get_toc(cdrom); err = cdrom_write_metadata(chd, toc); - if (err != CHDERR_NONE) - report_error(1, "Error writing upgraded CD metadata: %s", chd_file::error_string(err)); + if (err) + report_error(1, "Error writing upgraded CD metadata: %s", err.message()); if (cdda_swap) chd->m_toc = toc; } @@ -2342,9 +2344,9 @@ static void do_extract_raw(parameters_map ¶ms) try { // process output file - osd_file::error filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file); - if (filerr != osd_file::error::NONE) - report_error(1, "Unable to open file (%s)", output_file_str->second->c_str()); + std::error_condition const filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file); + if (filerr) + report_error(1, "Unable to open file (%s): %s", *output_file_str->second, filerr.message()); // copy all data std::vector<uint8_t> buffer((TEMP_BUFFER_SIZE / input_chd.hunk_bytes()) * input_chd.hunk_bytes()); @@ -2354,14 +2356,14 @@ static void do_extract_raw(parameters_map ¶ms) // determine how much to read uint32_t bytes_to_read = (std::min<uint64_t>)(buffer.size(), input_end - offset); - chd_error err = input_chd.read_bytes(offset, &buffer[0], bytes_to_read); - if (err != CHDERR_NONE) - report_error(1, "Error reading CHD file (%s): %s", params.find(OPTION_INPUT)->second->c_str(), chd_file::error_string(err)); + std::error_condition err = input_chd.read_bytes(offset, &buffer[0], bytes_to_read); + if (err) + report_error(1, "Error reading CHD file (%s): %s", *params.find(OPTION_INPUT)->second, err.message()); // write to the output uint32_t count = output_file->write(&buffer[0], bytes_to_read); if (count != bytes_to_read) - report_error(1, "Error writing to file; check disk space (%s)", output_file_str->second->c_str()); + report_error(1, "Error writing to file; check disk space (%s)", *output_file_str->second); // advance offset += bytes_to_read; @@ -2446,16 +2448,16 @@ static void do_extract_cd(parameters_map ¶ms) } // process output file - osd_file::error filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, output_toc_file); - if (filerr != osd_file::error::NONE) - report_error(1, "Unable to open file (%s)", output_file_str->second->c_str()); + std::error_condition filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, output_toc_file); + if (filerr) + report_error(1, "Unable to open file (%s): %s", *output_file_str->second, filerr.message()); // process output BIN file if (mode != MODE_GDI) { filerr = util::core_file::open(*output_bin_file_str, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file); - if (filerr != osd_file::error::NONE) - report_error(1, "Unable to open file (%s)", output_bin_file_str->c_str()); + if (filerr) + report_error(1, "Unable to open file (%s): %s", *output_bin_file_str, filerr.message()); } // determine total frames @@ -2490,8 +2492,8 @@ static void do_extract_cd(parameters_map ¶ms) output_bin_file.reset(); filerr = util::core_file::open(trackbin_name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file); - if (filerr != osd_file::error::NONE) - report_error(1, "Unable to open file (%s)", trackbin_name.c_str()); + if (filerr) + report_error(1, "Unable to open file (%s): %s", trackbin_name, filerr.message()); outputoffs = 0; } @@ -2555,7 +2557,7 @@ static void do_extract_cd(parameters_map ¶ms) output_bin_file->seek(outputoffs, SEEK_SET); uint32_t byteswritten = output_bin_file->write(&buffer[0], bufferoffs); if (byteswritten != bufferoffs) - report_error(1, "Error writing frame %d to file (%s): %s\n", frame, output_file_str->second->c_str(), chd_file::error_string(CHDERR_WRITE_ERROR)); + report_error(1, "Error writing frame %d to file (%s): %s\n", frame, *output_file_str->second, "Write error"); outputoffs += bufferoffs; bufferoffs = 0; } @@ -2595,8 +2597,8 @@ static void do_extract_ld(parameters_map ¶ms) // read core metadata std::string metadata; - chd_error err = input_chd.read_metadata(AV_METADATA_TAG, 0, metadata); - if (err != CHDERR_NONE) + std::error_condition err = input_chd.read_metadata(AV_METADATA_TAG, 0, metadata); + if (err) report_error(1, "Unable to find A/V metadata in the input CHD"); // parse the metadata @@ -2666,7 +2668,7 @@ static void do_extract_ld(parameters_map ¶ms) // process output file avi_file::error avierr = avi_file::create(*output_file_str->second, info, output_file); if (avierr != avi_file::error::NONE) - report_error(1, "Unable to open file (%s)", output_file_str->second->c_str()); + report_error(1, "Unable to open file (%s)", *output_file_str->second); // create the codec configuration avhuff_decoder::config avconfig; @@ -2693,11 +2695,12 @@ static void do_extract_ld(parameters_map ¶ms) input_chd.codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &avconfig); // read the hunk into the buffers - chd_error err = input_chd.read_hunk(framenum, nullptr); - if (err != CHDERR_NONE) + std::error_condition err = input_chd.read_hunk(framenum, nullptr); + if (err) { - uint64_t filepos = static_cast<util::core_file &>(input_chd).tell(); - report_error(1, "Error reading hunk %d at offset %d from CHD file (%s): %s\n", framenum, filepos, params.find(OPTION_INPUT)->second->c_str(), chd_file::error_string(err)); + uint64_t filepos = ~uint64_t(0); + input_chd.file().tell(filepos); + report_error(1, "Error reading hunk %d at offset %d from CHD file (%s): %s\n", framenum, filepos, *params.find(OPTION_INPUT)->second, err.message()); } // write audio @@ -2705,7 +2708,7 @@ static void do_extract_ld(parameters_map ¶ms) { avi_file::error avierr = output_file->append_sound_samples(chnum, avconfig.audio[chnum], actsamples, 0); if (avierr != avi_file::error::NONE) - report_error(1, "Error writing samples for hunk %d to file (%s): %s\n", framenum, output_file_str->second->c_str(), avi_file::error_string(avierr)); + report_error(1, "Error writing samples for hunk %d to file (%s): %s\n", framenum, *output_file_str->second, avi_file::error_string(avierr)); } // write video @@ -2713,7 +2716,7 @@ static void do_extract_ld(parameters_map ¶ms) { avi_file::error avierr = output_file->append_video_frame(fullbitmap); if (avierr != avi_file::error::NONE) - report_error(1, "Error writing video for hunk %d to file (%s): %s\n", framenum, output_file_str->second->c_str(), avi_file::error_string(avierr)); + report_error(1, "Error writing video for hunk %d to file (%s): %s\n", framenum, *output_file_str->second, avi_file::error_string(avierr)); } } @@ -2773,9 +2776,9 @@ static void do_add_metadata(parameters_map ¶ms) std::vector<uint8_t> file; if (file_str != params.end()) { - osd_file::error filerr = util::core_file::load(file_str->second->c_str(), file); - if (filerr != osd_file::error::NONE) - report_error(1, "Error reading metadata file (%s)", file_str->second->c_str()); + std::error_condition const filerr = util::core_file::load(*file_str->second, file); + if (filerr) + report_error(1, "Error reading metadata file (%s): %s", *file_str->second, filerr.message()); } // make sure we have one or the other @@ -2799,13 +2802,13 @@ static void do_add_metadata(parameters_map ¶ms) printf("Data: %s (%d bytes)\n", file_str->second->c_str(), int(file.size())); // write the metadata - chd_error err; + std::error_condition err; if (text_str != params.end()) err = input_chd.write_metadata(tag, index, text, flags); else err = input_chd.write_metadata(tag, index, file, flags); - if (err != CHDERR_NONE) - report_error(1, "Error adding metadata: %s", chd_file::error_string(err)); + if (err) + report_error(1, "Error adding metadata: %s", err.message()); else printf("Metadata added\n"); } @@ -2843,9 +2846,9 @@ static void do_del_metadata(parameters_map ¶ms) printf("Index: %d\n", index); // write the metadata - chd_error err = input_chd.delete_metadata(tag, index); - if (err != CHDERR_NONE) - report_error(1, "Error removing metadata: %s", chd_file::error_string(err)); + std::error_condition err = input_chd.delete_metadata(tag, index); + if (err) + report_error(1, "Error removing metadata: %s", err.message()); else printf("Metadata removed\n"); } @@ -2884,9 +2887,9 @@ static void do_dump_metadata(parameters_map ¶ms) // write the metadata std::vector<uint8_t> buffer; - chd_error err = input_chd.read_metadata(tag, index, buffer); - if (err != CHDERR_NONE) - report_error(1, "Error reading metadata: %s", chd_file::error_string(err)); + std::error_condition err = input_chd.read_metadata(tag, index, buffer); + if (err) + report_error(1, "Error reading metadata: %s", err.message()); // catch errors so we can close & delete the output file util::core_file::ptr output_file; @@ -2895,14 +2898,14 @@ static void do_dump_metadata(parameters_map ¶ms) // create the file if (output_file_str != params.end()) { - osd_file::error filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file); - if (filerr != osd_file::error::NONE) - report_error(1, "Unable to open file (%s)", output_file_str->second->c_str()); + std::error_condition const filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file); + if (filerr) + report_error(1, "Unable to open file (%s): %s", *output_file_str->second, filerr.message()); // output the metadata uint32_t count = output_file->write(&buffer[0], buffer.size()); if (count != buffer.size()) - report_error(1, "Error writing file (%s)", output_file_str->second->c_str()); + report_error(1, "Error writing file (%s)", *output_file_str->second); output_file.reset(); // provide some feedback @@ -3056,9 +3059,9 @@ int CLIB_DECL main(int argc, char *argv[]) (*s_command.handler)(parameters); return 0; } - catch (chd_error &err) + catch (std::error_condition const &err) { - fprintf(stderr, "CHD error occurred (main): %s\n", chd_file::error_string(err)); + fprintf(stderr, "CHD error occurred (main): %s\n", err.message().c_str()); return 1; } catch (fatal_error &err) diff --git a/src/tools/floptool.cpp b/src/tools/floptool.cpp index 6e9e2097233..f021e084a62 100644 --- a/src/tools/floptool.cpp +++ b/src/tools/floptool.cpp @@ -6,17 +6,19 @@ ***************************************************************************/ -#include <cstdio> -#include <cstring> +#include "image_handler.h" + +#include "corestr.h" +#include "ioprocs.h" + +#include <cassert> #include <cctype> +#include <cstdarg> +#include <cstdio> #include <cstdlib> +#include <cstring> #include <ctime> -#include <cstdarg> -#include <cassert> -#include <map> -#include "image_handler.h" -#include "corestr.h" static formats_table formats; diff --git a/src/tools/image_handler.cpp b/src/tools/image_handler.cpp index abb45de2db3..a520383846d 100644 --- a/src/tools/image_handler.cpp +++ b/src/tools/image_handler.cpp @@ -4,10 +4,16 @@ // Image generic handler class and helpers #include "image_handler.h" + #include "formats/all.h" #include "formats/fsblk_vec.h" #include "formats/fs_unformatted.h" +#include "ioprocs.h" +#include "ioprocsfill.h" +#include "ioprocsvec.h" + + // Fatalerror implementation emu_fatalerror::emu_fatalerror(util::format_argument_pack<std::ostream> const &args) @@ -21,70 +27,6 @@ emu_fatalerror::emu_fatalerror(int _exitcode, util::format_argument_pack<std::os { } -// io_generic from vector<u8> - -static void ram_closeproc(void *file) -{ - auto f = (iofile_ram *)file; - delete f; -} - -static int ram_seekproc(void *file, int64_t offset, int whence) -{ - auto f = (iofile_ram *)file; - switch(whence) { - case SEEK_SET: f->pos = offset; break; - case SEEK_CUR: f->pos += offset; break; - case SEEK_END: f->pos = f->data->size() + offset; break; - } - - if(whence == SEEK_CUR) - f->pos = std::max<int64_t>(f->pos, 0); - else - f->pos = std::clamp<int64_t>(f->pos, 0, f->data->size()); - return 0; -} - -static size_t ram_readproc(void *file, void *buffer, size_t length) -{ - auto f = (iofile_ram *)file; - size_t l = std::min<std::common_type_t<size_t, int64_t> >(length, f->data->size() - f->pos); - memcpy(buffer, f->data->data() + f->pos, l); - return l; -} - -static size_t ram_writeproc(void *file, const void *buffer, size_t length) -{ - auto f = (iofile_ram *)file; - size_t l = std::max<std::common_type_t<size_t, int64_t> >(f->pos + length, f->data->size()); - f->data->resize(l); - memcpy(f->data->data() + f->pos, buffer, length); - return length; -} - -static uint64_t ram_filesizeproc(void *file) -{ - auto f = (iofile_ram *)file; - return f->data->size(); -} - - -static const io_procs iop_ram = { - ram_closeproc, - ram_seekproc, - ram_readproc, - ram_writeproc, - ram_filesizeproc -}; - -io_generic *ram_open(std::vector<u8> &data) -{ - iofile_ram *f = new iofile_ram; - f->data = &data; - f->pos = 0; - return new io_generic({ &iop_ram, f }); -} - // Format enumeration @@ -304,45 +246,37 @@ std::vector<std::pair<u8, const floppy_format_info *>> image_handler::identify(c std::vector<std::pair<u8, const floppy_format_info *>> res; std::vector<uint32_t> variants; - std::string msg = util::string_format("Error opening %s for reading", m_on_disk_path); FILE *f = fopen(m_on_disk_path.c_str(), "rb"); if (!f) { + std::string msg = util::string_format("Error opening %s for reading", m_on_disk_path); perror(msg.c_str()); return res; } - io_generic io; - io.file = f; - io.procs = &stdio_ioprocs_noclose; - io.filler = 0xff; + auto io = util::stdio_read(f, 0xff); for(const auto &e : formats.floppy_format_info_by_key) { - u8 score = e.second->m_format->identify(&io, floppy_image::FF_UNKNOWN, variants); + u8 score = e.second->m_format->identify(*io, floppy_image::FF_UNKNOWN, variants); if(score) res.emplace_back(std::make_pair(score, e.second)); } - fclose(f); - return res; } bool image_handler::floppy_load(const floppy_format_info *format) { std::vector<uint32_t> variants; - std::string msg = util::string_format("Error opening %s for reading", m_on_disk_path); FILE *f = fopen(m_on_disk_path.c_str(), "rb"); if (!f) { + std::string msg = util::string_format("Error opening %s for reading", m_on_disk_path); perror(msg.c_str()); return true; } - io_generic io; - io.file = f; - io.procs = &stdio_ioprocs_noclose; - io.filler = 0xff; + auto io = util::stdio_read(f, 0xff); - return !format->m_format->load(&io, floppy_image::FF_UNKNOWN, variants, &m_floppy_image); + return !format->m_format->load(*io, floppy_image::FF_UNKNOWN, variants, &m_floppy_image); } bool image_handler::floppy_save(const floppy_format_info *format) @@ -355,12 +289,9 @@ bool image_handler::floppy_save(const floppy_format_info *format) return true; } - io_generic io; - io.file = f; - io.procs = &stdio_ioprocs_noclose; - io.filler = 0xff; + auto io = util::stdio_read_write(f, 0xff); - return !format->m_format->save(&io, variants, &m_floppy_image); + return !format->m_format->save(*io, variants, &m_floppy_image); } void image_handler::floppy_create(const floppy_create_info *format, fs_meta_data meta) @@ -372,14 +303,13 @@ void image_handler::floppy_create(const floppy_create_info *format, fs_meta_data auto fs = format->m_manager->mount(blockdev); fs->format(meta); - auto iog = ram_open(img); auto source_format = format->m_type(); - source_format->load(iog, floppy_image::FF_UNKNOWN, variants, &m_floppy_image); + auto io = util::ram_read(img.data(), img.size(), 0xff); + source_format->load(*io, floppy_image::FF_UNKNOWN, variants, &m_floppy_image); delete source_format; - delete iog; - - } else + } else { fs_unformatted::format(format->m_key, &m_floppy_image); + } } bool image_handler::floppy_mount_fs(const filesystem_format *format) @@ -390,11 +320,10 @@ bool image_handler::floppy_mount_fs(const filesystem_format *format) std::vector<uint32_t> variants; m_floppy_fs_converter = ci->m_type; m_sector_image.clear(); - auto iog = ram_open(m_sector_image); auto load_format = m_floppy_fs_converter(); - load_format->save(iog, variants, &m_floppy_image); + util::random_read_write_fill_wrapper<util::vector_read_write_adapter<u8>, 0xff> io(m_sector_image); + load_format->save(io, variants, &m_floppy_image); delete load_format; - delete iog; } if(ci->m_image_size == m_sector_image.size()) @@ -425,11 +354,10 @@ bool image_handler::hd_mount_fs(const filesystem_format *format) void image_handler::fs_to_floppy() { std::vector<uint32_t> variants; - auto iog = ram_open(m_sector_image); + auto io = util::ram_read(m_sector_image.data(), m_sector_image.size(), 0xff); auto format = m_floppy_fs_converter(); - format->load(iog, floppy_image::FF_UNKNOWN, variants, &m_floppy_image); + format->load(*io, floppy_image::FF_UNKNOWN, variants, &m_floppy_image); delete format; - delete iog; } std::vector<std::string> image_handler::path_split(std::string path) const diff --git a/src/tools/image_handler.h b/src/tools/image_handler.h index f004bd7d91f..d9a861bb3fd 100644 --- a/src/tools/image_handler.h +++ b/src/tools/image_handler.h @@ -3,27 +3,26 @@ // Image generic handler class and helpers -#ifndef TOOLS_IMAGE_HANDLER_H -#define TOOLS_IMAGE_HANDLER_H +#ifndef MAME_TOOLS_IMAGE_HANDLER_H +#define MAME_TOOLS_IMAGE_HANDLER_H + +#pragma once #include "../emu/emucore.h" + #include "formats/fsmgr.h" +#include <cstdint> #include <map> -#include <vector> #include <memory> +#include <string> +#include <vector> + using u8 = uint8_t; using u16 = uint16_t; using u32 = uint32_t; -struct iofile_ram { - std::vector<u8> *data; - int64_t pos; -}; - -io_generic *ram_open(std::vector<u8> &data); - struct floppy_format_info { floppy_image_format_t *m_format; std::string m_category; @@ -117,5 +116,4 @@ private: }; -#endif - +#endif // MAME_TOOLS_IMAGE_HANDLER_H diff --git a/src/tools/imgtool/iflopimg.cpp b/src/tools/imgtool/iflopimg.cpp index f6e79e6cd5d..951b75978e8 100644 --- a/src/tools/imgtool/iflopimg.cpp +++ b/src/tools/imgtool/iflopimg.cpp @@ -8,10 +8,15 @@ *********************************************************************/ +#include "iflopimg.h" + #include "imgtool.h" -#include "formats/flopimg.h" #include "library.h" -#include "iflopimg.h" + +#include "formats/flopimg.h" + +#include "ioprocs.h" + imgtoolerr_t imgtool_floppy_error(floperr_t err) { @@ -40,57 +45,6 @@ imgtoolerr_t imgtool_floppy_error(floperr_t err) /********************************************************************* - Imgtool ioprocs -*********************************************************************/ - -static void imgtool_floppy_closeproc(void *file) -{ - delete reinterpret_cast<imgtool::stream *>(file); -} - -static int imgtool_floppy_seekproc(void *file, int64_t offset, int whence) -{ - reinterpret_cast<imgtool::stream *>(file)->seek(offset, whence); - return 0; -} - -static size_t imgtool_floppy_readproc(void *file, void *buffer, size_t length) -{ - return reinterpret_cast<imgtool::stream *>(file)->read(buffer, length); -} - -static size_t imgtool_floppy_writeproc(void *file, const void *buffer, size_t length) -{ - reinterpret_cast<imgtool::stream *>(file)->write(buffer, length); - return length; -} - -static uint64_t imgtool_floppy_filesizeproc(void *file) -{ - return reinterpret_cast<imgtool::stream *>(file)->size(); -} - -static const struct io_procs imgtool_ioprocs = -{ - imgtool_floppy_closeproc, - imgtool_floppy_seekproc, - imgtool_floppy_readproc, - imgtool_floppy_writeproc, - imgtool_floppy_filesizeproc -}; - -static const struct io_procs imgtool_noclose_ioprocs = -{ - nullptr, - imgtool_floppy_seekproc, - imgtool_floppy_readproc, - imgtool_floppy_writeproc, - imgtool_floppy_filesizeproc -}; - - - -/********************************************************************* Imgtool handlers *********************************************************************/ @@ -102,11 +56,10 @@ struct imgtool_floppy_image -static imgtoolerr_t imgtool_floppy_open_internal(imgtool::image &image, imgtool::stream::ptr &&stream, int noclose) +static imgtoolerr_t imgtool_floppy_open_internal(imgtool::image &image, imgtool::stream::ptr &&stream) { floperr_t ferr; imgtoolerr_t err = IMGTOOLERR_SUCCESS; - imgtool::stream *f = nullptr; struct imgtool_floppy_image *fimg; const imgtool_class *imgclass; const struct FloppyFormat *format; @@ -117,18 +70,13 @@ static imgtoolerr_t imgtool_floppy_open_internal(imgtool::image &image, imgtool: format = (const struct FloppyFormat *) imgclass->derived_param; open = (imgtoolerr_t (*)(imgtool::image &, imgtool::stream *)) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_FLOPPY_OPEN); - // extract the pointer - f = stream.release(); - // open up the floppy - ferr = floppy_open(f, noclose ? &imgtool_noclose_ioprocs : &imgtool_ioprocs, - "", format, FLOPPY_FLAGS_READWRITE, &fimg->floppy); + ferr = floppy_open(imgtool::stream_read_write(std::move(stream), 0xff), "", format, FLOPPY_FLAGS_READWRITE, &fimg->floppy); if (ferr) { err = imgtool_floppy_error(ferr); goto done; } - f = nullptr; // the floppy object has the stream now if (open) { @@ -138,8 +86,6 @@ static imgtoolerr_t imgtool_floppy_open_internal(imgtool::image &image, imgtool: } done: - if (f) - delete f; if (err && fimg->floppy) { floppy_close(fimg->floppy); @@ -152,7 +98,7 @@ done: static imgtoolerr_t imgtool_floppy_open(imgtool::image &image, imgtool::stream::ptr &&stream) { - return imgtool_floppy_open_internal(image, std::move(stream), false); + return imgtool_floppy_open_internal(image, std::move(stream)); } @@ -161,7 +107,6 @@ static imgtoolerr_t imgtool_floppy_create(imgtool::image &image, imgtool::stream { floperr_t ferr; imgtoolerr_t err = IMGTOOLERR_SUCCESS; - imgtool::stream *f = nullptr; struct imgtool_floppy_image *fimg; const imgtool_class *imgclass; const struct FloppyFormat *format; @@ -174,17 +119,13 @@ static imgtoolerr_t imgtool_floppy_create(imgtool::image &image, imgtool::stream create = (imgtoolerr_t (*)(imgtool::image &, imgtool::stream *, util::option_resolution *)) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_FLOPPY_CREATE); open = (imgtoolerr_t (*)(imgtool::image &, imgtool::stream *)) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_FLOPPY_OPEN); - // extract the pointer - f = stream.release(); - // open up the floppy - ferr = floppy_create(f, &imgtool_ioprocs, format, opts, &fimg->floppy); + ferr = floppy_create(imgtool::stream_read_write(std::move(stream), 0xff), format, opts, &fimg->floppy); if (ferr) { err = imgtool_floppy_error(ferr); goto done; } - f = nullptr; // the floppy object has the stream now // do we have to do extra stuff when creating the image? if (create) @@ -203,8 +144,6 @@ static imgtoolerr_t imgtool_floppy_create(imgtool::image &image, imgtool::stream } done: - if (f) - delete f; if (err && fimg->floppy) { floppy_close(fimg->floppy); diff --git a/src/tools/imgtool/iflopimg.h b/src/tools/imgtool/iflopimg.h index 078a1247ae3..d27ba952e16 100644 --- a/src/tools/imgtool/iflopimg.h +++ b/src/tools/imgtool/iflopimg.h @@ -7,13 +7,16 @@ Bridge code for Imgtool into the standard floppy code *********************************************************************/ +#ifndef MAME_TOOLS_IMGTOOL_IFLOPIMG_H +#define MAME_TOOLS_IMGTOOL_IFLOPIMG_H -#ifndef IFLOPIMG_H -#define IFLOPIMG_H +#pragma once -#include "formats/flopimg.h" #include "library.h" +#include "formats/flopimg.h" + + /*************************************************************************** Prototypes @@ -38,4 +41,4 @@ imgtoolerr_t imgtool_floppy_write_sector_from_stream(imgtool::image &img, int he void *imgtool_floppy_extrabytes(imgtool::image &img); -#endif /* IFLOPIMG_H */ +#endif // MAME_TOOLS_IMGTOOL_IFLOPIMG_H diff --git a/src/tools/imgtool/imghd.cpp b/src/tools/imgtool/imghd.cpp index 45ac262a9ba..8e077295b93 100644 --- a/src/tools/imgtool/imghd.cpp +++ b/src/tools/imgtool/imghd.cpp @@ -9,34 +9,21 @@ Raphael Nabet 2003 */ +#include "imghd.h" #include "imgtool.h" #include "harddisk.h" -#include "imghd.h" -static imgtoolerr_t map_chd_error(chd_error chderr) +static imgtoolerr_t map_chd_error(std::error_condition chderr) { - imgtoolerr_t err; - - switch(chderr) - { - case CHDERR_NONE: - err = IMGTOOLERR_SUCCESS; - break; - case CHDERR_OUT_OF_MEMORY: - err = IMGTOOLERR_OUTOFMEMORY; - break; - case CHDERR_FILE_NOT_WRITEABLE: - err = IMGTOOLERR_READONLY; - break; - case CHDERR_NOT_SUPPORTED: - err = IMGTOOLERR_UNIMPLEMENTED; - break; - default: - err = IMGTOOLERR_UNEXPECTED; - break; - } - return err; + if (!chderr) + return IMGTOOLERR_SUCCESS; + else if (std::errc::not_enough_memory == chderr) + return IMGTOOLERR_OUTOFMEMORY; + else if (chd_file::error::FILE_NOT_WRITEABLE == chderr) + return IMGTOOLERR_READONLY; + else + return IMGTOOLERR_UNEXPECTED; } @@ -50,7 +37,7 @@ imgtoolerr_t imghd_create(imgtool::stream &stream, uint32_t hunksize, uint32_t c { imgtoolerr_t err = IMGTOOLERR_SUCCESS; chd_file chd; - chd_error rc; + std::error_condition rc; chd_codec_type compression[4] = { CHD_CODEC_NONE }; /* sanity check args -- see parse_hunk_size() in src/lib/util/chd.cpp */ @@ -73,8 +60,8 @@ imgtoolerr_t imghd_create(imgtool::stream &stream, uint32_t hunksize, uint32_t c const uint64_t logicalbytes = (uint64_t)cylinders * heads * sectors * seclen; /* create the new hard drive */ - rc = chd.create(*stream.core_file(), logicalbytes, hunksize, seclen, compression); - if (rc != CHDERR_NONE) + rc = chd.create(stream_read_write(stream, 0), logicalbytes, hunksize, seclen, compression); + if (rc) { err = map_chd_error(rc); return err; @@ -82,8 +69,8 @@ imgtoolerr_t imghd_create(imgtool::stream &stream, uint32_t hunksize, uint32_t c /* write the metadata */ const std::string metadata = util::string_format(HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, seclen); - err = (imgtoolerr_t)chd.write_metadata(HARD_DISK_METADATA_TAG, 0, metadata); - if (rc != CHDERR_NONE) + rc = chd.write_metadata(HARD_DISK_METADATA_TAG, 0, metadata); + if (rc) { err = map_chd_error(rc); return err; @@ -118,12 +105,12 @@ imgtoolerr_t imghd_create(imgtool::stream &stream, uint32_t hunksize, uint32_t c */ imgtoolerr_t imghd_open(imgtool::stream &stream, struct mess_hard_disk_file *hard_disk) { - chd_error chderr; + std::error_condition chderr; imgtoolerr_t err = IMGTOOLERR_SUCCESS; hard_disk->hard_disk = nullptr; - chderr = hard_disk->chd.open(*stream.core_file(), !stream.is_read_only()); + chderr = hard_disk->chd.open(stream_read_write(stream, 0), !stream.is_read_only()); if (chderr) { err = map_chd_error(chderr); @@ -174,9 +161,8 @@ void imghd_close(struct mess_hard_disk_file *disk) */ imgtoolerr_t imghd_read(struct mess_hard_disk_file *disk, uint32_t lbasector, void *buffer) { - uint32_t reply; - reply = hard_disk_read(disk->hard_disk, lbasector, buffer); - return (imgtoolerr_t)(reply ? IMGTOOLERR_SUCCESS : map_chd_error((chd_error)reply)); + uint32_t reply = hard_disk_read(disk->hard_disk, lbasector, buffer); + return reply ? IMGTOOLERR_SUCCESS : IMGTOOLERR_READERROR; } @@ -188,9 +174,8 @@ imgtoolerr_t imghd_read(struct mess_hard_disk_file *disk, uint32_t lbasector, vo */ imgtoolerr_t imghd_write(struct mess_hard_disk_file *disk, uint32_t lbasector, const void *buffer) { - uint32_t reply; - reply = hard_disk_write(disk->hard_disk, lbasector, buffer); - return (imgtoolerr_t)(reply ? IMGTOOLERR_SUCCESS : map_chd_error((chd_error)reply)); + uint32_t reply = hard_disk_write(disk->hard_disk, lbasector, buffer); + return reply ? IMGTOOLERR_SUCCESS : IMGTOOLERR_WRITEERROR; } diff --git a/src/tools/imgtool/imghd.h b/src/tools/imgtool/imghd.h index d4ae341af1e..0eadc6e2eb3 100644 --- a/src/tools/imgtool/imghd.h +++ b/src/tools/imgtool/imghd.h @@ -11,8 +11,11 @@ #ifndef IMGHD_H #define IMGHD_H +#include "stream.h" + #include "harddisk.h" + struct mess_hard_disk_file { imgtool::stream *stream; diff --git a/src/tools/imgtool/imgtool.cpp b/src/tools/imgtool/imgtool.cpp index 841147ae26e..ce4dd22d186 100644 --- a/src/tools/imgtool/imgtool.cpp +++ b/src/tools/imgtool/imgtool.cpp @@ -8,14 +8,18 @@ ***************************************************************************/ +#include "imgtool.h" +#include "library.h" +#include "modules.h" + +#include "formats/imageutl.h" + +#include "corefile.h" + #include <cstring> #include <cctype> #include <iostream> -#include "imgtool.h" -#include "formats/imageutl.h" -#include "library.h" -#include "modules.h" /*************************************************************************** diff --git a/src/tools/imgtool/library.h b/src/tools/imgtool/library.h index 7406cc2e526..f0e0532e502 100644 --- a/src/tools/imgtool/library.h +++ b/src/tools/imgtool/library.h @@ -4,29 +4,31 @@ library.h - Code relevant to the Imgtool library; analogous to the MESS/MAME driver - list. + Code relevant to the Imgtool library; analogous to the MAME driver list. - Unlike MESS and MAME which have static driver lists, Imgtool has a - concept of a library and this library is built at startup time. + Unlike MAME which has a static driver lists, Imgtool has a concept of a + library and this library is built at startup time. dynamic for which modules are added to. This makes "dynamic" modules much easier ****************************************************************************/ +#ifndef MAME_TOOLS_IMGTOOL_LIBRARY_H +#define MAME_TOOLS_IMGTOOL_LIBRARY_H -#ifndef LIBRARY_H -#define LIBRARY_H +#pragma once -#include <ctime> -#include <list> -#include <chrono> +#include "charconv.h" +#include "stream.h" #include "corestr.h" #include "opresolv.h" -#include "stream.h" -#include "unicode.h" -#include "charconv.h" #include "timeconv.h" +#include "unicode.h" + +#include <chrono> +#include <ctime> +#include <list> + namespace imgtool { @@ -542,4 +544,4 @@ private: } // namespace imgtool -#endif // LIBRARY_H +#endif // MAME_TOOLS_IMGTOOL_LIBRARY_H diff --git a/src/tools/imgtool/main.cpp b/src/tools/imgtool/main.cpp index 75fcd52e7a2..77b3d8c6874 100644 --- a/src/tools/imgtool/main.cpp +++ b/src/tools/imgtool/main.cpp @@ -11,6 +11,8 @@ #include "imgtool.h" #include "main.h" #include "modules.h" + +#include "corefile.h" #include "strformat.h" #include <cstdio> diff --git a/src/tools/imgtool/modules/hp85_tape.cpp b/src/tools/imgtool/modules/hp85_tape.cpp index 0198b6251dd..fa32042efd3 100644 --- a/src/tools/imgtool/modules/hp85_tape.cpp +++ b/src/tools/imgtool/modules/hp85_tape.cpp @@ -7,12 +7,16 @@ HP-85 tape format *********************************************************************/ - #include "imgtool.h" -#include "formats/imageutl.h" + #include "formats/hti_tape.h" +#include "formats/imageutl.h" + +#include "ioprocs.h" + #include <iostream> + // Constants static constexpr unsigned CHARS_PER_FNAME = 6; // Characters in a filename static constexpr unsigned CHARS_PER_EXT = 4; // Characters in (simulated) file extension @@ -158,48 +162,13 @@ void tape_image_85::format_img(void) finalize_allocation(); } -namespace { - int my_seekproc(void *file, int64_t offset, int whence) - { - reinterpret_cast<imgtool::stream *>(file)->seek(offset, whence); - return 0; - } - - size_t my_readproc(void *file, void *buffer, size_t length) - { - return reinterpret_cast<imgtool::stream *>(file)->read(buffer, length); - } - - size_t my_writeproc(void *file, const void *buffer, size_t length) - { - reinterpret_cast<imgtool::stream *>(file)->write(buffer, length); - return length; - } - - uint64_t my_filesizeproc(void *file) - { - return reinterpret_cast<imgtool::stream *>(file)->size(); - } - - const struct io_procs my_stream_procs = { - nullptr, - my_seekproc, - my_readproc, - my_writeproc, - my_filesizeproc - }; -} - imgtoolerr_t tape_image_85::load_from_file(imgtool::stream *stream) { - io_generic io; - io.file = (void *)stream; - io.procs = &my_stream_procs; - io.filler = 0; - - if (!image.load_tape(&io)) { + auto io = imgtool::stream_read(*stream, 0); + if (!io || !image.load_tape(*io)) { return IMGTOOLERR_READERROR; } + io.reset(); // Prevent track boundary crossing when reading directory file_track_1 = 0; @@ -422,12 +391,7 @@ imgtoolerr_t tape_image_85::save_to_file(imgtool::stream *stream) file_0.clear(); save_sif_file(track , pos , dir.size() + 1 , file_0); - io_generic io; - io.file = (void *)stream; - io.procs = &my_stream_procs; - io.filler = 0; - - image.save_tape(&io); + image.save_tape(*imgtool::stream_read_write(*stream, 0)); return IMGTOOLERR_SUCCESS; } diff --git a/src/tools/imgtool/modules/hp9845_tape.cpp b/src/tools/imgtool/modules/hp9845_tape.cpp index 7a3e90b08d1..a1ae0377180 100644 --- a/src/tools/imgtool/modules/hp9845_tape.cpp +++ b/src/tools/imgtool/modules/hp9845_tape.cpp @@ -108,11 +108,16 @@ these special characters. *********************************************************************/ -#include <bitset> - #include "imgtool.h" -#include "formats/imageutl.h" + #include "formats/hti_tape.h" +#include "formats/imageutl.h" + +#include "corefile.h" +#include "ioprocs.h" + +#include <bitset> + // Constants #define SECTOR_LEN 256 // Bytes in a sector @@ -291,49 +296,16 @@ void tape_image_t::format_img(void) dirty = true; } -static int my_seekproc(void *file, int64_t offset, int whence) -{ - reinterpret_cast<imgtool::stream *>(file)->seek(offset, whence); - return 0; -} - -static size_t my_readproc(void *file, void *buffer, size_t length) -{ - return reinterpret_cast<imgtool::stream *>(file)->read(buffer, length); -} - -static size_t my_writeproc(void *file, const void *buffer, size_t length) -{ - reinterpret_cast<imgtool::stream *>(file)->write(buffer, length); - return length; -} - -static uint64_t my_filesizeproc(void *file) -{ - return reinterpret_cast<imgtool::stream *>(file)->size(); -} - -static const struct io_procs my_stream_procs = { - nullptr, - my_seekproc, - my_readproc, - my_writeproc, - my_filesizeproc -}; - imgtoolerr_t tape_image_t::load_from_file(imgtool::stream *stream) { hti_format_t inp_image; inp_image.set_image_format(hti_format_t::HTI_DELTA_MOD_16_BITS); - io_generic io; - io.file = (void *)stream; - io.procs = &my_stream_procs; - io.filler = 0; - - if (!inp_image.load_tape(&io)) { + auto io = imgtool::stream_read(*stream, 0); + if (!io || !inp_image.load_tape(*io)) { return IMGTOOLERR_READERROR; } + io.reset(); unsigned exp_sector = 0; unsigned last_sector_on_track = SECTORS_PER_TRACK; @@ -523,12 +495,7 @@ imgtoolerr_t tape_image_t::save_to_file(imgtool::stream *stream) } } - io_generic io; - io.file = (void *)stream; - io.procs = &my_stream_procs; - io.filler = 0; - - out_image.save_tape(&io); + out_image.save_tape(*imgtool::stream_read_write(*stream, 0)); return IMGTOOLERR_SUCCESS; } diff --git a/src/tools/imgtool/stream.cpp b/src/tools/imgtool/stream.cpp index bb0d95614f3..ed9814e504a 100644 --- a/src/tools/imgtool/stream.cpp +++ b/src/tools/imgtool/stream.cpp @@ -8,19 +8,178 @@ ***************************************************************************/ +#include "stream.h" + +#include "imgtool.h" + +#include "corefile.h" +#include "ioprocs.h" +#include "unzip.h" + +#include <cassert> #include <cstdio> #include <cstring> -#include <zlib.h> -#include "unzip.h" -#include "imgtool.h" +#include <zlib.h> // for crc32 + + +namespace imgtool { + +namespace { + +class stream_read_wrapper : public virtual util::random_read +{ +public: + stream_read_wrapper(stream::ptr &&stream, std::uint8_t filler) noexcept + : m_stream(stream.release()) + , m_filler(filler) + , m_close(true) + { + assert(m_stream); + } + + stream_read_wrapper(stream &stream, std::uint8_t filler) noexcept + : m_stream(&stream) + , m_filler(filler) + , m_close(false) + { + } + + virtual ~stream_read_wrapper() + { + if (m_close) + delete m_stream; + } + + virtual std::error_condition seek(std::int64_t offset, int whence) noexcept override + { + m_stream->seek(offset, whence); + return std::error_condition(); + } + + virtual std::error_condition tell(std::uint64_t &result) noexcept override + { + result = m_stream->tell(); + return std::error_condition(); + } + + virtual std::error_condition length(std::uint64_t &result) noexcept override + { + result = m_stream->size(); + return std::error_condition(); + } + + virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override + { + actual = m_stream->read(buffer, length); + if (actual < length) + std::memset(reinterpret_cast<std::uint8_t *>(buffer) + actual, m_filler, length - actual); + return std::error_condition(); + } + + virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override + { + std::uint64_t const pos = m_stream->tell(); + m_stream->seek(offset, SEEK_SET); + actual = m_stream->read(buffer, length); + m_stream->seek(pos, SEEK_SET); + if (actual < length) + std::memset(reinterpret_cast<std::uint8_t *>(buffer) + actual, m_filler, length - actual); + return std::error_condition(); + } + +protected: + stream *const m_stream; + std::uint8_t m_filler; + bool const m_close; +}; + + +class stream_read_write_wrapper : public stream_read_wrapper, public util::random_read_write +{ +public: + using stream_read_wrapper::stream_read_wrapper; + + virtual std::error_condition finalize() noexcept override + { + return std::error_condition(); + } + + virtual std::error_condition flush() noexcept override + { + return std::error_condition(); + } + + virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override + { + std::uint64_t const pos = m_stream->tell(); + std::uint64_t size = m_stream->size(); + if (size < pos) + { + m_stream->seek(size, SEEK_SET); + size += m_stream->fill(m_filler, pos - size); + } + actual = (size >= pos) ? m_stream->write(buffer, length) : 0U; + return (actual == length) ? std::error_condition() : std::errc::io_error; + } + + virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override + { + std::uint64_t const pos = m_stream->tell(); + std::uint64_t size = m_stream->size(); + if (offset > size) + { + m_stream->seek(size, SEEK_SET); + size += m_stream->fill(m_filler, offset - size); + } + else + { + m_stream->seek(offset, SEEK_SET); + } + actual = (size >= offset) ? m_stream->write(buffer, length) : 0U; + m_stream->seek(pos, SEEK_SET); + return (actual == length) ? std::error_condition() : std::errc::io_error; + } +}; + +} // anonymous namespace + + +util::random_read::ptr stream_read(stream::ptr &&s, std::uint8_t filler) noexcept +{ + util::random_read::ptr result; + if (s) + result.reset(new (std::nothrow) stream_read_wrapper(std::move(s), filler)); + return result; +} + +util::random_read::ptr stream_read(stream &s, std::uint8_t filler) noexcept +{ + util::random_read::ptr result(new (std::nothrow) stream_read_wrapper(s, filler)); + return result; +} + +util::random_read_write::ptr stream_read_write(stream::ptr &&s, std::uint8_t filler) noexcept +{ + util::random_read_write::ptr result; + if (s) + result.reset(new (std::nothrow) stream_read_write_wrapper(std::move(s), filler)); + return result; +} + +util::random_read_write::ptr stream_read_write(stream &s, std::uint8_t filler) noexcept +{ + util::random_read_write::ptr result(new (std::nothrow) stream_read_write_wrapper(s, filler)); + return result; +} + //------------------------------------------------- // ctor //------------------------------------------------- -imgtool::stream::stream(bool wp) +stream::stream(bool wp) : imgtype(IMG_FILE) , write_protect(wp) , position(0) @@ -35,7 +194,7 @@ imgtool::stream::stream(bool wp) // ctor //------------------------------------------------- -imgtool::stream::stream(bool wp, util::core_file::ptr &&f) +stream::stream(bool wp, util::core_file::ptr &&f) : imgtype(IMG_FILE) , write_protect(wp) , position(0) @@ -50,7 +209,7 @@ imgtool::stream::stream(bool wp, util::core_file::ptr &&f) // ctor //------------------------------------------------- -imgtool::stream::stream(bool wp, std::size_t size) +stream::stream(bool wp, std::size_t size) : imgtype(IMG_MEM) , write_protect(wp) , position(0) @@ -65,7 +224,7 @@ imgtool::stream::stream(bool wp, std::size_t size) // ctor //------------------------------------------------- -imgtool::stream::stream(bool wp, std::size_t size, void *buf) +stream::stream(bool wp, std::size_t size, void *buf) : imgtype(IMG_MEM) , write_protect(wp) , position(0) @@ -80,7 +239,7 @@ imgtool::stream::stream(bool wp, std::size_t size, void *buf) // dtor //------------------------------------------------- -imgtool::stream::~stream() +stream::~stream() { if (buffer) free(buffer); @@ -91,39 +250,39 @@ imgtool::stream::~stream() // open_zip //------------------------------------------------- -imgtool::stream::ptr imgtool::stream::open_zip(const std::string &zipname, const char *subname, int read_or_write) +stream::ptr stream::open_zip(const std::string &zipname, const char *subname, int read_or_write) { if (read_or_write) - return imgtool::stream::ptr(); + return stream::ptr(); /* check to see if the file exists */ FILE *f = fopen(zipname.c_str(), "r"); if (!f) - return imgtool::stream::ptr(); + return stream::ptr(); fclose(f); - imgtool::stream::ptr imgfile(new imgtool::stream(true)); + stream::ptr imgfile(new stream(true)); imgfile->imgtype = IMG_MEM; util::archive_file::ptr z; util::archive_file::open_zip(zipname, z); if (!z) - return imgtool::stream::ptr(); + return stream::ptr(); int zipent = z->first_file(); while ((zipent >= 0) && subname && strcmp(subname, z->current_name().c_str())) zipent = z->next_file(); if (zipent < 0) - return imgtool::stream::ptr(); + return stream::ptr(); imgfile->filesize = z->current_uncompressed_length(); imgfile->buffer = reinterpret_cast<std::uint8_t *>(malloc(z->current_uncompressed_length())); if (!imgfile->buffer) - return imgtool::stream::ptr(); + return stream::ptr(); - if (z->decompress(imgfile->buffer, z->current_uncompressed_length()) != util::archive_file::error::NONE) - return imgtool::stream::ptr(); + if (z->decompress(imgfile->buffer, z->current_uncompressed_length())) + return stream::ptr(); return imgfile; } @@ -134,7 +293,7 @@ imgtool::stream::ptr imgtool::stream::open_zip(const std::string &zipname, const // open //------------------------------------------------- -imgtool::stream::ptr imgtool::stream::open(const std::string &filename, int read_or_write) +stream::ptr stream::open(const std::string &filename, int read_or_write) { static const uint32_t write_modes[] = { @@ -143,7 +302,7 @@ imgtool::stream::ptr imgtool::stream::open(const std::string &filename, int read OPEN_FLAG_READ | OPEN_FLAG_WRITE, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE }; - imgtool::stream::ptr s; + stream::ptr s; char c; // maybe we are just a ZIP? @@ -152,13 +311,13 @@ imgtool::stream::ptr imgtool::stream::open(const std::string &filename, int read util::core_file::ptr f = nullptr; auto const filerr = util::core_file::open(filename, write_modes[read_or_write], f); - if (filerr != osd_file::error::NONE) + if (filerr) { if (!read_or_write) { int const len = filename.size(); - /* can't open the file; try opening ZIP files with other names */ + // can't open the file; try opening ZIP files with other names std::vector<char> buf(len + 1); strcpy(&buf[0], filename.c_str()); @@ -177,11 +336,11 @@ imgtool::stream::ptr imgtool::stream::open(const std::string &filename, int read return s; } - /* ah well, it was worth a shot */ - return imgtool::stream::ptr(); + // ah well, it was worth a shot + return stream::ptr(); } - imgtool::stream::ptr imgfile(new imgtool::stream(read_or_write ? false : true, std::move(f))); + stream::ptr imgfile(new stream(read_or_write ? false : true, std::move(f))); // normal file return imgfile; @@ -192,11 +351,11 @@ imgtool::stream::ptr imgtool::stream::open(const std::string &filename, int read // open_write_stream //------------------------------------------------- -imgtool::stream::ptr imgtool::stream::open_write_stream(int size) +stream::ptr stream::open_write_stream(int size) { - imgtool::stream::ptr imgfile(new imgtool::stream(false, size)); + stream::ptr imgfile(new stream(false, size)); if (!imgfile->buffer) - return imgtool::stream::ptr(); + return stream::ptr(); return imgfile; } @@ -206,9 +365,9 @@ imgtool::stream::ptr imgtool::stream::open_write_stream(int size) // open_mem //------------------------------------------------- -imgtool::stream::ptr imgtool::stream::open_mem(void *buf, size_t sz) +stream::ptr stream::open_mem(void *buf, size_t sz) { - imgtool::stream::ptr imgfile(new imgtool::stream(false, sz, buf)); + stream::ptr imgfile(new stream(false, sz, buf)); return imgfile; } @@ -218,7 +377,7 @@ imgtool::stream::ptr imgtool::stream::open_mem(void *buf, size_t sz) // core_file //------------------------------------------------- -util::core_file *imgtool::stream::core_file() +util::core_file *stream::core_file() { return (imgtype == IMG_FILE) ? file.get() : nullptr; } @@ -228,7 +387,7 @@ util::core_file *imgtool::stream::core_file() // read //------------------------------------------------- -uint32_t imgtool::stream::read(void *buf, uint32_t sz) +uint32_t stream::read(void *buf, uint32_t sz) { uint32_t result = 0; @@ -262,7 +421,7 @@ uint32_t imgtool::stream::read(void *buf, uint32_t sz) // write //------------------------------------------------- -uint32_t imgtool::stream::write(const void *buf, uint32_t sz) +uint32_t stream::write(const void *buf, uint32_t sz) { void *new_buffer; uint32_t result = 0; @@ -317,7 +476,7 @@ uint32_t imgtool::stream::write(const void *buf, uint32_t sz) // size //------------------------------------------------- -uint64_t imgtool::stream::size() const +uint64_t stream::size() const { return filesize; } @@ -327,7 +486,7 @@ uint64_t imgtool::stream::size() const // getptr //------------------------------------------------- -void *imgtool::stream::getptr() +void *stream::getptr() { void *ptr; @@ -349,7 +508,7 @@ void *imgtool::stream::getptr() // seek //------------------------------------------------- -int imgtool::stream::seek(int64_t pos, int where) +int stream::seek(int64_t pos, int where) { switch(where) { @@ -377,7 +536,7 @@ int imgtool::stream::seek(int64_t pos, int where) // tell //------------------------------------------------- -uint64_t imgtool::stream::tell() +uint64_t stream::tell() { return position; } @@ -387,7 +546,7 @@ uint64_t imgtool::stream::tell() // transfer //------------------------------------------------- -uint64_t imgtool::stream::transfer(imgtool::stream &dest, imgtool::stream &source, uint64_t sz) +uint64_t stream::transfer(stream &dest, stream &source, uint64_t sz) { uint64_t result = 0; uint64_t readsz; @@ -407,7 +566,7 @@ uint64_t imgtool::stream::transfer(imgtool::stream &dest, imgtool::stream &sourc // transfer_all //------------------------------------------------- -uint64_t imgtool::stream::transfer_all(imgtool::stream &dest, imgtool::stream &source) +uint64_t stream::transfer_all(stream &dest, stream &source) { return transfer(dest, source, source.size()); } @@ -417,7 +576,7 @@ uint64_t imgtool::stream::transfer_all(imgtool::stream &dest, imgtool::stream &s // crc //------------------------------------------------- -int imgtool::stream::crc(unsigned long *result) +int stream::crc(unsigned long *result) { size_t sz; void *ptr; @@ -451,12 +610,12 @@ int imgtool::stream::crc(unsigned long *result) // file_crc //------------------------------------------------- -int imgtool::stream::file_crc(const char *fname, unsigned long *result) +int stream::file_crc(const char *fname, unsigned long *result) { int err; - imgtool::stream::ptr f; + stream::ptr f; - f = imgtool::stream::open(fname, OSD_FOPEN_READ); + f = stream::open(fname, OSD_FOPEN_READ); if (!f) return IMGTOOLERR_FILENOTFOUND; @@ -469,7 +628,7 @@ int imgtool::stream::file_crc(const char *fname, unsigned long *result) // fill //------------------------------------------------- -uint64_t imgtool::stream::fill(unsigned char b, uint64_t sz) +uint64_t stream::fill(unsigned char b, uint64_t sz) { uint64_t outsz; char buf[1024]; @@ -490,7 +649,7 @@ uint64_t imgtool::stream::fill(unsigned char b, uint64_t sz) // is_read_only //------------------------------------------------- -bool imgtool::stream::is_read_only() +bool stream::is_read_only() { return write_protect; } @@ -500,7 +659,7 @@ bool imgtool::stream::is_read_only() // putc //------------------------------------------------- -uint32_t imgtool::stream::putc(char c) +uint32_t stream::putc(char c) { return write(&c, 1); } @@ -510,7 +669,7 @@ uint32_t imgtool::stream::putc(char c) // puts //------------------------------------------------- -uint32_t imgtool::stream::puts(const char *s) +uint32_t stream::puts(const char *s) { return write(s, strlen(s)); } @@ -520,7 +679,7 @@ uint32_t imgtool::stream::puts(const char *s) // printf //------------------------------------------------- -uint32_t imgtool::stream::printf(const char *fmt, ...) +uint32_t stream::printf(const char *fmt, ...) { va_list va; char buf[256]; @@ -531,3 +690,5 @@ uint32_t imgtool::stream::printf(const char *fmt, ...) return puts(buf); } + +} // namespace imgtool diff --git a/src/tools/imgtool/stream.h b/src/tools/imgtool/stream.h index 73d0dcb494d..e7cfca9e425 100644 --- a/src/tools/imgtool/stream.h +++ b/src/tools/imgtool/stream.h @@ -7,78 +7,91 @@ Code for implementing Imgtool streams ***************************************************************************/ +#ifndef MAME_TOOLS_IMGTOOL_STREAM_H +#define MAME_TOOLS_IMGTOOL_STREAM_H -#ifndef STREAM_H -#define STREAM_H +#pragma once #include "imgterrs.h" -#include "corefile.h" + +#include "utilfwd.h" + #include "osdcomm.h" -namespace imgtool +#include <cstdint> +#include <memory> +#include <string> + + +namespace imgtool { + +class stream { - class stream +public: + typedef std::unique_ptr<stream> ptr; + + ~stream(); + + static imgtool::stream::ptr open(const std::string &filename, int read_or_write); /* similar params to mame_fopen */ + static imgtool::stream::ptr open_write_stream(int filesize); + static imgtool::stream::ptr open_mem(void *buf, size_t sz); + + util::core_file *core_file(); + uint32_t read(void *buf, uint32_t sz); + uint32_t write(const void *buf, uint32_t sz); + uint64_t size() const; + int seek(int64_t pos, int where); + uint64_t tell(); + void *getptr(); + uint32_t putc(char c); + uint32_t puts(const char *s); + uint32_t printf(const char *fmt, ...) ATTR_PRINTF(2, 3); + + // transfers sz bytes from source to dest + static uint64_t transfer(imgtool::stream &dest, imgtool::stream &source, uint64_t sz); + static uint64_t transfer_all(imgtool::stream &dest, imgtool::stream &source); + + // fills sz bytes with b + uint64_t fill(unsigned char b, uint64_t sz); + + // returns the CRC of a file + int crc(unsigned long *result); + static int file_crc(const char *fname, unsigned long *result); + + // returns whether a stream is read only or not + bool is_read_only(); + +private: + enum imgtype_t { - public: - typedef std::unique_ptr<stream> ptr; - - ~stream(); - - static imgtool::stream::ptr open(const std::string &filename, int read_or_write); /* similar params to mame_fopen */ - static imgtool::stream::ptr open_write_stream(int filesize); - static imgtool::stream::ptr open_mem(void *buf, size_t sz); - - util::core_file *core_file(); - uint32_t read(void *buf, uint32_t sz); - uint32_t write(const void *buf, uint32_t sz); - uint64_t size() const; - int seek(int64_t pos, int where); - uint64_t tell(); - void *getptr(); - uint32_t putc(char c); - uint32_t puts(const char *s); - uint32_t printf(const char *fmt, ...) ATTR_PRINTF(2, 3); - - // transfers sz bytes from source to dest - static uint64_t transfer(imgtool::stream &dest, imgtool::stream &source, uint64_t sz); - static uint64_t transfer_all(imgtool::stream &dest, imgtool::stream &source); - - // fills sz bytes with b - uint64_t fill(unsigned char b, uint64_t sz); - - // returns the CRC of a file - int crc(unsigned long *result); - static int file_crc(const char *fname, unsigned long *result); - - // returns whether a stream is read only or not - bool is_read_only(); - - private: - enum imgtype_t - { - IMG_FILE, - IMG_MEM - }; - - imgtype_t imgtype; - bool write_protect; - std::uint64_t position; - std::uint64_t filesize; - - util::core_file::ptr file; - std::uint8_t *buffer; - - // ctors - stream(bool wp); - stream(bool wp, util::core_file::ptr &&f); - stream(bool wp, std::size_t size); - stream(bool wp, std::size_t size, void *buf); - - // private methods - static stream::ptr open_zip(const std::string &zipname, const char *subname, int read_or_write); + IMG_FILE, + IMG_MEM }; -} + imgtype_t imgtype; + bool write_protect; + std::uint64_t position; + std::uint64_t filesize; + + std::unique_ptr<util::core_file> file; + std::uint8_t *buffer; + + // ctors + stream(bool wp); + stream(bool wp, std::unique_ptr<util::core_file> &&f); + stream(bool wp, std::size_t size); + stream(bool wp, std::size_t size, void *buf); + + // private methods + static stream::ptr open_zip(const std::string &zipname, const char *subname, int read_or_write); +}; + + +std::unique_ptr<util::random_read> stream_read(stream::ptr &&s, std::uint8_t filler) noexcept; +std::unique_ptr<util::random_read> stream_read(stream &s, std::uint8_t filler) noexcept; +std::unique_ptr<util::random_read_write> stream_read_write(stream::ptr &&s, std::uint8_t filler) noexcept; +std::unique_ptr<util::random_read_write> stream_read_write(stream &s, std::uint8_t filler) noexcept; +} // namespace imgtool -#endif /* STREAM_H */ +#endif // MAME_TOOLS_IMGTOOL_STREAM_H diff --git a/src/tools/ldresample.cpp b/src/tools/ldresample.cpp index a7dd165c2f9..f7c5fc8b923 100644 --- a/src/tools/ldresample.cpp +++ b/src/tools/ldresample.cpp @@ -8,17 +8,18 @@ ****************************************************************************/ -#include <cstdio> -#include <cctype> -#include <cstdlib> -#include <cmath> -#include <new> -#include <cassert> +#include "avhuff.h" #include "bitmap.h" #include "chd.h" -#include "avhuff.h" #include "vbiparse.h" +#include <cassert> +#include <cctype> +#include <cmath> +#include <cstdio> +#include <cstdlib> +#include <new> + //************************************************************************** @@ -156,22 +157,22 @@ inline uint32_t sample_number_to_field(const movie_info &info, uint32_t samplenu // information about it //------------------------------------------------- -static chd_error open_chd(chd_file &file, const char *filename, movie_info &info) +static std::error_condition open_chd(chd_file &file, const char *filename, movie_info &info) { // open the file - chd_error chderr = file.open(filename); - if (chderr != CHDERR_NONE) + std::error_condition chderr = file.open(filename); + if (chderr) { - fprintf(stderr, "Error opening CHD file: %s\n", chd_file::error_string(chderr)); + fprintf(stderr, "Error opening CHD file: %s\n", chderr.message().c_str()); return chderr; } // get the metadata std::string metadata; chderr = file.read_metadata(AV_METADATA_TAG, 0, metadata); - if (chderr != CHDERR_NONE) + if (chderr) { - fprintf(stderr, "Error getting A/V metadata: %s\n", chd_file::error_string(chderr)); + fprintf(stderr, "Error getting A/V metadata: %s\n", chderr.message().c_str()); return chderr; } @@ -180,7 +181,7 @@ static chd_error open_chd(chd_file &file, const char *filename, movie_info &info if (sscanf(metadata.c_str(), AV_METADATA_FORMAT, &fps, &fpsfrac, &width, &height, &interlaced, &channels, &rate) != 7) { fprintf(stderr, "Improperly formatted metadata\n"); - return CHDERR_INVALID_DATA; + return chd_file::error::INVALID_METADATA; } // extract movie info @@ -197,7 +198,7 @@ static chd_error open_chd(chd_file &file, const char *filename, movie_info &info info.bitmap.resize(info.width, info.height); info.lsound.resize(info.samplerate); info.rsound.resize(info.samplerate); - return CHDERR_NONE; + return std::error_condition(); } @@ -205,28 +206,28 @@ static chd_error open_chd(chd_file &file, const char *filename, movie_info &info // create_chd - create a new CHD file //------------------------------------------------- -static chd_error create_chd(chd_file_compressor &file, const char *filename, chd_file &source, const movie_info &info) +static std::error_condition create_chd(chd_file_compressor &file, const char *filename, chd_file &source, const movie_info &info) { // create the file chd_codec_type compression[4] = { CHD_CODEC_AVHUFF }; - chd_error chderr = file.create(filename, source.logical_bytes(), source.hunk_bytes(), source.unit_bytes(), compression); - if (chderr != CHDERR_NONE) + std::error_condition chderr = file.create(filename, source.logical_bytes(), source.hunk_bytes(), source.unit_bytes(), compression); + if (chderr) { - fprintf(stderr, "Error creating new CHD file: %s\n", chd_file::error_string(chderr)); + fprintf(stderr, "Error creating new CHD file: %s\n", chderr.message().c_str()); return chderr; } // clone the metadata chderr = file.clone_all_metadata(source); - if (chderr != CHDERR_NONE) + if (chderr) { - fprintf(stderr, "Error cloning metadata: %s\n", chd_file::error_string(chderr)); + fprintf(stderr, "Error cloning metadata: %s\n", chderr.message().c_str()); return chderr; } // begin compressing file.compress_begin(); - return CHDERR_NONE; + return std::error_condition(); } @@ -248,8 +249,8 @@ static bool read_chd(chd_file &file, uint32_t field, movie_info &info, uint32_t file.codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &avconfig); // read the field - chd_error chderr = file.read_hunk(field, nullptr); - return (chderr == CHDERR_NONE); + std::error_condition chderr = file.read_hunk(field, nullptr); + return !chderr; } @@ -524,8 +525,8 @@ int main(int argc, char *argv[]) // open the source file chd_file srcfile; movie_info info; - chd_error err = open_chd(srcfile, srcfilename, info); - if (err != CHDERR_NONE) + std::error_condition err = open_chd(srcfile, srcfilename, info); + if (err) { fprintf(stderr, "Unable to open file '%s'\n", srcfilename); return 1; @@ -563,7 +564,7 @@ int main(int argc, char *argv[]) // loop over all the fields in the source file double progress, ratio; osd_ticks_t last_update = 0; - while (dstfile.compress_continue(progress, ratio) == CHDERR_COMPRESSING) + while (dstfile.compress_continue(progress, ratio) == chd_file::error::COMPRESSING) if (osd_ticks() - last_update > osd_ticks_per_second() / 4) { last_update = osd_ticks(); diff --git a/src/tools/ldverify.cpp b/src/tools/ldverify.cpp index e8df214734c..bb95c3fbad4 100644 --- a/src/tools/ldverify.cpp +++ b/src/tools/ldverify.cpp @@ -8,18 +8,19 @@ ****************************************************************************/ -#include <cstdio> -#include <cstdlib> -#include <cctype> -#include <new> -#include <cassert> -#include "coretmpl.h" -#include "aviio.h" #include "avhuff.h" +#include "aviio.h" #include "bitmap.h" #include "chd.h" +#include "coretmpl.h" #include "vbiparse.h" +#include <cassert> +#include <cctype> +#include <cstdio> +#include <cstdlib> +#include <new> + //************************************************************************** @@ -174,10 +175,10 @@ static void *open_chd(const char *filename, movie_info &info) auto chd = new chd_file; // open the file - chd_error chderr = chd->open(filename); - if (chderr != CHDERR_NONE) + std::error_condition chderr = chd->open(filename); + if (chderr) { - fprintf(stderr, "Error opening CHD file: %s\n", chd_file::error_string(chderr)); + fprintf(stderr, "Error opening CHD file: %s\n", chderr.message().c_str()); delete chd; return nullptr; } @@ -185,9 +186,9 @@ static void *open_chd(const char *filename, movie_info &info) // get the metadata std::string metadata; chderr = chd->read_metadata(AV_METADATA_TAG, 0, metadata); - if (chderr != CHDERR_NONE) + if (chderr) { - fprintf(stderr, "Error getting A/V metadata: %s\n", chd_file::error_string(chderr)); + fprintf(stderr, "Error getting A/V metadata: %s\n", chderr.message().c_str()); delete chd; return nullptr; } @@ -251,8 +252,8 @@ static int read_chd(void *file, int frame, bitmap_yuy16 &bitmap, int16_t *lsound chdfile->codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &avconfig); // read the frame - chd_error chderr = chdfile->read_hunk(frame * interlace_factor + fieldnum, nullptr); - if (chderr != CHDERR_NONE) + std::error_condition chderr = chdfile->read_hunk(frame * interlace_factor + fieldnum, nullptr); + if (chderr) return false; // account for samples read diff --git a/src/tools/pngcmp.cpp b/src/tools/pngcmp.cpp index 43fc9324a06..624023425af 100644 --- a/src/tools/pngcmp.cpp +++ b/src/tools/pngcmp.cpp @@ -73,15 +73,15 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img bitmap_argb32 finalbitmap; int width, height, maxwidth; util::core_file::ptr file; - osd_file::error filerr; + std::error_condition filerr; util::png_error pngerr; int error = 100; /* open the source image */ filerr = util::core_file::open(imgfile1, OPEN_FLAG_READ, file); - if (filerr != osd_file::error::NONE) + if (filerr) { - printf("Could not open %s (%d)\n", imgfile1.c_str(), int(filerr)); + printf("Could not open %s (%s)\n", imgfile1.c_str(), filerr.message().c_str()); goto error; } @@ -96,9 +96,9 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img /* open the source image */ filerr = util::core_file::open(imgfile2, OPEN_FLAG_READ, file); - if (filerr != osd_file::error::NONE) + if (filerr) { - printf("Could not open %s (%d)\n", imgfile2.c_str(), int(filerr)); + printf("Could not open %s (%s)\n", imgfile2.c_str(), filerr.message().c_str()); goto error; } @@ -171,9 +171,9 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img /* write the final PNG */ filerr = util::core_file::open(outfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file); - if (filerr != osd_file::error::NONE) + if (filerr) { - printf("Could not open %s (%d)\n", outfilename.c_str(), int(filerr)); + printf("Could not open %s (%s)\n", outfilename.c_str(), filerr.message().c_str()); goto error; } pngerr = util::png_write_bitmap(*file, nullptr, finalbitmap, 0, nullptr); diff --git a/src/tools/regrep.cpp b/src/tools/regrep.cpp index a8877c54899..b0072accfab 100644 --- a/src/tools/regrep.cpp +++ b/src/tools/regrep.cpp @@ -239,7 +239,7 @@ int main(int argc, char *argv[]) /* read the template file into an astring */ std::string tempheader; - if (util::core_file::load(tempfilename.c_str(), &buffer, bufsize) == osd_file::error::NONE) + if (!util::core_file::load(tempfilename.c_str(), &buffer, bufsize)) { tempheader.assign((const char *)buffer, bufsize); free(buffer); @@ -569,7 +569,7 @@ static util::core_file::ptr create_file_and_output_header(std::string &filename, util::core_file::ptr file; /* create the indexfile */ - if (util::core_file::open(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, file) != osd_file::error::NONE) + if (util::core_file::open(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, file)) return util::core_file::ptr(); /* print a header */ @@ -730,7 +730,7 @@ static int compare_screenshots(summary_file *curfile) if (curfile->status[listnum] == STATUS_SUCCESS) { std::string fullname; - osd_file::error filerr; + std::error_condition filerr; util::core_file::ptr file; /* get the filename for the image */ @@ -740,7 +740,7 @@ static int compare_screenshots(summary_file *curfile) filerr = util::core_file::open(fullname, OPEN_FLAG_READ, file); /* if that failed, look in the old location */ - if (filerr != osd_file::error::NONE) + if (filerr) { /* get the filename for the image */ fullname = string_format("%s" PATH_SEPARATOR "snap" PATH_SEPARATOR "_%s.png", lists[listnum].dir, curfile->name); @@ -750,7 +750,7 @@ static int compare_screenshots(summary_file *curfile) } /* if that worked, load the file */ - if (filerr == osd_file::error::NONE) + if (!filerr) { util::png_read_bitmap(*file, bitmaps[listnum]); file.reset(); @@ -838,7 +838,7 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir, int width, height, maxwidth; int bitmapcount = 0; util::core_file::ptr file; - osd_file::error filerr; + std::error_condition filerr; util::png_error pngerr; int error = -1; int starty; @@ -855,7 +855,7 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir, /* open the source image */ filerr = util::core_file::open(tempname, OPEN_FLAG_READ, file); - if (filerr != osd_file::error::NONE) + if (filerr) goto error; /* load the source image */ @@ -926,7 +926,7 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir, /* write the final PNG */ filerr = util::core_file::open(dstfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file); - if (filerr != osd_file::error::NONE) + if (filerr) goto error; pngerr = util::png_write_bitmap(*file, nullptr, finalbitmap, 0, nullptr); file.reset(); diff --git a/src/tools/romcmp.cpp b/src/tools/romcmp.cpp index 4862f74a769..b65889c70a1 100644 --- a/src/tools/romcmp.cpp +++ b/src/tools/romcmp.cpp @@ -8,25 +8,20 @@ ***************************************************************************/ +#include "hash.h" +#include "path.h" #include "unzip.h" + #include "osdfile.h" #include "osdcomm.h" -#include "hash.h" #include <cstdarg> #include <cstdlib> +#include <memory> #define MAX_FILES 1000 -#ifndef MAX_FILENAME_LEN -#define MAX_FILENAME_LEN 255 -#endif - -#ifndef PATH_DELIM -#define PATH_DELIM '/' -#endif - /* compare modes when one file is twice as long as the other */ @@ -105,382 +100,383 @@ static void compatiblemodes(int mode,int *start,int *end) struct fileinfo { - char name[MAX_FILENAME_LEN+1]; + std::string name; int size; - unsigned char *buf; /* file is read in here */ + std::unique_ptr<unsigned char []> buf; // file is read in here int listed; -}; - -static fileinfo files[2][MAX_FILES]; -static float matchscore[MAX_FILES][MAX_FILES][TOTAL_MODES][TOTAL_MODES]; -static bool is_ascii_char(int ch) -{ - return (ch >= 0x20 && ch < 0x7f) || (ch == '\n') || (ch == '\r') || (ch == '\t'); -} - -static void checkintegrity(const fileinfo *file, int side, bool all_hashes) -{ - if (file->buf == nullptr) return; - - if (all_hashes) + static constexpr bool is_ascii_char(int ch) { - util::crc32_creator crc32; - util::sha1_creator sha1; - util::sum16_creator sum16; - crc32.append(file->buf, file->size); - sha1.append(file->buf, file->size); - sum16.append(file->buf, file->size); - printf("%-23s %-23s [0x%x] CRC(%s) SHA1(%s) SUM(%s)\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "", file->size, - crc32.finish().as_string().c_str(), sha1.finish().as_string().c_str(), sum16.finish().as_string().c_str()); - side = 0; + return (ch >= 0x20 && ch < 0x7f) || (ch == '\n') || (ch == '\r') || (ch == '\t'); } - /* check for bad data lines */ - unsigned mask0 = 0x0000; - unsigned mask1 = 0xffff; - bool is_ascii = true; - for (unsigned i = 0; i < file->size; i += 2) + void checkintegrity(int side, bool all_hashes) const { - is_ascii = is_ascii && is_ascii_char(file->buf[i]); - mask0 |= file->buf[i] << 8; - mask1 &= (file->buf[i] << 8) | 0x00ff; - if (i < file->size - 1) + if (!buf) + return; + + if (all_hashes) { - is_ascii = is_ascii && is_ascii_char(file->buf[i+1]); - mask0 |= file->buf[i+1]; - mask1 &= file->buf[i+1] | 0xff00; + util::crc32_creator crc32; + util::sha1_creator sha1; + util::sum16_creator sum16; + crc32.append(buf.get(), size); + sha1.append(buf.get(), size); + sum16.append(buf.get(), size); + printf("%-23s %-23s [0x%x] CRC(%s) SHA1(%s) SUM(%s)\n", + (side & 1) ? name.c_str() : "", + (side & 2) ? name.c_str() : "", + size, + crc32.finish().as_string().c_str(), + sha1.finish().as_string().c_str(), + sum16.finish().as_string().c_str()); + side = 0; } - if (mask0 == 0xffff && mask1 == 0x0000) break; - } - - if (is_ascii && mask0 == 0x7f7f && mask1 == 0) - { - printf("%-23s %-23s ASCII TEXT FILE\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - return; - } - if (mask0 != 0xffff || mask1 != 0x0000) - { - int fixedmask; - int bits; + // check for bad data lines + unsigned mask0 = 0x0000; + unsigned mask1 = 0xffff; - fixedmask = (~mask0 | mask1) & 0xffff; + bool is_ascii = true; + for (unsigned i = 0; i < size; i += 2) + { + is_ascii = is_ascii && is_ascii_char(buf[i]); + mask0 |= buf[i] << 8; + mask1 &= (buf[i] << 8) | 0x00ff; + if (i < size - 1) + { + is_ascii = is_ascii && is_ascii_char(buf[i+1]); + mask0 |= buf[i+1]; + mask1 &= buf[i+1] | 0xff00; + } + if (mask0 == 0xffff && mask1 == 0x0000) break; + } - if (((mask0 >> 8) & 0xff) == (mask0 & 0xff) && ((mask1 >> 8) & 0xff) == (mask1 & 0xff)) - bits = 8; - else bits = 16; + if (is_ascii && mask0 == 0x7f7f && mask1 == 0) + { + printf("%-23s %-23s ASCII TEXT FILE\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + return; + } - printf("%-23s %-23s FIXED BITS (", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - for (int i = 0; i < bits; i++) + if (mask0 != 0xffff || mask1 != 0x0000) { - if (~mask0 & 0x8000) printf("0"); - else if (mask1 & 0x8000) printf("1"); - else printf("x"); + int fixedmask; + int bits; - mask0 <<= 1; - mask1 <<= 1; - } - printf(")\n"); + fixedmask = (~mask0 | mask1) & 0xffff; - /* if the file contains a fixed value, we don't need to do the other */ - /* validity checks */ - if (fixedmask == 0xffff || fixedmask == 0x00ff || fixedmask == 0xff00) - return; - } + if (((mask0 >> 8) & 0xff) == (mask0 & 0xff) && ((mask1 >> 8) & 0xff) == (mask1 & 0xff)) + bits = 8; + else bits = 16; - unsigned addrbit = 1; - unsigned addrmirror = 0; - while (addrbit <= file->size/2) - { - unsigned i = 0; - for (i = 0; i < file->size; i++) + printf("%-23s %-23s FIXED BITS (", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + for (int i = 0; i < bits; i++) + { + if (~mask0 & 0x8000) printf("0"); + else if (mask1 & 0x8000) printf("1"); + else printf("x"); + + mask0 <<= 1; + mask1 <<= 1; + } + printf(")\n"); + + /* if the file contains a fixed value, we don't need to do the other */ + /* validity checks */ + if (fixedmask == 0xffff || fixedmask == 0x00ff || fixedmask == 0xff00) + return; + } + + unsigned addrbit = 1; + unsigned addrmirror = 0; + while (addrbit <= size/2) { - if ((i ^ addrbit) < file->size && file->buf[i] != file->buf[i ^ addrbit]) break; + unsigned i = 0; + for (i = 0; i < size; i++) + { + if ((i ^ addrbit) < size && buf[i] != buf[i ^ addrbit]) break; + } + + if (i == size) + addrmirror |= addrbit; + + addrbit <<= 1; } - if (i == file->size) - addrmirror |= addrbit; + if (addrmirror != 0) + { + if (addrmirror == size/2) + { + printf("%-23s %-23s 1ST AND 2ND HALF IDENTICAL\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + util::hash_collection hash; + hash.begin(); + hash.buffer(buf.get(), size / 2); + hash.end(); + printf("%-23s %-23s %s\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "", hash.attribute_string().c_str()); + } + else + { + printf("%-23s %-23s BADADDR", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + for (int i = 0; i < 24; i++) + { + if (size <= (1<<(23-i))) printf(" "); + else if (addrmirror & 0x800000) printf("-"); + else printf("x"); + addrmirror <<= 1; + } + printf("\n"); + } + return; + } - addrbit <<= 1; - } + unsigned sizemask = 1; + while (sizemask < size - 1) + sizemask = (sizemask << 1) | 1; - if (addrmirror != 0) - { - if (addrmirror == file->size/2) + mask0 = 0x000000; + mask1 = sizemask; + for (unsigned i = 0; i < size; i++) { - printf("%-23s %-23s 1ST AND 2ND HALF IDENTICAL\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - util::hash_collection hash; - hash.begin(); - hash.buffer(file->buf, file->size / 2); - hash.end(); - printf("%-23s %-23s %s\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "", hash.attribute_string().c_str()); + if (buf[i] != 0xff) + { + mask0 |= i; + mask1 &= i; + if (mask0 == sizemask && mask1 == 0x00) break; + } } - else + + if (mask0 != sizemask || mask1 != 0x00) { - printf("%-23s %-23s BADADDR", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); + printf("%-23s %-23s ", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); for (int i = 0; i < 24; i++) { - if (file->size <= (1<<(23-i))) printf(" "); - else if (addrmirror & 0x800000) printf("-"); + if (size <= (1<<(23-i))) printf(" "); + else if (~mask0 & 0x800000) printf("1"); + else if (mask1 & 0x800000) printf("0"); else printf("x"); - addrmirror <<= 1; + mask0 <<= 1; + mask1 <<= 1; } - printf("\n"); + printf(" = 0xFF\n"); + + return; } - return; - } - unsigned sizemask = 1; - while (sizemask < file->size - 1) - sizemask = (sizemask << 1) | 1; - mask0 = 0x000000; - mask1 = sizemask; - for (unsigned i = 0; i < file->size; i++) - { - if (file->buf[i] != 0xff) + mask0 = 0x000000; + mask1 = sizemask; + for (unsigned i = 0; i < size; i++) { - mask0 |= i; - mask1 &= i; - if (mask0 == sizemask && mask1 == 0x00) break; + if (buf[i] != 0x00) + { + mask0 |= i; + mask1 &= i; + if (mask0 == sizemask && mask1 == 0x00) break; + } } - } - if (mask0 != sizemask || mask1 != 0x00) - { - printf("%-23s %-23s ", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - for (int i = 0; i < 24; i++) + if (mask0 != sizemask || mask1 != 0x00) { - if (file->size <= (1<<(23-i))) printf(" "); - else if (~mask0 & 0x800000) printf("1"); - else if (mask1 & 0x800000) printf("0"); - else printf("x"); - mask0 <<= 1; - mask1 <<= 1; - } - printf(" = 0xFF\n"); - - return; - } + printf("%-23s %-23s ", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + for (int i = 0; i < 24; i++) + { + if (size <= (1<<(23-i))) printf(" "); + else if ((mask0 & 0x800000) == 0) printf("1"); + else if (mask1 & 0x800000) printf("0"); + else printf("x"); + mask0 <<= 1; + mask1 <<= 1; + } + printf(" = 0x00\n"); + return; + } - mask0 = 0x000000; - mask1 = sizemask; - for (unsigned i = 0; i < file->size; i++) - { - if (file->buf[i] != 0x00) + mask0 = 0xff; + for (unsigned i = 0; i < size/4 && mask0 != 0x00; i++) { - mask0 |= i; - mask1 &= i; - if (mask0 == sizemask && mask1 == 0x00) break; + if (buf[ 2*i ] != 0x00) mask0 &= ~0x01; + if (buf[ 2*i ] != 0xff) mask0 &= ~0x02; + if (buf[ 2*i+1] != 0x00) mask0 &= ~0x04; + if (buf[ 2*i+1] != 0xff) mask0 &= ~0x08; + if (buf[size/2 + 2*i ] != 0x00) mask0 &= ~0x10; + if (buf[size/2 + 2*i ] != 0xff) mask0 &= ~0x20; + if (buf[size/2 + 2*i+1] != 0x00) mask0 &= ~0x40; + if (buf[size/2 + 2*i+1] != 0xff) mask0 &= ~0x80; } + + if (mask0 & 0x01) printf("%-23s %-23s 1ST HALF = 00xx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x02) printf("%-23s %-23s 1ST HALF = FFxx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x04) printf("%-23s %-23s 1ST HALF = xx00\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x08) printf("%-23s %-23s 1ST HALF = xxFF\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x10) printf("%-23s %-23s 2ND HALF = 00xx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x20) printf("%-23s %-23s 2ND HALF = FFxx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x40) printf("%-23s %-23s 2ND HALF = xx00\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x80) printf("%-23s %-23s 2ND HALF = xxFF\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); } - if (mask0 != sizemask || mask1 != 0x00) + int usedbytes(int mode) const { - printf("%-23s %-23s ", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - for (int i = 0; i < 24; i++) + switch (mode) { - if (file->size <= (1<<(23-i))) printf(" "); - else if ((mask0 & 0x800000) == 0) printf("1"); - else if (mask1 & 0x800000) printf("0"); - else printf("x"); - mask0 <<= 1; - mask1 <<= 1; + case MODE_A: + case MODE_NIB1: + case MODE_NIB2: + return size; + case MODE_12: + case MODE_22: + case MODE_E: + case MODE_O: + return size / 2; + case MODE_14: + case MODE_24: + case MODE_34: + case MODE_44: + case MODE_E12: + case MODE_O12: + case MODE_E22: + case MODE_O22: + return size / 4; + default: + return 0; } - printf(" = 0x00\n"); - - return; } - mask0 = 0xff; - for (unsigned i = 0; i < file->size/4 && mask0 != 0x00; i++) + void basemultmask(int mode, int &base, int &mult, int &mask) const { - if (file->buf[ 2*i ] != 0x00) mask0 &= ~0x01; - if (file->buf[ 2*i ] != 0xff) mask0 &= ~0x02; - if (file->buf[ 2*i+1] != 0x00) mask0 &= ~0x04; - if (file->buf[ 2*i+1] != 0xff) mask0 &= ~0x08; - if (file->buf[file->size/2 + 2*i ] != 0x00) mask0 &= ~0x10; - if (file->buf[file->size/2 + 2*i ] != 0xff) mask0 &= ~0x20; - if (file->buf[file->size/2 + 2*i+1] != 0x00) mask0 &= ~0x40; - if (file->buf[file->size/2 + 2*i+1] != 0xff) mask0 &= ~0x80; - } + mult = 1; + if (mode >= MODE_E) + mult = 2; - if (mask0 & 0x01) printf("%-23s %-23s 1ST HALF = 00xx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x02) printf("%-23s %-23s 1ST HALF = FFxx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x04) printf("%-23s %-23s 1ST HALF = xx00\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x08) printf("%-23s %-23s 1ST HALF = xxFF\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x10) printf("%-23s %-23s 2ND HALF = 00xx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x20) printf("%-23s %-23s 2ND HALF = FFxx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x40) printf("%-23s %-23s 2ND HALF = xx00\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x80) printf("%-23s %-23s 2ND HALF = xxFF\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); -} - - -static int usedbytes(const fileinfo *file,int mode) -{ - switch (mode) - { - case MODE_A: - case MODE_NIB1: - case MODE_NIB2: - return file->size; - case MODE_12: - case MODE_22: - case MODE_E: - case MODE_O: - return file->size / 2; - case MODE_14: - case MODE_24: - case MODE_34: - case MODE_44: - case MODE_E12: - case MODE_O12: - case MODE_E22: - case MODE_O22: - return file->size / 4; - default: - return 0; + switch (mode) + { + case MODE_A: + case MODE_12: + case MODE_14: + case MODE_E: + case MODE_E12: + base = 0; mask = 0xff; break; + case MODE_NIB1: + base = 0; mask = 0x0f; break; + case MODE_NIB2: + base = 0; mask = 0xf0; break; + case MODE_O: + case MODE_O12: + base = 1; mask = 0xff; break; + case MODE_22: + case MODE_E22: + base = size / 2; mask = 0xff; break; + case MODE_O22: + base = 1 + size / 2; mask = 0xff; break; + case MODE_24: + base = size / 4; mask = 0xff; break; + case MODE_34: + base = 2*size / 4; mask = 0xff; break; + case MODE_44: + base = 3*size / 4; mask = 0xff; break; + } } -} - -static void basemultmask(const fileinfo *file,int mode,int *base,int *mult,int *mask) -{ - *mult = 1; - if (mode >= MODE_E) *mult = 2; - switch (mode) + float compare(const fileinfo &file2, int mode1, int mode2) const { - case MODE_A: - case MODE_12: - case MODE_14: - case MODE_E: - case MODE_E12: - *base = 0; *mask = 0xff; break; - case MODE_NIB1: - *base = 0; *mask = 0x0f; break; - case MODE_NIB2: - *base = 0; *mask = 0xf0; break; - case MODE_O: - case MODE_O12: - *base = 1; *mask = 0xff; break; - case MODE_22: - case MODE_E22: - *base = file->size / 2; *mask = 0xff; break; - case MODE_O22: - *base = 1 + file->size / 2; *mask = 0xff; break; - case MODE_24: - *base = file->size / 4; *mask = 0xff; break; - case MODE_34: - *base = 2*file->size / 4; *mask = 0xff; break; - case MODE_44: - *base = 3*file->size / 4; *mask = 0xff; break; - } -} - -static float filecompare(const fileinfo *file1,const fileinfo *file2,int mode1,int mode2) -{ - int i; - int match = 0; - int size1,size2; - int base1=0,base2=0,mult1=0,mult2=0,mask1=0,mask2=0; + if (!buf || !file2.buf) + return 0.0; + int const size1 = usedbytes(mode1); + int const size2 = file2.usedbytes(mode2); - if (file1->buf == nullptr || file2->buf == nullptr) return 0.0; + if (size1 != size2) + return 0.0; - size1 = usedbytes(file1,mode1); - size2 = usedbytes(file2,mode2); + int base1=0, base2=0, mult1=0, mult2=0, mask1=0, mask2=0; + basemultmask(mode1, base1, mult1, mask1); + file2.basemultmask(mode2, base2, mult2, mask2); - if (size1 != size2) return 0.0; - - basemultmask(file1,mode1,&base1,&mult1,&mask1); - basemultmask(file2,mode2,&base2,&mult2,&mask2); - - if (mask1 == mask2) - { - if (mask1 == 0xff) - { - /* normal compare */ - for (i = 0;i < size1;i++) - if (file1->buf[base1 + mult1 * i] == file2->buf[base2 + mult2 * i]) match++; - } - else + int match = 0; + if (mask1 == mask2) { - /* nibble compare, abort if other half is not empty */ - for (i = 0;i < size1;i++) + if (mask1 == 0xff) + { + // normal compare + for (int i = 0; i < size1; i++) + if (buf[base1 + mult1 * i] == file2.buf[base2 + mult2 * i]) match++; + } + else { - if (((file1->buf[base1 + mult1 * i] & ~mask1) != (0x00 & ~mask1) && - (file1->buf[base1 + mult1 * i] & ~mask1) != (0xff & ~mask1)) || - ((file2->buf[base1 + mult1 * i] & ~mask2) != (0x00 & ~mask2) && - (file2->buf[base1 + mult1 * i] & ~mask2) != (0xff & ~mask2))) + // nibble compare, abort if other half is not empty + for (int i = 0; i < size1; i++) { - match = 0; - break; + if (((buf[base1 + mult1 * i] & ~mask1) != (0x00 & ~mask1) && + (buf[base1 + mult1 * i] & ~mask1) != (0xff & ~mask1)) || + ((file2.buf[base1 + mult1 * i] & ~mask2) != (0x00 & ~mask2) && + (file2.buf[base1 + mult1 * i] & ~mask2) != (0xff & ~mask2))) + { + match = 0; + break; + } + if ((buf[base1 + mult1 * i] & mask1) == (file2.buf[base2 + mult2 * i] & mask2)) match++; } - if ((file1->buf[base1 + mult1 * i] & mask1) == (file2->buf[base2 + mult2 * i] & mask2)) match++; } } - } - return (float)match / size1; -} + return float(match) / size1; + } + void readfile(const char *path) + { + std::string fullname(path ? path : ""); + util::path_append(fullname, name); -static void readfile(const char *path,fileinfo *file) -{ - osd_file::error filerr; - uint64_t filesize; - uint32_t actual; - char fullname[256]; - osd_file::ptr f; + buf.reset(new (std::nothrow) unsigned char [size]); + if (!buf) + { + printf("%s: out of memory!\n", name.c_str()); + return; + } - if (path) - { - char delim[2] = { PATH_DELIM, '\0' }; - strcpy(fullname,path); - strcat(fullname,delim); - } - else fullname[0] = 0; - strcat(fullname,file->name); + std::error_condition filerr; + osd_file::ptr f; + uint64_t filesize; - if ((file->buf = (unsigned char *)malloc(file->size)) == nullptr) - { - printf("%s: out of memory!\n",file->name); - return; - } + filerr = osd_file::open(fullname, OPEN_FLAG_READ, f, filesize); + if (filerr) + { + printf("%s: error %s\n", fullname.c_str(), filerr.message().c_str()); + return; + } - filerr = osd_file::open(fullname, OPEN_FLAG_READ, f, filesize); - if (filerr != osd_file::error::NONE) - { - printf("%s: error %d\n", fullname, int(filerr)); - return; + uint32_t actual; + filerr = f->read(buf.get(), 0, size, actual); + if (filerr) + { + printf("%s: error %s\n", fullname.c_str(), filerr.message().c_str()); + return; + } } - filerr = f->read(file->buf, 0, file->size, actual); - if (filerr != osd_file::error::NONE) + void free() { - printf("%s: error %d\n", fullname, int(filerr)); - return; + buf.reset(); } -} - +}; -static void freefile(fileinfo *file) -{ - free(file->buf); - file->buf = nullptr; -} +static fileinfo files[2][MAX_FILES]; +static float matchscore[MAX_FILES][MAX_FILES][TOTAL_MODES][TOTAL_MODES]; -static void printname(const fileinfo *file1,const fileinfo *file2,float score,int mode1,int mode2) +static void printname(const fileinfo *file1, const fileinfo *file2, float score, int mode1, int mode2) { - printf("%-12s %s %-12s %s ",file1 ? file1->name : "",modenames[mode1],file2 ? file2->name : "",modenames[mode2]); + printf( + "%-12s %s %-12s %s ", + file1 ? file1->name.c_str() : "", + modenames[mode1], + file2 ? file2->name.c_str() : "", + modenames[mode2]); if (score == 0.0f) printf("NO MATCH\n"); else if (score == 1.0f) printf("IDENTICAL\n"); - else printf("%3.6f%%\n",(double) (score*100)); + else printf("%3.6f%%\n", double(score*100)); } @@ -496,24 +492,23 @@ static int load_files(int i, int *found, const char *path) while ((d = dir->read()) != nullptr) { const char *d_name = d->name; - char buf[255+1]; + const std::string buf(util::path_concat(path, d_name)); // FIXME: is this even used for anything? - sprintf(buf, "%s%c%s", path, PATH_DELIM, d_name); if (d->type == osd::directory::entry::entry_type::FILE) { uint64_t size = d->size; while (size && (size & 1) == 0) size >>= 1; //if (size & ~1) - // printf("%-23s %-23s ignored (not a ROM)\n",i ? "" : d_name,i ? d_name : ""); + // printf("%-23s %-23s ignored (not a ROM)\n", i ? "" : d_name, i ? d_name : ""); //else { - strcpy(files[i][found[i]].name,d_name); + files[i][found[i]].name = d_name; files[i][found[i]].size = d->size; - readfile(path,&files[i][found[i]]); + files[i][found[i]].readfile(path); files[i][found[i]].listed = 0; if (found[i] >= MAX_FILES) { - printf("%s: max of %d files exceeded\n",path,MAX_FILES); + printf("%s: max of %d files exceeded\n", path, MAX_FILES); break; } found[i]++; @@ -522,15 +517,13 @@ static int load_files(int i, int *found, const char *path) } dir.reset(); } - - /* if not, try to open as a ZIP file */ else { + /* if not, try to open as a ZIP file */ util::archive_file::ptr zip; /* wasn't a directory, so try to open it as a zip file */ - if ((util::archive_file::open_zip(path, zip) != util::archive_file::error::NONE) && - (util::archive_file::open_7z(path, zip) != util::archive_file::error::NONE)) + if (util::archive_file::open_zip(path, zip) && util::archive_file::open_7z(path, zip)) { printf("Error, cannot open zip file '%s' !\n", path); return 1; @@ -552,26 +545,26 @@ static int load_files(int i, int *found, const char *path) } else { - fileinfo *file = &files[i][found[i]]; + fileinfo &file = files[i][found[i]]; const char *delim = strrchr(zip->current_name().c_str(), '/'); if (delim) - strcpy (file->name,delim+1); + file.name = delim + 1; else - strcpy(file->name,zip->current_name().c_str()); - file->size = zip->current_uncompressed_length(); - if ((file->buf = (unsigned char *)malloc(file->size)) == nullptr) - printf("%s: out of memory!\n",file->name); + file.name = zip->current_name(); + file.size = zip->current_uncompressed_length(); + file.buf.reset(new (std::nothrow) unsigned char [file.size]); + if (!file.buf) + { + printf("%s: out of memory!\n", file.name.c_str()); + } else { - if (zip->decompress(file->buf, file->size) != util::archive_file::error::NONE) - { - free(file->buf); - file->buf = nullptr; - } + if (zip->decompress(file.buf.get(), file.size)) + file.free(); } - file->listed = 0; + file.listed = 0; if (found[i] >= MAX_FILES) { printf("%s: max of %d files exceeded\n",path,MAX_FILES); @@ -612,13 +605,8 @@ int CLIB_DECL main(int argc,char *argv[]) } { - int found[2]; - int i,j,mode1,mode2; - int besti,bestj; - - - found[0] = found[1] = 0; - for (i = 0;i < 2;i++) + int found[2] = { 0, 0 }; + for (int i = 0; i < 2; i++) { if (argc > i+1) { @@ -633,26 +621,26 @@ int CLIB_DECL main(int argc,char *argv[]) else printf("%d files\n",found[0]); - for (i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { - for (j = 0; j < found[i]; j++) + for (int j = 0; j < found[i]; j++) { - checkintegrity(&files[i][j], 1 << i, all_hashes); + files[i][j].checkintegrity(1 << i, all_hashes); } } if (argc < 3) { - /* find duplicates in one dir */ - for (i = 0;i < found[0];i++) + // find duplicates in one dir + for (int i = 0;i < found[0];i++) { - for (j = i+1;j < found[0];j++) + for (int j = i+1;j < found[0];j++) { - for (mode1 = 0;mode1 < total_modes;mode1++) + for (int mode1 = 0;mode1 < total_modes;mode1++) { - for (mode2 = 0;mode2 < total_modes;mode2++) + for (int mode2 = 0;mode2 < total_modes;mode2++) { - if (filecompare(&files[0][i],&files[0][j],mode1,mode2) == 1.0f) + if (files[0][i].compare(files[0][j],mode1,mode2) == 1.0f) printname(&files[0][i],&files[0][j],1.0,mode1,mode2); } } @@ -661,40 +649,38 @@ int CLIB_DECL main(int argc,char *argv[]) } else { - /* compare two dirs */ - for (i = 0;i < found[0];i++) + // compare two dirs + for (int i = 0;i < found[0];i++) { - for (j = 0;j < found[1];j++) + for (int j = 0;j < found[1];j++) { fprintf(stderr,"%2d%%\r",100*(i*found[1]+j)/(found[0]*found[1])); - for (mode1 = 0;mode1 < total_modes;mode1++) + for (int mode1 = 0;mode1 < total_modes;mode1++) { - for (mode2 = 0;mode2 < total_modes;mode2++) + for (int mode2 = 0;mode2 < total_modes;mode2++) { - matchscore[i][j][mode1][mode2] = filecompare(&files[0][i],&files[1][j],mode1,mode2); + matchscore[i][j][mode1][mode2] = files[0][i].compare(files[1][j],mode1,mode2); } } } } fprintf(stderr," \r"); + int besti; do { - float bestscore; - int bestmode1,bestmode2; - besti = -1; - bestj = -1; - bestscore = 0.0; - bestmode1 = bestmode2 = -1; + int bestj = -1; + float bestscore = 0.0; + int bestmode1 = -1, bestmode2 = -1; - for (mode1 = 0;mode1 < total_modes;mode1++) + for (int mode1 = 0;mode1 < total_modes;mode1++) { - for (mode2 = 0;mode2 < total_modes;mode2++) + for (int mode2 = 0;mode2 < total_modes;mode2++) { - for (i = 0;i < found[0];i++) + for (int i = 0;i < found[0];i++) { - for (j = 0;j < found[1];j++) + for (int j = 0;j < found[1];j++) { if (matchscore[i][j][mode1][mode2] > bestscore || (matchscore[i][j][mode1][mode2] == 1.0f && mode2 == 0 && bestmode2 > 0)) @@ -721,17 +707,17 @@ int CLIB_DECL main(int argc,char *argv[]) matchscore[besti][bestj][bestmode1][bestmode2] = 0.0; /* remove all matches using the same sections with a worse score */ - for (j = 0;j < found[1];j++) + for (int j = 0;j < found[1];j++) { - for (mode2 = 0;mode2 < total_modes;mode2++) + for (int mode2 = 0;mode2 < total_modes;mode2++) { if (matchscore[besti][j][bestmode1][mode2] < bestscore) matchscore[besti][j][bestmode1][mode2] = 0.0; } } - for (i = 0;i < found[0];i++) + for (int i = 0;i < found[0];i++) { - for (mode1 = 0;mode1 < total_modes;mode1++) + for (int mode1 = 0;mode1 < total_modes;mode1++) { if (matchscore[i][bestj][mode1][bestmode2] < bestscore) matchscore[i][bestj][mode1][bestmode2] = 0.0; @@ -740,49 +726,50 @@ int CLIB_DECL main(int argc,char *argv[]) /* remove all matches using incompatible sections */ compatiblemodes(bestmode1,&start,&end); - for (j = 0;j < found[1];j++) + for (int j = 0;j < found[1];j++) { - for (mode2 = 0;mode2 < total_modes;mode2++) + for (int mode2 = 0;mode2 < total_modes;mode2++) { - for (mode1 = 0;mode1 < start;mode1++) + for (int mode1 = 0;mode1 < start;mode1++) matchscore[besti][j][mode1][mode2] = 0.0; - for (mode1 = end+1;mode1 < total_modes;mode1++) + for (int mode1 = end+1;mode1 < total_modes;mode1++) matchscore[besti][j][mode1][mode2] = 0.0; } } compatiblemodes(bestmode2,&start,&end); - for (i = 0;i < found[0];i++) + for (int i = 0;i < found[0];i++) { - for (mode1 = 0;mode1 < total_modes;mode1++) + for (int mode1 = 0;mode1 < total_modes;mode1++) { - for (mode2 = 0;mode2 < start;mode2++) + for (int mode2 = 0;mode2 < start;mode2++) matchscore[i][bestj][mode1][mode2] = 0.0; - for (mode2 = end+1;mode2 < total_modes;mode2++) + for (int mode2 = end+1;mode2 < total_modes;mode2++) matchscore[i][bestj][mode1][mode2] = 0.0; } } } - } while (besti != -1); + } + while (besti != -1); - for (i = 0;i < found[0];i++) + for (int i = 0;i < found[0];i++) { if (files[0][i].listed == 0) printname(&files[0][i],nullptr,0.0,0,0); } - for (i = 0;i < found[1];i++) + for (int i = 0;i < found[1];i++) { if (files[1][i].listed == 0) printname(nullptr,&files[1][i],0.0,0,0); } } - for (i = 0;i < found[0];i++) + for (int i = 0;i < found[0];i++) { - freefile(&files[0][i]); + files[0][i].free(); } - for (i = 0;i < found[1];i++) + for (int i = 0;i < found[1];i++) { - freefile(&files[1][i]); + files[1][i].free(); } } diff --git a/src/tools/split.cpp b/src/tools/split.cpp index f8a8eb79234..24953c3d7cd 100644 --- a/src/tools/split.cpp +++ b/src/tools/split.cpp @@ -66,7 +66,7 @@ static int split_file(const char *filename, const char *basename, uint32_t split void *splitbuffer = nullptr; int index, partnum; uint64_t totallength; - osd_file::error filerr; + std::error_condition filerr; int error = 1; // convert split size to MB @@ -79,7 +79,7 @@ static int split_file(const char *filename, const char *basename, uint32_t split // open the file for read filerr = util::core_file::open(filename, OPEN_FLAG_READ, infile); - if (filerr != osd_file::error::NONE) + if (filerr) { fprintf(stderr, "Fatal error: unable to open file '%s'\n", filename); goto cleanup; @@ -117,7 +117,7 @@ static int split_file(const char *filename, const char *basename, uint32_t split // create the split file filerr = util::core_file::open(splitfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, splitfile); - if (filerr != osd_file::error::NONE) + if (filerr) { fprintf(stderr, "Fatal error: unable to create split file '%s'\n", splitfilename.c_str()); goto cleanup; @@ -153,7 +153,7 @@ static int split_file(const char *filename, const char *basename, uint32_t split // create it filerr = util::core_file::open(outfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile); - if (filerr != osd_file::error::NONE) + if (filerr) { printf("\n"); fprintf(stderr, "Fatal error: unable to create output file '%s'\n", outfilename.c_str()); @@ -216,7 +216,7 @@ static int join_file(const char *filename, const char *outname, int write_output std::string basepath; util::core_file::ptr outfile, infile, splitfile; void *splitbuffer = nullptr; - osd_file::error filerr; + std::error_condition filerr; uint32_t splitsize; char buffer[256]; int error = 1; @@ -224,7 +224,7 @@ static int join_file(const char *filename, const char *outname, int write_output // open the file for read filerr = util::core_file::open(filename, OPEN_FLAG_READ, splitfile); - if (filerr != osd_file::error::NONE) + if (filerr) { fprintf(stderr, "Fatal error: unable to open file '%s'\n", filename); goto cleanup; @@ -264,7 +264,7 @@ static int join_file(const char *filename, const char *outname, int write_output { // don't overwrite the original! filerr = util::core_file::open(outfilename, OPEN_FLAG_READ, outfile); - if (filerr == osd_file::error::NONE) + if (!filerr) { outfile.reset(); fprintf(stderr, "Fatal error: output file '%s' already exists\n", outfilename.c_str()); @@ -273,7 +273,7 @@ static int join_file(const char *filename, const char *outname, int write_output // open the output for write filerr = util::core_file::open(outfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile); - if (filerr != osd_file::error::NONE) + if (filerr) { fprintf(stderr, "Fatal error: unable to create file '%s'\n", outfilename.c_str()); goto cleanup; @@ -301,7 +301,7 @@ static int join_file(const char *filename, const char *outname, int write_output // read the file's contents infilename.insert(0, basepath); filerr = util::core_file::load(infilename.c_str(), &splitbuffer, length); - if (filerr != osd_file::error::NONE) + if (filerr) { printf("\n"); fprintf(stderr, "Fatal error: unable to load file '%s'\n", infilename.c_str()); diff --git a/src/tools/srcclean.cpp b/src/tools/srcclean.cpp index 052d2a37334..340217c7768 100644 --- a/src/tools/srcclean.cpp +++ b/src/tools/srcclean.cpp @@ -2254,13 +2254,13 @@ int main(int argc, char *argv[]) { // open the file util::core_file::ptr infile; - osd_file::error const err(util::core_file::open(argv[i], OPEN_FLAG_READ, infile)); - if (osd_file::error::NONE != err) + std::error_condition const err(util::core_file::open(argv[i], OPEN_FLAG_READ, infile)); + if (err) { if (affected) std::cerr << std::endl; affected = true; - util::stream_format(std::cerr, "Can't open %1$s\n", argv[i]); + util::stream_format(std::cerr, "Can't open %1$s (%2$s)\n", argv[i], err.message()); ++failures; continue; } diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index 14e7dbf2c6d..5395bc6ae01 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -1219,9 +1219,9 @@ int main(int argc, char *argv[]) void *data = nullptr; u32 length = 0; if(std::strcmp(opts.filename, "-") != 0) { - osd_file::error filerr = util::core_file::load(opts.filename, &data, length); - if(filerr != osd_file::error::NONE) { - std::fprintf(stderr, "Error opening file '%s'\n", opts.filename); + std::error_condition filerr = util::core_file::load(opts.filename, &data, length); + if(filerr) { + std::fprintf(stderr, "Error opening file '%s' (%s)\n", opts.filename, filerr.message().c_str()); return 1; } } |