From db10880ee02f6c4859b7a69fe42e249710fbce9f Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Fri, 25 Mar 2016 16:09:14 +1100 Subject: [PATCH] Try next archive type if file not found, not just on open error --- src/emu/fileio.cpp | 128 ++++++++++++++++++++++----------------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/src/emu/fileio.cpp b/src/emu/fileio.cpp index fec82d9e592..78be6e10faa 100644 --- a/src/emu/fileio.cpp +++ b/src/emu/fileio.cpp @@ -626,76 +626,76 @@ bool emu_file::part_of_mediapath(std::string path) osd_file::error emu_file::attempt_zipped() { + typedef util::archive_file::error (*open_func)(const std::string &filename, util::archive_file::ptr &result); + char const *const suffixes[] = { ".zip", ".7z" }; + open_func const open_funcs[ARRAY_LENGTH(suffixes)] = { &util::archive_file::open_zip, &util::archive_file::open_7z }; + + // loop over archive types + std::string const savepath(m_fullpath); std::string filename; - - // loop over directory parts up to the start of filename - while (1) + for (unsigned i = 0; i < ARRAY_LENGTH(suffixes); i++, m_fullpath = savepath, filename.clear()) { - // find the final path separator - 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() && !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 .zip extension - 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); - - if (ziperr != util::archive_file::error::NONE) + // loop over directory parts up to the start of filename + while (1) { - // remove this part of the filename and append a .7z extension - m_fullpath = m_fullpath.substr(0, dirsep).append(".7z"); + // find the final path separator + auto const dirsep = m_fullpath.find_last_of(PATH_SEPARATOR[0]); + if (dirsep == std::string::npos) + break; - // attempt to open the 7zip file - ziperr = util::archive_file::open_7z(m_fullpath, zip); + if (restrict_to_mediapath() && !part_of_mediapath(m_fullpath)) + break; + + // insert the part from the right of the separator into the head of the filename + if (!filename.empty()) filename.insert(0, 1, '/'); + filename.insert(0, m_fullpath.substr(dirsep + 1, std::string::npos)); + + // remove this part of the filename and append an archive extension + m_fullpath.resize(dirsep); + m_fullpath.append(suffixes[i]); + + // attempt to open the archive file + util::archive_file::ptr zip; + util::archive_file::error ziperr = open_funcs[i](m_fullpath, zip); + + // chop the archive suffix back off the filename before continuing + m_fullpath = m_fullpath.substr(0, dirsep); + + // if we failed to open this file, continue scanning + if (ziperr != util::archive_file::error::NONE) + continue; + + 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, 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, false); + if (header < 0) header = zip->search(filename, true); + + // if we got it, read the data + if (header >= 0) + { + m_zipfile = std::move(zip); + 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 archive file and try the next level + zip.reset(); } - - // 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 - if (ziperr != util::archive_file::error::NONE) - continue; - - 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, 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, false); - if (header < 0) header = zip->search(filename, true); - - // if we got it, read the data - if (header >= 0) - { - m_zipfile = std::move(zip); - 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 ZIP file and try the next level - zip.reset(); } + return osd_file::error::NOT_FOUND; }