//------------------------------------------------- // close - close a file and free all data; also // remove the file if requested //------------------------------------------------- public void close() { // close files and free memory if (m_zipfile != null) { m_zipfile.Dispose(); } m_zipfile = null; if (m_file != null) { m_file.Dispose(); } m_file = null; m_zipdata.clear(); if (m_remove_on_close) { m_osdfile.remove(m_fullpath); } m_remove_on_close = false; // reset our hashes and path as well m_hashes.reset(); m_fullpath = ""; }
//------------------------------------------------- // load_zipped_file - load a ZIPped file //------------------------------------------------- osd_file.error load_zipped_file() { assert(m_file == null); assert(m_zipdata.empty()); assert(m_zipfile != null); // allocate some memory m_zipdata.resize((int)m_ziplength); // read the data into our buffer and return var ziperr = m_zipfile.decompress(m_zipdata, (UInt32)m_zipdata.size()); if (ziperr != util.archive_file.error.NONE) { m_zipdata.clear(); return(osd_file.error.FAILURE); } // convert to RAM file osd_file.error filerr = util.core_file.open_ram(m_zipdata, (UInt32)m_zipdata.size(), m_openflags, out m_file); if (filerr != osd_file.error.NONE) { m_zipdata.clear(); return(osd_file.error.FAILURE); } // close out the ZIP file m_zipfile.Dispose(); m_zipfile = null; return(osd_file.error.NONE); }
//------------------------------------------------- // load_zipped_file - load a ZIPped file //------------------------------------------------- std.error_condition load_zipped_file() { assert(m_file == null); assert(m_zipdata.empty()); assert(m_zipfile != null); // allocate some memory m_zipdata.resize(m_ziplength); // read the data into our buffer and return var ziperr = m_zipfile.decompress(m_zipdata, (uint32_t)m_zipdata.size()); if (ziperr) { m_zipdata.clear(); return(ziperr); } // convert to RAM file std.error_condition filerr = util.core_file.open_ram(m_zipdata, m_zipdata.size(), m_openflags, out m_file); if (filerr) { m_zipdata.clear(); return(filerr); } // close out the ZIP file m_zipfile.Dispose(); m_zipfile = null; return(new std.error_condition()); }
public emu_file(string searchpath, u32 openflags) { m_file = null; m_iterator = new path_iterator(searchpath); m_mediapaths = new path_iterator(searchpath); m_crc = 0; m_openflags = openflags; m_zipfile = null; m_ziplength = 0; m_remove_on_close = false; m_restrict_to_mediapath = false; // sanity check the open flags if ((m_openflags & OPEN_FLAG_HAS_CRC) > 0 && (m_openflags & OPEN_FLAG_WRITE) > 0) { throw new emu_fatalerror("Attempted to open a file for write with OPEN_FLAG_HAS_CRC"); } }
emu_file(u32 openflags, empty_t unused) { m_filename = ""; m_fullpath = ""; m_file = null; m_iterator = new emu_file_searchpath_vector(); m_mediapaths = new emu_file_searchpath_vector(); m_first = true; m_crc = 0; m_openflags = openflags; m_zipfile = null; m_ziplength = 0; m_remove_on_close = false; m_restrict_to_mediapath = 0; // sanity check the open flags if ((m_openflags & OPEN_FLAG_HAS_CRC) != 0 && (m_openflags & OPEN_FLAG_WRITE) != 0) { throw new emu_fatalerror("Attempted to open a file for write with OPEN_FLAG_HAS_CRC"); } }
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); }