mirror of
https://github.com/holub/mame
synced 2025-04-17 22:13:04 +03:00
Make emu_file archive searh order CRC+path, CRC+partial path, CRC, path, partial path and fold some redundant code
This commit is contained in:
parent
f5d8ff8f43
commit
54279dbf11
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
*~
|
||||
.*.sw?
|
||||
*.mo
|
||||
*.pyc
|
||||
*.pyo
|
||||
.DS_Store
|
||||
@ -36,7 +37,6 @@
|
||||
/.idea
|
||||
regtests/chdman/temp
|
||||
regtests/jedutil/output
|
||||
*.mo
|
||||
/CMakeLists.txt
|
||||
/src/devices/cpu/m68000/m68kops.cpp
|
||||
/src/devices/cpu/m68000/m68kops.h
|
||||
|
@ -334,17 +334,9 @@ osd_file::error emu_file::open_next()
|
||||
// if we're opening for read-only we have other options
|
||||
if ((m_openflags & (OPEN_FLAG_READ | OPEN_FLAG_WRITE)) == OPEN_FLAG_READ)
|
||||
{
|
||||
std::string tempfullpath = m_fullpath;
|
||||
|
||||
filerr = attempt_zipped();
|
||||
if (filerr == osd_file::error::NONE)
|
||||
break;
|
||||
|
||||
m_fullpath = tempfullpath;
|
||||
|
||||
filerr = attempt__7zped();
|
||||
if (filerr == osd_file::error::NONE)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return filerr;
|
||||
@ -640,13 +632,12 @@ osd_file::error emu_file::attempt_zipped()
|
||||
while (1)
|
||||
{
|
||||
// find the final path separator
|
||||
int dirsep = m_fullpath.find_last_of(PATH_SEPARATOR[0]);
|
||||
if (dirsep == -1)
|
||||
auto const dirsep = m_fullpath.find_last_of(PATH_SEPARATOR[0]);
|
||||
if (dirsep == std::string::npos)
|
||||
return osd_file::error::NOT_FOUND;
|
||||
|
||||
if (restrict_to_mediapath())
|
||||
if ( !part_of_mediapath(m_fullpath) )
|
||||
return osd_file::error::NOT_FOUND;
|
||||
if (restrict_to_mediapath() && !part_of_mediapath(m_fullpath))
|
||||
return osd_file::error::NOT_FOUND;
|
||||
|
||||
// insert the part from the right of the separator into the head of the filename
|
||||
if (filename.length() > 0)
|
||||
@ -654,13 +645,22 @@ osd_file::error emu_file::attempt_zipped()
|
||||
filename.insert(0, m_fullpath.substr(dirsep + 1, -1));
|
||||
|
||||
// remove this part of the filename and append a .zip extension
|
||||
m_fullpath = m_fullpath.substr(0, dirsep).append(".zip");
|
||||
m_fullpath = m_fullpath.substr(0, dirsep).append(".zip");
|
||||
|
||||
// attempt to open the ZIP file
|
||||
util::archive_file::ptr zip;
|
||||
util::archive_file::error ziperr = util::archive_file::open_zip(m_fullpath, zip);
|
||||
|
||||
// chop the .zip back off the filename before continuing
|
||||
if (ziperr != util::archive_file::error::NONE)
|
||||
{
|
||||
// remove this part of the filename and append a .7z extension
|
||||
m_fullpath = m_fullpath.substr(0, dirsep).append(".7z");
|
||||
|
||||
// attempt to open the 7zip file
|
||||
ziperr = util::archive_file::open_7z(m_fullpath, zip);
|
||||
}
|
||||
|
||||
// chop the .zip/.7z back off the filename before continuing
|
||||
m_fullpath = m_fullpath.substr(0, dirsep);
|
||||
|
||||
// if we failed to open this file, continue scanning
|
||||
@ -670,14 +670,16 @@ osd_file::error emu_file::attempt_zipped()
|
||||
int header = -1;
|
||||
|
||||
// see if we can find a file with the right name and (if available) crc
|
||||
if (m_openflags & OPEN_FLAG_HAS_CRC) header = zip->search(m_crc, filename);
|
||||
if (m_openflags & OPEN_FLAG_HAS_CRC) header = zip->search(m_crc, filename, false);
|
||||
if (header < 0 && (m_openflags & OPEN_FLAG_HAS_CRC)) header = zip->search(m_crc, filename, true);
|
||||
|
||||
// if that failed, look for a file with the right crc, but the wrong filename
|
||||
if (header < 0 && (m_openflags & OPEN_FLAG_HAS_CRC)) header = zip->search(m_crc);
|
||||
|
||||
// if that failed, look for a file with the right name; reporting a bad checksum
|
||||
// is more helpful and less confusing than reporting "rom not found"
|
||||
if (header < 0) header = zip->search(filename);
|
||||
if (header < 0) header = zip->search(filename, false);
|
||||
if (header < 0) header = zip->search(filename, true);
|
||||
|
||||
// if we got it, read the data
|
||||
if (header >= 0)
|
||||
@ -697,74 +699,6 @@ osd_file::error emu_file::attempt_zipped()
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// attempt__7zped - attempt to open a .7z file
|
||||
//-------------------------------------------------
|
||||
|
||||
osd_file::error emu_file::attempt__7zped()
|
||||
{
|
||||
std::string filename;
|
||||
|
||||
// loop over directory parts up to the start of filename
|
||||
while (1)
|
||||
{
|
||||
// find the final path separator
|
||||
int dirsep = m_fullpath.find_last_of(PATH_SEPARATOR[0]);
|
||||
if (dirsep == -1)
|
||||
return osd_file::error::NOT_FOUND;
|
||||
|
||||
if (restrict_to_mediapath())
|
||||
if ( !part_of_mediapath(m_fullpath) )
|
||||
return osd_file::error::NOT_FOUND;
|
||||
|
||||
// insert the part from the right of the separator into the head of the filename
|
||||
if (filename.length() > 0)
|
||||
filename.insert(0, "/");
|
||||
filename.insert(0, m_fullpath.substr(dirsep + 1, -1));
|
||||
|
||||
// remove this part of the filename and append a .7z extension
|
||||
m_fullpath = m_fullpath.substr(0, dirsep).append(".7z");
|
||||
|
||||
// attempt to open the _7Z file
|
||||
util::archive_file::ptr _7z;
|
||||
util::archive_file::error _7zerr = util::archive_file::open_7z(m_fullpath, _7z);
|
||||
|
||||
// chop the ._7z back off the filename before continuing
|
||||
m_fullpath = m_fullpath.substr(0, dirsep);
|
||||
|
||||
// if we failed to open this file, continue scanning
|
||||
if (_7zerr != util::archive_file::error::NONE)
|
||||
continue;
|
||||
|
||||
int fileno = -1;
|
||||
|
||||
// see if we can find a file with the right name and (if available) crc
|
||||
if (m_openflags & OPEN_FLAG_HAS_CRC) fileno = _7z->search(m_crc, filename);
|
||||
|
||||
// if that failed, look for a file with the right crc, but the wrong filename
|
||||
if ((fileno < 0) && (m_openflags & OPEN_FLAG_HAS_CRC)) fileno = _7z->search(m_crc);
|
||||
|
||||
// if that failed, look for a file with the right name; reporting a bad checksum
|
||||
// is more helpful and less confusing than reporting "rom not found"
|
||||
if (fileno < 0) fileno = _7z->search(filename);
|
||||
|
||||
if (fileno >= 0)
|
||||
{
|
||||
m_zipfile = std::move(_7z);
|
||||
m_ziplength = m_zipfile->current_uncompressed_length();
|
||||
|
||||
// build a hash with just the CRC
|
||||
m_hashes.reset();
|
||||
m_hashes.add_crc(m_zipfile->current_crc());
|
||||
return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? osd_file::error::NONE : load_zipped_file();
|
||||
}
|
||||
|
||||
// close up the _7Z file and try the next level
|
||||
_7z.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// load_zipped_file - load a ZIPped file
|
||||
//-------------------------------------------------
|
||||
|
@ -145,7 +145,6 @@ private:
|
||||
|
||||
// internal helpers
|
||||
osd_file::error attempt_zipped();
|
||||
osd_file::error attempt__7zped();
|
||||
osd_file::error load_zipped_file();
|
||||
|
||||
// internal state
|
||||
|
@ -124,12 +124,21 @@ public:
|
||||
|
||||
archive_file::error initialize();
|
||||
|
||||
int first_file() { return search(0, 0, std::string(), false, false); }
|
||||
int next_file() { return (m_curr_file_idx < 0) ? -1 : search(m_curr_file_idx + 1, 0, std::string(), false, false); }
|
||||
int first_file() { return search(0, 0, std::string(), false, false, false); }
|
||||
int next_file() { return (m_curr_file_idx < 0) ? -1 : search(m_curr_file_idx + 1, 0, std::string(), false, false, false); }
|
||||
|
||||
int search(std::uint32_t crc) { return search(0, crc, std::string(), true, false); }
|
||||
int search(const std::string &filename) { return search(0, 0, filename, false, true); }
|
||||
int search(std::uint32_t crc, const std::string &filename) { return search(0, crc, filename, true, true); }
|
||||
int search(std::uint32_t crc)
|
||||
{
|
||||
return search(0, crc, std::string(), true, false, false);
|
||||
}
|
||||
int search(const std::string &filename, bool partialpath)
|
||||
{
|
||||
return search(0, 0, filename, false, true, partialpath);
|
||||
}
|
||||
int search(std::uint32_t crc, const std::string &filename, bool partialpath)
|
||||
{
|
||||
return search(0, crc, filename, true, true, partialpath);
|
||||
}
|
||||
|
||||
bool current_is_directory() const { return m_curr_is_dir; }
|
||||
const std::string ¤t_name() const { return m_curr_name; }
|
||||
@ -144,7 +153,13 @@ private:
|
||||
m7z_file_impl &operator=(const m7z_file_impl &) = delete;
|
||||
m7z_file_impl &operator=(m7z_file_impl &&) = delete;
|
||||
|
||||
int search(int i, std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname);
|
||||
int search(
|
||||
int i,
|
||||
std::uint32_t search_crc,
|
||||
const std::string &search_filename,
|
||||
bool matchcrc,
|
||||
bool matchname,
|
||||
bool partialpath);
|
||||
void make_utf8_name(int index);
|
||||
|
||||
static constexpr std::size_t CACHE_SIZE = 8;
|
||||
@ -187,9 +202,18 @@ public:
|
||||
virtual int first_file() override { return m_impl->first_file(); }
|
||||
virtual int next_file() override { return m_impl->next_file(); }
|
||||
|
||||
virtual int search(std::uint32_t crc) override { return m_impl->search(crc); }
|
||||
virtual int search(const std::string &filename) override { return m_impl->search(filename); }
|
||||
virtual int search(std::uint32_t crc, const std::string &filename) override { return m_impl->search(crc, filename); }
|
||||
virtual int search(std::uint32_t crc) override
|
||||
{
|
||||
return m_impl->search(crc);
|
||||
}
|
||||
virtual int search(const std::string &filename, bool partialpath) override
|
||||
{
|
||||
return m_impl->search(filename, partialpath);
|
||||
}
|
||||
virtual int search(std::uint32_t crc, const std::string &filename, bool partialpath) override
|
||||
{
|
||||
return m_impl->search(crc, filename, partialpath);
|
||||
}
|
||||
|
||||
virtual bool current_is_directory() const override { return m_impl->current_is_directory(); }
|
||||
virtual const std::string ¤t_name() const override { return m_impl->current_name(); }
|
||||
@ -373,7 +397,13 @@ archive_file::error m7z_file_impl::decompress(void *buffer, std::uint32_t length
|
||||
}
|
||||
|
||||
|
||||
int m7z_file_impl::search(int i, std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname)
|
||||
int m7z_file_impl::search(
|
||||
int i,
|
||||
std::uint32_t search_crc,
|
||||
const std::string &search_filename,
|
||||
bool matchcrc,
|
||||
bool matchname,
|
||||
bool partialpath)
|
||||
{
|
||||
for ( ; i < m_db.db.NumFiles; i++)
|
||||
{
|
||||
@ -383,7 +413,11 @@ int m7z_file_impl::search(int i, std::uint32_t search_crc, const std::string &se
|
||||
const std::uint64_t size(f.Size);
|
||||
const std::uint32_t crc(f.Crc);
|
||||
const bool crcmatch(crc == search_crc);
|
||||
const bool namematch(!core_stricmp(search_filename.c_str(), &m_utf8_buf[0]));
|
||||
auto const partialoffset(m_utf8_buf.size() - 1 - search_filename.length());
|
||||
bool const partialpossible((m_utf8_buf.size() > (search_filename.length() + 1)) && (m_utf8_buf[partialoffset - 1] == '/'));
|
||||
const bool namematch(
|
||||
!core_stricmp(search_filename.c_str(), &m_utf8_buf[0]) ||
|
||||
(partialpath && partialpossible && !core_stricmp(search_filename.c_str(), &m_utf8_buf[partialoffset])));
|
||||
|
||||
const bool found = ((!matchcrc && !matchname) || !f.IsDir) && (!matchcrc || crcmatch) && (!matchname || namematch);
|
||||
if (found)
|
||||
|
@ -156,26 +156,27 @@ public:
|
||||
int first_file()
|
||||
{
|
||||
m_cd_pos = 0;
|
||||
return search(0, std::string(), false, false);
|
||||
return search(0, std::string(), false, false, false);
|
||||
}
|
||||
int next_file()
|
||||
{
|
||||
return search(0, std::string(), false, false);
|
||||
return search(0, std::string(), false, false, false);
|
||||
}
|
||||
|
||||
int search(std::uint32_t crc)
|
||||
{
|
||||
m_cd_pos = 0;
|
||||
return search(crc, std::string(), true, false);
|
||||
return search(crc, std::string(), true, false, false);
|
||||
}
|
||||
int search(const std::string &filename)
|
||||
int search(const std::string &filename, bool partialpath)
|
||||
{
|
||||
m_cd_pos = 0;
|
||||
return search(0, filename, false, true);
|
||||
return search(0, filename, false, true, partialpath);
|
||||
}
|
||||
int search(std::uint32_t crc, const std::string &filename)
|
||||
int search(std::uint32_t crc, const std::string &filename, bool partialpath)
|
||||
{
|
||||
m_cd_pos = 0;
|
||||
return search(crc, filename, true, true);
|
||||
return search(crc, filename, true, true, partialpath);
|
||||
}
|
||||
|
||||
bool current_is_directory() const { return m_curr_is_dir; }
|
||||
@ -191,7 +192,7 @@ private:
|
||||
zip_file_impl &operator=(const zip_file_impl &) = delete;
|
||||
zip_file_impl &operator=(zip_file_impl &&) = delete;
|
||||
|
||||
int search(std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname);
|
||||
int search(std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname, bool partialpath);
|
||||
|
||||
archive_file::error reopen()
|
||||
{
|
||||
@ -281,9 +282,18 @@ public:
|
||||
virtual int first_file() override { return m_impl->first_file(); }
|
||||
virtual int next_file() override { return m_impl->next_file(); }
|
||||
|
||||
virtual int search(std::uint32_t crc) override { return m_impl->search(crc); }
|
||||
virtual int search(const std::string &filename) override { return m_impl->search(filename); }
|
||||
virtual int search(std::uint32_t crc, const std::string &filename) override { return m_impl->search(crc, filename); }
|
||||
virtual int search(std::uint32_t crc) override
|
||||
{
|
||||
return m_impl->search(crc);
|
||||
}
|
||||
virtual int search(const std::string &filename, bool partialpath) override
|
||||
{
|
||||
return m_impl->search(filename, partialpath);
|
||||
}
|
||||
virtual int search(std::uint32_t crc, const std::string &filename, bool partialpath) override
|
||||
{
|
||||
return m_impl->search(crc, filename, partialpath);
|
||||
}
|
||||
|
||||
virtual bool current_is_directory() const override { return m_impl->current_is_directory(); }
|
||||
virtual const std::string ¤t_name() const override { return m_impl->current_name(); }
|
||||
@ -396,7 +406,7 @@ void zip_file_impl::close(ptr &&zip)
|
||||
in the ZIP
|
||||
-------------------------------------------------*/
|
||||
|
||||
int zip_file_impl::search(std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname)
|
||||
int zip_file_impl::search(std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname, bool partialpath)
|
||||
{
|
||||
// if we're at or past the end, we're done
|
||||
std::string filename;
|
||||
@ -437,7 +447,11 @@ int zip_file_impl::search(std::uint32_t search_crc, const std::string &search_fi
|
||||
|
||||
// check to see if it matches query
|
||||
bool const crcmatch(search_crc == m_header.crc);
|
||||
const bool namematch(!core_stricmp(search_filename.c_str(), filename.c_str()));
|
||||
auto const partialoffset(filename.length() - search_filename.length());
|
||||
bool const partialpossible((filename.length() > search_filename.length()) && (filename[partialoffset - 1] == '/'));
|
||||
const bool namematch(
|
||||
!core_stricmp(search_filename.c_str(), filename.c_str()) ||
|
||||
(partialpath && partialpossible && !core_stricmp(search_filename.c_str(), filename.c_str() + partialoffset)));
|
||||
|
||||
bool const found = ((!matchcrc && !matchname) || !is_dir) && (!matchcrc || crcmatch) && (!matchname || namematch);
|
||||
if (found)
|
||||
|
@ -71,8 +71,8 @@ public:
|
||||
|
||||
// find a file index by crc, filename or both - returns non-negative on match
|
||||
virtual int search(std::uint32_t crc) = 0;
|
||||
virtual int search(const std::string &filename) = 0;
|
||||
virtual int search(std::uint32_t crc, const std::string &filename) = 0;
|
||||
virtual int search(const std::string &filename, bool partialpath) = 0;
|
||||
virtual int search(std::uint32_t crc, const std::string &filename, bool partialpath) = 0;
|
||||
|
||||
// information on most recently found file
|
||||
virtual bool current_is_directory() const = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user