Example #1
0
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;
	for (unsigned i = 0; i < ARRAY_LENGTH(suffixes); i++, m_fullpath = savepath, filename.clear())
	{
		// loop over directory parts up to the start of filename
		while (1)
		{
			// find the final path separator
			auto const dirsep = m_fullpath.find_last_of(PATH_SEPARATOR[0]);
			if (dirsep == std::string::npos)
				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.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();
		}
	}
	return osd_file::error::NOT_FOUND;
}
Example #2
0
file_error emu_file::attempt_zipped()
{
	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 FILERR_NOT_FOUND;

		if (restrict_to_mediapath())
			if ( !part_of_mediapath(m_fullpath) )
				return FILERR_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
		zip_file *zip;
		zip_error ziperr = zip_file_open(m_fullpath.c_str(), &zip);

		// chop the .zip back off the filename before continuing
		m_fullpath = m_fullpath.substr(0, dirsep);

		// if we failed to open this file, continue scanning
		if (ziperr != ZIPERR_NONE)
			continue;

		// see if we can find a file with the right name and (if available) crc
		const zip_file_header *header;
		for (header = zip_file_first_file(zip); header != nullptr; header = zip_file_next_file(zip))
			if (zip_filename_match(*header, filename) && (!(m_openflags & OPEN_FLAG_HAS_CRC) || header->crc == m_crc))
				break;

		// if that failed, look for a file with the right crc, but the wrong filename
		if (header == nullptr && (m_openflags & OPEN_FLAG_HAS_CRC))
			for (header = zip_file_first_file(zip); header != nullptr; header = zip_file_next_file(zip))
				if (header->crc == m_crc && !zip_header_is_path(*header))
					break;

		// 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 == nullptr)
			for (header = zip_file_first_file(zip); header != nullptr; header = zip_file_next_file(zip))
				if (zip_filename_match(*header, filename))
					break;

		// if we got it, read the data
		if (header != nullptr)
		{
			m_zipfile = zip;
			m_ziplength = header->uncompressed_length;

			// build a hash with just the CRC
			m_hashes.reset();
			m_hashes.add_crc(header->crc);
			return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? FILERR_NONE : load_zipped_file();
		}

		// close up the ZIP file and try the next level
		zip_file_close(zip);
	}
}
Example #3
0
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 FILERR_NOT_FOUND;

		if (restrict_to_mediapath())
			if ( !part_of_mediapath(m_fullpath) )
				return FILERR_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
		_7z_file *_7z;
		_7z_error _7zerr = _7z_file_open(m_fullpath.c_str(), &_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 != _7ZERR_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_crc_match(_7z, m_crc, filename.c_str(), filename.length(), true, true);

		// if that failed, look for a file with the right crc, but the wrong filename
		if (fileno==-1)
			if (m_openflags & OPEN_FLAG_HAS_CRC) fileno = _7z_search_crc_match(_7z, m_crc, filename.c_str(), filename.length(), true, false);

		// 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==-1)
			fileno = _7z_search_crc_match(_7z, m_crc, filename.c_str(), filename.length(), false, true);

		if (fileno != -1)
		{
			m__7zfile = _7z;
			m__7zlength = _7z->uncompressed_length;

			// build a hash with just the CRC
			m_hashes.reset();
			m_hashes.add_crc(_7z->crc);
			return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? FILERR_NONE : load__7zped_file();
		}

		// close up the _7Z file and try the next level
		_7z_file_close(_7z);
	}
}
Example #4
0
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();
	}
}