summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2022-04-19 14:22:04 -0400
committer AJR <ajrhacker@users.noreply.github.com>2022-04-19 14:28:45 -0400
commitb45569d964aa8fae416d2049ba70699f5b2d7837 (patch)
tree522b58375072a7b7f3acc36081de7daa9302417d /src/emu
parent7780f53ffd266ad7a88058ecda056e5eeea3bc9f (diff)
File handling cleanup
- Remove fgetc, fgets and ptr methods from device_image_interface. - Remove the core_file::buffer method to read an entire file into memory and rewrite emu_file::hashes to not depend on it. - Make core_in_memory_file a final class; now that buffering is gone, core_osd_file no longer subclasses it but a new superclass that retains some common methods. - Rename the offset and length methods used internally in core_file implementations to index and size due to frequent clashes with parameter names. - Convert comments in util/corefile.cpp to C++ style. - Add a new overload of the hash_collection::compute method which hashes data from a random_read stream, reading it into memory one chunk at a time. As a result, the hash_collection::begin and hash_collection::end methods have been removed as obsolete (similar methods are now used internally only). - Enhance error messages for the frontend media identifier when it encounters file errors.
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/diimage.cpp44
-rw-r--r--src/emu/diimage.h25
-rw-r--r--src/emu/fileio.cpp19
3 files changed, 26 insertions, 62 deletions
diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp
index 2d192836ddd..4e5ca05e002 100644
--- a/src/emu/diimage.cpp
+++ b/src/emu/diimage.cpp
@@ -351,43 +351,25 @@ bool device_image_interface::load_software_region(std::string_view tag, std::uni
// to be loaded
// ****************************************************************************
-bool device_image_interface::run_hash(util::core_file &file, u32 skip_bytes, util::hash_collection &hashes, const char *types)
+std::error_condition device_image_interface::run_hash(util::random_read &file, u32 skip_bytes, util::hash_collection &hashes, const char *types)
{
// reset the hash; we want to override existing data
hashes.reset();
// figure out the size, and "cap" the skip bytes
u64 size;
- if (file.length(size))
- return false;
+ std::error_condition filerr = file.length(size);
+ if (filerr)
+ return filerr;
skip_bytes = u32(std::min<u64>(skip_bytes, size));
- // seek to the beginning
- file.seek(skip_bytes, SEEK_SET); // TODO: check error return
- u64 position = skip_bytes;
-
- // keep on reading hashes
- hashes.begin(types);
- while (position < size)
- {
- uint8_t buffer[8192];
-
- // read bytes
- const size_t count = size_t(std::min<u64>(size - position, sizeof(buffer)));
- size_t actual_count;
- const std::error_condition filerr = file.read(buffer, count, actual_count);
- if (filerr || !actual_count)
- return false;
- position += actual_count;
-
- // and compute the hashes
- hashes.buffer(buffer, actual_count);
- }
- hashes.end();
+ // and compute the hashes
+ size_t actual_count;
+ filerr = hashes.compute(file, skip_bytes, size - skip_bytes, actual_count, types);
+ if (filerr)
+ return filerr;
- // cleanup
- file.seek(0, SEEK_SET); // TODO: check error return
- return true;
+ return std::error_condition();
}
@@ -408,18 +390,18 @@ bool device_image_interface::image_checkhash()
return true;
// run the hash
- if (!run_hash(*m_file, unhashed_header_length(), m_hash, util::hash_collection::HASH_TYPES_ALL))
+ if (run_hash(*m_file, unhashed_header_length(), m_hash, util::hash_collection::HASH_TYPES_ALL))
return false;
}
return true;
}
-util::hash_collection device_image_interface::calculate_hash_on_file(util::core_file &file) const
+util::hash_collection device_image_interface::calculate_hash_on_file(util::random_read &file) const
{
// calculate the hash
util::hash_collection hash;
- if (!run_hash(file, unhashed_header_length(), hash, util::hash_collection::HASH_TYPES_ALL))
+ if (run_hash(file, unhashed_header_length(), hash, util::hash_collection::HASH_TYPES_ALL))
hash.reset();
return hash;
}
diff --git a/src/emu/diimage.h b/src/emu/diimage.h
index 4d97e4cd717..08d48020cc3 100644
--- a/src/emu/diimage.h
+++ b/src/emu/diimage.h
@@ -113,7 +113,7 @@ public:
const util::option_guide &device_get_creation_option_guide() const { return create_option_guide(); }
std::string_view error();
- void seterror(std::error_condition err, const char *message);
+ void seterror(std::error_condition err, const char *message = nullptr);
void message(const char *format, ...) ATTR_PRINTF(2,3);
bool exists() const noexcept { return !m_image_name.empty(); }
@@ -126,7 +126,7 @@ public:
bool is_filetype(std::string_view candidate_filetype) const;
bool is_open() const noexcept { return bool(m_file); }
- util::core_file &image_core_file() const noexcept { return *m_file; }
+ util::core_file &image_core_file() const noexcept { assert(is_open()); return *m_file; }
bool is_readonly() const noexcept { return m_readonly; }
// image file I/O wrappers
@@ -165,28 +165,11 @@ public:
m_file->tell(result);
return result;
}
- int fgetc()
- {
- char ch;
- if (fread(&ch, 1) != 1)
- ch = '\0';
- return ch;
- }
- char *fgets(char *buffer, u32 length)
- {
- check_for_file();
- return m_file->gets(buffer, length);
- }
bool image_feof()
{
check_for_file();
return m_file->eof();
}
- const void *ptr()
- {
- check_for_file();
- return m_file->buffer();
- }
// allocate and read into buffers
u32 fread(std::unique_ptr<u8 []> &ptr, u32 length) { ptr = std::make_unique<u8 []>(length); return fread(ptr.get(), length); }
@@ -211,7 +194,7 @@ public:
u32 crc();
util::hash_collection& hash() { return m_hash; }
- util::hash_collection calculate_hash_on_file(util::core_file &file) const;
+ util::hash_collection calculate_hash_on_file(util::random_read &file) const;
void battery_load(void *buffer, int length, int fill);
void battery_load(void *buffer, int length, const void *def_buffer);
@@ -294,7 +277,7 @@ private:
bool load_software_part(std::string_view identifier);
bool init_phase() const;
- static bool run_hash(util::core_file &file, u32 skip_bytes, util::hash_collection &hashes, const char *types);
+ static std::error_condition run_hash(util::random_read &file, u32 skip_bytes, util::hash_collection &hashes, const char *types);
// loads an image or software items and resets - called internally when we
// load an is_reset_on_load() item
diff --git a/src/emu/fileio.cpp b/src/emu/fileio.cpp
index 21634d8f211..a1bf4adbcb4 100644
--- a/src/emu/fileio.cpp
+++ b/src/emu/fileio.cpp
@@ -259,7 +259,7 @@ util::hash_collection &emu_file::hashes(std::string_view types)
// determine which hashes we need
std::string needed;
for (char scan : types)
- if (already_have.find_first_of(scan) == -1)
+ if (already_have.find_first_of(scan) == std::string::npos)
needed.push_back(scan);
// if we need nothing, skip it
@@ -279,15 +279,14 @@ util::hash_collection &emu_file::hashes(std::string_view types)
return m_hashes;
}
- // read the data if we can
- const u8 *filedata = (const u8 *)m_file->buffer();
- if (filedata == nullptr)
+ std::uint64_t length;
+ if (m_file->length(length))
return m_hashes;
- // compute the hash
- std::uint64_t length;
- if (!m_file->length(length))
- m_hashes.compute(filedata, length, needed.c_str());
+ // hash the data
+ std::size_t actual;
+ (void)m_hashes.compute(*m_file, 0U, length, actual, needed.c_str()); // FIXME: need better interface to report errors
+
return m_hashes;
}
@@ -805,7 +804,7 @@ std::error_condition emu_file::load_zipped_file()
m_zipdata.resize(m_ziplength);
// read the data into our buffer and return
- auto const ziperr = m_zipfile->decompress(&m_zipdata[0], m_zipdata.size());
+ auto const ziperr = m_zipfile->decompress(m_zipdata.data(), m_zipdata.size());
if (ziperr)
{
m_zipdata.clear();
@@ -813,7 +812,7 @@ std::error_condition emu_file::load_zipped_file()
}
// convert to RAM file
- std::error_condition const filerr = util::core_file::open_ram(&m_zipdata[0], m_zipdata.size(), m_openflags, m_file);
+ std::error_condition const filerr = util::core_file::open_ram(m_zipdata.data(), m_zipdata.size(), m_openflags, m_file);
if (filerr)
{
m_zipdata.clear();