diff options
Diffstat (limited to 'src')
31 files changed, 507 insertions, 580 deletions
diff --git a/src/devices/bus/ti99x/gromport.cpp b/src/devices/bus/ti99x/gromport.cpp index 2b9a66d028a..baa77932f7e 100644 --- a/src/devices/bus/ti99x/gromport.cpp +++ b/src/devices/bus/ti99x/gromport.cpp @@ -2245,43 +2245,46 @@ rpk_socket::rpk_socket(const char* id, int length, UINT8* contents) /* Locate a file in the ZIP container */ -const zip_file::file_header* rpk_reader::find_file(zip_file &zip, const char *filename, UINT32 crc) +int rpk_reader::find_file(util::archive_file &zip, const char *filename, UINT32 crc) { - const zip_file::file_header *header; - for (header = zip.first_file(); header != nullptr; header = zip.next_file()) + for (int header = zip.first_file(); header >= 0; header = zip.next_file()) { - // We don't check for CRC == 0. - if (crc != 0) + // Ignore directories + if (!zip.current_is_directory()) { - // if the CRC and name both match, we're good - // if the CRC matches and the name doesn't, we're still good - if (header->crc == crc) - return header; - } - else - { - if (core_stricmp(header->filename, filename)==0) + // We don't check for CRC == 0. + if (crc != 0) + { + // if the CRC and name both match, we're good + // if the CRC matches and the name doesn't, we're still good + if (zip.current_crc() == crc) + return header; + } + else { - return header; + if (core_stricmp(zip.current_name().c_str(), filename) == 0) + { + return header; + } } } } - return nullptr; + return -1; } /* Load a rom resource and put it in a pcb socket instance. */ -rpk_socket* rpk_reader::load_rom_resource(zip_file &zip, xml_data_node* rom_resource_node, const char* socketname) +rpk_socket* rpk_reader::load_rom_resource(util::archive_file &zip, xml_data_node* rom_resource_node, const char* socketname) { const char* file; const char* crcstr; const char* sha1; - zip_file::error ziperr; + util::archive_file::error ziperr; UINT32 crc; int length; UINT8* contents; - const zip_file::file_header *header; + int header; // find the file attribute (required) file = xml_get_attribute_string(rom_resource_node, "file", nullptr); @@ -2301,9 +2304,9 @@ rpk_socket* rpk_reader::load_rom_resource(zip_file &zip, xml_data_node* rom_reso crc = strtoul(crcstr, nullptr, 16); header = find_file(zip, file, crc); } - if (header == nullptr) throw rpk_exception(RPK_INVALID_FILE_REF, "File not found or CRC check failed"); + if (header < 0) throw rpk_exception(RPK_INVALID_FILE_REF, "File not found or CRC check failed"); - length = header->uncompressed_length; + length = zip.current_uncompressed_length(); // Allocate storage contents = global_alloc_array_clear<UINT8>(length); @@ -2311,9 +2314,9 @@ rpk_socket* rpk_reader::load_rom_resource(zip_file &zip, xml_data_node* rom_reso // and unzip file from the zip file ziperr = zip.decompress(contents, length); - if (ziperr != zip_file::error::NONE) + if (ziperr != util::archive_file::error::NONE) { - if (ziperr == zip_file::error::UNSUPPORTED) throw rpk_exception(RPK_ZIP_UNSUPPORTED); + if (ziperr == util::archive_file::error::UNSUPPORTED) throw rpk_exception(RPK_ZIP_UNSUPPORTED); else throw rpk_exception(RPK_ZIP_ERROR); } @@ -2414,15 +2417,14 @@ rpk_socket* rpk_reader::load_ram_resource(emu_options &options, xml_data_node* r rpk* rpk_reader::open(emu_options &options, const char *filename, const char *system_name) { - zip_file::error ziperr; + util::archive_file::error ziperr; - const zip_file::file_header *header; const char *pcb_type; const char *id; const char *uses_name; const char *resource_name; - zip_file::ptr zipfile; + util::archive_file::ptr zipfile; std::vector<char> layout_text; xml_data_node *layout_xml = nullptr; @@ -2442,25 +2444,24 @@ rpk* rpk_reader::open(emu_options &options, const char *filename, const char *sy try { /* open the ZIP file */ - ziperr = zip_file::open(filename, zipfile); - if (ziperr != zip_file::error::NONE) throw rpk_exception(RPK_NOT_ZIP_FORMAT); + ziperr = util::archive_file::open_zip(filename, zipfile); + if (ziperr != util::archive_file::error::NONE) throw rpk_exception(RPK_NOT_ZIP_FORMAT); /* find the layout.xml file */ - header = find_file(*zipfile, "layout.xml", 0); - if (header == nullptr) throw rpk_exception(RPK_MISSING_LAYOUT); + if (find_file(*zipfile, "layout.xml", 0) < 0) throw rpk_exception(RPK_MISSING_LAYOUT); /* reserve space for the layout file contents (+1 for the termination) */ - layout_text.resize(header->uncompressed_length + 1); + layout_text.resize(zipfile->current_uncompressed_length() + 1); /* uncompress the layout text */ - ziperr = zipfile->decompress(&layout_text[0], header->uncompressed_length); - if (ziperr != zip_file::error::NONE) + ziperr = zipfile->decompress(&layout_text[0], zipfile->current_uncompressed_length()); + if (ziperr != util::archive_file::error::NONE) { - if (ziperr == zip_file::error::UNSUPPORTED) throw rpk_exception(RPK_ZIP_UNSUPPORTED); + if (ziperr == util::archive_file::error::UNSUPPORTED) throw rpk_exception(RPK_ZIP_UNSUPPORTED); else throw rpk_exception(RPK_ZIP_ERROR); } - layout_text[header->uncompressed_length] = '\0'; // Null-terminate + layout_text[zipfile->current_uncompressed_length()] = '\0'; // Null-terminate /* parse the layout text */ layout_xml = xml_string_read(&layout_text[0], nullptr); diff --git a/src/devices/bus/ti99x/gromport.h b/src/devices/bus/ti99x/gromport.h index 9b60425aa06..36900c40045 100644 --- a/src/devices/bus/ti99x/gromport.h +++ b/src/devices/bus/ti99x/gromport.h @@ -454,10 +454,10 @@ public: rpk *open(emu_options &options, const char *filename, const char *system_name); private: - const zip_file::file_header* find_file(zip_file &zip, const char *filename, UINT32 crc); - rpk_socket* load_rom_resource(zip_file &zip, xml_data_node* rom_resource_node, const char* socketname); - rpk_socket* load_ram_resource(emu_options &options, xml_data_node* ram_resource_node, const char* socketname, const char* system_name); - const pcb_type* m_types; + int find_file(util::archive_file &zip, const char *filename, UINT32 crc); + rpk_socket* load_rom_resource(util::archive_file &zip, xml_data_node* rom_resource_node, const char* socketname); + rpk_socket* load_ram_resource(emu_options &options, xml_data_node* ram_resource_node, const char* socketname, const char* system_name); + const pcb_type* m_types; }; class rpk diff --git a/src/devices/imagedev/floppy.cpp b/src/devices/imagedev/floppy.cpp index 38e0a5ff9d8..345d6bce3cd 100644 --- a/src/devices/imagedev/floppy.cpp +++ b/src/devices/imagedev/floppy.cpp @@ -365,7 +365,7 @@ floppy_image_format_t *floppy_image_device::identify(std::string filename) util::core_file::ptr fd; std::string revised_path; - osd_file::error err = zippath_fopen(filename.c_str(), OPEN_FLAG_READ, fd, revised_path); + osd_file::error err = util::zippath_fopen(filename.c_str(), OPEN_FLAG_READ, fd, revised_path); if(err != osd_file::error::NONE) { seterror(IMAGE_ERROR_INVALIDIMAGE, "Unable to open the image file"); return nullptr; @@ -1004,7 +1004,7 @@ void ui_menu_control_floppy_image::hook_load(std::string filename, bool softlist std::string tmp_path; util::core_file::ptr tmp_file; /* attempt to open the file for writing but *without* create */ - filerr = zippath_fopen(filename.c_str(), OPEN_FLAG_READ | OPEN_FLAG_WRITE, tmp_file, tmp_path); + filerr = util::zippath_fopen(filename.c_str(), OPEN_FLAG_READ | OPEN_FLAG_WRITE, tmp_file, tmp_path); if(filerr == osd_file::error::NONE) tmp_file.reset(); else @@ -1048,7 +1048,7 @@ void ui_menu_control_floppy_image::handle() state = START_FILE; handle(); } else { - zippath_combine(output_filename, current_directory.c_str(), current_file.c_str()); + util::zippath_combine(output_filename, current_directory.c_str(), current_file.c_str()); output_format = format_array[submenu_result]; do_load_create(); ui_menu::stack_pop(machine()); diff --git a/src/emu/clifront.cpp b/src/emu/clifront.cpp index 79b53e943c7..ee2777257e2 100644 --- a/src/emu/clifront.cpp +++ b/src/emu/clifront.cpp @@ -15,7 +15,6 @@ #include "audit.h" #include "info.h" #include "unzip.h" -#include "un7z.h" #include "validity.h" #include "sound/samples.h" #include "cliopts.h" @@ -266,7 +265,7 @@ int cli_frontend::execute(int argc, char **argv) m_result = MAMERR_FATALERROR; } - _7z_file::cache_clear(); + util::archive_file::cache_clear(); global_free(manager); return m_result; @@ -1000,7 +999,7 @@ void cli_frontend::verifyroms(const char *gamename) } // clear out any cached files - zip_file::cache_clear(); + util::archive_file::cache_clear(); // return an error if none found if (matched == 0) @@ -1092,7 +1091,7 @@ void cli_frontend::verifysamples(const char *gamename) } // clear out any cached files - zip_file::cache_clear(); + util::archive_file::cache_clear(); // return an error if none found if (matched == 0) @@ -1407,7 +1406,7 @@ void cli_frontend::verifysoftware(const char *gamename) } // clear out any cached files - zip_file::cache_clear(); + util::archive_file::cache_clear(); // return an error if none found if (matched == 0) @@ -1529,7 +1528,7 @@ void cli_frontend::verifysoftlist(const char *gamename) } // clear out any cached files - zip_file::cache_clear(); + util::archive_file::cache_clear(); // return an error if none found if (matched == 0) @@ -1761,9 +1760,9 @@ void media_identifier::identify(const char *filename) if (core_filename_ends_with(filename, ".7z")) { // first attempt to examine it as a valid _7Z file - _7z_file::ptr _7z; - _7z_file::error _7zerr = _7z_file::open(filename, _7z); - if (_7zerr == _7z_file::error::NONE && _7z != nullptr) + 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) { std::vector<std::uint8_t> data; @@ -1771,14 +1770,14 @@ void media_identifier::identify(const char *filename) for (int i = _7z->first_file(); i >= 0; i = _7z->next_file()) { const std::uint64_t length(_7z->current_uncompressed_length()); - if ((length != 0) && (std::uint32_t(length) == length)) + if (!_7z->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 == _7z_file::error::NONE) + if (_7zerr == util::archive_file::error::NONE) identify_data(_7z->current_name().c_str(), &data[0], length); } catch (...) @@ -1792,30 +1791,43 @@ void media_identifier::identify(const char *filename) // clear out any cached files _7z.reset(); - _7z_file::cache_clear(); + util::archive_file::cache_clear(); } else if (core_filename_ends_with(filename, ".zip")) { // first attempt to examine it as a valid ZIP file - zip_file::ptr zip = nullptr; - zip_file::error ziperr = zip_file::open(filename, zip); - if (ziperr == zip_file::error::NONE && zip != nullptr) + 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 (const zip_file::file_header *entry = zip->first_file(); entry != nullptr; entry = zip->next_file()) - if (entry->uncompressed_length != 0) + 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 - dynamic_buffer data(entry->uncompressed_length); - ziperr = zip->decompress(&data[0], entry->uncompressed_length); - if (ziperr == zip_file::error::NONE) - identify_data(entry->filename, &data[0], entry->uncompressed_length); + 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(); - zip_file::cache_clear(); + util::archive_file::cache_clear(); } // otherwise, identify as a raw file diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index b8a7ebc4874..2e10b40356e 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -1872,6 +1872,7 @@ static void execute_dump(running_machine &machine, int ref, int params, const ch for (i = offset; i <= endoffset; i += 16) { output.clear(); + output.rdbuf()->clear(); /* print the address */ util::stream_format(output, "%0*X: ", space->logaddrchars(), (UINT32)space->byte_to_address(i)); @@ -2306,6 +2307,7 @@ static void execute_cheatlist(running_machine &machine, int ref, int params, con { active_cheat++; output.clear(); + output.rdbuf()->clear(); stream_format( output, " <cheat desc=\"Possibility %d : %0*X (%0*X)\">\n" @@ -2516,6 +2518,7 @@ static void execute_dasm(running_machine &machine, int ref, int params, const ch offs_t tempaddr; int numbytes = 0; output.clear(); + output.rdbuf()->clear(); /* print the address */ stream_format(output, "%0*X: ", space->logaddrchars(), (UINT32)space->byte_to_address(pcbyte)); diff --git a/src/emu/debug/dvbpoints.cpp b/src/emu/debug/dvbpoints.cpp index 463fc4dbe08..7da6ac4c399 100644 --- a/src/emu/debug/dvbpoints.cpp +++ b/src/emu/debug/dvbpoints.cpp @@ -240,6 +240,7 @@ void debug_view_breakpoints::view_update() if (m_visible.y > 0) { linebuf.clear(); + linebuf.rdbuf()->clear(); linebuf << "ID"; if (m_sortType == &cIndexAscending) linebuf.put('\\'); else if (m_sortType == &cIndexDescending) linebuf.put('/'); @@ -282,6 +283,7 @@ void debug_view_breakpoints::view_update() device_debug::breakpoint *const bp = m_buffer[bpi]; linebuf.clear(); + linebuf.rdbuf()->clear(); util::stream_format(linebuf, "%2X", bp->index()); pad_ostream_to_length(linebuf, tableBreaks[0]); linebuf.put(bp->enabled() ? 'X' : 'O'); diff --git a/src/emu/debug/dvdisasm.cpp b/src/emu/debug/dvdisasm.cpp index b4739fdcbcb..10cb3e75e64 100644 --- a/src/emu/debug/dvdisasm.cpp +++ b/src/emu/debug/dvdisasm.cpp @@ -370,7 +370,7 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines) // allocate disassembly buffer const auto total_bytes = m_total.x * m_total.y; - //m_dasm.clear(); // FIXME + m_dasm.clear(); m_dasm.reserve(total_bytes).seekp(total_bytes); // iterate over lines @@ -388,7 +388,7 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines) // convert back and set the address of this instruction m_byteaddress[instr] = pcbyte; - //m_dasm.clear(); // FIXME + m_dasm.clear(); util::stream_format(m_dasm.seekp(base), source.m_space.is_octal() ? " %0*o " : " %0*X ", source.m_space.logaddrchars()/2*char_num, source.m_space.byte_to_address(pcbyte)); diff --git a/src/emu/debug/dvwpoints.cpp b/src/emu/debug/dvwpoints.cpp index 4720f1dbf3c..8b82a6d3de0 100644 --- a/src/emu/debug/dvwpoints.cpp +++ b/src/emu/debug/dvwpoints.cpp @@ -266,6 +266,7 @@ void debug_view_watchpoints::view_update() if (m_visible.y > 0) { linebuf.clear(); + linebuf.rdbuf()->clear(); linebuf << "ID"; if (m_sortType == &cIndexAscending) linebuf.put('\\'); else if (m_sortType == &cIndexDescending) linebuf.put('/'); @@ -317,6 +318,7 @@ void debug_view_watchpoints::view_update() device_debug::watchpoint *const wp = m_buffer[wpi]; linebuf.clear(); + linebuf.rdbuf()->clear(); util::stream_format(linebuf, "%2X", wp->index()); pad_ostream_to_length(linebuf, tableBreaks[0]); linebuf.put(wp->enabled() ? 'X' : 'O'); diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp index 216b1af1fca..f225f6cd444 100644 --- a/src/emu/diimage.cpp +++ b/src/emu/diimage.cpp @@ -158,7 +158,7 @@ void device_image_interface::device_compute_hash(hash_collection &hashes, const image_error_t device_image_interface::set_image_filename(const char *filename) { m_image_name = filename; - zippath_parent(m_working_directory, filename); + util::zippath_parent(m_working_directory, filename); m_basename.assign(m_image_name); size_t loc1 = m_image_name.find_last_of('\\'); @@ -319,7 +319,7 @@ bool device_image_interface::try_change_working_directory(const char *subdir) /* did we successfully identify the directory? */ if (success) - zippath_combine(m_working_directory, m_working_directory.c_str(), subdir); + util::zippath_combine(m_working_directory, m_working_directory.c_str(), subdir); return success; } @@ -611,7 +611,7 @@ image_error_t device_image_interface::load_image_by_path(UINT32 open_flags, cons std::string revised_path; /* attempt to read the file */ - auto const filerr = zippath_fopen(path, open_flags, m_file, revised_path); + auto const filerr = util::zippath_fopen(path, open_flags, m_file, revised_path); /* did the open succeed? */ switch(filerr) @@ -663,7 +663,7 @@ int device_image_interface::reopen_for_write(const char *path) std::string revised_path; /* attempt to open the file for writing*/ - auto const filerr = zippath_fopen(path, OPEN_FLAG_READ|OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, m_file, revised_path); + auto const filerr = util::zippath_fopen(path, OPEN_FLAG_READ|OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, m_file, revised_path); /* did the open succeed? */ switch(filerr) diff --git a/src/emu/fileio.cpp b/src/emu/fileio.cpp index e0d7cdd7772..2b0f607160c 100644 --- a/src/emu/fileio.cpp +++ b/src/emu/fileio.cpp @@ -10,7 +10,6 @@ #include "emu.h" #include "unzip.h" -#include "un7z.h" #include "fileio.h" @@ -338,7 +337,7 @@ osd_file::error emu_file::open_next() while (m_iterator.next(m_fullpath, m_filename.c_str())) { // attempt to open the file directly - filerr = util::core_file::open(m_fullpath.c_str(), m_openflags, m_file); + filerr = util::core_file::open(m_fullpath, m_openflags, m_file); if (filerr == osd_file::error::NONE) break; @@ -676,44 +675,37 @@ osd_file::error emu_file::attempt_zipped() m_fullpath = m_fullpath.substr(0, dirsep).append(".zip"); // attempt to open the ZIP file - zip_file::ptr zip; - zip_file::error ziperr = zip_file::open(m_fullpath, zip); + util::archive_file::ptr zip; + util::archive_file::error ziperr = util::archive_file::open_zip(m_fullpath, 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 != zip_file::error::NONE) + 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 - const zip_file::file_header *header; - for (header = zip->first_file(); header != nullptr; header = zip->next_file()) - if (zip_filename_match(*header, filename) && (!(m_openflags & OPEN_FLAG_HAS_CRC) || header->crc == m_crc)) - break; + if (m_openflags & OPEN_FLAG_HAS_CRC) header = zip->search(m_crc, filename); // 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->first_file(); header != nullptr; header = zip->next_file()) - if (header->crc == m_crc && !zip_header_is_path(*header)) - break; + 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 == nullptr) - for (header = zip->first_file(); header != nullptr; header = zip->next_file()) - if (zip_filename_match(*header, filename)) - break; + if (header < 0) header = zip->search(filename); // if we got it, read the data - if (header != nullptr) + if (header >= 0) { m_zipfile = std::move(zip); - m_ziplength = header->uncompressed_length; + m_ziplength = m_zipfile->current_uncompressed_length(); // build a hash with just the CRC m_hashes.reset(); - m_hashes.add_crc(header->crc); + m_hashes.add_crc(m_zipfile->current_crc()); return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? osd_file::error::NONE : load_zipped_file(); } @@ -737,8 +729,8 @@ osd_file::error emu_file::load_zipped_file() m_zipdata.resize(m_ziplength); // read the data into our buffer and return - zip_file::error ziperr = m_zipfile->decompress(&m_zipdata[0], m_zipdata.size()); - if (ziperr != zip_file::error::NONE) + 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; @@ -759,29 +751,6 @@ osd_file::error emu_file::load_zipped_file() //------------------------------------------------- -// zip_filename_match - compare zip filename -// to expected filename, ignoring any directory -//------------------------------------------------- - -bool emu_file::zip_filename_match(const zip_file::file_header &header, const std::string &filename) -{ - const char *zipfile = header.filename + header.filename_length - filename.length(); - return (zipfile >= header.filename && core_stricmp(filename.c_str(),zipfile) == 0 && (zipfile == header.filename || zipfile[-1] == '/')); -} - - -//------------------------------------------------- -// zip_header_is_path - check whether filename -// in header is a path -//------------------------------------------------- - -bool emu_file::zip_header_is_path(const zip_file::file_header &header) -{ - const char *zipfile = header.filename + header.filename_length - 1; - return (zipfile >= header.filename && zipfile[0] == '/'); -} - -//------------------------------------------------- // attempt__7zped - attempt to open a .7z file //------------------------------------------------- @@ -810,14 +779,14 @@ osd_file::error emu_file::attempt__7zped() m_fullpath = m_fullpath.substr(0, dirsep).append(".7z"); // attempt to open the _7Z file - _7z_file::ptr _7z; - _7z_file::error _7zerr = _7z_file::open(m_fullpath, _7z); + 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 != _7z_file::error::NONE) + if (_7zerr != util::archive_file::error::NONE) continue; int fileno = -1; @@ -826,13 +795,13 @@ osd_file::error emu_file::attempt__7zped() 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 == -1) && (m_openflags & OPEN_FLAG_HAS_CRC)) fileno = _7z->search(m_crc); + 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 == -1) fileno = _7z->search(filename); + if (fileno < 0) fileno = _7z->search(filename); - if (fileno != -1) + if (fileno >= 0) { m__7zfile = std::move(_7z); m__7zlength = m__7zfile->current_uncompressed_length(); @@ -863,8 +832,8 @@ osd_file::error emu_file::load__7zped_file() m__7zdata.resize(m__7zlength); // read the data into our buffer and return - _7z_file::error _7zerr = m__7zfile->decompress(&m__7zdata[0], m__7zdata.size()); - if (_7zerr != _7z_file::error::NONE) + auto const _7zerr = m__7zfile->decompress(&m__7zdata[0], m__7zdata.size()); + if (_7zerr != util::archive_file::error::NONE) { m__7zdata.clear(); return osd_file::error::FAILURE; diff --git a/src/emu/fileio.h b/src/emu/fileio.h index c54c740d686..f45e8be3533 100644 --- a/src/emu/fileio.h +++ b/src/emu/fileio.h @@ -15,7 +15,6 @@ #include "corefile.h" #include "hash.h" -#include "unzip.h" // some systems use macros for getc/putc rather than functions #ifdef getc @@ -27,7 +26,7 @@ //************************************************************************** // forward declarations -class _7z_file; +namespace util { class archive_file; } // ======================> path_iterator @@ -147,8 +146,6 @@ private: // internal helpers osd_file::error attempt_zipped(); osd_file::error load_zipped_file(); - bool zip_filename_match(const zip_file::file_header &header, const std::string &filename); - bool zip_header_is_path(const zip_file::file_header &header); osd_file::error attempt__7zped(); osd_file::error load__7zped_file(); @@ -163,11 +160,11 @@ private: UINT32 m_openflags; // flags we used for the open hash_collection m_hashes; // collection of hashes - zip_file::ptr m_zipfile; // ZIP file pointer + std::unique_ptr<util::archive_file> m_zipfile; // ZIP file pointer dynamic_buffer m_zipdata; // ZIP file data UINT64 m_ziplength; // ZIP file length - std::unique_ptr<_7z_file> m__7zfile; // 7Z file pointer + std::unique_ptr<util::archive_file> m__7zfile; // 7Z file pointer dynamic_buffer m__7zdata; // 7Z file data UINT64 m__7zlength; // 7Z file length diff --git a/src/emu/machine.cpp b/src/emu/machine.cpp index 00db05b59c3..825843c4b10 100644 --- a/src/emu/machine.cpp +++ b/src/emu/machine.cpp @@ -440,7 +440,7 @@ int running_machine::run(bool firstrun) // call all exit callbacks registered call_notifiers(MACHINE_NOTIFY_EXIT); - zip_file::cache_clear(); + util::archive_file::cache_clear(); // close the logfile m_logfile.reset(); diff --git a/src/emu/ui/filesel.cpp b/src/emu/ui/filesel.cpp index 89658407279..a24a3e9a3cf 100644 --- a/src/emu/ui/filesel.cpp +++ b/src/emu/ui/filesel.cpp @@ -474,7 +474,7 @@ ui_menu_file_selector::file_selector_entry *ui_menu_file_selector::append_dirent } // determine the full path - zippath_combine(buffer, m_current_directory.c_str(), dirent->name); + util::zippath_combine(buffer, m_current_directory.c_str(), dirent->name); // create the file selector entry entry = append_entry( @@ -535,7 +535,7 @@ void ui_menu_file_selector::append_entry_menu_item(const file_selector_entry *en void ui_menu_file_selector::populate() { - zippath_directory *directory = nullptr; + util::zippath_directory *directory = nullptr; osd_file::error err; const osd_directory_entry *dirent; const file_selector_entry *entry; @@ -545,7 +545,7 @@ void ui_menu_file_selector::populate() const char *path = m_current_directory.c_str(); // open the directory - err = zippath_opendir(path, &directory); + err = util::zippath_opendir(path, &directory); // clear out the menu entries m_entrylist = nullptr; @@ -581,7 +581,7 @@ void ui_menu_file_selector::populate() // build the menu for each item if (err == osd_file::error::NONE) { - while((dirent = zippath_readdir(directory)) != nullptr) + while((dirent = util::zippath_readdir(directory)) != nullptr) { // append a dirent entry entry = append_dirent_entry(dirent); @@ -611,7 +611,7 @@ void ui_menu_file_selector::populate() customtop = machine().ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER; if (directory != nullptr) - zippath_closedir(directory); + util::zippath_closedir(directory); } @@ -656,7 +656,7 @@ void ui_menu_file_selector::handle() case SELECTOR_ENTRY_TYPE_DRIVE: case SELECTOR_ENTRY_TYPE_DIRECTORY: // drive/directory - first check the path - err = zippath_opendir(entry->fullpath, nullptr); + err = util::zippath_opendir(entry->fullpath, nullptr); if (err != osd_file::error::NONE) { // this path is problematic; present the user with an error and bail diff --git a/src/emu/ui/imgcntrl.cpp b/src/emu/ui/imgcntrl.cpp index f0b6f3da5b4..0b44f1f8e8c 100644 --- a/src/emu/ui/imgcntrl.cpp +++ b/src/emu/ui/imgcntrl.cpp @@ -59,12 +59,12 @@ ui_menu_control_device_image::ui_menu_control_device_image(running_machine &mach if (image->exists()) { current_file.assign(image->filename()); - zippath_parent(current_directory, current_file.c_str()); + util::zippath_parent(current_directory, current_file.c_str()); } else current_directory.assign(image->working_directory()); /* check to see if the path exists; if not clear it */ - if (zippath_opendir(current_directory.c_str(), nullptr) != osd_file::error::NONE) + if (util::zippath_opendir(current_directory.c_str(), nullptr) != osd_file::error::NONE) current_directory.clear(); } } @@ -90,7 +90,7 @@ void ui_menu_control_device_image::test_create(bool &can_create, bool &need_conf osd_dir_entry_type file_type; /* assemble the full path */ - zippath_combine(path, current_directory.c_str(), current_file.c_str()); + util::zippath_combine(path, current_directory.c_str(), current_file.c_str()); /* does a file or a directory exist at the path */ entry = osd_stat(path.c_str()); @@ -183,11 +183,11 @@ void ui_menu_control_device_image::handle() case START_FILE: { bool can_create = false; if(image->is_creatable()) { - zippath_directory *directory = nullptr; - osd_file::error err = zippath_opendir(current_directory.c_str(), &directory); - can_create = err == osd_file::error::NONE && !zippath_is_zip(directory); + util::zippath_directory *directory = nullptr; + osd_file::error err = util::zippath_opendir(current_directory.c_str(), &directory); + can_create = err == osd_file::error::NONE && !util::zippath_is_zip(directory); if(directory) - zippath_closedir(directory); + util::zippath_closedir(directory); } submenu_result = -1; ui_menu::stack_push(global_alloc_clear<ui_menu_file_selector>(machine(), container, image, current_directory, current_file, true, image->image_interface()!=nullptr, can_create, &submenu_result)); @@ -335,7 +335,7 @@ void ui_menu_control_device_image::handle() case DO_CREATE: { std::string path; - zippath_combine(path, current_directory.c_str(), current_file.c_str()); + util::zippath_combine(path, current_directory.c_str(), current_file.c_str()); int err = image->create(path.c_str(), nullptr, nullptr); if (err != 0) machine().popmessage("Error: %s", image->error()); diff --git a/src/lib/util/cdrom.cpp b/src/lib/util/cdrom.cpp index bd48a73d8d8..da3d921ae4a 100644 --- a/src/lib/util/cdrom.cpp +++ b/src/lib/util/cdrom.cpp @@ -244,7 +244,7 @@ cdrom_file *cdrom_open(const char *inputfile) for (i = 0; i < file->cdtoc.numtrks; i++) { - osd_file::error filerr = util::core_file::open(file->track_info.track[i].fname.c_str(), OPEN_FLAG_READ, file->fhandle[i]); + osd_file::error filerr = util::core_file::open(file->track_info.track[i].fname, OPEN_FLAG_READ, file->fhandle[i]); if (filerr != osd_file::error::NONE) { fprintf(stderr, "Unable to open file: %s\n", file->track_info.track[i].fname.c_str()); diff --git a/src/lib/util/corefile.cpp b/src/lib/util/corefile.cpp index 5c16d886fe3..e3d34ec3738 100644 --- a/src/lib/util/corefile.cpp +++ b/src/lib/util/corefile.cpp @@ -1084,7 +1084,7 @@ osd_file::error core_osd_file::osd_or_zlib_write(void const *buffer, std::uint64 return an error code -------------------------------------------------*/ -osd_file::error core_file::open(char const *filename, std::uint32_t openflags, ptr &file) +osd_file::error core_file::open(std::string const &filename, std::uint32_t openflags, ptr &file) { try { @@ -1190,7 +1190,7 @@ core_file::~core_file() pointer -------------------------------------------------*/ -osd_file::error core_file::load(char const *filename, void **data, std::uint32_t &length) +osd_file::error core_file::load(std::string const &filename, void **data, std::uint32_t &length) { ptr file; @@ -1219,7 +1219,7 @@ osd_file::error core_file::load(char const *filename, void **data, std::uint32_t return osd_file::error::NONE; } -osd_file::error core_file::load(char const *filename, dynamic_buffer &data) +osd_file::error core_file::load(std::string const &filename, dynamic_buffer &data) { ptr file; diff --git a/src/lib/util/corefile.h b/src/lib/util/corefile.h index e66545440c2..8f71832411f 100644 --- a/src/lib/util/corefile.h +++ b/src/lib/util/corefile.h @@ -48,7 +48,7 @@ public: // ----- file open/close ----- // open a file with the specified filename - static osd_file::error open(const char *filename, std::uint32_t openflags, ptr &file); + static osd_file::error open(std::string const &filename, std::uint32_t openflags, ptr &file); // open a RAM-based "file" using the given data and length (read-only) static osd_file::error open_ram(const void *data, std::size_t length, std::uint32_t openflags, ptr &file); @@ -100,8 +100,8 @@ public: virtual const void *buffer() = 0; // open a file with the specified filename, read it into memory, and return a pointer - static osd_file::error load(const char *filename, void **data, std::uint32_t &length); - static osd_file::error load(const char *filename, dynamic_buffer &data); + static osd_file::error load(std::string const &filename, void **data, std::uint32_t &length); + static osd_file::error load(std::string const &filename, dynamic_buffer &data); // ----- file write ----- diff --git a/src/lib/util/un7z.cpp b/src/lib/util/un7z.cpp index b05e4623e57..8b73faed49b 100644 --- a/src/lib/util/un7z.cpp +++ b/src/lib/util/un7z.cpp @@ -10,7 +10,7 @@ // this is based on unzip.c, with modifications needed to use the 7zip library -#include "un7z.h" +#include "unzip.h" #include "corestr.h" #include "unicode.h" @@ -19,6 +19,7 @@ #include "lzma/C/7zCrc.h" #include "lzma/C/7zVersion.h" +#include <algorithm> #include <array> #include <cassert> #include <cstdio> @@ -28,6 +29,7 @@ #include <vector> +namespace util { namespace { /*************************************************************************** TYPE DEFINITIONS @@ -98,6 +100,7 @@ public: static ptr find_cached(const std::string &filename) { + std::lock_guard<std::mutex> guard(s_cache_mutex); for (std::size_t cachenum = 0; cachenum < s_cache.size(); cachenum++) { // if we have a valid entry and it matches our filename, use it and remove from the cache @@ -114,10 +117,11 @@ public: static void cache_clear() { // clear call cache entries + std::lock_guard<std::mutex> guard(s_cache_mutex); for (std::size_t cachenum = 0; cachenum < s_cache.size(); s_cache[cachenum++].reset()) { } } - _7z_file::error initialize(); + archive_file::error initialize(); int first_file() { return search(0, 0, std::string(), false, false); } int next_file() { return (m_curr_file_idx < 0) ? -1 : search(m_curr_file_idx + 1, 0, std::string(), false, false); } @@ -126,11 +130,12 @@ public: int search(const std::string &filename) { return search(0, 0, filename, false, true); } int search(std::uint32_t crc, const std::string &filename) { return search(0, crc, filename, true, true); } + bool current_is_directory() const { return m_curr_is_dir; } const std::string ¤t_name() const { return m_curr_name; } std::uint64_t current_uncompressed_length() const { return m_curr_length; } std::uint32_t current_crc() const { return m_curr_crc; } - _7z_file::error decompress(void *buffer, std::uint32_t length); + archive_file::error decompress(void *buffer, std::uint32_t length); private: m7z_file_impl(const m7z_file_impl &) = delete; @@ -143,10 +148,12 @@ private: static constexpr std::size_t CACHE_SIZE = 8; static std::array<ptr, CACHE_SIZE> s_cache; + static std::mutex s_cache_mutex; const std::string m_filename; // copy of _7Z filename (for caching) int m_curr_file_idx; // current file index + bool m_curr_is_dir; // current file is directory std::string m_curr_name; // current file name std::uint64_t m_curr_length; // current file uncompressed length std::uint32_t m_curr_crc; // current file crc @@ -170,7 +177,7 @@ private: }; -class m7z_file_wrapper : public _7z_file +class m7z_file_wrapper : public archive_file { public: m7z_file_wrapper(m7z_file_impl::ptr &&impl) : m_impl(std::move(impl)) { assert(m_impl); } @@ -183,6 +190,7 @@ public: virtual int search(const std::string &filename) override { return m_impl->search(filename); } virtual int search(std::uint32_t crc, const std::string &filename) override { return m_impl->search(crc, filename); } + virtual bool current_is_directory() const override { return m_impl->current_is_directory(); } virtual const std::string ¤t_name() const override { return m_impl->current_name(); } virtual std::uint64_t current_uncompressed_length() const override { return m_impl->current_uncompressed_length(); } virtual std::uint32_t current_crc() const override { return m_impl->current_crc(); } @@ -200,6 +208,7 @@ private: ***************************************************************************/ std::array<m7z_file_impl::ptr, m7z_file_impl::CACHE_SIZE> m7z_file_impl::s_cache; +std::mutex m7z_file_impl::s_cache_mutex; @@ -250,6 +259,7 @@ CFileInStream::CFileInStream() m7z_file_impl::m7z_file_impl(const std::string &filename) : m_filename(filename) , m_curr_file_idx(-1) + , m_curr_is_dir(false) , m_curr_name() , m_curr_length(0) , m_curr_crc(0) @@ -269,11 +279,11 @@ m7z_file_impl::m7z_file_impl(const std::string &filename) } -_7z_file::error m7z_file_impl::initialize() +archive_file::error m7z_file_impl::initialize() { osd_file::error const err = osd_file::open(m_filename, OPEN_FLAG_READ, m_archive_stream.osdfile, m_archive_stream.length); if (err != osd_file::error::NONE) - return _7z_file::error::FILE_ERROR; + return archive_file::error::FILE_ERROR; LookToRead_CreateVTable(&m_look_stream, False); m_look_stream.realStream = &m_archive_stream; @@ -286,9 +296,9 @@ _7z_file::error m7z_file_impl::initialize() SRes const res = SzArEx_Open(&m_db, &m_look_stream.s, &m_alloc_imp, &m_alloc_temp_imp); if (res != SZ_OK) - return _7z_file::error::FILE_ERROR; + return archive_file::error::FILE_ERROR; - return _7z_file::error::NONE; + return archive_file::error::NONE; } @@ -305,6 +315,7 @@ void m7z_file_impl::close(ptr &&archive) archive->m_archive_stream.osdfile.reset(); // find the first NULL entry in the cache + std::lock_guard<std::mutex> guard(s_cache_mutex); std::size_t cachenum; for (cachenum = 0; cachenum < s_cache.size(); cachenum++) if (!s_cache[cachenum]) @@ -331,7 +342,7 @@ void m7z_file_impl::close(ptr &&archive) from a _7Z into the target buffer -------------------------------------------------*/ -_7z_file::error m7z_file_impl::decompress(void *buffer, std::uint32_t length) +archive_file::error m7z_file_impl::decompress(void *buffer, std::uint32_t length) { // make sure the file is open.. if (!m_archive_stream.osdfile) @@ -339,7 +350,7 @@ _7z_file::error m7z_file_impl::decompress(void *buffer, std::uint32_t length) m_archive_stream.currfpos = 0; osd_file::error const err = osd_file::open(m_filename, OPEN_FLAG_READ, m_archive_stream.osdfile, m_archive_stream.length); if (err != osd_file::error::NONE) - return _7z_file::error::FILE_ERROR; + return archive_file::error::FILE_ERROR; } size_t offset = 0; @@ -353,11 +364,11 @@ _7z_file::error m7z_file_impl::decompress(void *buffer, std::uint32_t length) &m_alloc_imp, &m_alloc_temp_imp); if (res != SZ_OK) - return _7z_file::error::FILE_ERROR; + return archive_file::error::FILE_ERROR; std::memcpy(buffer, m_out_buffer + offset, length); - return _7z_file::error::NONE; + return archive_file::error::NONE; } @@ -367,25 +378,22 @@ int m7z_file_impl::search(int i, std::uint32_t search_crc, const std::string &se { const CSzFileItem &f(m_db.db.Files[i]); - // if it's a directory entry we don't care about it.. - if (!f.IsDir) + make_utf8_name(i); + const std::uint64_t size(f.Size); + const std::uint32_t crc(f.Crc); + const bool crcmatch(crc == search_crc); + const bool namematch(!core_stricmp(search_filename.c_str(), &m_utf8_buf[0])); + + const bool found = ((!matchcrc && !matchname) || !f.IsDir) && (!matchcrc || crcmatch) && (!matchname || namematch); + if (found) { - make_utf8_name(i); - const std::uint64_t size(f.Size); - const std::uint32_t crc(f.Crc); - const bool crcmatch(crc == search_crc); - const bool namematch(core_stricmp(search_filename.c_str(), &m_utf8_buf[0]) == 0); - - const bool found = (!matchcrc || crcmatch) && (!matchname || namematch); - if (found) - { - m_curr_file_idx = i; - m_curr_name = &m_utf8_buf[0]; - m_curr_length = size; - m_curr_crc = crc; + m_curr_file_idx = i; + m_curr_is_dir = bool(f.IsDir); + m_curr_name = &m_utf8_buf[0]; + m_curr_length = size; + m_curr_crc = crc; - return i; - } + return i; } } @@ -432,17 +440,13 @@ void m7z_file_impl::make_utf8_name(int index) assert(out_pos < m_utf8_buf.size()); } m_utf8_buf[out_pos++] = '\0'; + m_utf8_buf.resize(out_pos); } } // anonymous namespace -_7z_file::~_7z_file() -{ -} - - -_7z_file::error _7z_file::open(const std::string &filename, ptr &result) +archive_file::error archive_file::open_7z(const std::string &filename, ptr &result) { // ensure we start with a NULL result result.reset(); @@ -477,7 +481,10 @@ _7z_file::error _7z_file::open(const std::string &filename, ptr &result) cache and free all memory -------------------------------------------------*/ -void _7z_file::cache_clear() +void m7z_file_cache_clear() { + // This is a trampoline called from unzip.cpp to avoid the need to have the zip and 7zip code in one file m7z_file_impl::cache_clear(); } + +} // namespace util diff --git a/src/lib/util/un7z.h b/src/lib/util/un7z.h deleted file mode 100644 index d2d2e18e25f..00000000000 --- a/src/lib/util/un7z.h +++ /dev/null @@ -1,83 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles, Vas Crabb -/*************************************************************************** - - un7z.h - - 7z file management. - -***************************************************************************/ - -// this is based on unzip.h, with modifications needed to use the 7zip library - -#pragma once - -#ifndef MAME_LIB_UTIL_UN7Z_H -#define MAME_LIB_UTIL_UN7Z_H - -#include "osdcore.h" - -#include <cstdint> -#include <memory> -#include <string> - - -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -// describes an open _7Z file -class _7z_file -{ -public: - - // Error types - enum class error - { - NONE = 0, - OUT_OF_MEMORY, - FILE_ERROR, - BAD_SIGNATURE, - DECOMPRESS_ERROR, - FILE_TRUNCATED, - FILE_CORRUPT, - UNSUPPORTED, - BUFFER_TOO_SMALL - }; - - typedef std::unique_ptr<_7z_file> ptr; - - - virtual ~_7z_file(); - - /* ----- 7Z file access ----- */ - - // open a 7Z file and parse its central directory - static error open(const std::string &filename, ptr &result); - - // clear out all open 7Z files from the cache - static void cache_clear(); - - - /* ----- contained file access ----- */ - - // iterating over files - virtual int first_file() = 0; - virtual int next_file() = 0; - - // find a file index by crc, filename or both - virtual int search(std::uint32_t crc) = 0; - virtual int search(const std::string &filename) = 0; - virtual int search(std::uint32_t crc, const std::string &filename) = 0; - - // information on most recently found file - virtual const std::string ¤t_name() const = 0; - virtual std::uint64_t current_uncompressed_length() const = 0; - virtual std::uint32_t current_crc() const = 0; - - // decompress the most recently found file in the _7Z - virtual error decompress(void *buffer, std::uint32_t length) = 0; - -}; - -#endif // MAME_LIB_UTIL_UN7Z_H diff --git a/src/lib/util/unzip.cpp b/src/lib/util/unzip.cpp index 321f4e0b69f..06ab41aae3a 100644 --- a/src/lib/util/unzip.cpp +++ b/src/lib/util/unzip.cpp @@ -8,21 +8,25 @@ ***************************************************************************/ -#include "osdcore.h" #include "unzip.h" +#include "corestr.h" +#include "osdcore.h" + + #include <algorithm> #include <array> #include <cassert> #include <cstring> #include <cstdlib> +#include <mutex> #include <utility> #include <vector> #include <zlib.h> - +namespace util { namespace { /*************************************************************************** CONSTANTS @@ -71,29 +75,8 @@ namespace { #define ZIPCRC 0x0e #define ZIPSIZE 0x12 #define ZIPUNCMP 0x16 - -/** - * @def ZIPFNLN - * - * @brief A macro that defines zipfnln. - */ - #define ZIPFNLN 0x1a - -/** - * @def ZIPXTRALN - * - * @brief A macro that defines zipxtraln. - */ - #define ZIPXTRALN 0x1c - -/** - * @def ZIPNAME - * - * @brief A macro that defines zipname. - */ - #define ZIPNAME 0x1e @@ -115,6 +98,8 @@ public: , m_cd() , m_cd_pos(0) , m_header() + , m_curr_is_dir(false) + , m_curr_name() , m_buffer() { std::memset(&m_header, 0, sizeof(m_header)); @@ -123,6 +108,7 @@ public: static ptr find_cached(const std::string &filename) { + std::lock_guard<std::mutex> guard(s_cache_mutex); for (std::size_t cachenum = 0; cachenum < s_cache.size(); cachenum++) { // if we have a valid entry and it matches our filename, use it and remove from the cache @@ -139,37 +125,65 @@ public: static void cache_clear() { // clear call cache entries + std::lock_guard<std::mutex> guard(s_cache_mutex); for (std::size_t cachenum = 0; cachenum < s_cache.size(); s_cache[cachenum++].reset()) { } } - zip_file::error initialize() + archive_file::error initialize() { // read ecd data auto const ziperr = read_ecd(); - if (ziperr != zip_file::error::NONE) + if (ziperr != archive_file::error::NONE) return ziperr; // verify that we can work with this zipfile (no disk spanning allowed) if ((m_ecd.disk_number != m_ecd.cd_start_disk_number) || (m_ecd.cd_disk_entries != m_ecd.cd_total_entries)) - return zip_file::error::UNSUPPORTED; + return archive_file::error::UNSUPPORTED; // allocate memory for the central directory try { m_cd.resize(m_ecd.cd_size + 1); } - catch (...) { return zip_file::error::OUT_OF_MEMORY; } + catch (...) { return archive_file::error::OUT_OF_MEMORY; } // read the central directory std::uint32_t read_length; auto const filerr = m_file->read(&m_cd[0], m_ecd.cd_start_disk_offset, m_ecd.cd_size, read_length); if ((filerr != osd_file::error::NONE) || (read_length != m_ecd.cd_size)) - return (filerr == osd_file::error::NONE) ? zip_file::error::FILE_TRUNCATED : zip_file::error::FILE_ERROR; + return (filerr == osd_file::error::NONE) ? archive_file::error::FILE_TRUNCATED : archive_file::error::FILE_ERROR; - return zip_file::error::NONE; + return archive_file::error::NONE; } - // contained file access - const zip_file::file_header *first_file(); - const zip_file::file_header *next_file(); - zip_file::error decompress(void *buffer, std::uint32_t length); + int first_file() + { + m_cd_pos = 0; + return search(0, std::string(), false, false); + } + int next_file() + { + return search(0, std::string(), false, false); + } + int search(std::uint32_t crc) + { + m_cd_pos = 0; + return search(crc, std::string(), true, false); + } + int search(const std::string &filename) + { + m_cd_pos = 0; + return search(0, filename, false, true); + } + int search(std::uint32_t crc, const std::string &filename) + { + m_cd_pos = 0; + return search(crc, filename, true, true); + } + + bool current_is_directory() const { return m_curr_is_dir; } + const std::string ¤t_name() const { return m_curr_name; } + std::uint64_t current_uncompressed_length() const { return m_header.uncompressed_length; } + std::uint32_t current_crc() const { return m_header.crc; } + + archive_file::error decompress(void *buffer, std::uint32_t length); private: zip_file_impl(const zip_file_impl &) = delete; @@ -177,30 +191,47 @@ private: zip_file_impl &operator=(const zip_file_impl &) = delete; zip_file_impl &operator=(zip_file_impl &&) = delete; - zip_file::error reopen() + int search(std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname); + + archive_file::error reopen() { if (!m_file) { auto const filerr = osd_file::open(m_filename, OPEN_FLAG_READ, m_file, m_length); if (filerr != osd_file::error::NONE) - return zip_file::error::FILE_ERROR; + return archive_file::error::FILE_ERROR; } - return zip_file::error::NONE; + return archive_file::error::NONE; } // ZIP file parsing - zip_file::error read_ecd(); - zip_file::error get_compressed_data_offset(std::uint64_t &offset); + archive_file::error read_ecd(); + archive_file::error get_compressed_data_offset(std::uint64_t &offset); // decompression interfaces - zip_file::error decompress_data_type_0(std::uint64_t offset, void *buffer, std::uint32_t length); - zip_file::error decompress_data_type_8(std::uint64_t offset, void *buffer, std::uint32_t length); + archive_file::error decompress_data_type_0(std::uint64_t offset, void *buffer, std::uint32_t length); + archive_file::error decompress_data_type_8(std::uint64_t offset, void *buffer, std::uint32_t length); - struct file_header_int : zip_file::file_header + struct file_header { - std::uint8_t * raw; // pointer to the raw data - std::uint32_t rawlength; // length of the raw data - std::uint8_t saved; // saved byte from after filename + std::uint32_t signature; // central file header signature + std::uint16_t version_created; // version made by + std::uint16_t version_needed; // version needed to extract + std::uint16_t bit_flag; // general purpose bit flag + std::uint16_t compression; // compression method + std::uint16_t file_time; // last mod file time + std::uint16_t file_date; // last mod file date + std::uint32_t crc; // crc-32 + std::uint32_t compressed_length; // compressed size + std::uint32_t uncompressed_length; // uncompressed size + std::uint16_t filename_length; // filename length + std::uint16_t extra_field_length; // extra field length + std::uint16_t file_comment_length; // file comment length + std::uint16_t start_disk_number; // disk number start + std::uint16_t internal_attributes; // internal file attributes + std::uint32_t external_attributes; // external file attributes + std::uint32_t local_header_offset; // relative offset of local header + const char * filename; // filename }; // contains extracted end of central directory information @@ -220,9 +251,10 @@ private: std::uint32_t rawlength; // length of the raw data }; - static constexpr std::size_t DECOMPRESS_BUFSIZE = 16384; - static constexpr std::size_t CACHE_SIZE = 8; // number of open files to cache - static std::array<ptr, CACHE_SIZE> s_cache; + static constexpr std::size_t DECOMPRESS_BUFSIZE = 16384; + static constexpr std::size_t CACHE_SIZE = 8; // number of open files to cache + static std::array<ptr, CACHE_SIZE> s_cache; + static std::mutex s_cache_mutex; const std::string m_filename; // copy of ZIP filename (for caching) osd_file::ptr m_file; // OSD file handle @@ -232,20 +264,32 @@ private: std::vector<std::uint8_t> m_cd; // central directory raw data std::uint32_t m_cd_pos; // position in central directory - file_header_int m_header; // current file header + file_header m_header; // current file header + bool m_curr_is_dir; // current file is directory + std::string m_curr_name; // current file name std::array<std::uint8_t, DECOMPRESS_BUFSIZE> m_buffer; // buffer for decompression }; -class zip_file_wrapper : public zip_file +class zip_file_wrapper : public archive_file { public: zip_file_wrapper(zip_file_impl::ptr &&impl) : m_impl(std::move(impl)) { assert(m_impl); } virtual ~zip_file_wrapper() { zip_file_impl::close(std::move(m_impl)); } - virtual const file_header *first_file() override { return m_impl->first_file(); } - virtual const file_header *next_file() override { return m_impl->next_file(); } + virtual int first_file() override { return m_impl->first_file(); } + virtual int next_file() override { return m_impl->next_file(); } + + virtual int search(std::uint32_t crc) override { return m_impl->search(crc); } + virtual int search(const std::string &filename) override { return m_impl->search(filename); } + virtual int search(std::uint32_t crc, const std::string &filename) override { return m_impl->search(crc, filename); } + + virtual bool current_is_directory() const override { return m_impl->current_is_directory(); } + virtual const std::string ¤t_name() const override { return m_impl->current_name(); } + virtual std::uint64_t current_uncompressed_length() const override { return m_impl->current_uncompressed_length(); } + virtual std::uint32_t current_crc() const override { return m_impl->current_crc(); } + virtual error decompress(void *buffer, std::uint32_t length) override { return m_impl->decompress(buffer, length); } private: @@ -268,7 +312,7 @@ private: * @return The word. */ -inline UINT16 read_word(UINT8 *buf) +inline std::uint16_t read_word(std::uint8_t const *buf) { return (buf[1] << 8) | buf[0]; } @@ -283,7 +327,7 @@ inline UINT16 read_word(UINT8 *buf) * @return The double word. */ -inline UINT32 read_dword(UINT8 *buf) +inline std::uint32_t read_dword(std::uint8_t const *buf) { return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; } @@ -296,6 +340,7 @@ inline UINT32 read_dword(UINT8 *buf) /** @brief The zip cache[ zip cache size]. */ std::array<zip_file_impl::ptr, zip_file_impl::CACHE_SIZE> zip_file_impl::s_cache; +std::mutex zip_file_impl::s_cache_mutex; @@ -320,6 +365,7 @@ void zip_file_impl::close(ptr &&zip) zip->m_file.reset(); // find the first NULL entry in the cache + std::lock_guard<std::mutex> guard(s_cache_mutex); std::size_t cachenum; for (cachenum = 0; cachenum < s_cache.size(); cachenum++) if (!s_cache[cachenum]) @@ -345,88 +391,63 @@ void zip_file_impl::close(ptr &&zip) in the ZIP -------------------------------------------------*/ -/** - * @fn const zip_file_header *zip_file_first_file(zip_file *zip) - * - * @brief Zip file first file. - * - * @param [in,out] zip If non-null, the zip. - * - * @return null if it fails, else a zip_file_header*. - */ - -const zip_file::file_header *zip_file_impl::first_file() -{ - /* reset the position and go from there */ - m_cd_pos = 0; - return next_file(); -} - - /*------------------------------------------------- zip_file_next_entry - return the next entry in the ZIP -------------------------------------------------*/ -/** - * @fn const zip_file_header *zip_file_next_file(zip_file *zip) - * - * @brief Zip file next file. - * - * @param [in,out] zip If non-null, the zip. - * - * @return null if it fails, else a zip_file_header*. - */ - -const zip_file::file_header *zip_file_impl::next_file() +int zip_file_impl::search(std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname) { - // fix up any modified data - if (m_header.raw) + // if we're at or past the end, we're done + std::string filename; + while (m_cd_pos <= m_ecd.cd_size) { - m_header.raw[ZIPCFN + m_header.filename_length] = m_header.saved; - m_header.raw = nullptr; - } + // extract file header info + std::uint8_t const *const raw = &m_cd[0] + m_cd_pos; + m_header.signature = read_dword(raw + ZIPCENSIG); + m_header.version_created = read_word (raw + ZIPCVER); + m_header.version_needed = read_word (raw + ZIPCVXT); + m_header.bit_flag = read_word (raw + ZIPCFLG); + m_header.compression = read_word (raw + ZIPCMTHD); + m_header.file_time = read_word (raw + ZIPCTIM); + m_header.file_date = read_word (raw + ZIPCDAT); + m_header.crc = read_dword(raw + ZIPCCRC); + m_header.compressed_length = read_dword(raw + ZIPCSIZ); + m_header.uncompressed_length = read_dword(raw + ZIPCUNC); + m_header.filename_length = read_word (raw + ZIPCFNL); + m_header.extra_field_length = read_word (raw + ZIPCXTL); + m_header.file_comment_length = read_word (raw + ZIPCCML); + m_header.start_disk_number = read_word (raw + ZIPDSK); + m_header.internal_attributes = read_word (raw + ZIPINT); + m_header.external_attributes = read_dword(raw + ZIPEXT); + m_header.local_header_offset = read_dword(raw + ZIPOFST); + m_header.filename = reinterpret_cast<const char *>(raw + ZIPCFN); + + // make sure we have enough data + std::uint32_t const rawlength = ZIPCFN + m_header.filename_length + m_header.extra_field_length + m_header.file_comment_length; + if ((m_cd_pos + rawlength) > m_ecd.cd_size) + break; - // if we're at or past the end, we're done - if (m_cd_pos >= m_ecd.cd_size) - return nullptr; - - // extract file header info - m_header.raw = &m_cd[0] + m_cd_pos; - m_header.rawlength = ZIPCFN; - m_header.signature = read_dword(m_header.raw + ZIPCENSIG); - m_header.version_created = read_word (m_header.raw + ZIPCVER); - m_header.version_needed = read_word (m_header.raw + ZIPCVXT); - m_header.bit_flag = read_word (m_header.raw + ZIPCFLG); - m_header.compression = read_word (m_header.raw + ZIPCMTHD); - m_header.file_time = read_word (m_header.raw + ZIPCTIM); - m_header.file_date = read_word (m_header.raw + ZIPCDAT); - m_header.crc = read_dword(m_header.raw + ZIPCCRC); - m_header.compressed_length = read_dword(m_header.raw + ZIPCSIZ); - m_header.uncompressed_length = read_dword(m_header.raw + ZIPCUNC); - m_header.filename_length = read_word (m_header.raw + ZIPCFNL); - m_header.extra_field_length = read_word (m_header.raw + ZIPCXTL); - m_header.file_comment_length = read_word (m_header.raw + ZIPCCML); - m_header.start_disk_number = read_word (m_header.raw + ZIPDSK); - m_header.internal_attributes = read_word (m_header.raw + ZIPINT); - m_header.external_attributes = read_dword(m_header.raw + ZIPEXT); - m_header.local_header_offset = read_dword(m_header.raw + ZIPOFST); - m_header.filename = reinterpret_cast<const char *>(m_header.raw + ZIPCFN); - - // make sure we have enough data - m_header.rawlength += m_header.filename_length; - m_header.rawlength += m_header.extra_field_length; - m_header.rawlength += m_header.file_comment_length; - if (m_cd_pos + m_header.rawlength > m_ecd.cd_size) - return nullptr; - - // NULL terminate the filename - m_header.saved = m_header.raw[ZIPCFN + m_header.filename_length]; - m_header.raw[ZIPCFN + m_header.filename_length] = 0; - - // advance the position - m_cd_pos += m_header.rawlength; - return &m_header; + // advance the position + m_cd_pos += rawlength; + + // copy the filename filename + bool const is_dir((m_header.filename_length > 0) && (m_header.filename[m_header.filename_length - 1] == '/')); + filename.assign(m_header.filename, m_header.filename_length - (is_dir ? 1 : 0)); + + // check to see if it matches query + bool const crcmatch(search_crc == m_header.crc); + const bool namematch(!core_stricmp(search_filename.c_str(), filename.c_str())); + + bool const found = ((!matchcrc && !matchname) || !is_dir) && (!matchcrc || crcmatch) && (!matchname || namematch); + if (found) + { + m_curr_is_dir = is_dir; + m_curr_name = std::move(filename); + return 0; + } + } + return -1; } @@ -447,22 +468,22 @@ const zip_file::file_header *zip_file_impl::next_file() * @return A zip_error. */ -zip_file::error zip_file_impl::decompress(void *buffer, UINT32 length) +archive_file::error zip_file_impl::decompress(void *buffer, std::uint32_t length) { - zip_file::error ziperr; + archive_file::error ziperr; std::uint64_t offset; // if we don't have enough buffer, error if (length < m_header.uncompressed_length) - return zip_file::error::BUFFER_TOO_SMALL; + return archive_file::error::BUFFER_TOO_SMALL; // make sure the info in the header aligns with what we know if (m_header.start_disk_number != m_ecd.disk_number) - return zip_file::error::UNSUPPORTED; + return archive_file::error::UNSUPPORTED; // get the compressed data offset ziperr = get_compressed_data_offset(offset); - if (ziperr != zip_file::error::NONE) + if (ziperr != archive_file::error::NONE) return ziperr; // handle compression types @@ -477,7 +498,7 @@ zip_file::error zip_file_impl::decompress(void *buffer, UINT32 length) break; default: - ziperr = zip_file::error::UNSUPPORTED; + ziperr = archive_file::error::UNSUPPORTED; break; } return ziperr; @@ -503,11 +524,11 @@ zip_file::error zip_file_impl::decompress(void *buffer, UINT32 length) * @return The ecd. */ -zip_file::error zip_file_impl::read_ecd() +archive_file::error zip_file_impl::read_ecd() { // make sure the file handle is open auto const ziperr = reopen(); - if (ziperr != zip_file::error::NONE) + if (ziperr != archive_file::error::NONE) return ziperr; // we may need multiple tries @@ -521,13 +542,13 @@ zip_file::error zip_file_impl::read_ecd() // allocate buffer std::unique_ptr<std::uint8_t []> buffer; try { buffer.reset(new std::uint8_t[buflen + 1]); } - catch (...) { return zip_file::error::OUT_OF_MEMORY; } + catch (...) { return archive_file::error::OUT_OF_MEMORY; } // read in one buffers' worth of data std::uint32_t read_length; auto const error = m_file->read(&buffer[0], m_length - buflen, buflen, read_length); if (error != osd_file::error::NONE || read_length != buflen) - return zip_file::error::FILE_ERROR; + return archive_file::error::FILE_ERROR; // find the ECD signature std::int32_t offset; @@ -556,16 +577,16 @@ zip_file::error zip_file_impl::read_ecd() m_ecd.cd_start_disk_offset = read_dword(&m_ecd.raw[ZIPEOFST]); m_ecd.comment_length = read_word (&m_ecd.raw[ZIPECOML]); m_ecd.comment = reinterpret_cast<const char *>(&m_ecd.raw[ZIPECOM]); - return zip_file::error::NONE; + return archive_file::error::NONE; } // didn't find it; free this buffer and expand our search if (buflen < m_length) buflen *= 2; else - return zip_file::error::BAD_SIGNATURE; + return archive_file::error::BAD_SIGNATURE; } - return zip_file::error::OUT_OF_MEMORY; + return archive_file::error::OUT_OF_MEMORY; } @@ -585,25 +606,25 @@ zip_file::error zip_file_impl::read_ecd() * @return The compressed data offset. */ -zip_file::error zip_file_impl::get_compressed_data_offset(std::uint64_t &offset) +archive_file::error zip_file_impl::get_compressed_data_offset(std::uint64_t &offset) { // make sure the file handle is open auto const ziperr = reopen(); - if (ziperr != zip_file::error::NONE) + if (ziperr != archive_file::error::NONE) return ziperr; // now go read the fixed-sized part of the local file header std::uint32_t read_length; auto const error = m_file->read(&m_buffer[0], m_header.local_header_offset, ZIPNAME, read_length); if (error != osd_file::error::NONE || read_length != ZIPNAME) - return (error == osd_file::error::NONE) ? zip_file::error::FILE_TRUNCATED : zip_file::error::FILE_ERROR; + return (error == osd_file::error::NONE) ? archive_file::error::FILE_TRUNCATED : archive_file::error::FILE_ERROR; /* compute the final offset */ offset = m_header.local_header_offset + ZIPNAME; offset += read_word(&m_buffer[ZIPFNLN]); offset += read_word(&m_buffer[ZIPXTRALN]); - return zip_file::error::NONE; + return archive_file::error::NONE; } @@ -630,18 +651,18 @@ zip_file::error zip_file_impl::get_compressed_data_offset(std::uint64_t &offset) * @return A zip_error. */ -zip_file::error zip_file_impl::decompress_data_type_0(std::uint64_t offset, void *buffer, std::uint32_t length) +archive_file::error zip_file_impl::decompress_data_type_0(std::uint64_t offset, void *buffer, std::uint32_t length) { std::uint32_t read_length; // the data is uncompressed; just read it auto const filerr = m_file->read(buffer, offset, m_header.compressed_length, read_length); if (filerr != osd_file::error::NONE) - return zip_file::error::FILE_ERROR; + return archive_file::error::FILE_ERROR; else if (read_length != m_header.compressed_length) - return zip_file::error::FILE_TRUNCATED; + return archive_file::error::FILE_TRUNCATED; else - return zip_file::error::NONE; + return archive_file::error::NONE; } @@ -663,14 +684,14 @@ zip_file::error zip_file_impl::decompress_data_type_0(std::uint64_t offset, void * @return A zip_error. */ -zip_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset, void *buffer, std::uint32_t length) +archive_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset, void *buffer, std::uint32_t length) { std::uint32_t input_remaining = m_header.compressed_length; int zerr; // make sure we don't need a newer mechanism if (m_header.version_needed > 0x14) - return zip_file::error::UNSUPPORTED; + return archive_file::error::UNSUPPORTED; /* reset the stream */ z_stream stream; @@ -681,7 +702,7 @@ zip_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset, void // initialize the decompressor zerr = inflateInit2(&stream, -MAX_WBITS); if (zerr != Z_OK) - return zip_file::error::DECOMPRESS_ERROR; + return archive_file::error::DECOMPRESS_ERROR; // loop until we're done while (1) @@ -692,7 +713,7 @@ zip_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset, void if (filerr != osd_file::error::NONE) { inflateEnd(&stream); - return zip_file::error::FILE_ERROR; + return archive_file::error::FILE_ERROR; } offset += read_length; @@ -700,7 +721,7 @@ zip_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset, void if (read_length == 0 && input_remaining > 0) { inflateEnd(&stream); - return zip_file::error::FILE_TRUNCATED; + return archive_file::error::FILE_TRUNCATED; } // fill out the input data @@ -719,20 +740,20 @@ zip_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset, void if (zerr != Z_OK) { inflateEnd(&stream); - return zip_file::error::DECOMPRESS_ERROR; + return archive_file::error::DECOMPRESS_ERROR; } } // finish decompression zerr = inflateEnd(&stream); if (zerr != Z_OK) - return zip_file::error::DECOMPRESS_ERROR; + return archive_file::error::DECOMPRESS_ERROR; /* if anything looks funny, report an error */ if (stream.avail_out > 0 || input_remaining > 0) - return zip_file::error::DECOMPRESS_ERROR; + return archive_file::error::DECOMPRESS_ERROR; - return zip_file::error::NONE; + return archive_file::error::NONE; } } // anonymous namespace @@ -740,6 +761,14 @@ zip_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset, void /*************************************************************************** + un7z.cpp TRAMPOLINES +***************************************************************************/ + +void m7z_file_cache_clear(); + + + +/*************************************************************************** ZIP FILE ACCESS ***************************************************************************/ @@ -758,10 +787,10 @@ zip_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset, void * @return A zip_error. */ -zip_file::error zip_file::open(const std::string &filename, ptr &zip) +archive_file::error archive_file::open_zip(const std::string &filename, ptr &result) { // ensure we start with a NULL result - zip.reset(); + result.reset(); // see if we are in the cache, and reopen if so zip_file_impl::ptr newimpl(zip_file_impl::find_cached(filename)); @@ -777,7 +806,7 @@ zip_file::error zip_file::open(const std::string &filename, ptr &zip) try { - zip = std::make_unique<zip_file_wrapper>(std::move(newimpl)); + result = std::make_unique<zip_file_wrapper>(std::move(newimpl)); return error::NONE; } catch (...) @@ -793,18 +822,15 @@ zip_file::error zip_file::open(const std::string &filename, ptr &zip) cache and free all memory -------------------------------------------------*/ -/** - * @fn void zip_file_cache_clear(void) - * - * @brief Zip file cache clear. - */ - -void zip_file::cache_clear() +void archive_file::cache_clear() { zip_file_impl::cache_clear(); + m7z_file_cache_clear(); } -zip_file::~zip_file() +archive_file::~archive_file() { } + +} // namespace util diff --git a/src/lib/util/unzip.h b/src/lib/util/unzip.h index 2882cda0fc3..5fafaec57a4 100644 --- a/src/lib/util/unzip.h +++ b/src/lib/util/unzip.h @@ -4,7 +4,7 @@ unzip.h - ZIP file management. + archive file management. ***************************************************************************/ @@ -20,12 +20,14 @@ #include <string> +namespace util { + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ -// describes an open ZIP file -class zip_file +// describes an open archive file +class archive_file { public: @@ -43,55 +45,45 @@ public: BUFFER_TOO_SMALL }; - // contains extracted file header information - struct file_header - { - std::uint32_t signature; // central file header signature - std::uint16_t version_created; // version made by - std::uint16_t version_needed; // version needed to extract - std::uint16_t bit_flag; // general purpose bit flag - std::uint16_t compression; // compression method - std::uint16_t file_time; // last mod file time - std::uint16_t file_date; // last mod file date - std::uint32_t crc; // crc-32 - std::uint32_t compressed_length; // compressed size - std::uint32_t uncompressed_length; // uncompressed size - std::uint16_t filename_length; // filename length - std::uint16_t extra_field_length; // extra field length - std::uint16_t file_comment_length; // file comment length - std::uint16_t start_disk_number; // disk number start - std::uint16_t internal_attributes; // internal file attributes - std::uint32_t external_attributes; // external file attributes - std::uint32_t local_header_offset; // relative offset of local header - const char * filename; // filename - }; - - typedef std::unique_ptr<zip_file> ptr; + typedef std::unique_ptr<archive_file> ptr; - /* ----- ZIP file access ----- */ + /* ----- archive file access ----- */ // open a ZIP file and parse its central directory - static error open(const std::string &filename, ptr &zip); + static error open_zip(const std::string &filename, ptr &zip); + + // open a 7Z file and parse its central directory + static error open_7z(const std::string &filename, ptr &result); - // close a ZIP file (may actually be left open due to caching) - virtual ~zip_file(); + // close an archive file (may actually be left open due to caching) + virtual ~archive_file(); - // clear out all open ZIP files from the cache + // clear out all open files from the cache static void cache_clear(); /* ----- contained file access ----- */ - // find the first file in the ZIP - virtual const file_header *first_file() = 0; + // iterating over files - returns negative on reaching end + virtual int first_file() = 0; + virtual int next_file() = 0; + + // find a file index by crc, filename or both - returns non-negative on match + virtual int search(std::uint32_t crc) = 0; + virtual int search(const std::string &filename) = 0; + virtual int search(std::uint32_t crc, const std::string &filename) = 0; - // find the next file in the ZIP - virtual const file_header *next_file() = 0; + // information on most recently found file + virtual bool current_is_directory() const = 0; + virtual const std::string ¤t_name() const = 0; + virtual std::uint64_t current_uncompressed_length() const = 0; + virtual std::uint32_t current_crc() const = 0; // decompress the most recently found file in the ZIP virtual error decompress(void *buffer, std::uint32_t length) = 0; }; +} // namespace util #endif // MAME_LIB_UTIL_UNZIP_H diff --git a/src/lib/util/vecstream.h b/src/lib/util/vecstream.h index bf144501253..fda218c3e68 100644 --- a/src/lib/util/vecstream.h +++ b/src/lib/util/vecstream.h @@ -320,11 +320,10 @@ public: basic_ivectorstream(vector_type const &content, std::ios_base::openmode mode = std::ios_base::in) : std::basic_istream<CharT, Traits>(&m_rdbuf), m_rdbuf(content, mode) { } basic_ivectorstream(vector_type &&content, std::ios_base::openmode mode = std::ios_base::in) : std::basic_istream<CharT, Traits>(&m_rdbuf), m_rdbuf(std::move(content), mode) { } - basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return reinterpret_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_istream<CharT, Traits>::rdbuf()); } + basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return static_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_istream<CharT, Traits>::rdbuf()); } vector_type const &vec() const { return rdbuf()->vec(); } void vec(const vector_type &content) { rdbuf()->vec(content); } void vec(vector_type &&content) { rdbuf()->vec(std::move(content)); } - basic_ivectorstream &clear() { rdbuf()->clear(); return *this; } void swap(basic_ivectorstream &that) { std::basic_istream<CharT, Traits>::swap(that); rdbuf()->swap(*that.rdbuf()); } @@ -342,12 +341,11 @@ public: basic_ovectorstream(vector_type const &content, std::ios_base::openmode mode = std::ios_base::out) : std::basic_ostream<CharT, Traits>(&m_rdbuf), m_rdbuf(content, mode) { } basic_ovectorstream(vector_type &&content, std::ios_base::openmode mode = std::ios_base::out) : std::basic_ostream<CharT, Traits>(&m_rdbuf), m_rdbuf(std::move(content), mode) { } - basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return reinterpret_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_ostream<CharT, Traits>::rdbuf()); } + basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return static_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_ostream<CharT, Traits>::rdbuf()); } vector_type const &vec() const { return rdbuf()->vec(); } void vec(const vector_type &content) { rdbuf()->vec(content); } void vec(vector_type &&content) { rdbuf()->vec(std::move(content)); } - basic_ovectorstream &clear() { rdbuf()->clear(); return *this; } basic_ovectorstream &reserve(typename vector_type::size_type size) { rdbuf()->reserve(size); return *this; } void swap(basic_ovectorstream &that) { std::basic_ostream<CharT, Traits>::swap(that); rdbuf()->swap(*that.rdbuf()); } @@ -366,12 +364,11 @@ public: basic_vectorstream(vector_type const &content, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_iostream<CharT, Traits>(&m_rdbuf), m_rdbuf(content, mode) { } basic_vectorstream(vector_type &&content, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_iostream<CharT, Traits>(&m_rdbuf), m_rdbuf(std::move(content), mode) { } - basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return reinterpret_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_iostream<CharT, Traits>::rdbuf()); } + basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return static_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_iostream<CharT, Traits>::rdbuf()); } vector_type const &vec() const { return rdbuf()->vec(); } void vec(const vector_type &content) { rdbuf()->vec(content); } void vec(vector_type &&content) { rdbuf()->vec(std::move(content)); } - basic_vectorstream &clear() { rdbuf()->clear(); return *this; } basic_vectorstream &reserve(typename vector_type::size_type size) { rdbuf()->reserve(size); return *this; } void swap(basic_vectorstream &that) { std::basic_iostream<CharT, Traits>::swap(that); rdbuf()->swap(*that.rdbuf()); } diff --git a/src/lib/util/zippath.cpp b/src/lib/util/zippath.cpp index 18e2031dcdd..a8fddb64b85 100644 --- a/src/lib/util/zippath.cpp +++ b/src/lib/util/zippath.cpp @@ -18,6 +18,8 @@ #include "osdcore.h" +namespace util { + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ @@ -66,7 +68,7 @@ public: /** @brief true to called zip first. */ bool called_zip_first; /** @brief The zipfile. */ - zip_file::ptr zipfile; + archive_file::ptr zipfile; /** @brief The zipprefix. */ std::string zipprefix; /** @brief The returned dirlist. */ @@ -78,7 +80,7 @@ public: FUNCTION PROTOTYPES ***************************************************************************/ -static const zip_file::file_header *zippath_find_sub_path(zip_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); @@ -255,7 +257,7 @@ std::string &zippath_combine(std::string &dst, const char *path1, const char *pa -------------------------------------------------*/ /** - * @fn static osd_file::error file_error_from_zip_error(zip_file::error ziperr) + * @fn static osd_file::error file_error_from_zip_error(archive_file::error ziperr) * * @brief File error from zip error. * @@ -264,26 +266,26 @@ std::string &zippath_combine(std::string &dst, const char *path1, const char *pa * @return A osd_file::error. */ -static osd_file::error file_error_from_zip_error(zip_file::error ziperr) +static osd_file::error file_error_from_zip_error(archive_file::error ziperr) { osd_file::error filerr; switch(ziperr) { - case zip_file::error::NONE: + case archive_file::error::NONE: filerr = osd_file::error::NONE; break; - case zip_file::error::OUT_OF_MEMORY: + case archive_file::error::OUT_OF_MEMORY: filerr = osd_file::error::OUT_OF_MEMORY; break; - case zip_file::error::BAD_SIGNATURE: - case zip_file::error::DECOMPRESS_ERROR: - case zip_file::error::FILE_TRUNCATED: - case zip_file::error::FILE_CORRUPT: - case zip_file::error::UNSUPPORTED: - case zip_file::error::FILE_ERROR: + case archive_file::error::BAD_SIGNATURE: + case archive_file::error::DECOMPRESS_ERROR: + case archive_file::error::FILE_TRUNCATED: + case archive_file::error::FILE_CORRUPT: + case archive_file::error::UNSUPPORTED: + case archive_file::error::FILE_ERROR: filerr = osd_file::error::INVALID_DATA; break; - case zip_file::error::BUFFER_TOO_SMALL: + case archive_file::error::BUFFER_TOO_SMALL: default: filerr = osd_file::error::FAILURE; break; @@ -298,7 +300,7 @@ static osd_file::error file_error_from_zip_error(zip_file::error ziperr) -------------------------------------------------*/ /** - * @fn static osd_file::error create_core_file_from_zip(zip_file *zip, const zip_file_header *header, util::core_file::ptr &file) + * @fn static osd_file::error create_core_file_from_zip(archive_file *zip, util::core_file::ptr &file) * * @brief Creates core file from zip. * @@ -309,27 +311,27 @@ static osd_file::error file_error_from_zip_error(zip_file::error ziperr) * @return The new core file from zip. */ -static osd_file::error create_core_file_from_zip(zip_file &zip, const zip_file::file_header *header, util::core_file::ptr &file) +static osd_file::error create_core_file_from_zip(archive_file &zip, util::core_file::ptr &file) { osd_file::error filerr; - zip_file::error ziperr; + archive_file::error ziperr; void *ptr; - ptr = malloc(header->uncompressed_length); + ptr = malloc(zip.current_uncompressed_length()); if (ptr == nullptr) { filerr = osd_file::error::OUT_OF_MEMORY; goto done; } - ziperr = zip.decompress(ptr, header->uncompressed_length); - if (ziperr != zip_file::error::NONE) + ziperr = zip.decompress(ptr, zip.current_uncompressed_length()); + if (ziperr != archive_file::error::NONE) { filerr = file_error_from_zip_error(ziperr); goto done; } - filerr = util::core_file::open_ram_copy(ptr, header->uncompressed_length, OPEN_FLAG_READ, file); + filerr = util::core_file::open_ram_copy(ptr, zip.current_uncompressed_length(), OPEN_FLAG_READ, file); if (filerr != osd_file::error::NONE) goto done; @@ -360,9 +362,9 @@ done: osd_file::error zippath_fopen(const char *filename, UINT32 openflags, util::core_file::ptr &file, std::string &revised_path) { osd_file::error filerr = osd_file::error::NOT_FOUND; - zip_file::error ziperr; - zip_file::ptr zip; - const zip_file::file_header *header; + archive_file::error ziperr; + archive_file::ptr zip; + int header; osd_dir_entry_type entry_type; int len; @@ -379,8 +381,8 @@ osd_file::error zippath_fopen(const char *filename, UINT32 openflags, util::core if (is_zip_file(mainpath.c_str())) { /* this file might be a zip file - lets take a look */ - ziperr = zip_file::open(mainpath, zip); - if (ziperr == zip_file::error::NONE) + ziperr = archive_file::open_zip(mainpath, zip); + if (ziperr == archive_file::error::NONE) { /* it is a zip file - error if we're not opening for reading */ if (openflags != OPEN_FLAG_READ) @@ -394,20 +396,20 @@ osd_file::error zippath_fopen(const char *filename, UINT32 openflags, util::core else header = zip->first_file(); - if (header == nullptr) + if (header < 0) { filerr = osd_file::error::NOT_FOUND; goto done; } /* attempt to read the file */ - filerr = create_core_file_from_zip(*zip, header, file); + filerr = create_core_file_from_zip(*zip, file); if (filerr != osd_file::error::NONE) goto done; /* update subpath, if appropriate */ if (subpath.length() == 0) - subpath.assign(header->filename); + subpath.assign(zip->current_name()); /* we're done */ goto done; @@ -656,7 +658,7 @@ static char next_path_char(const char *s, int *pos) -------------------------------------------------*/ /** - * @fn static const zip_file_header *zippath_find_sub_path(zip_file *zipfile, const char *subpath, osd_dir_entry_type *type) + * @fn static const zip_file_header *zippath_find_sub_path(archive_file *zipfile, const char *subpath, osd_dir_entry_type *type) * * @brief Zippath find sub path. * @@ -667,13 +669,9 @@ static char next_path_char(const char *s, int *pos) * @return null if it fails, else a zip_file_header*. */ -static const zip_file::file_header *zippath_find_sub_path(zip_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) { - int i, j; - char c1, c2, last_char; - const zip_file::file_header *header; - - for (header = zipfile.first_file(); header != nullptr; header = zipfile.next_file()) + for (int header = zipfile.first_file(); header >= 0; header = zipfile.next_file()) { /* special case */ if (subpath == nullptr) @@ -683,13 +681,12 @@ static const zip_file::file_header *zippath_find_sub_path(zip_file &zipfile, con return header; } - i = 0; - j = 0; + // 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(header->filename, &i)) == (c2 = next_path_char(subpath, &j))) && - ( c1 != '\0' && c2 != '\0' )) - last_char = c2; - + while(((c1 = next_path_char(zipfile.current_name().c_str(), &i)) == (c2 = next_path_char(subpath, &j))) && (c1 != '\0' && c2 != '\0')) + last_char = c2; if (c2 == '\0') { @@ -710,7 +707,7 @@ static const zip_file::file_header *zippath_find_sub_path(zip_file &zipfile, con if (type != nullptr) *type = ENTTYPE_NONE; - return nullptr; + return -1; } @@ -721,7 +718,7 @@ static const zip_file::file_header *zippath_find_sub_path(zip_file &zipfile, con -------------------------------------------------*/ /** - * @fn static osd_file::error zippath_resolve(const char *path, osd_dir_entry_type &entry_type, zip_file *&zipfile, std::string &newpath) + * @fn static osd_file::error zippath_resolve(const char *path, osd_dir_entry_type &entry_type, archive_file *&zipfile, std::string &newpath) * * @brief Zippath resolve. * @@ -733,7 +730,7 @@ static const zip_file::file_header *zippath_find_sub_path(zip_file &zipfile, con * @return A osd_file::error. */ -static osd_file::error zippath_resolve(const char *path, osd_dir_entry_type &entry_type, zip_file::ptr &zipfile, std::string &newpath) +static osd_file::error zippath_resolve(const char *path, osd_dir_entry_type &entry_type, archive_file::ptr &zipfile, std::string &newpath) { osd_file::error err; osd_directory_entry *current_entry = nullptr; @@ -789,7 +786,7 @@ static osd_file::error zippath_resolve(const char *path, osd_dir_entry_type &ent /* is this file a ZIP file? */ if ((current_entry_type == ENTTYPE_FILE) && is_zip_file(apath_trimmed.c_str()) - && (zip_file::open(apath_trimmed, zipfile) == zip_file::error::NONE)) + && (archive_file::open_zip(apath_trimmed, zipfile) == archive_file::error::NONE)) { i = strlen(path + apath.length()); while (i > 0 && is_zip_path_separator(path[apath.length() + i - 1])) @@ -943,15 +940,15 @@ void zippath_closedir(zippath_directory *directory) * @return null if it fails, else the relative path. */ -static const char *get_relative_path(zippath_directory *directory, const zip_file::file_header *header) +static const char *get_relative_path(zippath_directory *directory) { const char *result = nullptr; int len = directory->zipprefix.length(); - if ((len <= strlen(header->filename)) - && !strncmp(directory->zipprefix.c_str(), header->filename, len)) + if ((len <= directory->zipfile->current_name().length()) + && !strncmp(directory->zipprefix.c_str(), directory->zipfile->current_name().c_str(), len)) { - result = &header->filename[len]; + result = &directory->zipfile->current_name().c_str()[len]; while(is_zip_file_separator(*result)) result++; } @@ -977,7 +974,7 @@ static const char *get_relative_path(zippath_directory *directory, const zip_fil const osd_directory_entry *zippath_readdir(zippath_directory *directory) { const osd_directory_entry *result = nullptr; - const zip_file::file_header *header; + int header; const char *relpath; const char *separator; const char *s; @@ -1024,7 +1021,7 @@ const osd_directory_entry *zippath_readdir(zippath_directory *directory) directory->called_zip_first = true; relpath = nullptr; } - while((header != nullptr) && ((relpath = get_relative_path(directory, header)) == nullptr)); + while((header >= 0) && ((relpath = get_relative_path(directory)) == nullptr)); if (relpath != nullptr) { @@ -1063,7 +1060,7 @@ const osd_directory_entry *zippath_readdir(zippath_directory *directory) memset(&directory->returned_entry, 0, sizeof(directory->returned_entry)); directory->returned_entry.name = relpath; directory->returned_entry.type = ENTTYPE_FILE; - directory->returned_entry.size = header->uncompressed_length; + directory->returned_entry.size = directory->zipfile->current_uncompressed_length(); result = &directory->returned_entry; } } @@ -1094,3 +1091,5 @@ int zippath_is_zip(zippath_directory *directory) { return directory->zipfile != nullptr; } + +} // namespace util diff --git a/src/lib/util/zippath.h b/src/lib/util/zippath.h index d54dd68c38d..653617d66cc 100644 --- a/src/lib/util/zippath.h +++ b/src/lib/util/zippath.h @@ -10,14 +10,16 @@ #pragma once -#ifndef __ZIPPATH_H__ -#define __ZIPPATH_H__ +#ifndef MAME_LIB_UTIL_ZIPPATH_H +#define MAME_LIB_UTIL_ZIPPATH_H #include "corefile.h" #include <string> #include "unzip.h" +namespace util { + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ @@ -62,6 +64,7 @@ const osd_directory_entry *zippath_readdir(zippath_directory *directory); /* returns TRUE if this path is a ZIP path or FALSE if not */ int zippath_is_zip(zippath_directory *directory); +} // namespace util -#endif /* __ZIPPATH_H__ */ +#endif /* MAME_LIB_UTIL_ZIPPATH_H */ diff --git a/src/tools/chdman.cpp b/src/tools/chdman.cpp index edf7ee0b14a..95dd285a94d 100644 --- a/src/tools/chdman.cpp +++ b/src/tools/chdman.cpp @@ -333,7 +333,7 @@ public: { m_file.reset(); m_lastfile = m_info.track[tracknum].fname; - osd_file::error filerr = util::core_file::open(m_lastfile.c_str(), OPEN_FLAG_READ, m_file); + osd_file::error filerr = util::core_file::open(m_lastfile, OPEN_FLAG_READ, m_file); if (filerr != osd_file::error::NONE) report_error(1, "Error opening input file (%s)'", m_lastfile.c_str()); } @@ -1574,7 +1574,7 @@ static void do_create_raw(parameters_t ¶ms) auto input_file_str = params.find(OPTION_INPUT); if (input_file_str != params.end()) { - osd_file::error filerr = util::core_file::open(input_file_str->second->c_str(), OPEN_FLAG_READ, input_file); + osd_file::error filerr = util::core_file::open(*input_file_str->second, OPEN_FLAG_READ, input_file); if (filerr != osd_file::error::NONE) report_error(1, "Unable to open file (%s)", input_file_str->second->c_str()); } @@ -1671,7 +1671,7 @@ static void do_create_hd(parameters_t ¶ms) auto input_file_str = params.find(OPTION_INPUT); if (input_file_str != params.end()) { - osd_file::error filerr = util::core_file::open(input_file_str->second->c_str(), OPEN_FLAG_READ, input_file); + osd_file::error filerr = util::core_file::open(*input_file_str->second, OPEN_FLAG_READ, input_file); if (filerr != osd_file::error::NONE) report_error(1, "Unable to open file (%s)", input_file_str->second->c_str()); } @@ -2240,7 +2240,7 @@ static void do_extract_raw(parameters_t ¶ms) try { // process output file - osd_file::error filerr = util::core_file::open(output_file_str->second->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file); + osd_file::error filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file); if (filerr != osd_file::error::NONE) report_error(1, "Unable to open file (%s)", output_file_str->second->c_str()); @@ -2345,14 +2345,14 @@ static void do_extract_cd(parameters_t ¶ms) } // process output file - osd_file::error filerr = util::core_file::open(output_file_str->second->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, output_toc_file); + osd_file::error filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, output_toc_file); if (filerr != osd_file::error::NONE) report_error(1, "Unable to open file (%s)", output_file_str->second->c_str()); // process output BIN file if (mode != MODE_GDI) { - filerr = util::core_file::open(output_bin_file_str->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file); + filerr = util::core_file::open(*output_bin_file_str, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file); if (filerr != osd_file::error::NONE) report_error(1, "Unable to open file (%s)", output_bin_file_str->c_str()); } @@ -2388,7 +2388,7 @@ static void do_extract_cd(parameters_t ¶ms) output_bin_file.reset(); - filerr = util::core_file::open(trackbin_name.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file); + filerr = util::core_file::open(trackbin_name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file); if (filerr != osd_file::error::NONE) report_error(1, "Unable to open file (%s)", trackbin_name.c_str()); @@ -2795,7 +2795,7 @@ static void do_dump_metadata(parameters_t ¶ms) // create the file if (output_file_str != params.end()) { - osd_file::error filerr = util::core_file::open(output_file_str->second->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file); + osd_file::error filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file); if (filerr != osd_file::error::NONE) report_error(1, "Unable to open file (%s)", output_file_str->second->c_str()); diff --git a/src/tools/imgtool/stream.cpp b/src/tools/imgtool/stream.cpp index d96cf325a7a..b11e7a5e4be 100644 --- a/src/tools/imgtool/stream.cpp +++ b/src/tools/imgtool/stream.cpp @@ -104,24 +104,23 @@ static imgtool_stream *stream_open_zip(const char *zipname, const char *subname, imgfile->imgtype = IMG_MEM; - zip_file::ptr z; - const zip_file::file_header *zipent = nullptr; - zip_file::open(zipname, z); + util::archive_file::ptr z; + util::archive_file::open_zip(zipname, z); if (!z) return nullptr; - zipent = z->first_file(); - while (zipent && subname && strcmp(subname, zipent->filename)) + int zipent = z->first_file(); + while ((zipent >= 0) && subname && strcmp(subname, z->current_name().c_str())) zipent = z->next_file(); - if (!zipent) + if (zipent < 0) return nullptr; - imgfile->filesize = zipent->uncompressed_length; - imgfile->buffer = reinterpret_cast<std::uint8_t *>(malloc(zipent->uncompressed_length)); + imgfile->filesize = z->current_uncompressed_length(); + imgfile->buffer = reinterpret_cast<std::uint8_t *>(malloc(z->current_uncompressed_length())); if (!imgfile->buffer) return nullptr; - if (z->decompress(imgfile->buffer, zipent->uncompressed_length) != zip_file::error::NONE) + if (z->decompress(imgfile->buffer, z->current_uncompressed_length()) != util::archive_file::error::NONE) return nullptr; return imgfile.release(); diff --git a/src/tools/pngcmp.cpp b/src/tools/pngcmp.cpp index aa33a421e5d..e34bcf401e4 100644 --- a/src/tools/pngcmp.cpp +++ b/src/tools/pngcmp.cpp @@ -80,7 +80,7 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img int x, y; /* open the source image */ - filerr = util::core_file::open(imgfile1.c_str(), OPEN_FLAG_READ, file); + filerr = util::core_file::open(imgfile1, OPEN_FLAG_READ, file); if (filerr != osd_file::error::NONE) { printf("Could not open %s (%d)\n", imgfile1.c_str(), int(filerr)); @@ -97,7 +97,7 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img } /* open the source image */ - filerr = util::core_file::open(imgfile2.c_str(), OPEN_FLAG_READ, file); + filerr = util::core_file::open(imgfile2, OPEN_FLAG_READ, file); if (filerr != osd_file::error::NONE) { printf("Could not open %s (%d)\n", imgfile2.c_str(), int(filerr)); @@ -170,7 +170,7 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img } /* write the final PNG */ - filerr = util::core_file::open(outfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file); + filerr = util::core_file::open(outfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file); if (filerr != osd_file::error::NONE) { printf("Could not open %s (%d)\n", outfilename.c_str(), int(filerr)); diff --git a/src/tools/regrep.cpp b/src/tools/regrep.cpp index 4d02151672b..0c6d11093c6 100644 --- a/src/tools/regrep.cpp +++ b/src/tools/regrep.cpp @@ -565,7 +565,7 @@ static util::core_file::ptr create_file_and_output_header(std::string &filename, util::core_file::ptr file; /* create the indexfile */ - if (util::core_file::open(filename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, file) != osd_file::error::NONE) + if (util::core_file::open(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, file) != osd_file::error::NONE) return util::core_file::ptr(); /* print a header */ @@ -735,7 +735,7 @@ static int compare_screenshots(summary_file *curfile) fullname = string_format("%s" PATH_SEPARATOR "snap" PATH_SEPARATOR "%s" PATH_SEPARATOR "final.png", lists[listnum].dir, curfile->name); /* open the file */ - filerr = util::core_file::open(fullname.c_str(), OPEN_FLAG_READ, file); + filerr = util::core_file::open(fullname, OPEN_FLAG_READ, file); /* if that failed, look in the old location */ if (filerr != osd_file::error::NONE) @@ -744,7 +744,7 @@ static int compare_screenshots(summary_file *curfile) fullname = string_format("%s" PATH_SEPARATOR "snap" PATH_SEPARATOR "_%s.png", lists[listnum].dir, curfile->name); /* open the file */ - filerr = util::core_file::open(fullname.c_str(), OPEN_FLAG_READ, file); + filerr = util::core_file::open(fullname, OPEN_FLAG_READ, file); } /* if that worked, load the file */ @@ -853,7 +853,7 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir, tempname = string_format("%s" PATH_SEPARATOR "%s", lists[listnum].dir, srcimgname.c_str()); /* open the source image */ - filerr = util::core_file::open(tempname.c_str(), OPEN_FLAG_READ, file); + filerr = util::core_file::open(tempname, OPEN_FLAG_READ, file); if (filerr != osd_file::error::NONE) goto error; @@ -925,7 +925,7 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir, } /* write the final PNG */ - filerr = util::core_file::open(dstfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file); + filerr = util::core_file::open(dstfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file); if (filerr != osd_file::error::NONE) goto error; pngerr = png_write_bitmap(*file, nullptr, finalbitmap, 0, nullptr); diff --git a/src/tools/romcmp.cpp b/src/tools/romcmp.cpp index a6919631cd8..a940d4522af 100644 --- a/src/tools/romcmp.cpp +++ b/src/tools/romcmp.cpp @@ -490,43 +490,44 @@ static int load_files(int i, int *found, const char *path) /* if not, try to open as a ZIP file */ else { - zip_file::ptr zip; - const zip_file::file_header* zipent; - zip_file::error ziperr; + util::archive_file::ptr zip; + util::archive_file::error ziperr; /* wasn't a directory, so try to open it as a zip file */ - ziperr = zip_file::open(path, zip); - if (ziperr != zip_file::error::NONE) + ziperr = util::archive_file::open_zip(path, zip); + if (ziperr != util::archive_file::error::NONE) { printf("Error, cannot open zip file '%s' !\n", path); return 1; } /* load all files in zip file */ - for (zipent = zip->first_file(); zipent != nullptr; zipent = zip->next_file()) + for (int zipent = zip->first_file(); zipent >= 0; zipent = zip->next_file()) { int size; - size = zipent->uncompressed_length; + size = zip->current_uncompressed_length(); while (size && (size & 1) == 0) size >>= 1; - if (zipent->uncompressed_length == 0) // || (size & ~1)) + if (zip->current_uncompressed_length() == 0) // || (size & ~1)) + { printf("%-23s %-23s ignored (not a ROM)\n", - i ? "" : zipent->filename, i ? zipent->filename : ""); + i ? "" : zip->current_name().c_str(), i ? zip->current_name().c_str() : ""); + } else { fileinfo *file = &files[i][found[i]]; - const char *delim = strrchr(zipent->filename,'/'); + const char *delim = strrchr(zip->current_name().c_str(), '/'); if (delim) strcpy (file->name,delim+1); else - strcpy(file->name,zipent->filename); - file->size = zipent->uncompressed_length; + strcpy(file->name,zip->current_name().c_str()); + file->size = zip->current_uncompressed_length(); if ((file->buf = (unsigned char *)malloc(file->size)) == nullptr) printf("%s: out of memory!\n",file->name); else { - if (zip->decompress(file->buf, file->size) != zip_file::error::NONE) + if (zip->decompress(file->buf, file->size) != util::archive_file::error::NONE) { free(file->buf); file->buf = nullptr; @@ -743,6 +744,6 @@ int CLIB_DECL main(int argc,char *argv[]) } } - zip_file::cache_clear(); + util::archive_file::cache_clear(); return 0; } diff --git a/src/tools/split.cpp b/src/tools/split.cpp index 5151229edd8..586264283d7 100644 --- a/src/tools/split.cpp +++ b/src/tools/split.cpp @@ -119,7 +119,7 @@ static int split_file(const char *filename, const char *basename, UINT32 splitsi splitfilename.assign(basename).append(".split"); // create the split file - filerr = util::core_file::open(splitfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, splitfile); + filerr = util::core_file::open(splitfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, splitfile); if (filerr != osd_file::error::NONE) { fprintf(stderr, "Fatal error: unable to create split file '%s'\n", splitfilename.c_str()); @@ -155,7 +155,7 @@ static int split_file(const char *filename, const char *basename, UINT32 splitsi outfilename = string_format("%s.%03d", basename, partnum); // create it - filerr = util::core_file::open(outfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile); + filerr = util::core_file::open(outfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile); if (filerr != osd_file::error::NONE) { printf("\n"); @@ -267,7 +267,7 @@ static int join_file(const char *filename, const char *outname, int write_output if (write_output) { // don't overwrite the original! - filerr = util::core_file::open(outfilename.c_str(), OPEN_FLAG_READ, outfile); + filerr = util::core_file::open(outfilename, OPEN_FLAG_READ, outfile); if (filerr == osd_file::error::NONE) { outfile.reset(); @@ -276,7 +276,7 @@ static int join_file(const char *filename, const char *outname, int write_output } // open the output for write - filerr = util::core_file::open(outfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile); + filerr = util::core_file::open(outfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile); if (filerr != osd_file::error::NONE) { fprintf(stderr, "Fatal error: unable to create file '%s'\n", outfilename.c_str()); diff --git a/src/tools/src2html.cpp b/src/tools/src2html.cpp index 9b3110a212f..38260a62879 100644 --- a/src/tools/src2html.cpp +++ b/src/tools/src2html.cpp @@ -517,7 +517,7 @@ static int output_file(file_type type, int srcrootlen, int dstrootlen, std::stri // open the source file util::core_file::ptr src; - if (util::core_file::open(srcfile.c_str(), OPEN_FLAG_READ, src) != osd_file::error::NONE) + if (util::core_file::open(srcfile, OPEN_FLAG_READ, src) != osd_file::error::NONE) { fprintf(stderr, "Unable to read file '%s'\n", srcfile.c_str()); return 1; @@ -732,7 +732,7 @@ static util::core_file::ptr create_file_and_output_header(std::string &filename, { // create the indexfile util::core_file::ptr file; - if (util::core_file::open(filename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, file) != osd_file::error::NONE) + if (util::core_file::open(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, file) != osd_file::error::NONE) return util::core_file::ptr(); // print a header @@ -865,7 +865,7 @@ static bool find_include_file(std::string &srcincpath, int srcrootlen, int dstro // see if we can open it util::core_file::ptr testfile; - if (util::core_file::open(srcincpath.c_str(), OPEN_FLAG_READ, testfile) == osd_file::error::NONE) + if (util::core_file::open(srcincpath, OPEN_FLAG_READ, testfile) == osd_file::error::NONE) { // close the file testfile.reset(); |