* Remove confusing method from vectorstreams that hide base_ios method (fixes disassembly view)

* Allow std::string to pass through core_file unmolested (reduces temporary allocations)
* Make zip/7z instances of same class with uniform interface
* zippath browsing is broken at the moment

This is another step towards transparent archive support.  It's now
possible to access zip and 7z archives with the same code.  Nothing is
taking advantage of it yet.  There's now some very similar code in
fileio.cpp and clifront.cpp that could be folded at some point.
This commit is contained in:
Vas Crabb 2016-03-18 19:22:43 +11:00
parent acb27808d4
commit 100fa28671
32 changed files with 564 additions and 636 deletions

View File

@ -15,19 +15,20 @@
project("romcmp")
uuid ("1b40275b-194c-497b-8abd-9338775a21b8")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
links {
"utils",
"expat",
"7z",
"ocore_" .. _OPTIONS["osd"],
}
@ -64,13 +65,13 @@ strip()
project("chdman")
uuid ("7d948868-42db-432a-9bb5-70ce5c5f4620")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
@ -126,13 +127,13 @@ strip()
project("jedutil")
uuid ("bda60edb-f7f5-489f-b232-23d33c43dda1")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
@ -175,13 +176,13 @@ strip()
project("unidasm")
uuid ("65f81d3b-299a-4b08-a3fa-d5241afa9fd1")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
@ -189,7 +190,7 @@ links {
"dasm",
"utils",
"expat",
"7z",
"7z",
"ocore_" .. _OPTIONS["osd"],
}
@ -238,20 +239,20 @@ strip()
project("ldresample")
uuid ("3401561a-4407-4e13-9c6d-c0801330f7cc")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
links {
"utils",
"expat",
"7z",
"7z",
"ocore_" .. _OPTIONS["osd"],
}
@ -299,20 +300,20 @@ strip()
project("ldverify")
uuid ("3e66560d-b928-4227-928b-eadd0a10f00a")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
links {
"utils",
"expat",
"7z",
"7z",
"ocore_" .. _OPTIONS["osd"],
}
@ -360,13 +361,13 @@ strip()
project("regrep")
uuid ("7f6de580-d800-4e8d-bed6-9fc86829584d")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
@ -409,13 +410,13 @@ strip()
project("srcclean")
uuid ("4dd58139-313a-42c5-965d-f378bdeed220")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
@ -458,13 +459,13 @@ strip()
project("src2html")
uuid ("b31e963a-09ef-4696-acbd-e663e35ce6f7")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
@ -507,13 +508,13 @@ strip()
project("split")
uuid ("8ef6ff18-3199-4cc2-afd0-d64033070faa")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
@ -567,13 +568,13 @@ strip()
project("pngcmp")
uuid ("61f647d9-b129-409b-9c62-8acf98ed39be")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
@ -616,13 +617,13 @@ strip()
project("nltool")
uuid ("853a03b7-fa37-41a8-8250-0dc23dd935d6")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
@ -678,13 +679,13 @@ strip()
project("nlwav")
uuid ("7c5396d1-2a1a-4c93-bed6-6b8fa182054a")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
@ -718,13 +719,13 @@ strip()
project("castool")
uuid ("7d9ed428-e2ba-4448-832d-d882a64d5c22")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
@ -758,7 +759,7 @@ end
includedirs {
MAME_DIR .. "src/osd",
MAME_DIR .. "src/lib",
MAME_DIR .. "src/lib",
MAME_DIR .. "src/lib/util",
}
@ -780,13 +781,13 @@ strip()
project("floptool")
uuid ("85d8e3a6-1661-4ac9-8c21-281d20cbaf5b")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
@ -821,7 +822,7 @@ end
includedirs {
MAME_DIR .. "src/osd",
MAME_DIR .. "src/lib",
MAME_DIR .. "src/lib",
MAME_DIR .. "src/lib/util",
}
@ -843,13 +844,13 @@ strip()
project("imgtool")
uuid ("f3707807-e587-4297-a5d8-bc98f3d0b1ca")
kind "ConsoleApp"
kind "ConsoleApp"
flags {
"Symbols", -- always include minimum symbols for executables
"Symbols", -- always include minimum symbols for executables
}
if _OPTIONS["SEPARATE_BIN"]~="1" then
if _OPTIONS["SEPARATE_BIN"]~="1" then
targetdir(MAME_DIR)
end
@ -884,10 +885,10 @@ end
includedirs {
MAME_DIR .. "src/osd",
MAME_DIR .. "src/lib",
MAME_DIR .. "src/lib",
MAME_DIR .. "src/lib/util",
MAME_DIR .. "3rdparty/zlib",
MAME_DIR .. "src/tools/imgtool",
MAME_DIR .. "src/tools/imgtool",
}
files {
@ -908,21 +909,21 @@ files {
MAME_DIR .. "src/tools/imgtool/imgtool.cpp",
MAME_DIR .. "src/tools/imgtool/imgtool.h",
MAME_DIR .. "src/tools/imgtool/imgterrs.cpp",
MAME_DIR .. "src/tools/imgtool/imgterrs.h",
MAME_DIR .. "src/tools/imgtool/imghd.cpp",
MAME_DIR .. "src/tools/imgtool/imgterrs.h",
MAME_DIR .. "src/tools/imgtool/imghd.cpp",
MAME_DIR .. "src/tools/imgtool/imghd.h",
MAME_DIR .. "src/tools/imgtool/charconv.cpp",
MAME_DIR .. "src/tools/imgtool/charconv.h",
MAME_DIR .. "src/tools/imgtool/formats/vt_dsk.cpp",
MAME_DIR .. "src/tools/imgtool/formats/vt_dsk.h",
MAME_DIR .. "src/tools/imgtool/formats/coco_dsk.cpp",
MAME_DIR .. "src/tools/imgtool/formats/coco_dsk.h",
MAME_DIR .. "src/tools/imgtool/formats/coco_dsk.h",
MAME_DIR .. "src/tools/imgtool/modules/amiga.cpp",
MAME_DIR .. "src/tools/imgtool/modules/macbin.cpp",
MAME_DIR .. "src/tools/imgtool/modules/rsdos.cpp",
MAME_DIR .. "src/tools/imgtool/modules/os9.cpp",
MAME_DIR .. "src/tools/imgtool/modules/mac.cpp",
MAME_DIR .. "src/tools/imgtool/modules/ti99.cpp",
MAME_DIR .. "src/tools/imgtool/modules/ti99.cpp",
MAME_DIR .. "src/tools/imgtool/modules/ti990hd.cpp",
MAME_DIR .. "src/tools/imgtool/modules/concept.cpp",
MAME_DIR .. "src/tools/imgtool/modules/fat.cpp",

View File

@ -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)
{
return header;
// 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
{
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);

View File

@ -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

View File

@ -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());

View File

@ -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

View File

@ -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));

View File

@ -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');

View File

@ -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));

View File

@ -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');

View File

@ -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)

View File

@ -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;
@ -758,29 +750,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;

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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());

View File

@ -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());

View File

@ -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;

View File

@ -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 -----

View File

@ -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 &current_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 &current_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);
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;
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;
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

View File

@ -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 &current_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

View File

@ -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 &current_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 &current_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)
{
m_header.raw[ZIPCFN + m_header.filename_length] = m_header.saved;
m_header.raw = nullptr;
}
// if we're at or past the end, we're done
if (m_cd_pos >= m_ecd.cd_size)
return nullptr;
std::string filename;
while (m_cd_pos <= m_ecd.cd_size)
{
// 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);
// 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
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;
// 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;
// advance the position
m_cd_pos += rawlength;
// NULL terminate the filename
m_header.saved = m_header.raw[ZIPCFN + m_header.filename_length];
m_header.raw[ZIPCFN + m_header.filename_length] = 0;
// 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));
// advance the position
m_cd_pos += m_header.rawlength;
return &m_header;
// 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,26 +740,34 @@ 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
/***************************************************************************
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

View File

@ -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);
// close a ZIP file (may actually be left open due to caching)
virtual ~zip_file();
// open a 7Z file and parse its central directory
static error open_7z(const std::string &filename, ptr &result);
// clear out all open ZIP files from the cache
// close an archive file (may actually be left open due to caching)
virtual ~archive_file();
// 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 the next file in the ZIP
virtual const file_header *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;
// information on most recently found file
virtual bool current_is_directory() const = 0;
virtual const std::string &current_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

View File

@ -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()); }

View File

@ -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

View File

@ -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 */

View File

@ -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 &params)
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 &params)
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 &params)
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 &params)
}
// 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 &params)
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 &params)
// 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());

View File

@ -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();

View File

@ -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));

View File

@ -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);

View File

@ -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;
}

View File

@ -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());

View File

@ -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();