Fold some redundant code

This commit is contained in:
Vas Crabb 2016-03-18 20:37:44 +11:00
parent 100fa28671
commit 142292ee00
4 changed files with 46 additions and 144 deletions

View File

@ -1757,28 +1757,32 @@ void media_identifier::identify(const char *filename)
}
// if that failed, and the filename ends with .zip, identify as a ZIP file
if (core_filename_ends_with(filename, ".7z"))
if (core_filename_ends_with(filename, ".7z") || core_filename_ends_with(filename, ".zip"))
{
// first attempt to examine it as a valid _7Z file
util::archive_file::ptr _7z;
util::archive_file::error _7zerr = util::archive_file::open_7z(filename, _7z);
if ((_7zerr == util::archive_file::error::NONE) && _7z)
util::archive_file::ptr archive;
util::archive_file::error err;
if (core_filename_ends_with(filename, ".7z"))
err = util::archive_file::open_7z(filename, archive);
else
err = util::archive_file::open_zip(filename, archive);
if ((err == util::archive_file::error::NONE) && archive)
{
std::vector<std::uint8_t> data;
// loop over entries in the .7z, skipping empty files and directories
for (int i = _7z->first_file(); i >= 0; i = _7z->next_file())
for (int i = archive->first_file(); i >= 0; i = archive->next_file())
{
const std::uint64_t length(_7z->current_uncompressed_length());
if (!_7z->current_is_directory() && (length != 0) && (std::uint32_t(length) == length))
const std::uint64_t length(archive->current_uncompressed_length());
if (!archive->current_is_directory() && (length != 0) && (std::uint32_t(length) == length))
{
// decompress data into RAM and identify it
try
{
data.resize(std::size_t(length));
_7zerr = _7z->decompress(&data[0], std::uint32_t(length));
if (_7zerr == util::archive_file::error::NONE)
identify_data(_7z->current_name().c_str(), &data[0], length);
err = archive->decompress(&data[0], std::uint32_t(length));
if (err == util::archive_file::error::NONE)
identify_data(archive->current_name().c_str(), &data[0], length);
}
catch (...)
{
@ -1790,43 +1794,7 @@ void media_identifier::identify(const char *filename)
}
// clear out any cached files
_7z.reset();
util::archive_file::cache_clear();
}
else if (core_filename_ends_with(filename, ".zip"))
{
// first attempt to examine it as a valid ZIP file
util::archive_file::ptr zip;
util::archive_file::error ziperr = util::archive_file::open_zip(filename, zip);
if (ziperr == util::archive_file::error::NONE && zip)
{
std::vector<std::uint8_t> data;
// loop over entries in the ZIP, skipping empty files and directories
for (int i = zip->first_file(); i >= 0; i = zip->next_file())
{
const std::uint64_t length(zip->current_uncompressed_length());
if (!zip->current_is_directory() && (length != 0) && (std::uint32_t(length) == length))
{
// decompress data into RAM and identify it
try
{
data.resize(std::size_t(length));
ziperr = zip->decompress(&data[0], std::uint32_t(length));
if (ziperr == util::archive_file::error::NONE)
identify_data(zip->current_name().c_str(), &data[0], length);
}
catch (...)
{
// resizing the buffer could cause a bad_alloc if archive contains large files
}
data.clear();
}
}
}
// clear out any cached files
zip.reset();
archive.reset();
util::archive_file::cache_clear();
}

View File

@ -145,8 +145,6 @@ emu_file::emu_file(UINT32 openflags)
m_openflags(openflags),
m_zipfile(nullptr),
m_ziplength(0),
m__7zfile(),
m__7zlength(0),
m_remove_on_close(false),
m_restrict_to_mediapath(false)
{
@ -163,8 +161,6 @@ emu_file::emu_file(const char *searchpath, UINT32 openflags)
m_openflags(openflags),
m_zipfile(nullptr),
m_ziplength(0),
m__7zfile(),
m__7zlength(0),
m_remove_on_close(false),
m_restrict_to_mediapath(false)
{
@ -227,12 +223,6 @@ hash_collection &emu_file::hashes(const char *types)
return m_hashes;
// if we have ZIP data, just hash that directly
if (!m__7zdata.empty())
{
m_hashes.compute(&m__7zdata[0], m__7zdata.size(), needed.c_str());
return m_hashes;
}
if (!m_zipdata.empty())
{
m_hashes.compute(&m_zipdata[0], m_zipdata.size(), needed.c_str());
@ -385,11 +375,9 @@ osd_file::error emu_file::open_ram(const void *data, UINT32 length)
void emu_file::close()
{
// close files and free memory
m__7zfile.reset();
m_zipfile.reset();
m_file.reset();
m__7zdata.clear();
m_zipdata.clear();
if (m_remove_on_close)
@ -422,10 +410,7 @@ osd_file::error emu_file::compress(int level)
bool emu_file::compressed_file_ready(void)
{
// load the ZIP file now if we haven't yet
if (m__7zfile != nullptr && load__7zped_file() != osd_file::error::NONE)
return true;
if (m_zipfile != nullptr && load_zipped_file() != osd_file::error::NONE)
if (m_zipfile && (load_zipped_file() != osd_file::error::NONE))
return true;
return false;
@ -492,9 +477,6 @@ bool emu_file::eof()
UINT64 emu_file::size()
{
// use the ZIP length if present
if (m__7zfile != nullptr)
return m__7zlength;
if (m_zipfile != nullptr)
return m_ziplength;
@ -715,41 +697,6 @@ osd_file::error emu_file::attempt_zipped()
}
//-------------------------------------------------
// load_zipped_file - load a ZIPped file
//-------------------------------------------------
osd_file::error emu_file::load_zipped_file()
{
assert(m_file == nullptr);
assert(m_zipdata.empty());
assert(m_zipfile != nullptr);
// allocate some memory
m_zipdata.resize(m_ziplength);
// read the data into our buffer and return
auto const ziperr = m_zipfile->decompress(&m_zipdata[0], 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[0], m_zipdata.size(), m_openflags, m_file);
if (filerr != osd_file::error::NONE)
{
m_zipdata.clear();
return osd_file::error::FAILURE;
}
// close out the ZIP file
m_zipfile.reset();
return osd_file::error::NONE;
}
//-------------------------------------------------
// attempt__7zped - attempt to open a .7z file
//-------------------------------------------------
@ -803,13 +750,13 @@ osd_file::error emu_file::attempt__7zped()
if (fileno >= 0)
{
m__7zfile = std::move(_7z);
m__7zlength = m__7zfile->current_uncompressed_length();
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__7zfile->current_crc());
return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? osd_file::error::NONE : load__7zped_file();
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
@ -819,35 +766,35 @@ osd_file::error emu_file::attempt__7zped()
//-------------------------------------------------
// load__7zped_file - load a _7Zped file
// load_zipped_file - load a ZIPped file
//-------------------------------------------------
osd_file::error emu_file::load__7zped_file()
osd_file::error emu_file::load_zipped_file()
{
assert(m_file == nullptr);
assert(m__7zdata.empty());
assert(m__7zfile);
assert(m_zipdata.empty());
assert(m_zipfile);
// allocate some memory
m__7zdata.resize(m__7zlength);
m_zipdata.resize(m_ziplength);
// read the data into our buffer and return
auto const _7zerr = m__7zfile->decompress(&m__7zdata[0], m__7zdata.size());
if (_7zerr != util::archive_file::error::NONE)
auto const ziperr = m_zipfile->decompress(&m_zipdata[0], m_zipdata.size());
if (ziperr != util::archive_file::error::NONE)
{
m__7zdata.clear();
m_zipdata.clear();
return osd_file::error::FAILURE;
}
// convert to RAM file
osd_file::error filerr = util::core_file::open_ram(&m__7zdata[0], m__7zdata.size(), m_openflags, m_file);
osd_file::error filerr = util::core_file::open_ram(&m_zipdata[0], m_zipdata.size(), m_openflags, m_file);
if (filerr != osd_file::error::NONE)
{
m__7zdata.clear();
m_zipdata.clear();
return osd_file::error::FAILURE;
}
// close out the _7Z file
m__7zfile.reset();
// close out the ZIP file
m_zipfile.reset();
return osd_file::error::NONE;
}

View File

@ -145,10 +145,8 @@ private:
// internal helpers
osd_file::error attempt_zipped();
osd_file::error load_zipped_file();
osd_file::error attempt__7zped();
osd_file::error load__7zped_file();
osd_file::error load_zipped_file();
// internal state
std::string m_filename; // original filename provided
@ -164,10 +162,6 @@ private:
dynamic_buffer m_zipdata; // ZIP file data
UINT64 m_ziplength; // ZIP file length
std::unique_ptr<util::archive_file> m__7zfile; // 7Z file pointer
dynamic_buffer m__7zdata; // 7Z file data
UINT64 m__7zlength; // 7Z file length
bool m_remove_on_close; // flag: remove the file when closing
bool m_restrict_to_mediapath; // flag: restrict to paths inside the media-path
};

View File

@ -80,7 +80,7 @@ public:
FUNCTION PROTOTYPES
***************************************************************************/
static int zippath_find_sub_path(archive_file &zipfile, const char *subpath, osd_dir_entry_type *type);
static int zippath_find_sub_path(archive_file &zipfile, const char *subpath, osd_dir_entry_type &type);
static int is_zip_file(const char *path);
static int is_zip_file_separator(char c);
static int is_7z_file(const char *path);
@ -392,7 +392,7 @@ osd_file::error zippath_fopen(const char *filename, UINT32 openflags, util::core
}
if (subpath.length() > 0)
header = zippath_find_sub_path(*zip, subpath.c_str(), &entry_type);
header = zippath_find_sub_path(*zip, subpath.c_str(), entry_type);
else
header = zip->first_file();
@ -669,44 +669,37 @@ static char next_path_char(const char *s, int *pos)
* @return null if it fails, else a zip_file_header*.
*/
static int zippath_find_sub_path(archive_file &zipfile, const char *subpath, osd_dir_entry_type *type)
static int zippath_find_sub_path(archive_file &zipfile, const char *subpath, osd_dir_entry_type &type)
{
for (int header = zipfile.first_file(); header >= 0; header = zipfile.next_file())
{
/* special case */
if (subpath == nullptr)
{
if (type != nullptr)
*type = ENTTYPE_FILE;
type = ENTTYPE_FILE;
return header;
}
// FIXME: how is this actually supposed to work? I'm pretty sure it's broken right now anyway.
int i = 0, j = 0;
char c1, c2, last_char;
last_char = '/';
while(((c1 = next_path_char(zipfile.current_name().c_str(), &i)) == (c2 = next_path_char(subpath, &j))) && (c1 != '\0' && c2 != '\0'))
last_char = c2;
char c1, c2;
while (((c1 = next_path_char(zipfile.current_name().c_str(), &i)) == (c2 = next_path_char(subpath, &j))) && c1 && c2) { }
if (c2 == '\0')
if (!c1)
{
if (c1 == '\0')
if (!c2)
{
if (type != nullptr)
*type = ENTTYPE_FILE;
type = zipfile.current_is_directory() ? ENTTYPE_DIR : ENTTYPE_FILE;
return header;
}
else if ((last_char == '/') || (c1 == '/'))
else if ((c2 == '/') && !(c2 = next_path_char(subpath, &j)) && zipfile.current_is_directory())
{
if (type != nullptr)
*type = ENTTYPE_DIR;
type = ENTTYPE_DIR;
return header;
}
}
}
if (type != nullptr)
*type = ENTTYPE_NONE;
type = ENTTYPE_NONE;
return -1;
}
@ -794,7 +787,7 @@ static osd_file::error zippath_resolve(const char *path, osd_dir_entry_type &ent
newpath.assign(path + apath.length(), i);
/* this was a true ZIP path - attempt to identify the type of path */
zippath_find_sub_path(*zipfile, newpath.c_str(), &current_entry_type);
zippath_find_sub_path(*zipfile, newpath.c_str(), current_entry_type);
if (current_entry_type == ENTTYPE_NONE)
{
err = osd_file::error::NOT_FOUND;