osd_file.error attempt_zipped() { string [] suffixes = new string[] { ".zip", ".7z" }; //char const *const suffixes[] = { ".zip", ".7z" }; open_func [] open_funcs = new open_func[] { util.archive_file.open_zip, util.archive_file.open_7z }; // loop over archive types string savepath = m_fullpath; string filename = ""; for (int i = 0; i < suffixes.Length; i++, m_fullpath = savepath, filename = "") { // loop over directory parts up to the start of filename while (true) { // find the final path separator var dirsep = m_fullpath.find_last_of(PATH_SEPARATOR[0]); if (dirsep == -1) { break; } 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 = filename.Insert(0, "/"); } filename = filename.Insert(0, m_fullpath.substr(dirsep + 1)); // remove this part of the filename and append an archive extension m_fullpath = m_fullpath.Substring(0, dirsep); m_fullpath += suffixes[i]; // attempt to open the archive file util.archive_file zip; util.archive_file.error ziperr = open_funcs[i](m_fullpath, out 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) != 0) { header = zip.search(m_crc, filename, false); } if (header < 0 && ((m_openflags & OPEN_FLAG_HAS_CRC) != 0)) { 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) != 0)) { 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 = 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) != 0) ? osd_file.error.NONE : load_zipped_file()); } // close up the archive file and try the next level zip.Dispose(); zip = null; //.reset(); } } return(osd_file.error.NOT_FOUND); }
std.error_condition attempt_zipped() { //typedef std::error_condition (*open_func)(std::string_view 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 string savepath = m_fullpath; string filename = ""; for (unsigned i = 0; i < std.size(suffixes); i++, m_fullpath = savepath, filename = "") { // loop over directory parts up to the start of filename while (true) { if (!part_of_mediapath(m_fullpath)) { break; } // find the final path separator //auto const dirsepiter(std::find_if(m_fullpath.rbegin(), m_fullpath.rend(), util::is_directory_separator)); //if (dirsepiter == m_fullpath.rend()) // break; //std::string::size_type const dirsep(std::distance(m_fullpath.begin(), dirsepiter.base()) - 1); var dirsep = m_fullpath.find_last_of(PATH_SEPARATOR[0]); if (dirsep == npos) { break; } // insert the part from the right of the separator into the head of the filename if (!filename.empty()) { filename = filename.insert_(0, "/"); } filename = filename.insert_(0, m_fullpath.substr(dirsep + 1)); // remove this part of the filename and append an archive extension m_fullpath = m_fullpath.Substring(0, (int)dirsep); m_fullpath += suffixes[i]; LOG(null, "emu_file: looking for '{0}' in archive '{1}'\n", filename, m_fullpath); // attempt to open the archive file util.archive_file zip; std.error_condition ziperr = open_funcs[i](m_fullpath, out 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) { 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) != 0) { header = zip.search(m_crc, filename, false); } if (header < 0 && ((m_openflags & OPEN_FLAG_HAS_CRC) != 0)) { 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) != 0)) { 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 = 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()); m_fullpath = savepath; return((m_openflags & OPEN_FLAG_NO_PRELOAD) != 0 ? new std.error_condition() : load_zipped_file()); } // close up the archive file and try the next level zip.Dispose(); zip = null; //.reset(); } } return(std.errc.no_such_file_or_directory); }