diff options
author | 2016-03-06 18:02:37 +1100 | |
---|---|---|
committer | 2016-03-06 21:49:56 +1100 | |
commit | 73b44c94291c4d086477167a76fd7db239936c3b (patch) | |
tree | 9af214e443878f4b1e6452d63393ca9f9f8a0884 | |
parent | 00941faaab99d937a32bce4d225ec56951d21020 (diff) |
Turn core_file into a proper class that gets cleaned up safely using unique_ptr
Subverted somewhat by chd_file class
68 files changed, 1621 insertions, 1460 deletions
diff --git a/src/devices/bus/a7800/a78_slot.cpp b/src/devices/bus/a7800/a78_slot.cpp index 0509753a1c3..53541560fa4 100644 --- a/src/devices/bus/a7800/a78_slot.cpp +++ b/src/devices/bus/a7800/a78_slot.cpp @@ -537,7 +537,7 @@ std::string a78_cart_slot_device::get_default_card_software() int type = A78_TYPE0, mapper; // Load and check the header - core_fread(m_file, &head[0], 128); + m_file->read(&head[0], 128); // let's try to auto-fix some common errors in the header mapper = validate_header((head[53] << 8) | head[54], FALSE); @@ -558,7 +558,7 @@ std::string a78_cart_slot_device::get_default_card_software() break; case 0x0022: case 0x0026: - if (core_fsize(m_file) > 0x40000) + if (m_file->size() > 0x40000) type = A78_MEGACART; else type = A78_VERSABOARD; diff --git a/src/devices/bus/a800/a800_slot.cpp b/src/devices/bus/a800/a800_slot.cpp index b2e46a421da..8f0f416ab0f 100644 --- a/src/devices/bus/a800/a800_slot.cpp +++ b/src/devices/bus/a800/a800_slot.cpp @@ -412,13 +412,13 @@ std::string a800_cart_slot_device::get_default_card_software() { const char *slot_string; dynamic_buffer head(0x10); - UINT32 len = core_fsize(m_file); + UINT32 len = m_file->size(); int type = A800_8K; // check whether there is an header, to identify the cart type if ((len % 0x1000) == 0x10) { - core_fread(m_file, &head[0], 0x10); + m_file->read(&head[0], 0x10); type = identify_cart_type(&head[0]); } else // otherwise try to guess based on size @@ -449,13 +449,13 @@ std::string a5200_cart_slot_device::get_default_card_software() { const char *slot_string; dynamic_buffer head(0x10); - UINT32 len = core_fsize(m_file); + UINT32 len = m_file->size(); int type = A5200_8K; // check whether there is an header, to identify the cart type if ((len % 0x1000) == 0x10) { - core_fread(m_file, &head[0], 0x10); + m_file->read(&head[0], 0x10); type = identify_cart_type(&head[0]); std::string info; @@ -482,13 +482,13 @@ std::string xegs_cart_slot_device::get_default_card_software() { const char *slot_string; dynamic_buffer head(0x10); - UINT32 len = core_fsize(m_file); + UINT32 len = m_file->size(); int type = A800_8K; // check whether there is an header, to identify the cart type if ((len % 0x1000) == 0x10) { - core_fread(m_file, &head[0], 0x10); + m_file->read(&head[0], 0x10); type = identify_cart_type(&head[0]); } if (type != A800_XEGS) diff --git a/src/devices/bus/apf/slot.cpp b/src/devices/bus/apf/slot.cpp index eb2e17d9f80..af872826ce3 100644 --- a/src/devices/bus/apf/slot.cpp +++ b/src/devices/bus/apf/slot.cpp @@ -226,7 +226,7 @@ std::string apf_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 size = core_fsize(m_file); + UINT32 size = m_file->size(); int type = APF_STD; // attempt to identify Space Destroyer, which needs 1K of additional RAM diff --git a/src/devices/bus/astrocde/slot.cpp b/src/devices/bus/astrocde/slot.cpp index 8ae7bbe8c15..2cab9c3c285 100644 --- a/src/devices/bus/astrocde/slot.cpp +++ b/src/devices/bus/astrocde/slot.cpp @@ -203,7 +203,7 @@ std::string astrocade_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 size = core_fsize(m_file); + UINT32 size = m_file->size(); int type = ASTROCADE_STD; if (size == 0x40000) diff --git a/src/devices/bus/c64/exp.cpp b/src/devices/bus/c64/exp.cpp index 47e2a20cc14..31263c5f927 100644 --- a/src/devices/bus/c64/exp.cpp +++ b/src/devices/bus/c64/exp.cpp @@ -153,7 +153,7 @@ bool c64_expansion_slot_device::call_load() int exrom = 1; int game = 1; - if (cbm_crt_read_header(m_file, &roml_size, &romh_size, &exrom, &game)) + if (cbm_crt_read_header(*m_file, &roml_size, &romh_size, &exrom, &game)) { UINT8 *roml = nullptr; UINT8 *romh = nullptr; @@ -164,7 +164,7 @@ bool c64_expansion_slot_device::call_load() if (roml_size) roml = m_card->m_roml; if (romh_size) romh = m_card->m_roml; - cbm_crt_read_data(m_file, roml, romh); + cbm_crt_read_data(*m_file, roml, romh); } m_card->m_exrom = exrom; @@ -222,7 +222,7 @@ std::string c64_expansion_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { if (!core_stricmp(filetype(), "crt")) - return cbm_crt_get_card(m_file); + return cbm_crt_get_card(*m_file); clear(); } diff --git a/src/devices/bus/chanf/slot.cpp b/src/devices/bus/chanf/slot.cpp index 72045151cca..ea5b00b5348 100644 --- a/src/devices/bus/chanf/slot.cpp +++ b/src/devices/bus/chanf/slot.cpp @@ -222,7 +222,7 @@ std::string channelf_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 len = core_fsize(m_file); + UINT32 len = m_file->size(); int type; if (len == 0x40000) diff --git a/src/devices/bus/coleco/exp.cpp b/src/devices/bus/coleco/exp.cpp index 05a53b584a5..53953f82859 100644 --- a/src/devices/bus/coleco/exp.cpp +++ b/src/devices/bus/coleco/exp.cpp @@ -116,7 +116,7 @@ std::string colecovision_cartridge_slot_device::get_default_card_software() { if (open_image_file(mconfig().options())) { - UINT32 length = core_fsize(m_file); + UINT32 length = m_file->size(); if (length == 0x100000 || length == 0x200000) return software_get_default_slot("xin1"); } diff --git a/src/devices/bus/crvision/slot.cpp b/src/devices/bus/crvision/slot.cpp index 74c9eb28645..22af6ced64c 100644 --- a/src/devices/bus/crvision/slot.cpp +++ b/src/devices/bus/crvision/slot.cpp @@ -234,7 +234,7 @@ std::string crvision_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 size = core_fsize(m_file); + UINT32 size = m_file->size(); int type = CRV_4K; switch (size) diff --git a/src/devices/bus/gameboy/gb_slot.cpp b/src/devices/bus/gameboy/gb_slot.cpp index 55555a8d4b2..47236928fb7 100644 --- a/src/devices/bus/gameboy/gb_slot.cpp +++ b/src/devices/bus/gameboy/gb_slot.cpp @@ -605,11 +605,11 @@ std::string base_gb_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 len = core_fsize(m_file), offset = 0; + UINT32 len = m_file->size(), offset = 0; dynamic_buffer rom(len); int type; - core_fread(m_file, &rom[0], len); + m_file->read(&rom[0], len); if ((len % 0x4000) == 512) offset = 512; diff --git a/src/devices/bus/gba/gba_slot.cpp b/src/devices/bus/gba/gba_slot.cpp index 217f3f9e954..10c5d45a0a8 100644 --- a/src/devices/bus/gba/gba_slot.cpp +++ b/src/devices/bus/gba/gba_slot.cpp @@ -405,11 +405,11 @@ std::string gba_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 len = core_fsize(m_file); + UINT32 len = m_file->size(); dynamic_buffer rom(len); int type; - core_fread(m_file, &rom[0], len); + m_file->read(&rom[0], len); type = get_cart_type(&rom[0], len); slot_string = gba_get_slot(type); diff --git a/src/devices/bus/intv/slot.cpp b/src/devices/bus/intv/slot.cpp index 87f36e14bac..d502016fe76 100644 --- a/src/devices/bus/intv/slot.cpp +++ b/src/devices/bus/intv/slot.cpp @@ -464,11 +464,11 @@ std::string intv_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 len = core_fsize(m_file); + UINT32 len = m_file->size(); dynamic_buffer rom(len); int type = INTV_STD; - core_fread(m_file, &rom[0], len); + m_file->read(&rom[0], len); if (rom[0] == 0xa8 && (rom[1] == (rom[2] ^ 0xff))) { diff --git a/src/devices/bus/isa/omti8621.cpp b/src/devices/bus/isa/omti8621.cpp index c3eb61bf0e8..15255f1f3e5 100644 --- a/src/devices/bus/isa/omti8621.cpp +++ b/src/devices/bus/isa/omti8621.cpp @@ -1370,7 +1370,7 @@ void omti_disk_image_device::device_start() { m_image = this; - if (m_image->image_core_file() == nullptr) + if (!m_image->is_open()) { LOG1(("device_start_omti_disk: no disk")); } diff --git a/src/devices/bus/isa/sc499.cpp b/src/devices/bus/isa/sc499.cpp index 88a0272a9c1..5e044759603 100644 --- a/src/devices/bus/isa/sc499.cpp +++ b/src/devices/bus/isa/sc499.cpp @@ -344,7 +344,7 @@ void sc499_device::device_start() m_installed = false; - if (m_image->image_core_file() == nullptr) + if (!m_image->is_open()) { LOG2(("start sc499: no cartridge tape")); } diff --git a/src/devices/bus/megadrive/md_slot.cpp b/src/devices/bus/megadrive/md_slot.cpp index a2674838914..f44e0597cd4 100644 --- a/src/devices/bus/megadrive/md_slot.cpp +++ b/src/devices/bus/megadrive/md_slot.cpp @@ -905,11 +905,11 @@ std::string base_md_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 len = core_fsize(m_file), offset = 0; + UINT32 len = m_file->size(), offset = 0; dynamic_buffer rom(len); int type; - core_fread(m_file, &rom[0], len); + m_file->read(&rom[0], len); if (genesis_is_SMD(&rom[0x200], len - 0x200)) offset = 0x200; diff --git a/src/devices/bus/msx_slot/cartridge.cpp b/src/devices/bus/msx_slot/cartridge.cpp index c24df3bf1fb..ae806337359 100644 --- a/src/devices/bus/msx_slot/cartridge.cpp +++ b/src/devices/bus/msx_slot/cartridge.cpp @@ -283,7 +283,7 @@ std::string msx_slot_cartridge_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string = "nomapper"; - UINT32 length = core_fsize(m_file); + UINT32 length = m_file->size(); dynamic_buffer rom(length); int type = NOMAPPER; @@ -328,7 +328,7 @@ std::string msx_slot_cartridge_device::get_default_card_software() if (type == NOMAPPER) { // Not identified through hashfile, try automatic detection - core_fread(m_file, &rom[0], length); + m_file->read(&rom[0], length); type = get_cart_type(&rom[0], length); } diff --git a/src/devices/bus/nes/aladdin.cpp b/src/devices/bus/nes/aladdin.cpp index bad863b9255..bded198c5a7 100644 --- a/src/devices/bus/nes/aladdin.cpp +++ b/src/devices/bus/nes/aladdin.cpp @@ -147,11 +147,11 @@ std::string nes_aladdin_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string = "algn"; - UINT32 len = core_fsize(m_file); + UINT32 len = m_file->size(); dynamic_buffer rom(len); UINT8 mapper; - core_fread(m_file, &rom[0], len); + m_file->read(&rom[0], len); mapper = (rom[6] & 0xf0) >> 4; mapper |= rom[7] & 0xf0; diff --git a/src/devices/bus/nes/nes_slot.cpp b/src/devices/bus/nes/nes_slot.cpp index 05adca0f9ae..5eaf22852c9 100644 --- a/src/devices/bus/nes/nes_slot.cpp +++ b/src/devices/bus/nes/nes_slot.cpp @@ -917,10 +917,10 @@ std::string nes_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string = "nrom"; - UINT32 len = core_fsize(m_file); + UINT32 len = m_file->size(); dynamic_buffer rom(len); - core_fread(m_file, &rom[0], len); + m_file->read(&rom[0], len); if ((rom[0] == 'N') && (rom[1] == 'E') && (rom[2] == 'S')) slot_string = get_default_card_ines(&rom[0], len); diff --git a/src/devices/bus/odyssey2/slot.cpp b/src/devices/bus/odyssey2/slot.cpp index 0a6e35028b9..3d0f8714288 100644 --- a/src/devices/bus/odyssey2/slot.cpp +++ b/src/devices/bus/odyssey2/slot.cpp @@ -214,7 +214,7 @@ std::string o2_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 size = core_fsize(m_file); + UINT32 size = m_file->size(); int type = O2_STD; if (size == 12288) diff --git a/src/devices/bus/pce/pce_slot.cpp b/src/devices/bus/pce/pce_slot.cpp index 4fffa5172fc..6a1e5859f1f 100644 --- a/src/devices/bus/pce/pce_slot.cpp +++ b/src/devices/bus/pce/pce_slot.cpp @@ -344,11 +344,11 @@ std::string pce_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 len = core_fsize(m_file); + UINT32 len = m_file->size(); dynamic_buffer rom(len); int type; - core_fread(m_file, &rom[0], len); + m_file->read(&rom[0], len); type = get_cart_type(&rom[0], len); slot_string = pce_get_slot(type); diff --git a/src/devices/bus/scv/slot.cpp b/src/devices/bus/scv/slot.cpp index 15495afe918..daf31a27885 100644 --- a/src/devices/bus/scv/slot.cpp +++ b/src/devices/bus/scv/slot.cpp @@ -264,11 +264,11 @@ std::string scv_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 len = core_fsize(m_file); + UINT32 len = m_file->size(); dynamic_buffer rom(len); int type; - core_fread(m_file, &rom[0], len); + m_file->read(&rom[0], len); type = get_cart_type(&rom[0], len); slot_string = scv_get_slot(type); diff --git a/src/devices/bus/sega8/sega8_slot.cpp b/src/devices/bus/sega8/sega8_slot.cpp index df3c59adc05..a3ebf09c463 100644 --- a/src/devices/bus/sega8/sega8_slot.cpp +++ b/src/devices/bus/sega8/sega8_slot.cpp @@ -608,11 +608,11 @@ std::string sega8_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 len = core_fsize(m_file), offset = 0; + UINT32 len = m_file->size(), offset = 0; dynamic_buffer rom(len); int type; - core_fread(m_file, &rom[0], len); + m_file->read(&rom[0], len); if ((len % 0x4000) == 512) offset = 512; diff --git a/src/devices/bus/snes/snes_slot.cpp b/src/devices/bus/snes/snes_slot.cpp index 65c2fffdb4d..38260a06e84 100644 --- a/src/devices/bus/snes/snes_slot.cpp +++ b/src/devices/bus/snes/snes_slot.cpp @@ -1007,11 +1007,11 @@ std::string base_sns_cart_slot_device::get_default_card_software() { const char *slot_string; UINT32 offset; - UINT32 len = core_fsize(m_file); + UINT32 len = m_file->size(); dynamic_buffer rom(len); int type = 0, addon = 0; - core_fread(m_file, &rom[0], len); + m_file->read(&rom[0], len); offset = snes_skip_header(&rom[0], len); diff --git a/src/devices/bus/vc4000/slot.cpp b/src/devices/bus/vc4000/slot.cpp index 0b67a264c34..ba75cd67267 100644 --- a/src/devices/bus/vc4000/slot.cpp +++ b/src/devices/bus/vc4000/slot.cpp @@ -240,7 +240,7 @@ std::string vc4000_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 size = core_fsize(m_file); + UINT32 size = m_file->size(); int type = VC4000_STD; // attempt to identify the non-standard types diff --git a/src/devices/bus/vcs/vcs_slot.cpp b/src/devices/bus/vcs/vcs_slot.cpp index b946c8051e7..b8b25b864d4 100755..100644 --- a/src/devices/bus/vcs/vcs_slot.cpp +++ b/src/devices/bus/vcs/vcs_slot.cpp @@ -786,11 +786,11 @@ std::string vcs_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 len = core_fsize(m_file); + UINT32 len = m_file->size(); dynamic_buffer rom(len); int type; - core_fread(m_file, &rom[0], len); + m_file->read(&rom[0], len); type = identify_cart_type(&rom[0], len); slot_string = vcs_get_slot(type); diff --git a/src/devices/bus/vectrex/slot.cpp b/src/devices/bus/vectrex/slot.cpp index 1a9bbed7d29..14e531b8cd2 100644 --- a/src/devices/bus/vectrex/slot.cpp +++ b/src/devices/bus/vectrex/slot.cpp @@ -222,11 +222,11 @@ std::string vectrex_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 size = core_fsize(m_file); + UINT32 size = m_file->size(); dynamic_buffer rom(size); int type = VECTREX_STD; - core_fread(m_file, &rom[0], size); + m_file->read(&rom[0], size); if (!memcmp(&rom[0x06], "SRAM", 4)) type = VECTREX_SRAM; diff --git a/src/devices/bus/vic10/exp.cpp b/src/devices/bus/vic10/exp.cpp index 1aa6f2e6363..76c55ff7d79 100644 --- a/src/devices/bus/vic10/exp.cpp +++ b/src/devices/bus/vic10/exp.cpp @@ -139,7 +139,7 @@ bool vic10_expansion_slot_device::call_load() int exrom = 1; int game = 1; - if (cbm_crt_read_header(m_file, &roml_size, &romh_size, &exrom, &game)) + if (cbm_crt_read_header(*m_file, &roml_size, &romh_size, &exrom, &game)) { UINT8 *roml = nullptr; UINT8 *romh = nullptr; @@ -150,7 +150,7 @@ bool vic10_expansion_slot_device::call_load() if (roml_size) roml = m_card->m_lorom; if (romh_size) romh = m_card->m_lorom; - cbm_crt_read_data(m_file, roml, romh); + cbm_crt_read_data(*m_file, roml, romh); } } } @@ -187,7 +187,7 @@ std::string vic10_expansion_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { if (!core_stricmp(filetype(), "crt")) - return cbm_crt_get_card(m_file); + return cbm_crt_get_card(*m_file); clear(); } diff --git a/src/devices/bus/wswan/slot.cpp b/src/devices/bus/wswan/slot.cpp index b5b95851f00..256487bc8e1 100644 --- a/src/devices/bus/wswan/slot.cpp +++ b/src/devices/bus/wswan/slot.cpp @@ -311,12 +311,12 @@ std::string ws_cart_slot_device::get_default_card_software() if (open_image_file(mconfig().options())) { const char *slot_string; - UINT32 size = core_fsize(m_file); + UINT32 size = m_file->size(); dynamic_buffer rom(size); int type; UINT32 nvram; - core_fread(m_file, &rom[0], size); + m_file->read(&rom[0], size); // nvram size is not really used here, but we set it up nevertheless type = get_cart_type(&rom[0], size, nvram); diff --git a/src/devices/imagedev/chd_cd.cpp b/src/devices/imagedev/chd_cd.cpp index d9ab295dfad..630403001ff 100644 --- a/src/devices/imagedev/chd_cd.cpp +++ b/src/devices/imagedev/chd_cd.cpp @@ -109,7 +109,7 @@ bool cdrom_image_device::call_load() if (software_entry() == nullptr) { if (strstr(m_image_name.c_str(), ".chd") && is_loaded()) { - err = m_self_chd.open( *image_core_file() ); /* CDs are never writeable */ + err = m_self_chd.open( image_core_file() ); /* CDs are never writeable */ if ( err ) goto error; chd = &m_self_chd; diff --git a/src/devices/imagedev/diablo.cpp b/src/devices/imagedev/diablo.cpp index f9d4218856a..6ba6aad5cf2 100644 --- a/src/devices/imagedev/diablo.cpp +++ b/src/devices/imagedev/diablo.cpp @@ -124,7 +124,7 @@ bool diablo_image_device::call_create(int create_format, option_resolution *crea /* create the CHD file */ chd_codec_type compression[4] = { CHD_CODEC_NONE }; - err = m_origchd.create(*image_core_file(), (UINT64)totalsectors * (UINT64)sectorsize, hunksize, sectorsize, compression); + err = m_origchd.create(image_core_file(), (UINT64)totalsectors * (UINT64)sectorsize, hunksize, sectorsize, compression); if (err != CHDERR_NONE) goto error; @@ -219,14 +219,14 @@ int diablo_image_device::internal_load_dsk() } else { - err = m_origchd.open(*image_core_file(), true); + err = m_origchd.open(image_core_file(), true); if (err == CHDERR_NONE) { m_chd = &m_origchd; } else if (err == CHDERR_FILE_NOT_WRITEABLE) { - err = m_origchd.open(*image_core_file(), false); + err = m_origchd.open(image_core_file(), false); if (err == CHDERR_NONE) { err = open_disk_diff(device().machine().options(), basename_noext(), m_origchd, m_diffchd); diff --git a/src/devices/imagedev/floppy.cpp b/src/devices/imagedev/floppy.cpp index cb7e184f811..9a2bd21d764 100644 --- a/src/devices/imagedev/floppy.cpp +++ b/src/devices/imagedev/floppy.cpp @@ -295,7 +295,7 @@ void floppy_image_device::commit_image() io.procs = &image_ioprocs; io.filler = 0xff; - file_error err = core_truncate(image_core_file(), 0); + file_error err = image_core_file().truncate(0); if (err != 0) popmessage("Error, unable to truncate image: %d", err); @@ -362,7 +362,7 @@ void floppy_image_device::device_timer(emu_timer &timer, device_timer_id id, int floppy_image_format_t *floppy_image_device::identify(std::string filename) { - core_file *fd; + util::core_file::ptr fd; std::string revised_path; file_error err = zippath_fopen(filename.c_str(), OPEN_FLAG_READ, fd, revised_path); @@ -372,19 +372,20 @@ floppy_image_format_t *floppy_image_device::identify(std::string filename) } io_generic io; - io.file = fd; + io.file = fd.get(); io.procs = &corefile_ioprocs_noclose; io.filler = 0xff; int best = 0; floppy_image_format_t *best_format = nullptr; - for(floppy_image_format_t *format = fif_list; format; format = format->next) { + for (floppy_image_format_t *format = fif_list; format; format = format->next) + { int score = format->identify(&io, form_factor); if(score > best) { best = score; best_format = format; } } - core_fclose(fd); + fd.reset(); return best_format; } @@ -1001,11 +1002,11 @@ void ui_menu_control_floppy_image::hook_load(std::string filename, bool softlist if(can_in_place) { file_error filerr; std::string tmp_path; - core_file *tmp_file; + 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); if(!filerr) - core_fclose(tmp_file); + tmp_file.reset(); else can_in_place = false; } diff --git a/src/devices/imagedev/harddriv.cpp b/src/devices/imagedev/harddriv.cpp index c03b0e4075b..d07852e166f 100644 --- a/src/devices/imagedev/harddriv.cpp +++ b/src/devices/imagedev/harddriv.cpp @@ -148,7 +148,7 @@ bool harddisk_image_device::call_create(int create_format, option_resolution *cr /* create the CHD file */ chd_codec_type compression[4] = { CHD_CODEC_NONE }; - err = m_origchd.create(*image_core_file(), (UINT64)totalsectors * (UINT64)sectorsize, hunksize, sectorsize, compression); + err = m_origchd.create(image_core_file(), (UINT64)totalsectors * (UINT64)sectorsize, hunksize, sectorsize, compression); if (err != CHDERR_NONE) goto error; @@ -243,14 +243,14 @@ int harddisk_image_device::internal_load_hd() } else { - err = m_origchd.open(*image_core_file(), true); + err = m_origchd.open(image_core_file(), true); if (err == CHDERR_NONE) { m_chd = &m_origchd; } else if (err == CHDERR_FILE_NOT_WRITEABLE) { - err = m_origchd.open(*image_core_file(), false); + err = m_origchd.open(image_core_file(), false); if (err == CHDERR_NONE) { err = open_disk_diff(device().machine().options(), basename_noext(), m_origchd, m_diffchd); diff --git a/src/devices/machine/serflash.cpp b/src/devices/machine/serflash.cpp index ebdd1dd53a9..f5a002ae929 100644 --- a/src/devices/machine/serflash.cpp +++ b/src/devices/machine/serflash.cpp @@ -77,7 +77,7 @@ void serflash_device::nvram_read(emu_file &file) int size = m_length / FLASH_PAGE_SIZE; - if (file) + if (file.is_open()) { UINT32 page; file.read(&page, 4); diff --git a/src/devices/sound/samples.cpp b/src/devices/sound/samples.cpp index 7a756dbb0fe..62bd8e02657 100644 --- a/src/devices/sound/samples.cpp +++ b/src/devices/sound/samples.cpp @@ -571,7 +571,7 @@ bool samples_device::read_flac_sample(emu_file &file, sample_t &sample) file.seek(0, SEEK_SET); // create the FLAC decoder and fill in the sample data - flac_decoder decoder((core_file&) file); + flac_decoder decoder((util::core_file &)file); sample.frequency = decoder.sample_rate(); // error if more than 1 channel or not 16bpp diff --git a/src/emu/clifront.cpp b/src/emu/clifront.cpp index 4476e4e0151..7c6c974cce7 100644 --- a/src/emu/clifront.cpp +++ b/src/emu/clifront.cpp @@ -1880,7 +1880,7 @@ void media_identifier::identify_file(const char *name) // load the file and process if it opens and has a valid length UINT32 length; void *data; - file_error filerr = core_fload(name, &data, &length); + const file_error filerr = util::core_file::load(name, &data, length); if (filerr == FILERR_NONE && length > 0) { identify_data(name, reinterpret_cast<UINT8 *>(data), length); diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp index d43cfe02fed..704f7d987e8 100644 --- a/src/emu/diimage.cpp +++ b/src/emu/diimage.cpp @@ -57,8 +57,8 @@ const image_device_type_info device_image_interface::m_device_info_array[] = device_image_interface::device_image_interface(const machine_config &mconfig, device_t &device) : device_interface(device, "image"), m_err(), - m_file(nullptr), - m_mame_file(nullptr), + m_file(), + m_mame_file(), m_software_info_ptr(nullptr), m_software_part_ptr(nullptr), m_supported(0), @@ -611,12 +611,11 @@ bool device_image_interface::is_loaded() image_error_t device_image_interface::load_image_by_path(UINT32 open_flags, const char *path) { - file_error filerr; image_error_t err; std::string revised_path; /* attempt to read the file */ - filerr = zippath_fopen(path, open_flags, m_file, revised_path); + auto const filerr = zippath_fopen(path, open_flags, m_file, revised_path); /* did the open succeed? */ switch(filerr) @@ -662,15 +661,13 @@ image_error_t device_image_interface::load_image_by_path(UINT32 open_flags, cons int device_image_interface::reopen_for_write(const char *path) { - if(m_file) - core_fclose(m_file); + m_file.reset(); - file_error filerr; image_error_t err; std::string revised_path; /* attempt to open the file for writing*/ - filerr = zippath_fopen(path, OPEN_FLAG_READ|OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, m_file, revised_path); + auto const filerr = zippath_fopen(path, OPEN_FLAG_READ|OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, m_file, revised_path); /* did the open succeed? */ switch(filerr) @@ -876,10 +873,9 @@ bool device_image_interface::load_software(software_list_device &swlist, const c warningcount += verify_length_and_hash(m_mame_file.get(),ROM_GETNAME(romp),ROM_GETLENGTH(romp),hash_collection(ROM_GETHASHDATA(romp))); if (filerr == FILERR_NONE) - { - m_file = *m_mame_file; + filerr = util::core_file::open_proxy(*m_mame_file, m_file); + if (filerr == FILERR_NONE) retVal = TRUE; - } break; // load first item for start } @@ -1118,17 +1114,8 @@ bool device_image_interface::create(const char *path, const image_device_format void device_image_interface::clear() { - if (m_mame_file) - { - m_mame_file = nullptr; - m_file = nullptr; - } else { - if (m_file) - { - core_fclose(m_file); - m_file = nullptr; - } - } + m_mame_file.reset(); + m_file.reset(); m_image_name.clear(); m_readonly = false; diff --git a/src/emu/diimage.h b/src/emu/diimage.h index b1a8a16ad70..f15e0e555a9 100644 --- a/src/emu/diimage.h +++ b/src/emu/diimage.h @@ -178,21 +178,22 @@ public: const char *basename() { if (m_basename.empty()) return nullptr; else return m_basename.c_str(); } const char *basename_noext() { if (m_basename_noext.empty()) return nullptr; else return m_basename_noext.c_str(); } const char *filetype() { if (m_filetype.empty()) return nullptr; else return m_filetype.c_str(); } - core_file *image_core_file() { return m_file; } - UINT64 length() { check_for_file(); return core_fsize(m_file); } + bool is_open() const { return bool(m_file); } + util::core_file &image_core_file() { return *m_file; } + UINT64 length() { check_for_file(); return m_file->size(); } bool is_readonly() { return m_readonly; } bool has_been_created() { return m_created; } void make_readonly() { m_readonly = true; } - UINT32 fread(void *buffer, UINT32 length) { check_for_file(); return core_fread(m_file, buffer, length); } + UINT32 fread(void *buffer, UINT32 length) { check_for_file(); return m_file->read(buffer, length); } UINT32 fread(optional_shared_ptr<UINT8> &ptr, UINT32 length) { ptr.allocate(length); return fread(ptr.target(), length); } UINT32 fread(optional_shared_ptr<UINT8> &ptr, UINT32 length, offs_t offset) { ptr.allocate(length); return fread(ptr + offset, length - offset); } - UINT32 fwrite(const void *buffer, UINT32 length) { check_for_file(); return core_fwrite(m_file, buffer, length); } - int fseek(INT64 offset, int whence) { check_for_file(); return core_fseek(m_file, offset, whence); } - UINT64 ftell() { check_for_file(); return core_ftell(m_file); } + UINT32 fwrite(const void *buffer, UINT32 length) { check_for_file(); return m_file->write(buffer, length); } + int fseek(INT64 offset, int whence) { check_for_file(); return m_file->seek(offset, whence); } + UINT64 ftell() { check_for_file(); return m_file->tell(); } int fgetc() { char ch; if (fread(&ch, 1) != 1) ch = '\0'; return ch; } - char *fgets(char *buffer, UINT32 length) { check_for_file(); return core_fgets(buffer, length, m_file); } - int image_feof() { check_for_file(); return core_feof(m_file); } - void *ptr() {check_for_file(); return (void *) core_fbuffer(m_file); } + char *fgets(char *buffer, UINT32 length) { check_for_file(); return m_file->gets(buffer, length); } + int image_feof() { check_for_file(); return m_file->eof(); } + void *ptr() {check_for_file(); return const_cast<void *>(m_file->buffer()); } // configuration access void set_init_phase() { m_init_phase = TRUE; } @@ -250,7 +251,7 @@ protected: void clear_error(); - void check_for_file() { assert_always(m_file != nullptr, "Illegal operation on unmounted image"); } + void check_for_file() { assert_always(m_file, "Illegal operation on unmounted image"); } void setup_working_directory(); bool try_change_working_directory(const char *subdir); @@ -274,7 +275,7 @@ protected: std::string m_err_message; /* variables that are only non-zero when an image is mounted */ - core_file *m_file; + util::core_file::ptr m_file; std::unique_ptr<emu_file> m_mame_file; std::string m_image_name; std::string m_basename; diff --git a/src/emu/emuopts.cpp b/src/emu/emuopts.cpp index 079080c08a3..b9187edea57 100644 --- a/src/emu/emuopts.cpp +++ b/src/emu/emuopts.cpp @@ -571,7 +571,7 @@ bool emu_options::parse_one_ini(const char *basename, int priority, std::string // parse the file osd_printf_verbose("Parsing %s.ini\n", basename); std::string error; - bool result = parse_ini_file((core_file&)file, priority, OPTION_PRIORITY_DRIVER_INI, error); + bool result = parse_ini_file((util::core_file&)file, priority, OPTION_PRIORITY_DRIVER_INI, error); // append errors if requested if (!error.empty() && error_string) diff --git a/src/emu/fileio.cpp b/src/emu/fileio.cpp index d13e162f990..23f21f8b9b7 100644 --- a/src/emu/fileio.cpp +++ b/src/emu/fileio.cpp @@ -187,21 +187,11 @@ emu_file::~emu_file() //------------------------------------------------- -// operator core_file - automatically convert -// ourselves to a core_file pointer +// operator util::core_file - automatically +// convert ourselves to a core_file reference //------------------------------------------------- -emu_file::operator core_file *() -{ - // load the ZIP file now if we haven't yet - if (compressed_file_ready()) - return nullptr; - - // return the core file - return m_file; -} - -emu_file::operator core_file &() +emu_file::operator util::core_file &() { // load the ZIP file now if we haven't yet if (compressed_file_ready()) @@ -251,12 +241,12 @@ hash_collection &emu_file::hashes(const char *types) } // read the data if we can - const UINT8 *filedata = (const UINT8 *)core_fbuffer(m_file); + const UINT8 *filedata = (const UINT8 *)m_file->buffer(); if (filedata == nullptr) return m_hashes; // compute the hash - m_hashes.compute(filedata, core_fsize(m_file), needed.c_str()); + m_hashes.compute(filedata, m_file->size(), needed.c_str()); return m_hashes; } @@ -348,7 +338,7 @@ file_error emu_file::open_next() while (m_iterator.next(m_fullpath, m_filename.c_str())) { // attempt to open the file directly - filerr = core_fopen(m_fullpath.c_str(), m_openflags, &m_file); + filerr = util::core_file::open(m_fullpath.c_str(), m_openflags, m_file); if (filerr == FILERR_NONE) break; @@ -384,7 +374,7 @@ file_error emu_file::open_ram(const void *data, UINT32 length) m_crc = 0; // use the core_file's built-in RAM support - return core_fopen_ram(data, length, m_openflags, &m_file); + return util::core_file::open_ram(data, length, m_openflags, m_file); } @@ -404,9 +394,7 @@ void emu_file::close() zip_file_close(m_zipfile); m_zipfile = nullptr; - if (m_file != nullptr) - core_fclose(m_file); - m_file = nullptr; + m_file.reset(); m__7zdata.clear(); m_zipdata.clear(); @@ -429,7 +417,7 @@ void emu_file::close() file_error emu_file::compress(int level) { - return core_fcompress(m_file, level); + return m_file->compress(level); } @@ -461,8 +449,8 @@ int emu_file::seek(INT64 offset, int whence) return 1; // seek if we can - if (m_file != nullptr) - return core_fseek(m_file, offset, whence); + if (m_file) + return m_file->seek(offset, whence); return 1; } @@ -479,8 +467,8 @@ UINT64 emu_file::tell() return 0; // tell if we can - if (m_file != nullptr) - return core_ftell(m_file); + if (m_file) + return m_file->tell(); return 0; } @@ -497,8 +485,8 @@ bool emu_file::eof() return 0; // return EOF if we can - if (m_file != nullptr) - return core_feof(m_file); + if (m_file) + return m_file->eof(); return 0; } @@ -518,8 +506,8 @@ UINT64 emu_file::size() return m_ziplength; // return length if we can - if (m_file != nullptr) - return core_fsize(m_file); + if (m_file) + return m_file->size(); return 0; } @@ -536,8 +524,8 @@ UINT32 emu_file::read(void *buffer, UINT32 length) return 0; // read the data if we can - if (m_file != nullptr) - return core_fread(m_file, buffer, length); + if (m_file) + return m_file->read(buffer, length); return 0; } @@ -554,8 +542,8 @@ int emu_file::getc() return EOF; // read the data if we can - if (m_file != nullptr) - return core_fgetc(m_file); + if (m_file) + return m_file->getc(); return EOF; } @@ -572,8 +560,8 @@ int emu_file::ungetc(int c) return 1; // read the data if we can - if (m_file != nullptr) - return core_ungetc(c, m_file); + if (m_file) + return m_file->ungetc(c); return 1; } @@ -590,8 +578,8 @@ char *emu_file::gets(char *s, int n) return nullptr; // read the data if we can - if (m_file != nullptr) - return core_fgets(s, n, m_file); + if (m_file) + return m_file->gets(s, n); return nullptr; } @@ -604,8 +592,8 @@ char *emu_file::gets(char *s, int n) UINT32 emu_file::write(const void *buffer, UINT32 length) { // write the data if we can - if (m_file != nullptr) - return core_fwrite(m_file, buffer, length); + if (m_file) + return m_file->write(buffer, length); return 0; } @@ -618,8 +606,8 @@ UINT32 emu_file::write(const void *buffer, UINT32 length) int emu_file::puts(const char *s) { // write the data if we can - if (m_file != nullptr) - return core_fputs(m_file, s); + if (m_file) + return m_file->puts(s); return 0; } @@ -632,7 +620,7 @@ int emu_file::puts(const char *s) int emu_file::vprintf(const char *fmt, va_list va) { // write the data if we can - return (m_file != nullptr) ? core_vfprintf(m_file, fmt, va) : 0; + return (m_file) ? m_file->vprintf(fmt, va) : 0; } @@ -658,8 +646,8 @@ int CLIB_DECL emu_file::printf(const char *fmt, ...) void emu_file::flush() { // flush the buffers if we can - if (m_file != nullptr) - core_fflush(m_file); + if (m_file) + m_file->flush(); } @@ -778,7 +766,7 @@ file_error emu_file::load_zipped_file() } // convert to RAM file - file_error filerr = core_fopen_ram(&m_zipdata[0], m_zipdata.size(), m_openflags, &m_file); + file_error filerr = util::core_file::open_ram(&m_zipdata[0], m_zipdata.size(), m_openflags, m_file); if (filerr != FILERR_NONE) { m_zipdata.clear(); @@ -907,7 +895,7 @@ file_error emu_file::load__7zped_file() } // convert to RAM file - file_error filerr = core_fopen_ram(&m__7zdata[0], m__7zdata.size(), m_openflags, &m_file); + file_error filerr = util::core_file::open_ram(&m__7zdata[0], m__7zdata.size(), m_openflags, m_file); if (filerr != FILERR_NONE) { m__7zdata.clear(); diff --git a/src/emu/fileio.h b/src/emu/fileio.h index 60111304abc..9a65349614f 100644 --- a/src/emu/fileio.h +++ b/src/emu/fileio.h @@ -90,9 +90,8 @@ public: virtual ~emu_file(); // getters - operator core_file *(); - operator core_file &(); - bool is_open() const { return (m_file != nullptr); } + operator util::core_file &(); + bool is_open() const { return bool(m_file); } const char *filename() const { return m_filename.c_str(); } const char *fullpath() const { return m_fullpath.c_str(); } UINT32 openflags() const { return m_openflags; } @@ -102,7 +101,7 @@ public: // setters void remove_on_close() { m_remove_on_close = true; } - void set_openflags(UINT32 openflags) { assert(m_file == nullptr); m_openflags = openflags; } + void set_openflags(UINT32 openflags) { assert(!m_file); m_openflags = openflags; } void set_restrict_to_mediapath(bool rtmp = true) { m_restrict_to_mediapath = rtmp; } // open/close @@ -157,9 +156,9 @@ private: // internal state std::string m_filename; // original filename provided std::string m_fullpath; // full filename - core_file * m_file; // core file pointer + util::core_file::ptr m_file; // core file pointer path_iterator m_iterator; // iterator for paths - path_iterator m_mediapaths; // media-path iterator + path_iterator m_mediapaths; // media-path iterator UINT32 m_crc; // file's CRC UINT32 m_openflags; // flags we used for the open hash_collection m_hashes; // collection of hashes diff --git a/src/emu/ui/optsmenu.cpp b/src/emu/ui/optsmenu.cpp index 80eb5b5bbf1..00e108d52bd 100644 --- a/src/emu/ui/optsmenu.cpp +++ b/src/emu/ui/optsmenu.cpp @@ -341,7 +341,7 @@ void save_main_option(running_machine &machine) emu_file file(machine.options().ini_path(), OPEN_FLAG_READ); if (file.open(emulator_info::get_configname(), ".ini") == FILERR_NONE) { - bool result = options.parse_ini_file((core_file&)file, OPTION_PRIORITY_MAME_INI, OPTION_PRIORITY_DRIVER_INI, error); + bool result = options.parse_ini_file((util::core_file&)file, OPTION_PRIORITY_MAME_INI, OPTION_PRIORITY_DRIVER_INI, error); if (!result) { osd_printf_error(_("**Error loading %s.ini**"), emulator_info::get_configname()); diff --git a/src/emu/ui/ui.cpp b/src/emu/ui/ui.cpp index 1933db93bcd..839e7c2d7a2 100644 --- a/src/emu/ui/ui.cpp +++ b/src/emu/ui/ui.cpp @@ -171,7 +171,7 @@ static void load_ui_options(running_machine &machine) emu_file file(machine.options().ini_path(), OPEN_FLAG_READ); if (file.open("ui.ini") == FILERR_NONE) { - bool result = machine.ui().options().parse_ini_file((core_file&)file, OPTION_PRIORITY_MAME_INI, OPTION_PRIORITY_DRIVER_INI, error); + bool result = machine.ui().options().parse_ini_file((util::core_file&)file, OPTION_PRIORITY_MAME_INI, OPTION_PRIORITY_DRIVER_INI, error); if (!result) osd_printf_error("**Error loading ui.ini**"); } diff --git a/src/lib/formats/cbm_crt.cpp b/src/lib/formats/cbm_crt.cpp index 6484dbf108c..43e440e725c 100644 --- a/src/lib/formats/cbm_crt.cpp +++ b/src/lib/formats/cbm_crt.cpp @@ -122,11 +122,11 @@ static const char * CRT_C64_SLOT_NAMES[_CRT_C64_COUNT] = // cbm_crt_get_card - get slot interface card //------------------------------------------------- -std::string cbm_crt_get_card(core_file *file) +std::string cbm_crt_get_card(util::core_file &file) { // read the header cbm_crt_header header; - core_fread(file, &header, CRT_HEADER_LENGTH); + file.read(&header, CRT_HEADER_LENGTH); if (memcmp(header.signature, CRT_SIGNATURE, 16) == 0) { @@ -143,11 +143,11 @@ std::string cbm_crt_get_card(core_file *file) // cbm_crt_read_header - read cartridge header //------------------------------------------------- -bool cbm_crt_read_header(core_file* file, size_t *roml_size, size_t *romh_size, int *exrom, int *game) +bool cbm_crt_read_header(util::core_file &file, size_t *roml_size, size_t *romh_size, int *exrom, int *game) { // read the header cbm_crt_header header; - core_fread(file, &header, CRT_HEADER_LENGTH); + file.read(&header, CRT_HEADER_LENGTH); if (memcmp(header.signature, CRT_SIGNATURE, 16) != 0) return false; @@ -166,10 +166,10 @@ bool cbm_crt_read_header(core_file* file, size_t *roml_size, size_t *romh_size, } // determine ROM region lengths - while (!core_feof(file)) + while (!file.eof()) { cbm_crt_chip chip; - core_fread(file, &chip, CRT_CHIP_LENGTH); + file.read(&chip, CRT_CHIP_LENGTH); UINT16 address = pick_integer_be(chip.start_address, 0, 2); UINT16 size = pick_integer_be(chip.image_size, 0, 2); @@ -190,7 +190,7 @@ bool cbm_crt_read_header(core_file* file, size_t *roml_size, size_t *romh_size, default: osd_printf_verbose("Invalid CHIP loading address!\n"); break; } - core_fseek(file, size, SEEK_CUR); + file.seek(size, SEEK_CUR); } return true; @@ -201,26 +201,26 @@ bool cbm_crt_read_header(core_file* file, size_t *roml_size, size_t *romh_size, // cbm_crt_read_data - read cartridge data //------------------------------------------------- -bool cbm_crt_read_data(core_file* file, UINT8 *roml, UINT8 *romh) +bool cbm_crt_read_data(util::core_file &file, UINT8 *roml, UINT8 *romh) { UINT32 roml_offset = 0; UINT32 romh_offset = 0; - core_fseek(file, CRT_HEADER_LENGTH, SEEK_SET); + file.seek(CRT_HEADER_LENGTH, SEEK_SET); - while (!core_feof(file)) + while (!file.eof()) { cbm_crt_chip chip; - core_fread(file, &chip, CRT_CHIP_LENGTH); + file.read(&chip, CRT_CHIP_LENGTH); UINT16 address = pick_integer_be(chip.start_address, 0, 2); UINT16 size = pick_integer_be(chip.image_size, 0, 2); switch (address) { - case 0x8000: core_fread(file, roml + roml_offset, size); roml_offset += size; break; - case 0xa000: core_fread(file, romh + romh_offset, size); romh_offset += size; break; - case 0xe000: core_fread(file, romh + romh_offset, size); romh_offset += size; break; + case 0x8000: file.read(roml + roml_offset, size); roml_offset += size; break; + case 0xa000: file.read(romh + romh_offset, size); romh_offset += size; break; + case 0xe000: file.read(romh + romh_offset, size); romh_offset += size; break; } } diff --git a/src/lib/formats/cbm_crt.h b/src/lib/formats/cbm_crt.h index f3cfb6bb164..96d04cea2f6 100644 --- a/src/lib/formats/cbm_crt.h +++ b/src/lib/formats/cbm_crt.h @@ -135,9 +135,9 @@ struct cbm_crt_chip // FUNCTION PROTOTYPES //************************************************************************** -std::string cbm_crt_get_card(core_file *file); -bool cbm_crt_read_header(core_file* file, size_t *roml_size, size_t *romh_size, int *exrom, int *game); -bool cbm_crt_read_data(core_file* file, UINT8 *roml, UINT8 *romh); +std::string cbm_crt_get_card(util::core_file &file); +bool cbm_crt_read_header(util::core_file &file, size_t *roml_size, size_t *romh_size, int *exrom, int *game); +bool cbm_crt_read_data(util::core_file &file, UINT8 *roml, UINT8 *romh); #endif diff --git a/src/lib/formats/ioprocs.cpp b/src/lib/formats/ioprocs.cpp index 24f92060a82..9f00e3bb9d5 100644 --- a/src/lib/formats/ioprocs.cpp +++ b/src/lib/formats/ioprocs.cpp @@ -68,34 +68,33 @@ const struct io_procs stdio_ioprocs_noclose = static void corefile_closeproc(void *file) { - core_fclose((core_file*)file); + delete (util::core_file*)file; } static int corefile_seekproc(void *file, INT64 offset, int whence) { - return core_fseek((core_file*)file, (long) offset, whence); + return ((util::core_file*)file)->seek(offset, whence); } static size_t corefile_readproc(void *file, void *buffer, size_t length) { - return core_fread((core_file*)file, buffer, length); + return ((util::core_file*)file)->read(buffer, length); } static size_t corefile_writeproc(void *file, const void *buffer, size_t length) { - return core_fwrite((core_file*)file, buffer, length); + return ((util::core_file*)file)->write(buffer, length); } static UINT64 corefile_filesizeproc(void *file) { - long l, sz; - l = core_ftell((core_file*)file); - if (core_fseek((core_file*)file, 0, SEEK_END)) - return (size_t) -1; - sz = core_ftell((core_file*)file); - if (core_fseek((core_file*)file, l, SEEK_SET)) + const auto l = ((util::core_file*)file)->tell(); + if (((util::core_file*)file)->seek(0, SEEK_END)) return (size_t) -1; - return (size_t) sz; + const auto sz = ((util::core_file*)file)->tell(); + if (((util::core_file*)file)->seek(l, SEEK_SET)) + return UINT64(-1); + return UINT64(sz); } const struct io_procs corefile_ioprocs = diff --git a/src/lib/util/cdrom.cpp b/src/lib/util/cdrom.cpp index 10a1828d5e4..8bdf4af6c0f 100644 --- a/src/lib/util/cdrom.cpp +++ b/src/lib/util/cdrom.cpp @@ -115,7 +115,7 @@ struct cdrom_file /** @brief Information describing the track. */ chdcd_track_input_info track_info; /* track info */ /** @brief The fhandle[ CD maximum tracks]. */ - core_file * fhandle[CD_MAX_TRACKS];/* file handle */ + util::core_file::ptr fhandle[CD_MAX_TRACKS];/* file handle */ }; @@ -244,7 +244,7 @@ cdrom_file *cdrom_open(const char *inputfile) for (i = 0; i < file->cdtoc.numtrks; i++) { - file_error filerr = core_fopen(file->track_info.track[i].fname.c_str(), OPEN_FLAG_READ, &file->fhandle[i]); + file_error filerr = util::core_file::open(file->track_info.track[i].fname.c_str(), OPEN_FLAG_READ, file->fhandle[i]); if (filerr != FILERR_NONE) { fprintf(stderr, "Unable to open file: %s\n", file->track_info.track[i].fname.c_str()); @@ -418,7 +418,7 @@ void cdrom_close(cdrom_file *file) { for (int i = 0; i < file->cdtoc.numtrks; i++) { - core_fclose(file->fhandle[i]); + file->fhandle[i].reset(); } } @@ -474,7 +474,7 @@ chd_error read_partial_sector(cdrom_file *file, void *dest, UINT32 lbasector, UI else { // else read from the appropriate file - core_file *srcfile = file->fhandle[tracknum]; + util::core_file &srcfile = *file->fhandle[tracknum]; UINT64 sourcefileoffset = file->track_info.track[tracknum].offset; int bytespersector = file->cdtoc.tracks[tracknum].datasize + file->cdtoc.tracks[tracknum].subsize; @@ -483,8 +483,8 @@ chd_error read_partial_sector(cdrom_file *file, void *dest, UINT32 lbasector, UI // printf("Reading sector %d from track %d at offset %lld\n", chdsector, tracknum, sourcefileoffset); - core_fseek(srcfile, sourcefileoffset, SEEK_SET); - core_fread(srcfile, dest, length); + srcfile.seek(sourcefileoffset, SEEK_SET); + srcfile.read(dest, length); needswap = file->track_info.track[tracknum].swap; } diff --git a/src/lib/util/chd.cpp b/src/lib/util/chd.cpp index 3419f404c09..93a1b34ba29 100644 --- a/src/lib/util/chd.cpp +++ b/src/lib/util/chd.cpp @@ -190,8 +190,8 @@ inline void chd_file::file_read(UINT64 offset, void *dest, UINT32 length) throw CHDERR_NOT_OPEN; // seek and read - core_fseek(m_file, offset, SEEK_SET); - UINT32 count = core_fread(m_file, dest, length); + m_file->seek(offset, SEEK_SET); + UINT32 count = m_file->read(dest, length); if (count != length) throw CHDERR_READ_ERROR; } @@ -209,8 +209,8 @@ inline void chd_file::file_write(UINT64 offset, const void *source, UINT32 lengt throw CHDERR_NOT_OPEN; // seek and write - core_fseek(m_file, offset, SEEK_SET); - UINT32 count = core_fwrite(m_file, source, length); + m_file->seek(offset, SEEK_SET); + UINT32 count = m_file->write(source, length); if (count != length) throw CHDERR_WRITE_ERROR; } @@ -229,10 +229,10 @@ inline UINT64 chd_file::file_append(const void *source, UINT32 length, UINT32 al throw CHDERR_NOT_OPEN; // seek to the end and align if necessary - core_fseek(m_file, 0, SEEK_END); + m_file->seek(0, SEEK_END); if (alignment != 0) { - UINT64 offset = core_ftell(m_file); + UINT64 offset = m_file->tell(); UINT32 delta = offset % alignment; if (delta != 0) { @@ -243,7 +243,7 @@ inline UINT64 chd_file::file_append(const void *source, UINT32 length, UINT32 al while (delta != 0) { UINT32 bytes_to_write = MIN(sizeof(buffer), delta); - UINT32 count = core_fwrite(m_file, buffer, bytes_to_write); + UINT32 count = m_file->write(buffer, bytes_to_write); if (count != bytes_to_write) throw CHDERR_WRITE_ERROR; delta -= bytes_to_write; @@ -252,8 +252,8 @@ inline UINT64 chd_file::file_append(const void *source, UINT32 length, UINT32 al } // write the real data - UINT64 offset = core_ftell(m_file); - UINT32 count = core_fwrite(m_file, source, length); + UINT64 offset = m_file->tell(); + UINT32 count = m_file->write(source, length); if (count != length) throw CHDERR_READ_ERROR; return offset; @@ -567,7 +567,7 @@ void chd_file::set_parent_sha1(sha1_t parent) } /** - * @fn chd_error chd_file::create(core_file &file, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 unitbytes, chd_codec_type compression[4]) + * @fn chd_error chd_file::create(util::core_file &file, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 unitbytes, chd_codec_type compression[4]) * * @brief ------------------------------------------------- * create - create a new file with no parent using an existing opened file handle @@ -582,7 +582,7 @@ void chd_file::set_parent_sha1(sha1_t parent) * @return A chd_error. */ -chd_error chd_file::create(core_file &file, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 unitbytes, chd_codec_type compression[4]) +chd_error chd_file::create(util::core_file &file, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 unitbytes, chd_codec_type compression[4]) { // make sure we don't already have a file open if (m_file != nullptr) @@ -602,7 +602,7 @@ chd_error chd_file::create(core_file &file, UINT64 logicalbytes, UINT32 hunkbyte } /** - * @fn chd_error chd_file::create(core_file &file, UINT64 logicalbytes, UINT32 hunkbytes, chd_codec_type compression[4], chd_file &parent) + * @fn chd_error chd_file::create(util::core_file &file, UINT64 logicalbytes, UINT32 hunkbytes, chd_codec_type compression[4], chd_file &parent) * * @brief ------------------------------------------------- * create - create a new file with a parent using an existing opened file handle @@ -617,7 +617,7 @@ chd_error chd_file::create(core_file &file, UINT64 logicalbytes, UINT32 hunkbyte * @return A chd_error. */ -chd_error chd_file::create(core_file &file, UINT64 logicalbytes, UINT32 hunkbytes, chd_codec_type compression[4], chd_file &parent) +chd_error chd_file::create(util::core_file &file, UINT64 logicalbytes, UINT32 hunkbytes, chd_codec_type compression[4], chd_file &parent) { // make sure we don't already have a file open if (m_file != nullptr) @@ -659,21 +659,25 @@ chd_error chd_file::create(const char *filename, UINT64 logicalbytes, UINT32 hun return CHDERR_ALREADY_OPEN; // create the new file - core_file *file = nullptr; - file_error filerr = core_fopen(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &file); + util::core_file::ptr file; + const file_error filerr = util::core_file::open(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file); if (filerr != FILERR_NONE) return CHDERR_FILE_NOT_FOUND; // create the file normally, then claim the file - chd_error chderr = create(*file, logicalbytes, hunkbytes, unitbytes, compression); + const chd_error chderr = create(*file, logicalbytes, hunkbytes, unitbytes, compression); m_owns_file = true; // if an error happened, close and delete the file if (chderr != CHDERR_NONE) { - core_fclose(file); + file.reset(); osd_rmfile(filename); } + else + { + file.release(); + } return chderr; } @@ -700,21 +704,25 @@ chd_error chd_file::create(const char *filename, UINT64 logicalbytes, UINT32 hun return CHDERR_ALREADY_OPEN; // create the new file - core_file *file = nullptr; - file_error filerr = core_fopen(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &file); + util::core_file::ptr file; + const file_error filerr = util::core_file::open(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file); if (filerr != FILERR_NONE) return CHDERR_FILE_NOT_FOUND; // create the file normally, then claim the file - chd_error chderr = create(*file, logicalbytes, hunkbytes, compression, parent); + const chd_error chderr = create(*file, logicalbytes, hunkbytes, compression, parent); m_owns_file = true; // if an error happened, close and delete the file if (chderr != CHDERR_NONE) { - core_fclose(file); + file.reset(); osd_rmfile(filename); } + else + { + file.release(); + } return chderr; } @@ -739,27 +747,25 @@ chd_error chd_file::open(const char *filename, bool writeable, chd_file *parent) return CHDERR_ALREADY_OPEN; // open the file - UINT32 openflags = writeable ? (OPEN_FLAG_READ | OPEN_FLAG_WRITE) : OPEN_FLAG_READ; - core_file *file = nullptr; - file_error filerr = core_fopen(filename, openflags, &file); + const UINT32 openflags = writeable ? (OPEN_FLAG_READ | OPEN_FLAG_WRITE) : OPEN_FLAG_READ; + util::core_file::ptr file; + const file_error filerr = util::core_file::open(filename, openflags, file); if (filerr != FILERR_NONE) return CHDERR_FILE_NOT_FOUND; // now open the CHD chd_error err = open(*file, writeable, parent); if (err != CHDERR_NONE) - { - core_fclose(file); return err; - } // we now own this file + file.release(); m_owns_file = true; return err; } /** - * @fn chd_error chd_file::open(core_file &file, bool writeable, chd_file *parent) + * @fn chd_error chd_file::open(util::core_file &file, bool writeable, chd_file *parent) * * @brief ------------------------------------------------- * open - open an existing file for read or read/write @@ -772,7 +778,7 @@ chd_error chd_file::open(const char *filename, bool writeable, chd_file *parent) * @return A chd_error. */ -chd_error chd_file::open(core_file &file, bool writeable, chd_file *parent) +chd_error chd_file::open(util::core_file &file, bool writeable, chd_file *parent) { // make sure we don't already have a file open if (m_file != nullptr) @@ -796,8 +802,8 @@ chd_error chd_file::open(core_file &file, bool writeable, chd_file *parent) void chd_file::close() { // reset file characteristics - if (m_owns_file && m_file != nullptr) - core_fclose(m_file); + if (m_owns_file && m_file) + delete m_file; m_file = nullptr; m_owns_file = false; m_allow_reads = false; diff --git a/src/lib/util/chd.h b/src/lib/util/chd.h index d9a1dd57f51..ee8a03f5d17 100644 --- a/src/lib/util/chd.h +++ b/src/lib/util/chd.h @@ -304,7 +304,7 @@ public: virtual ~chd_file(); // operators - operator core_file *() { return m_file; } + operator util::core_file &() { return *m_file; } // getters bool opened() const { return (m_file != nullptr); } @@ -328,13 +328,13 @@ public: // file create chd_error create(const char *filename, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 unitbytes, chd_codec_type compression[4]); - chd_error create(core_file &file, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 unitbytes, chd_codec_type compression[4]); + chd_error create(util::core_file &file, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 unitbytes, chd_codec_type compression[4]); chd_error create(const char *filename, UINT64 logicalbytes, UINT32 hunkbytes, chd_codec_type compression[4], chd_file &parent); - chd_error create(core_file &file, UINT64 logicalbytes, UINT32 hunkbytes, chd_codec_type compression[4], chd_file &parent); + chd_error create(util::core_file &file, UINT64 logicalbytes, UINT32 hunkbytes, chd_codec_type compression[4], chd_file &parent); // file open chd_error open(const char *filename, bool writeable = false, chd_file *parent = nullptr); - chd_error open(core_file &file, bool writeable = false, chd_file *parent = nullptr); + chd_error open(util::core_file &file, bool writeable = false, chd_file *parent = nullptr); // file close void close(); @@ -401,7 +401,7 @@ private: static int CLIB_DECL metadata_hash_compare(const void *elem1, const void *elem2); // file characteristics - core_file * m_file; // handle to the open core file + util::core_file * m_file; // handle to the open core file bool m_owns_file; // flag indicating if this file should be closed on chd_close() bool m_allow_reads; // permit reads from this CHD? bool m_allow_writes; // permit writes to this CHD? diff --git a/src/lib/util/corefile.cpp b/src/lib/util/corefile.cpp index 25978afdb2c..e4eda2477d5 100644 --- a/src/lib/util/corefile.cpp +++ b/src/lib/util/corefile.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders:Aaron Giles, Vas Crabb /*************************************************************************** corefile.c @@ -14,11 +14,17 @@ #include "unicode.h" #include <zlib.h> -#include <stdarg.h> +#include <algorithm> +#include <cstdarg> +#include <cstring> #include <ctype.h> +namespace util { + +namespace { + /*************************************************************************** VALIDATION ***************************************************************************/ @@ -30,613 +36,510 @@ /*************************************************************************** - CONSTANTS -***************************************************************************/ - -#define FILE_BUFFER_SIZE 512 - -#define OPEN_FLAG_HAS_CRC 0x10000 - - - -/*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ -enum text_file_type -{ - TFT_OSD = 0, /* OSD depdendent encoding format used when BOMs missing */ - TFT_UTF8, /* UTF-8 */ - TFT_UTF16BE, /* UTF-16 (big endian) */ - TFT_UTF16LE, /* UTF-16 (little endian) */ - TFT_UTF32BE, /* UTF-32 (UCS-4) (big endian) */ - TFT_UTF32LE /* UTF-32 (UCS-4) (little endian) */ -}; - - -struct zlib_data -{ - z_stream stream; - UINT8 buffer[1024]; - UINT64 realoffset; - UINT64 nextoffset; -}; - - -struct core_file -{ - osd_file * file; /* OSD file handle */ - zlib_data * zdata; /* compression data */ - UINT32 openflags; /* flags we were opened with */ - UINT8 data_allocated; /* was the data allocated by us? */ - UINT8 * data; /* file data, if RAM-based */ - UINT64 offset; /* current file offset */ - UINT64 length; /* total file length */ - text_file_type text_type; /* text output format */ - char back_chars[UTF8_CHAR_MAX]; /* buffer to hold characters for ungetc */ - int back_char_head; /* head of ungetc buffer */ - int back_char_tail; /* tail of ungetc buffer */ - UINT64 bufferbase; /* base offset of internal buffer */ - UINT32 bufferbytes; /* bytes currently loaded into buffer */ - UINT8 buffer[FILE_BUFFER_SIZE]; /* buffer data */ -}; - - - -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -/* misc helpers */ -static UINT32 safe_buffer_copy(const void *source, UINT32 sourceoffs, UINT32 sourcelen, void *dest, UINT32 destoffs, UINT32 destlen); -static file_error osd_or_zlib_read(core_file *file, void *buffer, UINT64 offset, UINT32 length, UINT32 *actual); -static file_error osd_or_zlib_write(core_file *file, const void *buffer, UINT64 offset, UINT32 length, UINT32 *actual); - - - -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ - -/*------------------------------------------------- - is_directory_separator - is a given character - a directory separator? The following logic - works for most platforms --------------------------------------------------*/ - -static inline int is_directory_separator(char c) +class zlib_data { - return (c == '\\' || c == '/' || c == ':'); -} - +public: + typedef std::unique_ptr<zlib_data> ptr; + static int start_compression(int level, std::uint64_t offset, ptr &data) + { + ptr result(new zlib_data(offset)); + result->reset_output(); + auto const zerr = deflateInit(&result->m_stream, level); + result->m_compress = (Z_OK == zerr); + if (result->m_compress) data = std::move(result); + return zerr; + } + static int start_decompression(std::uint64_t offset, ptr &data) + { + ptr result(new zlib_data(offset)); + auto const zerr = inflateInit(&result->m_stream); + result->m_decompress = (Z_OK == zerr); + if (result->m_decompress) data = std::move(result); + return zerr; + } -/*************************************************************************** - FILE OPEN/CLOSE -***************************************************************************/ - -/*------------------------------------------------- - core_fopen - open a file for access and - return an error code --------------------------------------------------*/ + ~zlib_data() + { + if (m_compress) deflateEnd(&m_stream); + else if (m_decompress) inflateEnd(&m_stream); + } -file_error core_fopen(const char *filename, UINT32 openflags, core_file **file) -{ - file_error filerr = FILERR_NOT_FOUND; + std::size_t buffer_size() const { return sizeof(m_buffer); } + void const *buffer_data() const { return m_buffer; } + void *buffer_data() { return m_buffer; } - /* allocate the file itself */ - *file = (core_file *)malloc(sizeof(**file)); - if (*file == nullptr) - return FILERR_OUT_OF_MEMORY; - memset(*file, 0, sizeof(**file)); + // general-purpose output buffer manipulation + bool output_full() const { return 0 == m_stream.avail_out; } + std::size_t output_space() const { return m_stream.avail_out; } + void set_output(void *data, std::uint32_t size) + { + m_stream.next_out = reinterpret_cast<Bytef *>(data); + m_stream.avail_out = size; + } - /* attempt to open the file */ - filerr = osd_open(filename, openflags, &(*file)->file, &(*file)->length); - (*file)->openflags = openflags; + // working with output to the internal buffer + bool has_output() const { return m_stream.avail_out != sizeof(m_buffer); } + std::size_t output_size() const { return sizeof(m_buffer) - m_stream.avail_out; } + void reset_output() + { + m_stream.next_out = m_buffer; + m_stream.avail_out = sizeof(m_buffer); + } - /* handle errors and return */ - if (filerr != FILERR_NONE) + // general-purpose input buffer manipulation + bool has_input() const { return 0 != m_stream.avail_in; } + std::size_t input_size() const { return m_stream.avail_in; } + void set_input(void const *data, std::uint32_t size) { - core_fclose(*file); - *file = nullptr; + m_stream.next_in = const_cast<Bytef *>(reinterpret_cast<Bytef const *>(data)); + m_stream.avail_in = size; } - return filerr; -} + // working with input from the internal buffer + void reset_input(std::uint32_t size) + { + m_stream.next_in = m_buffer; + m_stream.avail_in = size; + } -/*------------------------------------------------- - core_fopen_ram_internal - open a RAM-based buffer - for file-like access, possibly copying the data, - and return an error code --------------------------------------------------*/ + int compress() { assert(m_compress); return deflate(&m_stream, Z_NO_FLUSH); } + int finalise() { assert(m_compress); return deflate(&m_stream, Z_FINISH); } + int decompress() { assert(m_decompress); return inflate(&m_stream, Z_SYNC_FLUSH); } -static file_error core_fopen_ram_internal(const void *data, size_t length, int copy_buffer, UINT32 openflags, core_file **file) -{ - /* can only do this for read access */ - if ((openflags & OPEN_FLAG_WRITE) != 0) - return FILERR_INVALID_ACCESS; - if ((openflags & OPEN_FLAG_CREATE) != 0) - return FILERR_INVALID_ACCESS; + std::uint64_t realoffset() const { return m_realoffset; } + void add_realoffset(std::uint32_t increment) { m_realoffset += increment; } - /* allocate the file itself */ - *file = (core_file *)malloc(sizeof(**file) + (copy_buffer ? length : 0)); - if (*file == nullptr) - return FILERR_OUT_OF_MEMORY; - memset(*file, 0, sizeof(**file)); + bool is_nextoffset(std::uint64_t value) const { return m_nextoffset == value; } + void add_nextoffset(std::uint32_t increment) { m_nextoffset += increment; } - /* copy the buffer, if we're asked to */ - if (copy_buffer) +private: + zlib_data(std::uint64_t offset) + : m_compress(false) + , m_decompress(false) + , m_realoffset(offset) + , m_nextoffset(offset) { - void *dest = ((UINT8 *) *file) + sizeof(**file); - memcpy(dest, data, length); - data = dest; + m_stream.zalloc = Z_NULL; + m_stream.zfree = Z_NULL; + m_stream.opaque = Z_NULL; } - /* claim the buffer */ - (*file)->data = (UINT8 *)data; - (*file)->length = length; - (*file)->openflags = openflags; - - return FILERR_NONE; -} - + bool m_compress, m_decompress; + z_stream m_stream; + std::uint8_t m_buffer[1024]; + std::uint64_t m_realoffset; + std::uint64_t m_nextoffset; +}; -/*------------------------------------------------- - core_fopen_ram - open a RAM-based buffer for - file-like access and return an error code --------------------------------------------------*/ -file_error core_fopen_ram(const void *data, size_t length, UINT32 openflags, core_file **file) +class core_proxy_file : public core_file { - return core_fopen_ram_internal(data, length, FALSE, openflags, file); -} +public: + core_proxy_file(core_file &file) : m_file(file) { } + virtual ~core_proxy_file() override { } + virtual file_error compress(int level) override { return m_file.compress(level); } + + virtual int seek(std::int64_t offset, int whence) override { return m_file.seek(offset, whence); } + virtual std::uint64_t tell() const override { return m_file.tell(); } + virtual bool eof() const override { return m_file.eof(); } + virtual std::uint64_t size() const override { return m_file.size(); } + + virtual std::uint32_t read(void *buffer, std::uint32_t length) override { return m_file.read(buffer, length); } + virtual int getc() override { return m_file.getc(); } + virtual int ungetc(int c) override { return m_file.ungetc(c); } + virtual char *gets(char *s, int n) override { return m_file.gets(s, n); } + virtual const void *buffer() override { return m_file.buffer(); } + + virtual std::uint32_t write(const void *buffer, std::uint32_t length) override { return m_file.write(buffer, length); } + virtual int puts(const char *s) override { return m_file.puts(s); } + virtual int vprintf(const char *fmt, va_list va) override { return m_file.vprintf(fmt, va); } + virtual file_error truncate(std::uint64_t offset) override { return m_file.truncate(offset); } + + virtual file_error flush() override { return m_file.flush(); } + +private: + core_file &m_file; +}; -/*------------------------------------------------- - core_fopen_ram_copy - open a copy of a RAM-based - buffer for file-like access and return an error code --------------------------------------------------*/ - -file_error core_fopen_ram_copy(const void *data, size_t length, UINT32 openflags, core_file **file) +class core_text_file : public core_file { - return core_fopen_ram_internal(data, length, TRUE, openflags, file); -} - +public: + enum class text_file_type + { + OSD, // OSD dependent encoding format used when BOMs missing + UTF8, // UTF-8 + UTF16BE, // UTF-16 (big endian) + UTF16LE, // UTF-16 (little endian) + UTF32BE, // UTF-32 (UCS-4) (big endian) + UTF32LE // UTF-32 (UCS-4) (little endian) + }; + + virtual int getc() override; + virtual int ungetc(int c) override; + virtual char *gets(char *s, int n) override; + virtual int puts(char const *s) override; + virtual int vprintf(char const *fmt, va_list va) override; + +protected: + core_text_file(std::uint32_t openflags) + : m_openflags(openflags) + , m_text_type(text_file_type::OSD) + , m_back_char_head(0) + , m_back_char_tail(0) + { + } -/*------------------------------------------------- - core_fclose - closes a file --------------------------------------------------*/ + bool read_access() const { return 0U != (m_openflags & OPEN_FLAG_READ); } + bool write_access() const { return 0U != (m_openflags & OPEN_FLAG_WRITE); } + bool no_bom() const { return 0U != (m_openflags & OPEN_FLAG_NO_BOM); } -void core_fclose(core_file *file) -{ - /* close files and free memory */ - if (file->zdata != nullptr) - core_fcompress(file, FCOMPRESS_NONE); - if (file->file != nullptr) - osd_close(file->file); - if (file->data != nullptr && file->data_allocated) - free(file->data); - free(file); -} + bool has_putback() const { return m_back_char_head != m_back_char_tail; } + void clear_putback() { m_back_char_head = m_back_char_tail = 0; } +private: + std::uint32_t const m_openflags; // flags we were opened with + text_file_type m_text_type; // text output format + char m_back_chars[UTF8_CHAR_MAX]; // buffer to hold characters for ungetc + int m_back_char_head; // head of ungetc buffer + int m_back_char_tail; // tail of ungetc buffer +}; -/*------------------------------------------------- - core_fcompress - enable/disable streaming file - compression via zlib; level is 0 to disable - compression, or up to 9 for max compression --------------------------------------------------*/ -file_error core_fcompress(core_file *file, int level) +class core_in_memory_file : public core_text_file { - file_error result = FILERR_NONE; - - /* can only do this for read-only and write-only cases */ - if ((file->openflags & OPEN_FLAG_WRITE) != 0 && (file->openflags & OPEN_FLAG_READ) != 0) - return FILERR_INVALID_ACCESS; - - /* if we have been compressing, flush and free the data */ - if (file->zdata != nullptr && level == FCOMPRESS_NONE) +public: + core_in_memory_file(std::uint32_t openflags, void const *data, std::size_t length, bool copy) + : core_text_file(openflags) + , m_data_allocated(false) + , m_data(copy ? nullptr : data) + , m_offset(0) + , m_length(length) { - int zerr = Z_OK; - - /* flush any remaining data if we are writing */ - while ((file->openflags & OPEN_FLAG_WRITE) != 0 && zerr != Z_STREAM_END) + if (copy) { - UINT32 actualdata; - file_error filerr; - - /* deflate some more */ - zerr = deflate(&file->zdata->stream, Z_FINISH); - if (zerr != Z_STREAM_END && zerr != Z_OK) - { - result = FILERR_INVALID_DATA; - break; - } - - /* write the data */ - if (file->zdata->stream.avail_out != sizeof(file->zdata->buffer)) - { - filerr = osd_write(file->file, file->zdata->buffer, file->zdata->realoffset, sizeof(file->zdata->buffer) - file->zdata->stream.avail_out, &actualdata); - if (filerr != FILERR_NONE) - break; - file->zdata->realoffset += actualdata; - file->zdata->stream.next_out = file->zdata->buffer; - file->zdata->stream.avail_out = sizeof(file->zdata->buffer); - } + void *const buf = allocate(); + if (buf) std::memcpy(buf, data, length); } + } - /* end the appropriate operation */ - if ((file->openflags & OPEN_FLAG_WRITE) != 0) - deflateEnd(&file->zdata->stream); - else - inflateEnd(&file->zdata->stream); + ~core_in_memory_file() override { purge(); } + virtual file_error compress(int level) override { return FILERR_INVALID_ACCESS; } - /* free memory */ - free(file->zdata); - file->zdata = nullptr; - } + virtual int seek(std::int64_t offset, int whence) override; + virtual std::uint64_t tell() const override { return m_offset; } + virtual bool eof() const override; + virtual std::uint64_t size() const override { return m_length; } - /* if we are just starting to compress, allocate a new buffer */ - if (file->zdata == nullptr && level > FCOMPRESS_NONE) - { - int zerr; + virtual std::uint32_t read(void *buffer, std::uint32_t length) override; + virtual void const *buffer() override { return m_data; } - /* allocate memory */ - file->zdata = (zlib_data *)malloc(sizeof(*file->zdata)); - if (file->zdata == nullptr) - return FILERR_OUT_OF_MEMORY; - memset(file->zdata, 0, sizeof(*file->zdata)); + virtual std::uint32_t write(void const *buffer, std::uint32_t length) override { return 0; } + virtual file_error truncate(std::uint64_t offset) override; + virtual file_error flush() override { clear_putback(); return FILERR_NONE; } - /* initialize the stream and compressor */ - if ((file->openflags & OPEN_FLAG_WRITE) != 0) - { - file->zdata->stream.next_out = file->zdata->buffer; - file->zdata->stream.avail_out = sizeof(file->zdata->buffer); - zerr = deflateInit(&file->zdata->stream, level); - } - else - zerr = inflateInit(&file->zdata->stream); +protected: + core_in_memory_file(std::uint32_t openflags, std::uint64_t length) + : core_text_file(openflags) + , m_data_allocated(false) + , m_data(nullptr) + , m_offset(0) + , m_length(length) + { + } - /* on error, return an error */ - if (zerr != Z_OK) + bool is_loaded() const { return nullptr != m_data; } + void *allocate() + { + if (m_data) return nullptr; + void *data = malloc(m_length); + if (data) { - free(file->zdata); - file->zdata = nullptr; - return FILERR_OUT_OF_MEMORY; + m_data_allocated = true; + m_data = data; } - - /* flush buffers */ - file->bufferbytes = 0; - - /* set the initial offset */ - file->zdata->realoffset = file->offset; - file->zdata->nextoffset = file->offset; + return data; + } + void purge() + { + if (m_data && m_data_allocated) free(const_cast<void *>(m_data)); + m_data_allocated = false; + m_data = nullptr; } - return result; -} - + std::uint64_t offset() const { return m_offset; } + void add_offset(std::uint32_t increment) { m_offset += increment; m_length = (std::max)(m_length, m_offset); } + std::uint64_t length() const { return m_length; } + void set_length(std::uint64_t value) { m_length = value; m_offset = (std::min)(m_offset, m_length); } + static std::size_t safe_buffer_copy( + void const *source, std::size_t sourceoffs, std::size_t sourcelen, + void *dest, std::size_t destoffs, std::size_t destlen); -/*************************************************************************** - FILE POSITIONING -***************************************************************************/ +private: + bool m_data_allocated; // was the data allocated by us? + void const * m_data; // file data, if RAM-based + std::uint64_t m_offset; // current file offset + std::uint64_t m_length; // total file length +}; -/*------------------------------------------------- - core_fseek - seek within a file --------------------------------------------------*/ -int core_fseek(core_file *file, INT64 offset, int whence) +class core_osd_file : public core_in_memory_file { - int err = 0; - - /* error if compressing */ - if (file->zdata != nullptr) - return 1; - - /* flush any buffered char */ - file->back_char_head = 0; - file->back_char_tail = 0; - - /* switch off the relative location */ - switch (whence) +public: + core_osd_file(std::uint32_t openmode, osd_file *file, std::uint64_t length) + : core_in_memory_file(openmode, length) + , m_file(file) + , m_zdata() + , m_bufferbase(0) + , m_bufferbytes(0) { - case SEEK_SET: - file->offset = offset; - break; - - case SEEK_CUR: - file->offset += offset; - break; - - case SEEK_END: - file->offset = file->length + offset; - break; } - return err; -} + ~core_osd_file() override; + virtual file_error compress(int level) override; -/*------------------------------------------------- - core_ftell - return the current file position --------------------------------------------------*/ - -UINT64 core_ftell(core_file *file) -{ - /* return the current offset */ - return file->offset; -} + virtual int seek(std::int64_t offset, int whence) override; + virtual std::uint32_t read(void *buffer, std::uint32_t length) override; + virtual void const *buffer() override; -/*------------------------------------------------- - core_feof - return 1 if we're at the end - of file --------------------------------------------------*/ + virtual std::uint32_t write(void const *buffer, std::uint32_t length) override; + virtual file_error truncate(std::uint64_t offset) override; + virtual file_error flush() override; -int core_feof(core_file *file) -{ - /* check for buffered chars */ - if (file->back_char_head != file->back_char_tail) - return 0; +protected: - /* if the offset == length, we're at EOF */ - return (file->offset >= file->length); -} + bool is_buffered() const { return (offset() >= m_bufferbase) && (offset() < (m_bufferbase + m_bufferbytes)); } +private: + static constexpr std::size_t FILE_BUFFER_SIZE = 512; -/*------------------------------------------------- - core_fsize - returns the size of a file --------------------------------------------------*/ + file_error osd_or_zlib_read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual); + file_error osd_or_zlib_write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual); -UINT64 core_fsize(core_file *file) -{ - return file->length; -} + osd_file * m_file; // OSD file handle + zlib_data::ptr m_zdata; // compression data + std::uint64_t m_bufferbase; // base offset of internal buffer + std::uint32_t m_bufferbytes; // bytes currently loaded into buffer + std::uint8_t m_buffer[FILE_BUFFER_SIZE]; // buffer data +}; /*************************************************************************** - FILE READ + INLINE FUNCTIONS ***************************************************************************/ /*------------------------------------------------- - core_fread - read from a file + is_directory_separator - is a given character + a directory separator? The following logic + works for most platforms -------------------------------------------------*/ -UINT32 core_fread(core_file *file, void *buffer, UINT32 length) +static inline int is_directory_separator(char c) { - UINT32 bytes_read = 0; - - /* flush any buffered char */ - file->back_char_head = 0; - file->back_char_tail = 0; - - /* handle real files */ - if (file->file && file->data == nullptr) - { - /* if we're within the buffer, consume that first */ - if (file->offset >= file->bufferbase && file->offset < file->bufferbase + file->bufferbytes) - bytes_read += safe_buffer_copy(file->buffer, file->offset - file->bufferbase, file->bufferbytes, buffer, bytes_read, length); - - /* if we've got a small amount left, read it into the buffer first */ - if (bytes_read < length) - { - if (length - bytes_read < sizeof(file->buffer) / 2) - { - /* read as much as makes sense into the buffer */ - file->bufferbase = file->offset + bytes_read; - file->bufferbytes = 0; - osd_or_zlib_read(file, file->buffer, file->bufferbase, sizeof(file->buffer), &file->bufferbytes); - - /* do a bounded copy from the buffer to the destination */ - bytes_read += safe_buffer_copy(file->buffer, 0, file->bufferbytes, buffer, bytes_read, length); - } + return (c == '\\' || c == '/' || c == ':'); +} - /* read the remainder directly from the file */ - else - { - UINT32 new_bytes_read = 0; - osd_or_zlib_read(file, (UINT8 *)buffer + bytes_read, file->offset + bytes_read, length - bytes_read, &new_bytes_read); - bytes_read += new_bytes_read; - } - } - } - /* handle RAM-based files */ - else - bytes_read += safe_buffer_copy(file->data, (UINT32)file->offset, file->length, buffer, bytes_read, length); - - /* return the number of bytes read */ - file->offset += bytes_read; - return bytes_read; -} +/*************************************************************************** + core_text_file +***************************************************************************/ /*------------------------------------------------- - core_fgetc - read a character from a file + getc - read a character from a file -------------------------------------------------*/ -int core_fgetc(core_file *file) +int core_text_file::getc() { int result; - /* refresh buffer, if necessary */ - if (file->back_char_head == file->back_char_tail) + // refresh buffer, if necessary + if (m_back_char_head == m_back_char_tail) { - utf16_char utf16_buffer[UTF16_CHAR_MAX]; - char utf8_buffer[UTF8_CHAR_MAX]; - char default_buffer[16]; - unicode_char uchar = (unicode_char) ~0; - int readlen, charlen; - - /* do we need to check the byte order marks? */ - if (file->offset == 0) + // do we need to check the byte order marks? + if (tell() == 0) { - UINT8 bom[4]; + std::uint8_t bom[4]; int pos = 0; - if (core_fread(file, bom, 4) == 4) + if (read(bom, 4) == 4) { if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf) { - file->text_type = TFT_UTF8; + m_text_type = text_file_type::UTF8; pos = 3; } else if (bom[0] == 0x00 && bom[1] == 0x00 && bom[2] == 0xfe && bom[3] == 0xff) { - file->text_type = TFT_UTF32BE; + m_text_type = text_file_type::UTF32BE; pos = 4; } else if (bom[0] == 0xff && bom[1] == 0xfe && bom[2] == 0x00 && bom[3] == 0x00) { - file->text_type = TFT_UTF32LE; + m_text_type = text_file_type::UTF32LE; pos = 4; } else if (bom[0] == 0xfe && bom[1] == 0xff) { - file->text_type = TFT_UTF16BE; + m_text_type = text_file_type::UTF16BE; pos = 2; } else if (bom[0] == 0xff && bom[1] == 0xfe) { - file->text_type = TFT_UTF16LE; + m_text_type = text_file_type::UTF16LE; pos = 2; } else { - file->text_type = TFT_OSD; + m_text_type = text_file_type::OSD; pos = 0; } } - core_fseek(file, pos, SEEK_SET); + seek(pos, SEEK_SET); } - /* fetch the next character */ - switch (file->text_type) + // fetch the next character + utf16_char utf16_buffer[UTF16_CHAR_MAX]; + unicode_char uchar = unicode_char(~0); + switch (m_text_type) { - default: - case TFT_OSD: - readlen = core_fread(file, default_buffer, sizeof(default_buffer)); + default: + case text_file_type::OSD: + { + char default_buffer[16]; + auto const readlen = read(default_buffer, sizeof(default_buffer)); if (readlen > 0) { - charlen = osd_uchar_from_osdchar(&uchar, default_buffer, readlen / sizeof(default_buffer[0])); - core_fseek(file, (INT64) (charlen * sizeof(default_buffer[0])) - readlen, SEEK_CUR); + auto const charlen = osd_uchar_from_osdchar(&uchar, default_buffer, readlen / sizeof(default_buffer[0])); + seek(std::int64_t(charlen * sizeof(default_buffer[0])) - readlen, SEEK_CUR); } - break; + } + break; - case TFT_UTF8: - readlen = core_fread(file, utf8_buffer, sizeof(utf8_buffer)); + case text_file_type::UTF8: + { + char utf8_buffer[UTF8_CHAR_MAX]; + auto const readlen = read(utf8_buffer, sizeof(utf8_buffer)); if (readlen > 0) { - charlen = uchar_from_utf8(&uchar, utf8_buffer, readlen / sizeof(utf8_buffer[0])); - core_fseek(file, (INT64) (charlen * sizeof(utf8_buffer[0])) - readlen, SEEK_CUR); + auto const charlen = uchar_from_utf8(&uchar, utf8_buffer, readlen / sizeof(utf8_buffer[0])); + seek(std::int64_t(charlen * sizeof(utf8_buffer[0])) - readlen, SEEK_CUR); } - break; + } + break; - case TFT_UTF16BE: - readlen = core_fread(file, utf16_buffer, sizeof(utf16_buffer)); + case text_file_type::UTF16BE: + { + auto const readlen = read(utf16_buffer, sizeof(utf16_buffer)); if (readlen > 0) { - charlen = uchar_from_utf16be(&uchar, utf16_buffer, readlen / sizeof(utf16_buffer[0])); - core_fseek(file, (INT64) (charlen * sizeof(utf16_buffer[0])) - readlen, SEEK_CUR); + auto const charlen = uchar_from_utf16be(&uchar, utf16_buffer, readlen / sizeof(utf16_buffer[0])); + seek(std::int64_t(charlen * sizeof(utf16_buffer[0])) - readlen, SEEK_CUR); } - break; + } + break; - case TFT_UTF16LE: - readlen = core_fread(file, utf16_buffer, sizeof(utf16_buffer)); + case text_file_type::UTF16LE: + { + auto const readlen = read(utf16_buffer, sizeof(utf16_buffer)); if (readlen > 0) { - charlen = uchar_from_utf16le(&uchar, utf16_buffer, readlen / sizeof(utf16_buffer[0])); - core_fseek(file, (INT64) (charlen * sizeof(utf16_buffer[0])) - readlen, SEEK_CUR); + auto const charlen = uchar_from_utf16le(&uchar, utf16_buffer, readlen / sizeof(utf16_buffer[0])); + seek(std::int64_t(charlen * sizeof(utf16_buffer[0])) - readlen, SEEK_CUR); } - break; + } + break; - case TFT_UTF32BE: - if (core_fread(file, &uchar, sizeof(uchar)) == sizeof(uchar)) - uchar = BIG_ENDIANIZE_INT32(uchar); - break; + case text_file_type::UTF32BE: + if (read(&uchar, sizeof(uchar)) == sizeof(uchar)) + uchar = BIG_ENDIANIZE_INT32(uchar); + break; - case TFT_UTF32LE: - if (core_fread(file, &uchar, sizeof(uchar)) == sizeof(uchar)) - uchar = LITTLE_ENDIANIZE_INT32(uchar); - break; + case text_file_type::UTF32LE: + if (read(&uchar, sizeof(uchar)) == sizeof(uchar)) + uchar = LITTLE_ENDIANIZE_INT32(uchar); + break; } if (uchar != ~0) { - /* place the new character in the ring buffer */ - file->back_char_head = 0; - file->back_char_tail = utf8_from_uchar(file->back_chars, ARRAY_LENGTH(file->back_chars), uchar); -/* assert(file->back_char_tail != -1);*/ + // place the new character in the ring buffer + m_back_char_head = 0; + m_back_char_tail = utf8_from_uchar(m_back_chars, ARRAY_LENGTH(m_back_chars), uchar); + //assert(file->back_char_tail != -1); } } - /* now read from the ring buffer */ - if (file->back_char_head != file->back_char_tail) + // now read from the ring buffer + if (m_back_char_head == m_back_char_tail) + result = EOF; + else { - result = file->back_chars[file->back_char_head++]; - file->back_char_head %= ARRAY_LENGTH(file->back_chars); + result = m_back_chars[m_back_char_head++]; + m_back_char_head %= ARRAY_LENGTH(m_back_chars); } - else - result = EOF; return result; } /*------------------------------------------------- - core_ungetc - put back a character read from - a file + ungetc - put back a character read from a + file -------------------------------------------------*/ -int core_ungetc(int c, core_file *file) +int core_text_file::ungetc(int c) { - file->back_chars[file->back_char_tail++] = (char) c; - file->back_char_tail %= ARRAY_LENGTH(file->back_chars); + m_back_chars[m_back_char_tail++] = char(c); + m_back_char_tail %= ARRAY_LENGTH(m_back_chars); return c; } /*------------------------------------------------- - core_fgets - read a line from a text file + gets - read a line from a text file -------------------------------------------------*/ -char *core_fgets(char *s, int n, core_file *file) +char *core_text_file::gets(char *s, int n) { char *cur = s; - /* loop while we have characters */ + // loop while we have characters while (n > 0) { - int c = core_fgetc(file); + int const c = getc(); if (c == EOF) break; - - /* if there's a CR, look for an LF afterwards */ - if (c == 0x0d) + else if (c == 0x0d) // if there's a CR, look for an LF afterwards { - int c2 = core_fgetc(file); + int const c2 = getc(); if (c2 != 0x0a) - core_ungetc(c2, file); + ungetc(c2); *cur++ = 0x0d; n--; break; } - - /* if there's an LF, reinterp as a CR for consistency */ - else if (c == 0x0a) + else if (c == 0x0a) // if there's an LF, reinterp as a CR for consistency { *cur++ = 0x0d; n--; break; } - - /* otherwise, pop the character in and continue */ - *cur++ = c; - n--; + else // otherwise, pop the character in and continue + { + *cur++ = c; + n--; + } } - /* if we put nothing in, return NULL */ + // if we put nothing in, return NULL if (cur == s) return nullptr; @@ -648,335 +551,412 @@ char *core_fgets(char *s, int n, core_file *file) /*------------------------------------------------- - core_fbuffer - return a pointer to the file - buffer; if it doesn't yet exist, load the - file into RAM first + puts - write a line to a text file -------------------------------------------------*/ -const void *core_fbuffer(core_file *file) +int core_text_file::puts(char const *s) { - file_error filerr; - UINT32 read_length; - - /* if we already have data, just return it */ - if (file->data != nullptr || !file->length) - return file->data; + char convbuf[1024]; + char *pconvbuf = convbuf; + int count = 0; - /* allocate some memory */ - file->data = (UINT8 *)malloc(file->length); - if (file->data == nullptr) - return nullptr; - file->data_allocated = TRUE; + // is this the beginning of the file? if so, write a byte order mark + if (tell() == 0 && !no_bom()) + { + *pconvbuf++ = char(0xef); + *pconvbuf++ = char(0xbb); + *pconvbuf++ = char(0xbf); + } - /* read the file */ - filerr = osd_or_zlib_read(file, file->data, 0, file->length, &read_length); - if (filerr != FILERR_NONE || read_length != file->length) + // convert '\n' to platform dependant line endings + while (*s != '\0') { - free(file->data); - file->data = nullptr; - return nullptr; + if (*s == '\n') + { + if (CRLF == 1) // CR only + *pconvbuf++ = 13; + else if (CRLF == 2) // LF only + *pconvbuf++ = 10; + else if (CRLF == 3) // CR+LF + { + *pconvbuf++ = 13; + *pconvbuf++ = 10; + } + } + else + *pconvbuf++ = *s; + s++; + + // if we overflow, break into chunks + if (pconvbuf >= convbuf + ARRAY_LENGTH(convbuf) - 10) + { + count += write(convbuf, pconvbuf - convbuf); + pconvbuf = convbuf; + } } - /* close the file because we don't need it anymore */ - osd_close(file->file); - file->file = nullptr; - return file->data; + // final flush + if (pconvbuf != convbuf) + count += write(convbuf, pconvbuf - convbuf); + + return count; } /*------------------------------------------------- - core_fload - open a file with the specified - filename, read it into memory, and return a - pointer + vprintf - vfprintf to a text file -------------------------------------------------*/ -file_error core_fload(const char *filename, void **data, UINT32 *length) +int core_text_file::vprintf(char const *fmt, va_list va) { - core_file *file = nullptr; - file_error err; - UINT64 size; + char buf[1024]; + vsnprintf(buf, sizeof(buf), fmt, va); + return puts(buf); +} - /* attempt to open the file */ - err = core_fopen(filename, OPEN_FLAG_READ, &file); - if (err != FILERR_NONE) - return err; - /* get the size */ - size = core_fsize(file); - if ((UINT32)size != size) - { - core_fclose(file); - return FILERR_OUT_OF_MEMORY; - } - /* allocate memory */ - *data = osd_malloc(size); - if (length != nullptr) - *length = (UINT32)size; +/*************************************************************************** + core_in_memory_file +***************************************************************************/ - /* read the data */ - if (core_fread(file, *data, size) != size) +/*------------------------------------------------- + seek - seek within a file +-------------------------------------------------*/ + +int core_in_memory_file::seek(std::int64_t offset, int whence) +{ + // flush any buffered char + clear_putback(); + + // switch off the relative location + switch (whence) { - core_fclose(file); - free(*data); - return FILERR_FAILURE; + case SEEK_SET: + m_offset = offset; + break; + + case SEEK_CUR: + m_offset += offset; + break; + + case SEEK_END: + m_offset = m_length + offset; + break; } + return 0; +} - /* close the file and return data */ - core_fclose(file); - return FILERR_NONE; + +/*------------------------------------------------- + eof - return 1 if we're at the end of file +-------------------------------------------------*/ + +bool core_in_memory_file::eof() const +{ + // check for buffered chars + if (has_putback()) + return 0; + + // if the offset == length, we're at EOF + return (m_offset >= m_length); } -file_error core_fload(const char *filename, dynamic_buffer &data) + +/*------------------------------------------------- + read - read from a file +-------------------------------------------------*/ + +std::uint32_t core_in_memory_file::read(void *buffer, std::uint32_t length) { - core_file *file = nullptr; - file_error err; - UINT64 size; + clear_putback(); - /* attempt to open the file */ - err = core_fopen(filename, OPEN_FLAG_READ, &file); - if (err != FILERR_NONE) - return err; + // handle RAM-based files + auto const bytes_read = safe_buffer_copy(m_data, std::size_t(m_offset), std::size_t(m_length), buffer, 0, length); + m_offset += bytes_read; + return bytes_read; +} - /* get the size */ - size = core_fsize(file); - if ((UINT32)size != size) - { - core_fclose(file); - return FILERR_OUT_OF_MEMORY; - } - /* allocate memory */ - data.resize(size); +/*------------------------------------------------- + truncate - truncate a file +-------------------------------------------------*/ - /* read the data */ - if (core_fread(file, &data[0], size) != size) - { - core_fclose(file); - data.clear(); +file_error core_in_memory_file::truncate(std::uint64_t offset) +{ + if (m_length < offset) return FILERR_FAILURE; - } - /* close the file and return data */ - core_fclose(file); + // adjust to new length and offset + set_length(offset); return FILERR_NONE; } - -/*************************************************************************** - FILE WRITE -***************************************************************************/ - /*------------------------------------------------- - core_fwrite - write to a file + safe_buffer_copy - copy safely from one + bounded buffer to another -------------------------------------------------*/ -UINT32 core_fwrite(core_file *file, const void *buffer, UINT32 length) +std::size_t core_in_memory_file::safe_buffer_copy( + void const *source, std::size_t sourceoffs, std::size_t sourcelen, + void *dest, std::size_t destoffs, std::size_t destlen) { - UINT32 bytes_written = 0; + auto const sourceavail = sourcelen - sourceoffs; + auto const destavail = destlen - destoffs; + auto const bytes_to_copy = (std::min)(sourceavail, destavail); + if (bytes_to_copy > 0) + { + std::memcpy( + reinterpret_cast<std::uint8_t *>(dest) + destoffs, + reinterpret_cast<std::uint8_t const *>(source) + sourceoffs, + bytes_to_copy); + } + return bytes_to_copy; +} - /* can't write to RAM-based stuff */ - if (file->data != nullptr) - return 0; - /* flush any buffered char */ - file->back_char_head = 0; - file->back_char_tail = 0; - /* invalidate any buffered data */ - file->bufferbytes = 0; +/*************************************************************************** + core_osd_file +***************************************************************************/ - /* do the write */ - osd_or_zlib_write(file, buffer, file->offset, length, &bytes_written); +/*------------------------------------------------- + closes a file +-------------------------------------------------*/ - /* return the number of bytes read */ - file->offset += bytes_written; - file->length = MAX(file->length, file->offset); - return bytes_written; +core_osd_file::~core_osd_file() +{ + // close files and free memory + if (m_zdata) + compress(FCOMPRESS_NONE); + if (m_file) + osd_close(m_file); } /*------------------------------------------------- - core_fputs - write a line to a text file + compress - enable/disable streaming file + compression via zlib; level is 0 to disable + compression, or up to 9 for max compression -------------------------------------------------*/ -int core_fputs(core_file *f, const char *s) +file_error core_osd_file::compress(int level) { - char convbuf[1024]; - char *pconvbuf = convbuf; - int count = 0; + file_error result = FILERR_NONE; - /* is this the beginning of the file? if so, write a byte order mark */ - if (f->offset == 0 && !(f->openflags & OPEN_FLAG_NO_BOM)) - { - *pconvbuf++ = (char)0xef; - *pconvbuf++ = (char)0xbb; - *pconvbuf++ = (char)0xbf; - } + // can only do this for read-only and write-only cases + if (read_access() && write_access()) + return FILERR_INVALID_ACCESS; - /* convert '\n' to platform dependant line endings */ - while (*s != 0) + // if we have been compressing, flush and free the data + if (m_zdata && (level == FCOMPRESS_NONE)) { - if (*s == '\n') + int zerr = Z_OK; + + // flush any remaining data if we are writing + while (write_access() != 0 && (zerr != Z_STREAM_END)) { - if (CRLF == 1) /* CR only */ - *pconvbuf++ = 13; - else if (CRLF == 2) /* LF only */ - *pconvbuf++ = 10; - else if (CRLF == 3) /* CR+LF */ + // deflate some more + zerr = m_zdata->finalise(); + if (zerr != Z_STREAM_END && zerr != Z_OK) { - *pconvbuf++ = 13; - *pconvbuf++ = 10; + result = FILERR_INVALID_DATA; + break; } - } - else - *pconvbuf++ = *s; - s++; - /* if we overflow, break into chunks */ - if (pconvbuf >= convbuf + ARRAY_LENGTH(convbuf) - 10) - { - count += core_fwrite(f, convbuf, pconvbuf - convbuf); - pconvbuf = convbuf; + // write the data + if (m_zdata->has_output()) + { + std::uint32_t actualdata; + auto const filerr = osd_write(m_file, m_zdata->buffer_data(), m_zdata->realoffset(), m_zdata->output_size(), &actualdata); + if (filerr != FILERR_NONE) + break; + m_zdata->add_realoffset(actualdata); + m_zdata->reset_output(); + } } + + // free memory + m_zdata.reset(); } - /* final flush */ - if (pconvbuf != convbuf) - count += core_fwrite(f, convbuf, pconvbuf - convbuf); + // if we are just starting to compress, allocate a new buffer + if (!m_zdata && (level > FCOMPRESS_NONE)) + { + int zerr; - return count; -} + // initialize the stream and compressor + if (write_access()) + zerr = zlib_data::start_compression(level, offset(), m_zdata); + else + zerr = zlib_data::start_decompression(offset(), m_zdata); + // on error, return an error + if (zerr != Z_OK) + return FILERR_OUT_OF_MEMORY; -/*------------------------------------------------- - core_vfprintf - vfprintf to a text file --------------------------------------------------*/ + // flush buffers + m_bufferbytes = 0; + } -int core_vfprintf(core_file *f, const char *fmt, va_list va) -{ - char buf[1024]; - vsnprintf(buf, sizeof(buf), fmt, va); - return core_fputs(f, buf); + return result; } /*------------------------------------------------- - core_fprintf - vfprintf to a text file + seek - seek within a file -------------------------------------------------*/ -int CLIB_DECL core_fprintf(core_file *f, const char *fmt, ...) +int core_osd_file::seek(std::int64_t offset, int whence) { - int rc; - va_list va; - va_start(va, fmt); - rc = core_vfprintf(f, fmt, va); - va_end(va); - return rc; + // error if compressing + if (m_zdata) + return 1; + else + return core_in_memory_file::seek(offset, whence); } /*------------------------------------------------- - core_truncate - truncate a file + read - read from a file -------------------------------------------------*/ -file_error core_truncate(core_file *f, UINT64 offset) +std::uint32_t core_osd_file::read(void *buffer, std::uint32_t length) { - file_error err; + if (!m_file || is_loaded()) + return core_in_memory_file::read(buffer, length); - /* truncate file */ - err = osd_truncate(f->file, offset); - if (err != FILERR_NONE) - return err; + // flush any buffered char + clear_putback(); - /* and adjust to new length and offset */ - f->length = offset; - f->offset = MIN(f->offset, f->length); + std::uint32_t bytes_read = 0; - return FILERR_NONE; + // if we're within the buffer, consume that first + if (is_buffered()) + bytes_read += safe_buffer_copy(m_buffer, offset() - m_bufferbase, m_bufferbytes, buffer, bytes_read, length); + + // if we've got a small amount left, read it into the buffer first + if (bytes_read < length) + { + if ((length - bytes_read) < (sizeof(m_buffer) / 2)) + { + // read as much as makes sense into the buffer + m_bufferbase = offset() + bytes_read; + m_bufferbytes = 0; + osd_or_zlib_read(m_buffer, m_bufferbase, sizeof(m_buffer), m_bufferbytes); + + // do a bounded copy from the buffer to the destination + bytes_read += safe_buffer_copy(m_buffer, 0, m_bufferbytes, buffer, bytes_read, length); + } + else + { + // read the remainder directly from the file + std::uint32_t new_bytes_read = 0; + osd_or_zlib_read(reinterpret_cast<std::uint8_t *>(buffer) + bytes_read, offset() + bytes_read, length - bytes_read, new_bytes_read); + bytes_read += new_bytes_read; + } + } + + // return the number of bytes read + add_offset(bytes_read); + return bytes_read; } /*------------------------------------------------- - core_truncate - flush write buffer + buffer - return a pointer to the file buffer; + if it doesn't yet exist, load the file into + RAM first -------------------------------------------------*/ -file_error core_fflush(core_file *f) +void const *core_osd_file::buffer() { - return osd_fflush(f->file); + // if we already have data, just return it + if (!is_loaded() && length()) + { + // allocate some memory + void *buf = allocate(); + if (!buf) return nullptr; + + // read the file + std::uint32_t read_length = 0; + auto const filerr = osd_or_zlib_read(buf, 0, length(), read_length); + if ((filerr != FILERR_NONE) || (read_length != length())) + purge(); + else + { + // close the file because we don't need it anymore + osd_close(m_file); + m_file = nullptr; + } + } + return core_in_memory_file::buffer(); } - -/*************************************************************************** - FILENAME UTILITIES -***************************************************************************/ - /*------------------------------------------------- - core_filename_extract_base - extract the base - name from a filename; note that this makes - assumptions about path separators + write - write to a file -------------------------------------------------*/ -std::string core_filename_extract_base(const char *name, bool strip_extension) +std::uint32_t core_osd_file::write(void const *buffer, std::uint32_t length) { - /* find the start of the name */ - const char *start = name + strlen(name); - while (start > name && !is_directory_separator(start[-1])) - start--; + // can't write to RAM-based stuff + if (is_loaded()) + return core_in_memory_file::write(buffer, length); - /* copy the rest into an astring */ - std::string result(start); + // flush any buffered char + clear_putback(); - /* chop the extension if present */ - if (strip_extension) - result = result.substr(0, result.find_last_of('.')); - return result; + // invalidate any buffered data + m_bufferbytes = 0; + + // do the write + std::uint32_t bytes_written = 0; + osd_or_zlib_write(buffer, offset(), length, bytes_written); + + // return the number of bytes written + add_offset(bytes_written); + return bytes_written; } /*------------------------------------------------- - core_filename_ends_with - does the given - filename end with the specified extension? + truncate - truncate a file -------------------------------------------------*/ -int core_filename_ends_with(const char *filename, const char *extension) +file_error core_osd_file::truncate(std::uint64_t offset) { - int namelen = strlen(filename); - int extlen = strlen(extension); - int matches = TRUE; + if (is_loaded()) + return core_in_memory_file::truncate(offset); - /* work backwards checking for a match */ - while (extlen > 0) - if (tolower((UINT8)filename[--namelen]) != tolower((UINT8)extension[--extlen])) - { - matches = FALSE; - break; - } + // truncate file + auto const err = osd_truncate(m_file, offset); + if (err != FILERR_NONE) + return err; - return matches; + // and adjust to new length and offset + set_length(offset); + return FILERR_NONE; } - -/*************************************************************************** - MISC HELPERS -***************************************************************************/ - /*------------------------------------------------- - safe_buffer_copy - copy safely from one - bounded buffer to another + flush - flush file buffers -------------------------------------------------*/ -static UINT32 safe_buffer_copy(const void *source, UINT32 sourceoffs, UINT32 sourcelen, void *dest, UINT32 destoffs, UINT32 destlen) +file_error core_osd_file::flush() { - UINT32 sourceavail = sourcelen - sourceoffs; - UINT32 destavail = destlen - destoffs; - UINT32 bytes_to_copy = MIN(sourceavail, destavail); - if (bytes_to_copy > 0) - memcpy((UINT8 *)dest + destoffs, (const UINT8 *)source + sourceoffs, bytes_to_copy); - return bytes_to_copy; + if (is_loaded()) + return core_in_memory_file::flush(); + + // flush any buffered char + clear_putback(); + + // invalidate any buffered data + m_bufferbytes = 0; + + return osd_fflush(m_file); } @@ -985,50 +965,47 @@ static UINT32 safe_buffer_copy(const void *source, UINT32 sourceoffs, UINT32 sou handles zlib-compressed data -------------------------------------------------*/ -static file_error osd_or_zlib_read(core_file *file, void *buffer, UINT64 offset, UINT32 length, UINT32 *actual) +file_error core_osd_file::osd_or_zlib_read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) { - /* if no compression, just pass through */ - if (file->zdata == nullptr) - return osd_read(file->file, buffer, offset, length, actual); + // if no compression, just pass through + if (!m_zdata) + return osd_read(m_file, buffer, offset, length, &actual); - /* if the offset doesn't match the next offset, fail */ - if (offset != file->zdata->nextoffset) + // if the offset doesn't match the next offset, fail + if (m_zdata->is_nextoffset(offset)) return FILERR_INVALID_ACCESS; - /* set up the destination */ - file->zdata->stream.next_out = (Bytef *)buffer; - file->zdata->stream.avail_out = length; - while (file->zdata->stream.avail_out != 0) + // set up the destination + m_zdata->set_output(buffer, length); + while (!m_zdata->output_full()) { - file_error filerr; - UINT32 actualdata; int zerr = Z_OK; - /* if we didn't make progress, report an error or the end */ - if (file->zdata->stream.avail_in != 0) - zerr = inflate(&file->zdata->stream, Z_SYNC_FLUSH); + // if we didn't make progress, report an error or the end + if (m_zdata->has_input()) + zerr = m_zdata->decompress(); if (zerr != Z_OK) { - *actual = length - file->zdata->stream.avail_out; - file->zdata->nextoffset += *actual; + actual = length - m_zdata->output_space(); + m_zdata->add_nextoffset(actual); return (zerr == Z_STREAM_END) ? FILERR_NONE : FILERR_INVALID_DATA; } - /* fetch more data if needed */ - if (file->zdata->stream.avail_in == 0) + // fetch more data if needed + if (!m_zdata->has_input()) { - filerr = osd_read(file->file, file->zdata->buffer, file->zdata->realoffset, sizeof(file->zdata->buffer), &actualdata); + std::uint32_t actualdata; + auto const filerr = osd_read(m_file, m_zdata->buffer_data(), m_zdata->realoffset(), m_zdata->buffer_size(), &actualdata); if (filerr != FILERR_NONE) return filerr; - file->zdata->realoffset += actualdata; - file->zdata->stream.next_in = file->zdata->buffer; - file->zdata->stream.avail_in = sizeof(file->zdata->buffer); + m_zdata->add_realoffset(actual); + m_zdata->reset_input(actualdata); } } - /* we read everything */ - *actual = length; - file->zdata->nextoffset += *actual; + // we read everything + actual = length; + m_zdata->add_nextoffset(actual); return FILERR_NONE; } @@ -1039,61 +1016,307 @@ static file_error osd_or_zlib_read(core_file *file, void *buffer, UINT64 offset, -------------------------------------------------*/ /** - * @fn static file_error osd_or_zlib_write(core_file *file, const void *buffer, UINT64 offset, UINT32 length, UINT32 *actual) + * @fn file_error osd_or_zlib_write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t actual) * * @brief OSD or zlib write. * - * @param [in,out] file If non-null, the file. * @param buffer The buffer. * @param offset The offset. * @param length The length. - * @param [in,out] actual If non-null, the actual. + * @param [in,out] actual The actual. * * @return A file_error. */ -static file_error osd_or_zlib_write(core_file *file, const void *buffer, UINT64 offset, UINT32 length, UINT32 *actual) +file_error core_osd_file::osd_or_zlib_write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) { - /* if no compression, just pass through */ - if (file->zdata == nullptr) - return osd_write(file->file, buffer, offset, length, actual); + // if no compression, just pass through + if (!m_zdata) + return osd_write(m_file, buffer, offset, length, &actual); - /* if the offset doesn't match the next offset, fail */ - if (offset != file->zdata->nextoffset) + // if the offset doesn't match the next offset, fail + if (!m_zdata->is_nextoffset(offset)) return FILERR_INVALID_ACCESS; - /* set up the source */ - file->zdata->stream.next_in = (Bytef *)buffer; - file->zdata->stream.avail_in = length; - while (file->zdata->stream.avail_in != 0) + // set up the source + m_zdata->set_input(buffer, length); + while (m_zdata->has_input()) { - file_error filerr; - UINT32 actualdata; - int zerr; - - /* if we didn't make progress, report an error or the end */ - zerr = deflate(&file->zdata->stream, Z_NO_FLUSH); + // if we didn't make progress, report an error or the end + auto const zerr = m_zdata->compress(); if (zerr != Z_OK) { - *actual = length - file->zdata->stream.avail_in; - file->zdata->nextoffset += *actual; + actual = length - m_zdata->input_size(); + m_zdata->add_nextoffset(actual); return FILERR_INVALID_DATA; } - /* write more data if we are full up */ - if (file->zdata->stream.avail_out == 0) + // write more data if we are full up + if (m_zdata->output_full()) { - filerr = osd_write(file->file, file->zdata->buffer, file->zdata->realoffset, sizeof(file->zdata->buffer), &actualdata); + std::uint32_t actualdata; + auto const filerr = osd_write(m_file, m_zdata->buffer_data(), m_zdata->realoffset(), m_zdata->output_size(), &actualdata); if (filerr != FILERR_NONE) return filerr; - file->zdata->realoffset += actualdata; - file->zdata->stream.next_out = file->zdata->buffer; - file->zdata->stream.avail_out = sizeof(file->zdata->buffer); + m_zdata->add_realoffset(actualdata); + m_zdata->reset_output(); } } - /* we read everything */ - *actual = length; - file->zdata->nextoffset += *actual; + // we wrote everything + actual = length; + m_zdata->add_nextoffset(actual); return FILERR_NONE; } + +} // anonymous namespace + + + +/*************************************************************************** + core_file +***************************************************************************/ + +/*------------------------------------------------- + open - open a file for access and + return an error code +-------------------------------------------------*/ + +file_error core_file::open(char const *filename, std::uint32_t openflags, ptr &file) +{ + // attempt to open the file + osd_file *f = nullptr; + std::uint64_t length = 0; + auto const filerr = osd_open(filename, openflags, &f, &length); + if (filerr != FILERR_NONE) + return filerr; + + try + { + file = std::make_unique<core_osd_file>(openflags, f, length); + return FILERR_NONE; + } + catch (...) + { + osd_close(f); + return FILERR_OUT_OF_MEMORY; + } +} + + +/*------------------------------------------------- + open_ram - open a RAM-based buffer for file- + like access and return an error code +-------------------------------------------------*/ + +file_error core_file::open_ram(void const *data, std::size_t length, std::uint32_t openflags, ptr &file) +{ + // can only do this for read access + if ((openflags & OPEN_FLAG_WRITE) || (openflags & OPEN_FLAG_CREATE)) + return FILERR_INVALID_ACCESS; + + try + { + file.reset(new core_in_memory_file(openflags, data, length, false)); + return FILERR_NONE; + } + catch (...) + { + return FILERR_OUT_OF_MEMORY; + } +} + + +/*------------------------------------------------- + open_ram_copy - open a copy of a RAM-based + buffer for file-like access and return an + error code +-------------------------------------------------*/ + +file_error core_file::open_ram_copy(void const *data, std::size_t length, std::uint32_t openflags, ptr &file) +{ + // can only do this for read access + if ((openflags & OPEN_FLAG_WRITE) || (openflags & OPEN_FLAG_CREATE)) + return FILERR_INVALID_ACCESS; + + try + { + ptr result(new core_in_memory_file(openflags, data, length, true)); + if (!result->buffer()) + return FILERR_OUT_OF_MEMORY; + + return FILERR_NONE; + } + catch (...) + { + return FILERR_OUT_OF_MEMORY; + } +} + + +/*------------------------------------------------- + open_proxy - open a proxy to an existing file + object and return an error code +-------------------------------------------------*/ + +file_error core_file::open_proxy(core_file &file, ptr &proxy) +{ + try + { + proxy = std::make_unique<core_proxy_file>(file); + return FILERR_NONE; + } + catch (...) + { + return FILERR_OUT_OF_MEMORY; + } +} + + +/*------------------------------------------------- + closes a file +-------------------------------------------------*/ + +core_file::~core_file() +{ +} + + +/*------------------------------------------------- + load - open a file with the specified + filename, read it into memory, and return a + pointer +-------------------------------------------------*/ + +file_error core_file::load(char const *filename, void **data, std::uint32_t &length) +{ + ptr file; + + // attempt to open the file + auto const err = open(filename, OPEN_FLAG_READ, file); + if (err != FILERR_NONE) + return err; + + // get the size + auto const size = file->size(); + if (std::uint32_t(size) != size) + return FILERR_OUT_OF_MEMORY; + + // allocate memory + *data = osd_malloc(size); + length = std::uint32_t(size); + + // read the data + if (file->read(*data, size) != size) + { + free(*data); + return FILERR_FAILURE; + } + + // close the file and return data + return FILERR_NONE; +} + +file_error core_file::load(char const *filename, dynamic_buffer &data) +{ + ptr file; + + // attempt to open the file + auto const err = open(filename, OPEN_FLAG_READ, file); + if (err != FILERR_NONE) + return err; + + // get the size + auto const size = file->size(); + if (std::uint32_t(size) != size) + return FILERR_OUT_OF_MEMORY; + + // allocate memory + data.resize(size); + + // read the data + if (file->read(&data[0], size) != size) + { + data.clear(); + return FILERR_FAILURE; + } + + // close the file and return data + return FILERR_NONE; +} + + +/*------------------------------------------------- + printf - printf to a text file +-------------------------------------------------*/ + +int CLIB_DECL core_file::printf(char const *fmt, ...) +{ + va_list va; + va_start(va, fmt); + auto const rc = vprintf(fmt, va); + va_end(va); + return rc; +} + + +/*------------------------------------------------- + protected constructor +-------------------------------------------------*/ + +core_file::core_file() +{ +} + +} // namespace util + + + +/*************************************************************************** + FILENAME UTILITIES +***************************************************************************/ + +/*------------------------------------------------- + core_filename_extract_base - extract the base + name from a filename; note that this makes + assumptions about path separators +-------------------------------------------------*/ + +std::string core_filename_extract_base(const char *name, bool strip_extension) +{ + /* find the start of the name */ + const char *start = name + strlen(name); + while (start > name && !util::is_directory_separator(start[-1])) + start--; + + /* copy the rest into an astring */ + std::string result(start); + + /* chop the extension if present */ + if (strip_extension) + result = result.substr(0, result.find_last_of('.')); + return result; +} + + +/*------------------------------------------------- + core_filename_ends_with - does the given + filename end with the specified extension? +-------------------------------------------------*/ + +int core_filename_ends_with(const char *filename, const char *extension) +{ + int namelen = strlen(filename); + int extlen = strlen(extension); + int matches = TRUE; + + /* work backwards checking for a match */ + while (extlen > 0) + if (tolower((UINT8)filename[--namelen]) != tolower((UINT8)extension[--extlen])) + { + matches = FALSE; + break; + } + + return matches; +} diff --git a/src/lib/util/corefile.h b/src/lib/util/corefile.h index 36060631f35..a5837e6de21 100644 --- a/src/lib/util/corefile.h +++ b/src/lib/util/corefile.h @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders:Aaron Giles, Vas Crabb /*************************************************************************** corefile.h @@ -15,10 +15,14 @@ #include <stdarg.h> #include "corestr.h" -#include <string> #include "coretmpl.h" +#include <cstdint> +#include <memory> +#include <string> + +namespace util { /*************************************************************************** ADDITIONAL OPEN FLAGS @@ -32,98 +36,104 @@ #define FCOMPRESS_MAX 9 /* maximum compression */ - /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ -struct core_file; - - +class core_file +{ +public: + typedef std::unique_ptr<core_file> ptr; -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ + // ----- file open/close ----- -/* ----- file open/close ----- */ + // open a file with the specified filename + static file_error open(const char *filename, std::uint32_t openflags, ptr &file); -/* open a file with the specified filename */ -file_error core_fopen(const char *filename, UINT32 openflags, core_file **file); + // open a RAM-based "file" using the given data and length (read-only) + static file_error open_ram(const void *data, std::size_t length, std::uint32_t openflags, ptr &file); -/* open a RAM-based "file" using the given data and length (read-only) */ -file_error core_fopen_ram(const void *data, size_t length, UINT32 openflags, core_file **file); + // open a RAM-based "file" using the given data and length (read-only), copying the data + static file_error open_ram_copy(const void *data, std::size_t length, std::uint32_t openflags, ptr &file); -/* open a RAM-based "file" using the given data and length (read-only), copying the data */ -file_error core_fopen_ram_copy(const void *data, size_t length, UINT32 openflags, core_file **file); + // open a proxy "file" that forwards requests to another file object + static file_error open_proxy(core_file &file, ptr &proxy); -/* close an open file */ -void core_fclose(core_file *file); + // close an open file + virtual ~core_file(); -/* enable/disable streaming file compression via zlib; level is 0 to disable compression, or up to 9 for max compression */ -file_error core_fcompress(core_file *file, int level); + // enable/disable streaming file compression via zlib; level is 0 to disable compression, or up to 9 for max compression + virtual file_error compress(int level) = 0; + // ----- file positioning ----- -/* ----- file positioning ----- */ + // adjust the file pointer within the file + virtual int seek(std::int64_t offset, int whence) = 0; -/* adjust the file pointer within the file */ -int core_fseek(core_file *file, INT64 offset, int whence); + // return the current file pointer + virtual std::uint64_t tell() const = 0; -/* return the current file pointer */ -UINT64 core_ftell(core_file *file); + // return true if we are at the EOF + virtual bool eof() const = 0; -/* return true if we are at the EOF */ -int core_feof(core_file *file); + // return the total size of the file + virtual std::uint64_t size() const = 0; -/* return the total size of the file */ -UINT64 core_fsize(core_file *file); + // ----- file read ----- + // standard binary read from a file + virtual std::uint32_t read(void *buffer, std::uint32_t length) = 0; -/* ----- file read ----- */ + // read one character from the file + virtual int getc() = 0; -/* standard binary read from a file */ -UINT32 core_fread(core_file *file, void *buffer, UINT32 length); + // put back one character from the file + virtual int ungetc(int c) = 0; -/* read one character from the file */ -int core_fgetc(core_file *file); + // read a full line of text from the file + virtual char *gets(char *s, int n) = 0; -/* put back one character from the file */ -int core_ungetc(int c, core_file *file); + // get a pointer to a buffer that holds the full file data in RAM + // this function may cause the full file data to be read + virtual const void *buffer() = 0; -/* read a full line of text from the file */ -char *core_fgets(char *s, int n, core_file *file); + // open a file with the specified filename, read it into memory, and return a pointer + static file_error load(const char *filename, void **data, std::uint32_t &length); + static file_error load(const char *filename, dynamic_buffer &data); -/* get a pointer to a buffer that holds the full file data in RAM */ -/* this function may cause the full file data to be read */ -const void *core_fbuffer(core_file *file); -/* open a file with the specified filename, read it into memory, and return a pointer */ -file_error core_fload(const char *filename, void **data, UINT32 *length); -file_error core_fload(const char *filename, dynamic_buffer &data); + // ----- file write ----- + // standard binary write to a file + virtual std::uint32_t write(const void *buffer, std::uint32_t length) = 0; + // write a line of text to the file + virtual int puts(const char *s) = 0; -/* ----- file write ----- */ + // printf-style text write to a file + virtual int vprintf(const char *fmt, va_list va) = 0; + int CLIB_DECL printf(const char *fmt, ...) ATTR_PRINTF(2,3); -/* standard binary write to a file */ -UINT32 core_fwrite(core_file *file, const void *buffer, UINT32 length); + // file truncation + virtual file_error truncate(std::uint64_t offset) = 0; -/* write a line of text to the file */ -int core_fputs(core_file *f, const char *s); + // flush file buffers + virtual file_error flush() = 0; -/* printf-style text write to a file */ -int core_vfprintf(core_file *f, const char *fmt, va_list va); -int CLIB_DECL core_fprintf(core_file *f, const char *fmt, ...) ATTR_PRINTF(2,3); -/* file truncation */ -file_error core_truncate(core_file *f, UINT64 offset); +protected: + core_file(); +}; -/* flush file buffers */ -file_error core_fflush(core_file *f); +} // namespace util +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ /* ----- filename utilities ----- */ diff --git a/src/lib/util/flac.cpp b/src/lib/util/flac.cpp index f70ae709978..c66cc281931 100644 --- a/src/lib/util/flac.cpp +++ b/src/lib/util/flac.cpp @@ -35,7 +35,7 @@ flac_encoder::flac_encoder(void *buffer, UINT32 buflength) } -flac_encoder::flac_encoder(core_file &file) +flac_encoder::flac_encoder(util::core_file &file) { init_common(); reset(file); @@ -100,7 +100,7 @@ bool flac_encoder::reset(void *buffer, UINT32 buflength) // reset - reset state with new file parameters //------------------------------------------------- -bool flac_encoder::reset(core_file &file) +bool flac_encoder::reset(util::core_file &file) { // configure the output m_compressed_start = nullptr; @@ -185,7 +185,7 @@ UINT32 flac_encoder::finish() { // process the data and return the amount written FLAC__stream_encoder_finish(m_encoder); - return (m_file != nullptr) ? core_ftell(m_file) : m_compressed_offset; + return (m_file != nullptr) ? m_file->tell() : m_compressed_offset; } @@ -252,7 +252,7 @@ FLAC__StreamEncoderWriteStatus flac_encoder::write_callback(const FLAC__byte buf { int count = bytes - offset; if (m_file != nullptr) - core_fwrite(m_file, buffer, count); + m_file->write(buffer, count); else { if (m_compressed_offset + count <= m_compressed_length) @@ -308,7 +308,7 @@ flac_decoder::flac_decoder(const void *buffer, UINT32 length, const void *buffer // flac_decoder - constructor //------------------------------------------------- -flac_decoder::flac_decoder(core_file &file) +flac_decoder::flac_decoder(util::core_file &file) : m_decoder(FLAC__stream_decoder_new()), m_file(&file), m_compressed_offset(0), @@ -414,7 +414,7 @@ bool flac_decoder::reset(UINT32 sample_rate, UINT8 num_channels, UINT32 block_si // reset - reset state with new file parameter //------------------------------------------------- -bool flac_decoder::reset(core_file &file) +bool flac_decoder::reset(util::core_file &file) { m_file = &file; m_compressed_start = nullptr; @@ -511,7 +511,7 @@ FLAC__StreamDecoderReadStatus flac_decoder::read_callback(FLAC__byte buffer[], s // if a file, just read if (m_file != nullptr) - *bytes = core_fread(m_file, buffer, expected); + *bytes = m_file->read(buffer, expected); // otherwise, copy from memory else diff --git a/src/lib/util/flac.h b/src/lib/util/flac.h index 563c40974e0..1f9a49b14bd 100644 --- a/src/lib/util/flac.h +++ b/src/lib/util/flac.h @@ -35,7 +35,7 @@ public: // construction/destruction flac_encoder(); flac_encoder(void *buffer, UINT32 buflength); - flac_encoder(core_file &file); + flac_encoder(util::core_file &file); ~flac_encoder(); // configuration @@ -51,7 +51,7 @@ public: // reset bool reset(); bool reset(void *buffer, UINT32 buflength); - bool reset(core_file &file); + bool reset(util::core_file &file); // encode a buffer bool encode_interleaved(const INT16 *samples, UINT32 samples_per_channel, bool swap_endian = false); @@ -68,7 +68,7 @@ private: // internal state FLAC__StreamEncoder * m_encoder; // actual encoder - core_file * m_file; // output file + util::core_file * m_file; // output file UINT32 m_compressed_offset; // current offset with the compressed stream FLAC__byte * m_compressed_start; // start of compressed data UINT32 m_compressed_length; // length of the compressed stream @@ -93,7 +93,7 @@ public: // construction/destruction flac_decoder(); flac_decoder(const void *buffer, UINT32 length, const void *buffer2 = nullptr, UINT32 length2 = 0); - flac_decoder(core_file &file); + flac_decoder(util::core_file &file); ~flac_decoder(); // getters (valid after reset) @@ -108,7 +108,7 @@ public: bool reset(); bool reset(const void *buffer, UINT32 length, const void *buffer2 = nullptr, UINT32 length2 = 0); bool reset(UINT32 sample_rate, UINT8 num_channels, UINT32 block_size, const void *buffer, UINT32 length); - bool reset(core_file &file); + bool reset(util::core_file &file); // decode to a buffer; num_samples must be a multiple of the block size bool decode_interleaved(INT16 *samples, UINT32 num_samples, bool swap_endian = false); @@ -129,7 +129,7 @@ private: // output state FLAC__StreamDecoder * m_decoder; // actual encoder - core_file * m_file; // output file + util::core_file * m_file; // output file UINT32 m_sample_rate; // decoded sample rate UINT8 m_channels; // decoded number of channels UINT8 m_bits_per_sample; // decoded bits per sample diff --git a/src/lib/util/options.cpp b/src/lib/util/options.cpp index 56bad147bcb..9890ae46115 100644 --- a/src/lib/util/options.cpp +++ b/src/lib/util/options.cpp @@ -400,11 +400,11 @@ bool core_options::parse_command_line(int argc, char **argv, int priority, std:: // an INI file //------------------------------------------------- -bool core_options::parse_ini_file(core_file &inifile, int priority, int ignore_priority, std::string &error_string) +bool core_options::parse_ini_file(util::core_file &inifile, int priority, int ignore_priority, std::string &error_string) { // loop over lines in the file char buffer[4096]; - while (core_fgets(buffer, ARRAY_LENGTH(buffer), &inifile) != nullptr) + while (inifile.gets(buffer, ARRAY_LENGTH(buffer)) != nullptr) { // find the extent of the name char *optionname; diff --git a/src/lib/util/options.h b/src/lib/util/options.h index cf58bc67222..4ffdf00ae35 100644 --- a/src/lib/util/options.h +++ b/src/lib/util/options.h @@ -142,7 +142,7 @@ public: // parsing/input bool parse_command_line(int argc, char **argv, int priority, std::string &error_string); - bool parse_ini_file(core_file &inifile, int priority, int ignore_priority, std::string &error_string); + bool parse_ini_file(util::core_file &inifile, int priority, int ignore_priority, std::string &error_string); // reverting void revert(int priority = OPTION_PRIORITY_MAXIMUM); diff --git a/src/lib/util/png.cpp b/src/lib/util/png.cpp index a6b269593ef..8023d350cdc 100644 --- a/src/lib/util/png.cpp +++ b/src/lib/util/png.cpp @@ -148,12 +148,12 @@ void png_free(png_info *pnginfo) header at the current file location -------------------------------------------------*/ -static png_error verify_header(core_file *fp) +static png_error verify_header(util::core_file &fp) { UINT8 signature[8]; /* read 8 bytes */ - if (core_fread(fp, signature, 8) != 8) + if (fp.read(signature, 8) != 8) return PNGERR_FILE_TRUNCATED; /* return an error if we don't match */ @@ -168,18 +168,18 @@ static png_error verify_header(core_file *fp) read_chunk - read the next PNG chunk -------------------------------------------------*/ -static png_error read_chunk(core_file *fp, UINT8 **data, UINT32 *type, UINT32 *length) +static png_error read_chunk(util::core_file &fp, UINT8 **data, UINT32 *type, UINT32 *length) { UINT32 crc, chunk_crc; UINT8 tempbuff[4]; /* fetch the length of this chunk */ - if (core_fread(fp, tempbuff, 4) != 4) + if (fp.read(tempbuff, 4) != 4) return PNGERR_FILE_TRUNCATED; *length = fetch_32bit(tempbuff); /* fetch the type of this chunk */ - if (core_fread(fp, tempbuff, 4) != 4) + if (fp.read(tempbuff, 4) != 4) return PNGERR_FILE_TRUNCATED; *type = fetch_32bit(tempbuff); @@ -200,7 +200,7 @@ static png_error read_chunk(core_file *fp, UINT8 **data, UINT32 *type, UINT32 *l return PNGERR_OUT_OF_MEMORY; /* read the data from the file */ - if (core_fread(fp, *data, *length) != *length) + if (fp.read(*data, *length) != *length) { free(*data); *data = nullptr; @@ -212,7 +212,7 @@ static png_error read_chunk(core_file *fp, UINT8 **data, UINT32 *type, UINT32 *l } /* read the CRC */ - if (core_fread(fp, tempbuff, 4) != 4) + if (fp.read(tempbuff, 4) != 4) { free(*data); *data = nullptr; @@ -502,7 +502,7 @@ handle_error: png_read_file - read a PNG from a core stream -------------------------------------------------*/ -png_error png_read_file(core_file *fp, png_info *pnginfo) +png_error png_read_file(util::core_file &fp, png_info *pnginfo) { UINT8 *chunk_data = nullptr; png_private png; @@ -579,7 +579,7 @@ handle_error: bitmap -------------------------------------------------*/ -png_error png_read_bitmap(core_file *fp, bitmap_argb32 &bitmap) +png_error png_read_bitmap(util::core_file &fp, bitmap_argb32 &bitmap) { png_error result; png_info png; @@ -747,7 +747,7 @@ png_error png_add_text(png_info *pnginfo, const char *keyword, const char *text) the given file -------------------------------------------------*/ -static png_error write_chunk(core_file *fp, const UINT8 *data, UINT32 type, UINT32 length) +static png_error write_chunk(util::core_file &fp, const UINT8 *data, UINT32 type, UINT32 length) { UINT8 tempbuff[8]; UINT32 crc; @@ -758,20 +758,20 @@ static png_error write_chunk(core_file *fp, const UINT8 *data, UINT32 type, UINT crc = crc32(0, tempbuff + 4, 4); /* write that data */ - if (core_fwrite(fp, tempbuff, 8) != 8) + if (fp.write(tempbuff, 8) != 8) return PNGERR_FILE_ERROR; /* append the actual data */ if (length > 0) { - if (core_fwrite(fp, data, length) != length) + if (fp.write(data, length) != length) return PNGERR_FILE_ERROR; crc = crc32(crc, data, length); } /* write the CRC */ put_32bit(tempbuff, crc); - if (core_fwrite(fp, tempbuff, 4) != 4) + if (fp.write(tempbuff, 4) != 4) return PNGERR_FILE_ERROR; return PNGERR_NONE; @@ -783,9 +783,9 @@ static png_error write_chunk(core_file *fp, const UINT8 *data, UINT32 type, UINT chunk to the given file by deflating it -------------------------------------------------*/ -static png_error write_deflated_chunk(core_file *fp, UINT8 *data, UINT32 type, UINT32 length) +static png_error write_deflated_chunk(util::core_file &fp, UINT8 *data, UINT32 type, UINT32 length) { - UINT64 lengthpos = core_ftell(fp); + UINT64 lengthpos = fp.tell(); UINT8 tempbuff[8192]; UINT32 zlength = 0; z_stream stream; @@ -798,7 +798,7 @@ static png_error write_deflated_chunk(core_file *fp, UINT8 *data, UINT32 type, U crc = crc32(0, tempbuff + 4, 4); /* write that data */ - if (core_fwrite(fp, tempbuff, 8) != 8) + if (fp.write(tempbuff, 8) != 8) return PNGERR_FILE_ERROR; /* initialize the stream */ @@ -821,7 +821,7 @@ static png_error write_deflated_chunk(core_file *fp, UINT8 *data, UINT32 type, U if (stream.avail_out < sizeof(tempbuff)) { int bytes = sizeof(tempbuff) - stream.avail_out; - if (core_fwrite(fp, tempbuff, bytes) != bytes) + if (fp.write(tempbuff, bytes) != bytes) { deflateEnd(&stream); return PNGERR_FILE_ERROR; @@ -849,17 +849,17 @@ static png_error write_deflated_chunk(core_file *fp, UINT8 *data, UINT32 type, U /* write the CRC */ put_32bit(tempbuff, crc); - if (core_fwrite(fp, tempbuff, 4) != 4) + if (fp.write(tempbuff, 4) != 4) return PNGERR_FILE_ERROR; /* seek back and update the length */ - core_fseek(fp, lengthpos, SEEK_SET); + fp.seek(lengthpos, SEEK_SET); put_32bit(tempbuff + 0, zlength); - if (core_fwrite(fp, tempbuff, 4) != 4) + if (fp.write(tempbuff, 4) != 4) return PNGERR_FILE_ERROR; /* return to the end */ - core_fseek(fp, lengthpos + 8 + zlength + 4, SEEK_SET); + fp.seek(lengthpos + 8 + zlength + 4, SEEK_SET); return PNGERR_NONE; } @@ -1006,7 +1006,7 @@ static png_error convert_bitmap_to_image_rgb(png_info *pnginfo, const bitmap_t & chunks to the given file -------------------------------------------------*/ -static png_error write_png_stream(core_file *fp, png_info *pnginfo, const bitmap_t &bitmap, int palette_length, const rgb_t *palette) +static png_error write_png_stream(util::core_file &fp, png_info *pnginfo, const bitmap_t &bitmap, int palette_length, const rgb_t *palette) { UINT8 tempbuff[16]; png_text *text; @@ -1061,7 +1061,7 @@ handle_error: } -png_error png_write_bitmap(core_file *fp, png_info *info, bitmap_t &bitmap, int palette_length, const rgb_t *palette) +png_error png_write_bitmap(util::core_file &fp, png_info *info, bitmap_t &bitmap, int palette_length, const rgb_t *palette) { png_info pnginfo; png_error error; @@ -1074,7 +1074,7 @@ png_error png_write_bitmap(core_file *fp, png_info *info, bitmap_t &bitmap, int } /* write the PNG signature */ - if (core_fwrite(fp, PNG_Signature, 8) != 8) + if (fp.write(PNG_Signature, 8) != 8) { if (info == &pnginfo) png_free(&pnginfo); @@ -1097,7 +1097,7 @@ png_error png_write_bitmap(core_file *fp, png_info *info, bitmap_t &bitmap, int ********************************************************************************/ /** - * @fn png_error mng_capture_start(core_file *fp, bitmap_t &bitmap, double rate) + * @fn png_error mng_capture_start(util::core_file &fp, bitmap_t &bitmap, double rate) * * @brief Mng capture start. * @@ -1108,12 +1108,12 @@ png_error png_write_bitmap(core_file *fp, png_info *info, bitmap_t &bitmap, int * @return A png_error. */ -png_error mng_capture_start(core_file *fp, bitmap_t &bitmap, double rate) +png_error mng_capture_start(util::core_file &fp, bitmap_t &bitmap, double rate) { UINT8 mhdr[28]; png_error error; - if (core_fwrite(fp, MNG_Signature, 8) != 8) + if (fp.write(MNG_Signature, 8) != 8) return PNGERR_FILE_ERROR; memset(mhdr, 0, 28); @@ -1131,7 +1131,7 @@ png_error mng_capture_start(core_file *fp, bitmap_t &bitmap, double rate) } /** - * @fn png_error mng_capture_frame(core_file *fp, png_info *info, bitmap_t &bitmap, int palette_length, const rgb_t *palette) + * @fn png_error mng_capture_frame(util::core_file &fp, png_info *info, bitmap_t &bitmap, int palette_length, const rgb_t *palette) * * @brief Mng capture frame. * @@ -1144,13 +1144,13 @@ png_error mng_capture_start(core_file *fp, bitmap_t &bitmap, double rate) * @return A png_error. */ -png_error mng_capture_frame(core_file *fp, png_info *info, bitmap_t &bitmap, int palette_length, const rgb_t *palette) +png_error mng_capture_frame(util::core_file &fp, png_info *info, bitmap_t &bitmap, int palette_length, const rgb_t *palette) { return write_png_stream(fp, info, bitmap, palette_length, palette); } /** - * @fn png_error mng_capture_stop(core_file *fp) + * @fn png_error mng_capture_stop(util::core_file &fp) * * @brief Mng capture stop. * @@ -1159,7 +1159,7 @@ png_error mng_capture_frame(core_file *fp, png_info *info, bitmap_t &bitmap, int * @return A png_error. */ -png_error mng_capture_stop(core_file *fp) +png_error mng_capture_stop(util::core_file &fp) { return write_chunk(fp, nullptr, MNG_CN_MEND, 0); } diff --git a/src/lib/util/png.h b/src/lib/util/png.h index 52e5111d199..00522f12f5c 100644 --- a/src/lib/util/png.h +++ b/src/lib/util/png.h @@ -119,15 +119,15 @@ struct png_info void png_free(png_info *pnginfo); -png_error png_read_file(core_file *fp, png_info *pnginfo); -png_error png_read_bitmap(core_file *fp, bitmap_argb32 &bitmap); +png_error png_read_file(util::core_file &fp, png_info *pnginfo); +png_error png_read_bitmap(util::core_file &fp, bitmap_argb32 &bitmap); png_error png_expand_buffer_8bit(png_info *p); png_error png_add_text(png_info *pnginfo, const char *keyword, const char *text); -png_error png_write_bitmap(core_file *fp, png_info *info, bitmap_t &bitmap, int palette_length, const rgb_t *palette); +png_error png_write_bitmap(util::core_file &fp, png_info *info, bitmap_t &bitmap, int palette_length, const rgb_t *palette); -png_error mng_capture_start(core_file *fp, bitmap_t &bitmap, double rate); -png_error mng_capture_frame(core_file *fp, png_info *info, bitmap_t &bitmap, int palette_length, const rgb_t *palette); -png_error mng_capture_stop(core_file *fp); +png_error mng_capture_start(util::core_file &fp, bitmap_t &bitmap, double rate); +png_error mng_capture_frame(util::core_file &fp, png_info *info, bitmap_t &bitmap, int palette_length, const rgb_t *palette); +png_error mng_capture_stop(util::core_file &fp); #endif /* __PNG_H__ */ diff --git a/src/lib/util/xmlfile.cpp b/src/lib/util/xmlfile.cpp index 620f12a66b3..db288b0a807 100644 --- a/src/lib/util/xmlfile.cpp +++ b/src/lib/util/xmlfile.cpp @@ -52,7 +52,7 @@ static xml_data_node *add_child(xml_data_node *parent, const char *name, const c static xml_attribute_node *add_attribute(xml_data_node *node, const char *name, const char *value); /* recursive tree operations */ -static void write_node_recursive(xml_data_node *node, int indent, core_file *file); +static void write_node_recursive(xml_data_node *node, int indent, util::core_file &file); static void free_node_recursive(xml_data_node *node); @@ -139,7 +139,7 @@ xml_data_node *xml_file_create(void) nodes -------------------------------------------------*/ -xml_data_node *xml_file_read(core_file *file, xml_parse_options *opts) +xml_data_node *xml_file_read(util::core_file &file, xml_parse_options *opts) { xml_parse_info parse_info; int done; @@ -154,8 +154,8 @@ xml_data_node *xml_file_read(core_file *file, xml_parse_options *opts) char tempbuf[TEMP_BUFFER_SIZE]; /* read as much as we can */ - int bytes = core_fread(file, tempbuf, sizeof(tempbuf)); - done = core_feof(file); + int bytes = file.read(tempbuf, sizeof(tempbuf)); + done = file.eof(); /* parse the data */ if (XML_Parse(parse_info.parser, tempbuf, bytes, done) == XML_STATUS_ERROR) @@ -223,15 +223,15 @@ xml_data_node *xml_string_read(const char *string, xml_parse_options *opts) xml_file_write - write an XML tree to a file -------------------------------------------------*/ -void xml_file_write(xml_data_node *node, core_file *file) +void xml_file_write(xml_data_node *node, util::core_file &file) { /* ensure this is a root node */ if (node->name != nullptr) return; /* output a simple header */ - core_fprintf(file, "<?xml version=\"1.0\"?>\n"); - core_fprintf(file, "<!-- This file is autogenerated; comments and unknown tags will be stripped -->\n"); + file.printf("<?xml version=\"1.0\"?>\n"); + file.printf("<!-- This file is autogenerated; comments and unknown tags will be stripped -->\n"); /* loop over children of the root and output */ for (node = node->child; node; node = node->next) @@ -1002,7 +1002,7 @@ static xml_attribute_node *add_attribute(xml_data_node *node, const char *name, -------------------------------------------------*/ /** - * @fn static void write_node_recursive(xml_data_node *node, int indent, core_file *file) + * @fn static void write_node_recursive(xml_data_node *node, int indent, util::core_file &file) * * @brief Writes a node recursive. * @@ -1011,30 +1011,30 @@ static xml_attribute_node *add_attribute(xml_data_node *node, const char *name, * @param [in,out] file If non-null, the file. */ -static void write_node_recursive(xml_data_node *node, int indent, core_file *file) +static void write_node_recursive(xml_data_node *node, int indent, util::core_file &file) { xml_attribute_node *anode; xml_data_node *child; /* output this tag */ - core_fprintf(file, "%*s<%s", indent, "", node->name); + file.printf("%*s<%s", indent, "", node->name); /* output any attributes */ for (anode = node->attribute; anode; anode = anode->next) - core_fprintf(file, " %s=\"%s\"", anode->name, anode->value); + file.printf(" %s=\"%s\"", anode->name, anode->value); /* if there are no children and no value, end the tag here */ if (node->child == nullptr && node->value == nullptr) - core_fprintf(file, " />\n"); + file.printf(" />\n"); /* otherwise, close this tag and output more stuff */ else { - core_fprintf(file, ">\n"); + file.printf(">\n"); /* if there is a value, output that here */ if (node->value != nullptr) - core_fprintf(file, "%*s%s\n", indent + 4, "", node->value); + file.printf("%*s%s\n", indent + 4, "", node->value); /* loop over children and output them as well */ if (node->child != nullptr) @@ -1044,7 +1044,7 @@ static void write_node_recursive(xml_data_node *node, int indent, core_file *fil } /* write a closing tag */ - core_fprintf(file, "%*s</%s>\n", indent, "", node->name); + file.printf("%*s</%s>\n", indent, "", node->name); } } diff --git a/src/lib/util/xmlfile.h b/src/lib/util/xmlfile.h index 06412abbefe..e116366643f 100644 --- a/src/lib/util/xmlfile.h +++ b/src/lib/util/xmlfile.h @@ -97,13 +97,13 @@ struct xml_parse_options xml_data_node *xml_file_create(void); /* parse an XML file into its nodes */ -xml_data_node *xml_file_read(core_file *file, xml_parse_options *opts); +xml_data_node *xml_file_read(util::core_file &file, xml_parse_options *opts); /* parse an XML string into its nodes */ xml_data_node *xml_string_read(const char *string, xml_parse_options *opts); /* write an XML tree to a file */ -void xml_file_write(xml_data_node *node, core_file *file); +void xml_file_write(xml_data_node *node, util::core_file &file); /* free an XML file object */ void xml_file_free(xml_data_node *node); diff --git a/src/lib/util/zippath.cpp b/src/lib/util/zippath.cpp index 84674eb1fe2..efe7c710481 100644 --- a/src/lib/util/zippath.cpp +++ b/src/lib/util/zippath.cpp @@ -298,7 +298,7 @@ static file_error file_error_from_zip_error(zip_error ziperr) -------------------------------------------------*/ /** - * @fn static file_error create_core_file_from_zip(zip_file *zip, const zip_file_header *header, core_file *&file) + * @fn static file_error create_core_file_from_zip(zip_file *zip, const zip_file_header *header, util::core_file::ptr &file) * * @brief Creates core file from zip. * @@ -309,7 +309,7 @@ static file_error file_error_from_zip_error(zip_error ziperr) * @return The new core file from zip. */ -static file_error create_core_file_from_zip(zip_file *zip, const zip_file_header *header, core_file *&file) +static file_error create_core_file_from_zip(zip_file *zip, const zip_file_header *header, util::core_file::ptr &file) { file_error filerr; zip_error ziperr; @@ -329,7 +329,7 @@ static file_error create_core_file_from_zip(zip_file *zip, const zip_file_header goto done; } - filerr = core_fopen_ram_copy(ptr, header->uncompressed_length, OPEN_FLAG_READ, &file); + filerr = util::core_file::open_ram_copy(ptr, header->uncompressed_length, OPEN_FLAG_READ, file); if (filerr != FILERR_NONE) goto done; @@ -345,7 +345,7 @@ done: -------------------------------------------------*/ /** - * @fn file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&file, std::string &revised_path) + * @fn file_error zippath_fopen(const char *filename, UINT32 openflags, util::core_file::ptr &file, std::string &revised_path) * * @brief Zippath fopen. * @@ -357,7 +357,7 @@ done: * @return A file_error. */ -file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&file, std::string &revised_path) +file_error zippath_fopen(const char *filename, UINT32 openflags, util::core_file::ptr &file, std::string &revised_path) { file_error filerr = FILERR_NOT_FOUND; zip_error ziperr; @@ -421,7 +421,7 @@ file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&fil } if (subpath.length() == 0) - filerr = core_fopen(filename, openflags, &file); + filerr = util::core_file::open(filename, openflags, file); else filerr = FILERR_NOT_FOUND; diff --git a/src/lib/util/zippath.h b/src/lib/util/zippath.h index 960b50851e7..ce40c87ba8d 100644 --- a/src/lib/util/zippath.h +++ b/src/lib/util/zippath.h @@ -45,7 +45,7 @@ std::string &zippath_combine(std::string &dst, const char *path1, const char *pa /* ----- file operations ----- */ /* opens a zip path file */ -file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&file, std::string &revised_path); +file_error zippath_fopen(const char *filename, UINT32 openflags, util::core_file::ptr &file, std::string &revised_path); /* ----- directory operations ----- */ diff --git a/src/tools/chdman.cpp b/src/tools/chdman.cpp index 94ea358e825..5c7e88c233e 100644 --- a/src/tools/chdman.cpp +++ b/src/tools/chdman.cpp @@ -187,10 +187,10 @@ class chd_rawfile_compressor : public chd_file_compressor { public: // construction/destruction - chd_rawfile_compressor(core_file *file, UINT64 offset = 0, UINT64 maxoffset = ~0) + chd_rawfile_compressor(util::core_file &file, UINT64 offset = 0, UINT64 maxoffset = ~0) : m_file(file), m_offset(offset), - m_maxoffset(MIN(maxoffset, (file != nullptr) ? core_fsize(file) : 0)) { } + m_maxoffset((std::min)(maxoffset, file.size())) { } // read interface virtual UINT32 read_data(void *dest, UINT64 offset, UINT32 length) @@ -200,15 +200,15 @@ public: return 0; if (offset + length > m_maxoffset) length = m_maxoffset - offset; - core_fseek(m_file, offset, SEEK_SET); - return core_fread(m_file, dest, length); + m_file.seek(offset, SEEK_SET); + return m_file.read(dest, length); } private: // internal state - core_file * m_file; - UINT64 m_offset; - UINT64 m_maxoffset; + util::core_file & m_file; + UINT64 m_offset; + UINT64 m_maxoffset; }; @@ -290,14 +290,12 @@ class chd_cd_compressor : public chd_file_compressor public: // construction/destruction chd_cd_compressor(cdrom_toc &toc, chdcd_track_input_info &info) - : m_file(nullptr), + : m_file(), m_toc(toc), m_info(info) { } ~chd_cd_compressor() { - if (m_file != nullptr) - core_fclose(m_file); } // read interface @@ -321,12 +319,11 @@ public: if (offset >= startoffs && offset < endoffs) { // if we don't already have this file open, open it now - if (m_file == nullptr || m_lastfile.compare(m_info.track[tracknum].fname)!=0) + if (!m_file || m_lastfile.compare(m_info.track[tracknum].fname)!=0) { - if (m_file != nullptr) - core_fclose(m_file); + m_file.reset(); m_lastfile = m_info.track[tracknum].fname; - file_error filerr = core_fopen(m_lastfile.c_str(), OPEN_FLAG_READ, &m_file); + file_error filerr = util::core_file::open(m_lastfile.c_str(), OPEN_FLAG_READ, m_file); if (filerr != FILERR_NONE) report_error(1, "Error opening input file (%s)'", m_lastfile.c_str()); } @@ -349,8 +346,8 @@ public: } else { - core_fseek(m_file, src_frame_start, SEEK_SET); - UINT32 count = core_fread(m_file, dest, bytesperframe); + m_file->seek(src_frame_start, SEEK_SET); + UINT32 count = m_file->read(dest, bytesperframe); if (count != bytesperframe) report_error(1, "Error reading input file (%s)'", m_lastfile.c_str()); } @@ -383,7 +380,7 @@ public: private: // internal state std::string m_lastfile; - core_file * m_file; + util::core_file::ptr m_file; cdrom_toc & m_toc; chdcd_track_input_info & m_info; }; @@ -1008,11 +1005,11 @@ static void check_existing_output_file(const parameters_t ¶ms, const char *f { if (params.find(OPTION_OUTPUT_FORCE) == params.end()) { - core_file *file; - file_error filerr = core_fopen(filename, OPEN_FLAG_READ, &file); + util::core_file::ptr file; + file_error filerr = util::core_file::open(filename, OPEN_FLAG_READ, file); if (filerr == FILERR_NONE) { - core_fclose(file); + file.reset(); report_error(1, "Error: file already exists (%s)\nUse --force (or -f) to force overwriting", filename); } } @@ -1185,7 +1182,7 @@ static void compress_common(chd_file_compressor &chd) // to a CUE file //------------------------------------------------- -void output_track_metadata(int mode, core_file *file, int tracknum, const cdrom_track_info &info, const char *filename, UINT32 frameoffs, UINT64 discoffs) +void output_track_metadata(int mode, util::core_file &file, int tracknum, const cdrom_track_info &info, const char *filename, UINT32 frameoffs, UINT64 discoffs) { if (mode == MODE_GDI) { @@ -1234,13 +1231,13 @@ void output_track_metadata(int mode, core_file *file, int tracknum, const cdrom_ break; } bool needquote = strchr(filename, ' ') != nullptr; - core_fprintf(file, "%d %d %d %d %s%s%s %" I64FMT "d\n", tracknum+1, frameoffs, mode, size, needquote?"\"":"", filename, needquote?"\"":"", discoffs); + file.printf("%d %d %d %d %s%s%s %" I64FMT "d\n", tracknum+1, frameoffs, mode, size, needquote?"\"":"", filename, needquote?"\"":"", discoffs); } else if (mode == MODE_CUEBIN) { // first track specifies the file if (tracknum == 0) - core_fprintf(file, "FILE \"%s\" BINARY\n", filename); + file.printf("FILE \"%s\" BINARY\n", filename); // determine submode std::string tempstr; @@ -1265,37 +1262,37 @@ void output_track_metadata(int mode, core_file *file, int tracknum, const cdrom_ } // output TRACK entry - core_fprintf(file, " TRACK %02d %s\n", tracknum + 1, tempstr.c_str()); + file.printf(" TRACK %02d %s\n", tracknum + 1, tempstr.c_str()); // output PREGAP tag if pregap sectors are not in the file if ((info.pregap > 0) && (info.pgdatasize == 0)) { - core_fprintf(file, " PREGAP %s\n", msf_string_from_frames(tempstr, info.pregap)); - core_fprintf(file, " INDEX 01 %s\n", msf_string_from_frames(tempstr, frameoffs)); + file.printf(" PREGAP %s\n", msf_string_from_frames(tempstr, info.pregap)); + file.printf(" INDEX 01 %s\n", msf_string_from_frames(tempstr, frameoffs)); } else if ((info.pregap > 0) && (info.pgdatasize > 0)) { - core_fprintf(file, " INDEX 00 %s\n", msf_string_from_frames(tempstr, frameoffs)); - core_fprintf(file, " INDEX 01 %s\n", msf_string_from_frames(tempstr, frameoffs+info.pregap)); + file.printf(" INDEX 00 %s\n", msf_string_from_frames(tempstr, frameoffs)); + file.printf(" INDEX 01 %s\n", msf_string_from_frames(tempstr, frameoffs+info.pregap)); } // if no pregap at all, output index 01 only if (info.pregap == 0) { - core_fprintf(file, " INDEX 01 %s\n", msf_string_from_frames(tempstr, frameoffs)); + file.printf(" INDEX 01 %s\n", msf_string_from_frames(tempstr, frameoffs)); } // output POSTGAP if (info.postgap > 0) - core_fprintf(file, " POSTGAP %s\n", msf_string_from_frames(tempstr, info.postgap)); + file.printf(" POSTGAP %s\n", msf_string_from_frames(tempstr, info.postgap)); } // non-CUE mode else if (mode == MODE_NORMAL) { // header on the first track if (tracknum == 0) - core_fprintf(file, "CD_ROM\n\n\n"); - core_fprintf(file, "// Track %d\n", tracknum + 1); + file.printf("CD_ROM\n\n\n"); + file.printf("// Track %d\n", tracknum + 1); // write out the track type std::string modesubmode; @@ -1303,32 +1300,32 @@ void output_track_metadata(int mode, core_file *file, int tracknum, const cdrom_ modesubmode = string_format("%s %s", cdrom_get_type_string(info.trktype), cdrom_get_subtype_string(info.subtype)); else modesubmode = string_format("%s", cdrom_get_type_string(info.trktype)); - core_fprintf(file, "TRACK %s\n", modesubmode.c_str()); + file.printf("TRACK %s\n", modesubmode.c_str()); // write out the attributes - core_fprintf(file, "NO COPY\n"); + file.printf("NO COPY\n"); if (info.trktype == CD_TRACK_AUDIO) { - core_fprintf(file, "NO PRE_EMPHASIS\n"); - core_fprintf(file, "TWO_CHANNEL_AUDIO\n"); + file.printf("NO PRE_EMPHASIS\n"); + file.printf("TWO_CHANNEL_AUDIO\n"); } // output pregap std::string tempstr; if (info.pregap > 0) - core_fprintf(file, "ZERO %s %s\n", modesubmode.c_str(), msf_string_from_frames(tempstr, info.pregap)); + file.printf("ZERO %s %s\n", modesubmode.c_str(), msf_string_from_frames(tempstr, info.pregap)); // all tracks but the first one have a file offset if (tracknum > 0) - core_fprintf(file, "DATAFILE \"%s\" #%d %s // length in bytes: %d\n", filename, UINT32(discoffs), msf_string_from_frames(tempstr, info.frames), info.frames * (info.datasize + info.subsize)); + file.printf("DATAFILE \"%s\" #%d %s // length in bytes: %d\n", filename, UINT32(discoffs), msf_string_from_frames(tempstr, info.frames), info.frames * (info.datasize + info.subsize)); else - core_fprintf(file, "DATAFILE \"%s\" %s // length in bytes: %d\n", filename, msf_string_from_frames(tempstr, info.frames), info.frames * (info.datasize + info.subsize)); + file.printf("DATAFILE \"%s\" %s // length in bytes: %d\n", filename, msf_string_from_frames(tempstr, info.frames), info.frames * (info.datasize + info.subsize)); // tracks with pregaps get a START marker too if (info.pregap > 0) - core_fprintf(file, "START %s\n", msf_string_from_frames(tempstr, info.pregap)); + file.printf("START %s\n", msf_string_from_frames(tempstr, info.pregap)); - core_fprintf(file, "\n\n"); + file.printf("\n\n"); } } @@ -1361,9 +1358,9 @@ static void do_info(parameters_t ¶ms) printf("Unit Size: %s bytes\n", big_int_string(tempstr, input_chd.unit_bytes())); printf("Total Units: %s\n", big_int_string(tempstr, input_chd.unit_count())); printf("Compression: %s\n", compression_string(tempstr, compression)); - printf("CHD size: %s bytes\n", big_int_string(tempstr, core_fsize(input_chd))); + printf("CHD size: %s bytes\n", big_int_string(tempstr, static_cast<util::core_file &>(input_chd).size())); if (compression[0] != CHD_CODEC_NONE) - printf("Ratio: %.1f%%\n", 100.0 * double(core_fsize(input_chd)) / double(input_chd.logical_bytes())); + printf("Ratio: %.1f%%\n", 100.0 * double(static_cast<util::core_file &>(input_chd).size()) / double(input_chd.logical_bytes())); // add SHA1 output sha1_t overall = input_chd.sha1(); @@ -1570,11 +1567,11 @@ static void do_verify(parameters_t ¶ms) static void do_create_raw(parameters_t ¶ms) { // process input file - core_file *input_file = nullptr; + util::core_file::ptr input_file; auto input_file_str = params.find(OPTION_INPUT); if (input_file_str != params.end()) { - file_error filerr = core_fopen(input_file_str->second->c_str(), OPEN_FLAG_READ, &input_file); + file_error filerr = util::core_file::open(input_file_str->second->c_str(), OPEN_FLAG_READ, input_file); if (filerr != FILERR_NONE) report_error(1, "Unable to open file (%s)", input_file_str->second->c_str()); } @@ -1600,7 +1597,7 @@ static void do_create_raw(parameters_t ¶ms) // process input start/end (needs to know hunk_size) UINT64 input_start; UINT64 input_end; - parse_input_start_end(params, core_fsize(input_file), hunk_size, hunk_size, input_start, input_end); + parse_input_start_end(params, input_file->size(), hunk_size, hunk_size, input_start, input_end); // process compression chd_codec_type compression[4]; @@ -1616,7 +1613,7 @@ static void do_create_raw(parameters_t ¶ms) if (output_parent.opened()) printf("Parent CHD: %s\n", params.find(OPTION_OUTPUT_PARENT)->second->c_str()); printf("Input file: %s\n", input_file_str->second->c_str()); - if (input_start != 0 || input_end != core_fsize(input_file)) + if (input_start != 0 || input_end != input_file->size()) { printf("Input start: %s\n", big_int_string(tempstr, input_start)); printf("Input length: %s\n", big_int_string(tempstr, input_end - input_start)); @@ -1630,7 +1627,7 @@ static void do_create_raw(parameters_t ¶ms) try { // create the new CHD - chd = new chd_rawfile_compressor(input_file, input_start, input_end); + chd = new chd_rawfile_compressor(*input_file, input_start, input_end); chd_error err; if (output_parent.opened()) err = chd->create(output_chd_str->c_str(), input_end - input_start, hunk_size, compression, output_parent); @@ -1667,11 +1664,11 @@ static void do_create_raw(parameters_t ¶ms) static void do_create_hd(parameters_t ¶ms) { // process input file - core_file *input_file = nullptr; + util::core_file::ptr input_file; auto input_file_str = params.find(OPTION_INPUT); if (input_file_str != params.end()) { - file_error filerr = core_fopen(input_file_str->second->c_str(), OPEN_FLAG_READ, &input_file); + file_error filerr = util::core_file::open(input_file_str->second->c_str(), OPEN_FLAG_READ, input_file); if (filerr != FILERR_NONE) report_error(1, "Unable to open file (%s)", input_file_str->second->c_str()); } @@ -1698,9 +1695,9 @@ static void do_create_hd(parameters_t ¶ms) UINT64 filesize = 0; UINT64 input_start = 0; UINT64 input_end = 0; - if (input_file != nullptr) + if (input_file) { - parse_input_start_end(params, core_fsize(input_file), hunk_size, hunk_size, input_start, input_end); + parse_input_start_end(params, input_file->size(), hunk_size, hunk_size, input_start, input_end); filesize = input_end - input_start; } else @@ -1716,10 +1713,10 @@ static void do_create_hd(parameters_t ¶ms) // process compression chd_codec_type compression[4]; memcpy(compression, s_default_hd_compression, sizeof(compression)); - if (input_file == nullptr) + if (!input_file) compression[0] = compression[1] = compression[2] = compression[3] = CHD_CODEC_NONE; parse_compression(params, compression); - if (input_file == nullptr && compression[0] != CHD_CODEC_NONE) + if (!input_file && compression[0] != CHD_CODEC_NONE) report_error(1, "Blank hard disks must be uncompressed"); // process numprocessors @@ -1746,7 +1743,7 @@ static void do_create_hd(parameters_t ¶ms) if (ident_str != params.end()) { // load the file - file_error filerr = core_fload(ident_str->second->c_str(), identdata); + file_error filerr = util::core_file::load(ident_str->second->c_str(), identdata); if (filerr != FILERR_NONE) report_error(1, "Error reading ident file (%s)", ident_str->second->c_str()); @@ -1775,7 +1772,7 @@ static void do_create_hd(parameters_t ¶ms) // if no CHS values, try to guess them if (cylinders == 0) { - if (input_file == nullptr && filesize == 0) + if (!input_file && filesize == 0) report_error(1, "Blank hard drives must specify either a length or a set of CHS values"); guess_chs((input_file_str != params.end()) ? input_file_str->second : nullptr, filesize, sector_size, cylinders, heads, sectors, sector_size); } @@ -1786,10 +1783,10 @@ static void do_create_hd(parameters_t ¶ms) printf("Output CHD: %s\n", output_chd_str->c_str()); if (output_parent.opened()) printf("Parent CHD: %s\n", params.find(OPTION_OUTPUT_PARENT)->second->c_str()); - if (input_file != nullptr) + if (input_file) { printf("Input file: %s\n", input_file_str->second->c_str()); - if (input_start != 0 || input_end != core_fsize(input_file)) + if (input_start != 0 || input_end != input_file->size()) { printf("Input start: %s\n", big_int_string(tempstr, input_start)); printf("Input length: %s\n", big_int_string(tempstr, filesize)); @@ -1808,7 +1805,7 @@ static void do_create_hd(parameters_t ¶ms) try { // create the new hard drive - chd = new chd_rawfile_compressor(input_file, input_start, input_end); + chd = new chd_rawfile_compressor(*input_file, input_start, input_end); chd_error err; if (output_parent.opened()) err = chd->create(output_chd_str->c_str(), UINT64(totalsectors) * UINT64(sector_size), hunk_size, compression, output_parent); @@ -1832,7 +1829,7 @@ static void do_create_hd(parameters_t ¶ms) } // compress it generically - if (input_file != nullptr) + if (input_file) compress_common(*chd); delete chd; } @@ -2236,11 +2233,11 @@ static void do_extract_raw(parameters_t ¶ms) } // catch errors so we can close & delete the output file - core_file *output_file = nullptr; + util::core_file::ptr output_file; try { // process output file - file_error filerr = core_fopen(output_file_str->second->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &output_file); + file_error filerr = util::core_file::open(output_file_str->second->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file); if (filerr != FILERR_NONE) report_error(1, "Unable to open file (%s)", output_file_str->second->c_str()); @@ -2257,7 +2254,7 @@ static void do_extract_raw(parameters_t ¶ms) report_error(1, "Error reading CHD file (%s): %s", params.find(OPTION_INPUT)->second->c_str(), chd_file::error_string(err)); // write to the output - UINT32 count = core_fwrite(output_file, &buffer[0], bytes_to_read); + UINT32 count = output_file->write(&buffer[0], bytes_to_read); if (count != bytes_to_read) report_error(1, "Error writing to file; check disk space (%s)", output_file_str->second->c_str()); @@ -2266,7 +2263,7 @@ static void do_extract_raw(parameters_t ¶ms) } // finish up - core_fclose(output_file); + output_file.reset(); printf("Extraction complete \n"); } catch (...) @@ -2274,7 +2271,7 @@ static void do_extract_raw(parameters_t ¶ms) // delete the output file if (output_file != nullptr) { - core_fclose(output_file); + output_file.reset(); osd_rmfile(output_file_str->second->c_str()); } throw; @@ -2329,8 +2326,8 @@ static void do_extract_cd(parameters_t ¶ms) printf("Input CHD: %s\n", params.find(OPTION_INPUT)->second->c_str()); // catch errors so we can close & delete the output file - core_file *output_bin_file = nullptr; - core_file *output_toc_file = nullptr; + util::core_file::ptr output_bin_file; + util::core_file::ptr output_toc_file; try { int mode = MODE_NORMAL; @@ -2345,14 +2342,14 @@ static void do_extract_cd(parameters_t ¶ms) } // process output file - file_error filerr = core_fopen(output_file_str->second->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, &output_toc_file); + 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); if (filerr != FILERR_NONE) report_error(1, "Unable to open file (%s)", output_file_str->second->c_str()); // process output BIN file if (mode != MODE_GDI) { - filerr = core_fopen(output_bin_file_str->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &output_bin_file); + filerr = util::core_file::open(output_bin_file_str->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file); if (filerr != FILERR_NONE) report_error(1, "Unable to open file (%s)", output_bin_file_str->c_str()); } @@ -2365,7 +2362,7 @@ static void do_extract_cd(parameters_t ¶ms) // GDI must start with the # of tracks if (mode == MODE_GDI) { - core_fprintf(output_toc_file, "%d\n", toc->numtrks); + output_toc_file->printf("%d\n", toc->numtrks); } // iterate over tracks and copy all data @@ -2386,13 +2383,9 @@ static void do_extract_cd(parameters_t ¶ms) else trackbin_name.append(".bin"); - if (output_bin_file) - { - core_fclose(output_bin_file); - output_bin_file = nullptr; - } + output_bin_file.reset(); - filerr = core_fopen(trackbin_name.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &output_bin_file); + filerr = util::core_file::open(trackbin_name.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file); if (filerr != FILERR_NONE) report_error(1, "Unable to open file (%s)", trackbin_name.c_str()); @@ -2403,11 +2396,11 @@ static void do_extract_cd(parameters_t ¶ms) const cdrom_track_info &trackinfo = toc->tracks[tracknum]; if (mode == MODE_GDI) { - output_track_metadata(mode, output_toc_file, tracknum, trackinfo, core_filename_extract_base(trackbin_name.c_str()).c_str(), discoffs, outputoffs); + output_track_metadata(mode, *output_toc_file, tracknum, trackinfo, core_filename_extract_base(trackbin_name.c_str()).c_str(), discoffs, outputoffs); } else { - output_track_metadata(mode, output_toc_file, tracknum, trackinfo, core_filename_extract_base(output_bin_file_str->c_str()).c_str(), discoffs, outputoffs); + output_track_metadata(mode, *output_toc_file, tracknum, trackinfo, core_filename_extract_base(output_bin_file_str->c_str()).c_str(), discoffs, outputoffs); } // If this is bin/cue output and the CHD contains subdata, warn the user and don't include @@ -2455,8 +2448,8 @@ static void do_extract_cd(parameters_t ¶ms) // write it out if we need to if (bufferoffs == buffer.size() || frame == actualframes - 1) { - core_fseek(output_bin_file, outputoffs, SEEK_SET); - UINT32 byteswritten = core_fwrite(output_bin_file, &buffer[0], bufferoffs); + output_bin_file->seek(outputoffs, SEEK_SET); + UINT32 byteswritten = output_bin_file->write(&buffer[0], bufferoffs); if (byteswritten != bufferoffs) report_error(1, "Error writing frame %d to file (%s): %s\n", frame, output_file_str->second->c_str(), chd_file::error_string(CHDERR_WRITE_ERROR)); outputoffs += bufferoffs; @@ -2468,17 +2461,15 @@ static void do_extract_cd(parameters_t ¶ms) } // finish up - core_fclose(output_bin_file); - core_fclose(output_toc_file); + output_bin_file.reset(); + output_toc_file.reset(); printf("Extraction complete \n"); } catch (...) { // delete the output files - if (output_bin_file != nullptr) - core_fclose(output_bin_file); - if (output_toc_file != nullptr) - core_fclose(output_toc_file); + output_bin_file.reset(); + output_toc_file.reset(); osd_rmfile(output_bin_file_str->c_str()); osd_rmfile(output_file_str->second->c_str()); throw; @@ -2600,7 +2591,7 @@ static void do_extract_ld(parameters_t ¶ms) chd_error err = input_chd.read_hunk(framenum, nullptr); if (err != CHDERR_NONE) { - UINT64 filepos = core_ftell(input_chd); + UINT64 filepos = static_cast<util::core_file &>(input_chd).tell(); report_error(1, "Error reading hunk %" I64FMT "d at offset %" I64FMT "d from CHD file (%s): %s\n", framenum, filepos, params.find(OPTION_INPUT)->second->c_str(), chd_file::error_string(err)); } @@ -2678,7 +2669,7 @@ static void do_add_metadata(parameters_t ¶ms) dynamic_buffer file; if (file_str != params.end()) { - file_error filerr = core_fload(file_str->second->c_str(), file); + file_error filerr = util::core_file::load(file_str->second->c_str(), file); if (filerr != FILERR_NONE) report_error(1, "Error reading metadata file (%s)", file_str->second->c_str()); } @@ -2796,21 +2787,21 @@ static void do_dump_metadata(parameters_t ¶ms) report_error(1, "Error reading metadata: %s", chd_file::error_string(err)); // catch errors so we can close & delete the output file - core_file *output_file = nullptr; + util::core_file::ptr output_file; try { // create the file if (output_file_str != params.end()) { - file_error filerr = core_fopen(output_file_str->second->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &output_file); + file_error filerr = util::core_file::open(output_file_str->second->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file); if (filerr != FILERR_NONE) report_error(1, "Unable to open file (%s)", output_file_str->second->c_str()); // output the metadata - UINT32 count = core_fwrite(output_file, &buffer[0], buffer.size()); + UINT32 count = output_file->write(&buffer[0], buffer.size()); if (count != buffer.size()) report_error(1, "Error writing file (%s)", output_file_str->second->c_str()); - core_fclose(output_file); + output_file.reset(); // provide some feedback std::string tempstr; @@ -2827,8 +2818,7 @@ static void do_dump_metadata(parameters_t ¶ms) catch (...) { // delete the output file - if (output_file != nullptr) - core_fclose(output_file); + output_file.reset(); osd_rmfile(output_file_str->second->c_str()); throw; } diff --git a/src/tools/imgtool/stream.cpp b/src/tools/imgtool/stream.cpp index 461d2fd99bd..4cc4c9ec2db 100644 --- a/src/tools/imgtool/stream.cpp +++ b/src/tools/imgtool/stream.cpp @@ -24,78 +24,112 @@ enum imgtype_t struct imgtool_stream { - imgtype_t imgtype; - int write_protect; - const char *name; // needed for clear - UINT64 position; - UINT64 filesize; + typedef std::unique_ptr<imgtool_stream> ptr; + + imgtool_stream(bool wp) + : imgtype(IMG_FILE) + , write_protect(wp) + , name(nullptr) + , position(0) + , filesize(0) + , file() + , buffer(nullptr) + { + } + + imgtool_stream( + bool wp, + util::core_file::ptr &&f) + : imgtype(IMG_FILE) + , write_protect(wp) + , name(nullptr) + , position(0) + , filesize(f->size()) + , file(std::move(f)) + , buffer(nullptr) + { + } + + imgtool_stream(bool wp, std::size_t size) + : imgtype(IMG_MEM) + , write_protect(wp) + , name(nullptr) + , position(0) + , filesize(size) + , file() + , buffer(reinterpret_cast<std::uint8_t *>(malloc(size))) + { + } + + imgtool_stream(bool wp, std::size_t size, void *buf) + : imgtype(IMG_MEM) + , write_protect(wp) + , name(nullptr) + , position(0) + , filesize(size) + , file() + , buffer(reinterpret_cast<std::uint8_t *>(buf)) + { + } - union + ~imgtool_stream() { - core_file *file; - UINT8 *buffer; - } u; + free(buffer); + } + + imgtype_t imgtype; + bool write_protect; + const char *name; // needed for clear + std::uint64_t position; + std::uint64_t filesize; + + util::core_file::ptr file; + std::uint8_t *buffer; }; static imgtool_stream *stream_open_zip(const char *zipname, const char *subname, int read_or_write) { - imgtool_stream *imgfile = nullptr; -// zip_error ziperr; - zip_file *z = nullptr; - const zip_file_header *zipent; - FILE *f; - if (read_or_write) - goto error; + return nullptr; /* check to see if the file exists */ - f = fopen(zipname, "r"); + FILE *f = fopen(zipname, "r"); if (!f) - goto error; + return nullptr; fclose(f); - imgfile = (imgtool_stream *)malloc(sizeof(imgtool_stream)); - if (!imgfile) - goto error; + imgtool_stream::ptr imgfile(new imgtool_stream(true)); - memset(imgfile, 0, sizeof(*imgfile)); imgfile->imgtype = IMG_MEM; - imgfile->write_protect = 1; - imgfile->position = 0; -// ziperr = + zip_file *z = nullptr; + const zip_file_header *zipent = nullptr; zip_file_open(zipname, &z); if (!z) goto error; zipent = zip_file_first_file(z); - while(zipent && subname && strcmp(subname, zipent->filename)) + while (zipent && subname && strcmp(subname, zipent->filename)) zipent = zip_file_next_file(z); if (!zipent) goto error; imgfile->filesize = zipent->uncompressed_length; - imgfile->u.buffer = (UINT8*)malloc(zipent->uncompressed_length); - if (!imgfile->u.buffer) + imgfile->buffer = reinterpret_cast<std::uint8_t *>(malloc(zipent->uncompressed_length)); + if (!imgfile->buffer) goto error; - if (zip_file_decompress(z, imgfile->u.buffer, zipent->uncompressed_length)) + if (zip_file_decompress(z, imgfile->buffer, zipent->uncompressed_length)) goto error; zip_file_close(z); - return imgfile; + return imgfile.release(); error: if (z) zip_file_close(z); - if (imgfile) - { - if (imgfile->u.buffer) - free(imgfile->u.buffer); - free(imgfile); - } return nullptr; } @@ -103,9 +137,6 @@ error: imgtool_stream *stream_open(const char *fname, int read_or_write) { - file_error filerr; - const char *ext; - imgtool_stream *imgfile = nullptr; static const UINT32 write_modes[] = { OPEN_FLAG_READ, @@ -113,118 +144,70 @@ imgtool_stream *stream_open(const char *fname, int read_or_write) OPEN_FLAG_READ | OPEN_FLAG_WRITE, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE }; - core_file *f = nullptr; - char *buf = nullptr; - int len, i; imgtool_stream *s = nullptr; char c; /* maybe we are just a ZIP? */ - ext = strrchr(fname, '.'); + const char *ext = strrchr(fname, '.'); if (ext && !core_stricmp(ext, ".zip")) return stream_open_zip(fname, nullptr, read_or_write); - filerr = core_fopen(fname, write_modes[read_or_write], &f); + util::core_file::ptr f = nullptr; + auto const filerr = util::core_file::open(fname, write_modes[read_or_write], f); if (filerr != FILERR_NONE) { if (!read_or_write) { - len = strlen(fname); + int const len = strlen(fname); /* can't open the file; try opening ZIP files with other names */ - buf = (char*)malloc(len + 1); - if (!buf) - goto error; - strcpy(buf, fname); + std::vector<char> buf(len + 1); + strcpy(&buf[0], fname); - for(i = len-1; !s && (i >= 0); i--) + for (int i = len-1; !s && (i >= 0); i--) { if ((buf[i] == '\\') || (buf[i] == '/')) { c = buf[i]; buf[i] = '\0'; - s = stream_open_zip(buf, buf + i + 1, read_or_write); + s = stream_open_zip(&buf[0], &buf[i + 1], read_or_write); buf[i] = c; } } - free(buf); - buf = nullptr; if (s) return s; } /* ah well, it was worth a shot */ - goto error; + return nullptr; } - imgfile = (imgtool_stream *)malloc(sizeof(imgtool_stream)); - if (!imgfile) - goto error; + imgtool_stream::ptr imgfile(new imgtool_stream(read_or_write ? false : true, std::move(f))); /* Normal file */ - memset(imgfile, 0, sizeof(*imgfile)); - imgfile->imgtype = IMG_FILE; - imgfile->position = 0; - imgfile->filesize = core_fsize(f); - imgfile->write_protect = read_or_write ? 0 : 1; - imgfile->u.file = f; imgfile->name = fname; - return imgfile; - -error: - if (imgfile != nullptr) - free((void *) imgfile); - if (f != nullptr) - core_fclose(f); - if (buf) - free(buf); - return (imgtool_stream *) nullptr; + return imgfile.release(); } imgtool_stream *stream_open_write_stream(int size) { - imgtool_stream *imgfile; - - imgfile = (imgtool_stream *)malloc(sizeof(imgtool_stream)); - if (!imgfile) - return nullptr; - - imgfile->imgtype = IMG_MEM; - imgfile->write_protect = 0; - imgfile->position = 0; - imgfile->filesize = size; - imgfile->u.buffer = (UINT8*)malloc(size); - - if (!imgfile->u.buffer) - { - free(imgfile); + imgtool_stream::ptr imgfile(new imgtool_stream(false, size)); + if (!imgfile->buffer) return nullptr; - } - return imgfile; + return imgfile.release(); } imgtool_stream *stream_open_mem(void *buf, size_t sz) { - imgtool_stream *imgfile; - - imgfile = (imgtool_stream *)malloc(sizeof(imgtool_stream)); - if (!imgfile) - return nullptr; + imgtool_stream::ptr imgfile(new imgtool_stream(false, sz, buf)); - memset(imgfile, 0, sizeof(*imgfile)); - imgfile->imgtype = IMG_MEM; - imgfile->position = 0; - imgfile->write_protect = 0; - - imgfile->filesize = sz; - imgfile->u.buffer = (UINT8*)buf; - return imgfile; + return imgfile.release(); } @@ -233,36 +216,14 @@ void stream_close(imgtool_stream *s) { assert(s != nullptr); - switch(s->imgtype) - { - case IMG_FILE: - if (s->u.file != nullptr) - { - core_fclose(s->u.file); - s->u.file = nullptr; - } - break; - - case IMG_MEM: - if (s->u.buffer != nullptr) - { - free(s->u.buffer); - s->u.buffer = nullptr; - } - break; - - default: - assert(0); - break; - } - free((void *) s); + delete s; } -core_file *stream_core_file(imgtool_stream *stream) +util::core_file *stream_core_file(imgtool_stream *stream) { - return (stream->imgtype == IMG_FILE) ? stream->u.file : nullptr; + return (stream->imgtype == IMG_FILE) ? stream->file.get() : nullptr; } @@ -275,8 +236,8 @@ UINT32 stream_read(imgtool_stream *stream, void *buf, UINT32 sz) { case IMG_FILE: assert(sz == (UINT32) sz); - core_fseek(stream->u.file, stream->position, SEEK_SET); - result = core_fread(stream->u.file, buf, (UINT32) sz); + stream->file->seek(stream->position, SEEK_SET); + result = stream->file->read(buf, (UINT32) sz); break; case IMG_MEM: @@ -284,7 +245,7 @@ UINT32 stream_read(imgtool_stream *stream, void *buf, UINT32 sz) if (sz > (stream->filesize - stream->position)) sz = (UINT32) (stream->filesize - stream->position); - memcpy(buf, stream->u.buffer + stream->position, sz); + memcpy(buf, stream->buffer + stream->position, sz); result = sz; break; @@ -312,11 +273,11 @@ UINT32 stream_write(imgtool_stream *s, const void *buf, UINT32 sz) if (s->filesize < s->position + sz) { /* try to expand the buffer */ - if (s->u.buffer) free(s->u.buffer); + if (s->buffer) free(s->buffer); new_buffer = malloc(s->position + sz); if (new_buffer) { - s->u.buffer = (UINT8*)new_buffer; + s->buffer = (UINT8*)new_buffer; s->filesize = s->position + sz; } } @@ -325,14 +286,14 @@ UINT32 stream_write(imgtool_stream *s, const void *buf, UINT32 sz) if (sz > (s->filesize - s->position)) sz = (UINT32) (s->filesize - s->position); - memcpy(s->u.buffer + s->position, buf, sz); + memcpy(s->buffer + s->position, buf, sz); result = sz; } break; case IMG_FILE: - core_fseek(s->u.file, s->position, SEEK_SET); - result = core_fwrite(s->u.file, buf, sz); + s->file->seek(s->position, SEEK_SET); + result = s->file->write(buf, sz); break; default: @@ -365,7 +326,7 @@ void *stream_getptr(imgtool_stream *f) switch(f->imgtype) { case IMG_MEM: - ptr = f->u.buffer; + ptr = f->buffer; break; default: @@ -445,7 +406,7 @@ int stream_crc(imgtool_stream *s, unsigned long *result) switch(s->imgtype) { case IMG_MEM: - *result = crc32(0, (unsigned char *) s->u.buffer, (size_t) s->filesize); + *result = crc32(0, (unsigned char *) s->buffer, (size_t) s->filesize); break; default: diff --git a/src/tools/imgtool/stream.h b/src/tools/imgtool/stream.h index 13e6e0d727f..ee362c9c32b 100644 --- a/src/tools/imgtool/stream.h +++ b/src/tools/imgtool/stream.h @@ -20,7 +20,7 @@ imgtool_stream *stream_open(const char *fname, int read_or_write); /* similar p imgtool_stream *stream_open_write_stream(int filesize); imgtool_stream *stream_open_mem(void *buf, size_t sz); void stream_close(imgtool_stream *stream); -core_file *stream_core_file(imgtool_stream *stream); +util::core_file *stream_core_file(imgtool_stream *stream); UINT32 stream_read(imgtool_stream *stream, void *buf, UINT32 sz); UINT32 stream_write(imgtool_stream *stream, const void *buf, UINT32 sz); UINT64 stream_size(imgtool_stream *stream); diff --git a/src/tools/ldresample.cpp b/src/tools/ldresample.cpp index 771c4e94676..1f04edac3f0 100644 --- a/src/tools/ldresample.cpp +++ b/src/tools/ldresample.cpp @@ -554,7 +554,7 @@ int main(int argc, char *argv[]) // open the destination file chd_resample_compressor dstfile(srcfile, info, INT64(offset * 65536.0 * 256.0), INT64(slope * 65536.0 * 256.0)); err = create_chd(dstfile, dstfilename, srcfile, info); - if (dstfile == nullptr) + if (!dstfile.opened()) { fprintf(stderr, "Unable to create file '%s'\n", dstfilename); return 1; diff --git a/src/tools/pngcmp.cpp b/src/tools/pngcmp.cpp index dda54ed7730..5103740389b 100644 --- a/src/tools/pngcmp.cpp +++ b/src/tools/pngcmp.cpp @@ -72,7 +72,7 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img bitmap_argb32 bitmap2; bitmap_argb32 finalbitmap; int width, height, maxwidth; - core_file *file = nullptr; + util::core_file::ptr file; file_error filerr; png_error pngerr; int error = 100; @@ -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 = core_fopen(imgfile1.c_str(), OPEN_FLAG_READ, &file); + filerr = util::core_file::open(imgfile1.c_str(), OPEN_FLAG_READ, file); if (filerr != FILERR_NONE) { printf("Could not open %s (%d)\n", imgfile1.c_str(), filerr); @@ -88,8 +88,8 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img } /* load the source image */ - pngerr = png_read_bitmap(file, bitmap1); - core_fclose(file); + pngerr = png_read_bitmap(*file, bitmap1); + file.reset(); if (pngerr != PNGERR_NONE) { printf("Could not read %s (%d)\n", imgfile1.c_str(), pngerr); @@ -97,7 +97,7 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img } /* open the source image */ - filerr = core_fopen(imgfile2.c_str(), OPEN_FLAG_READ, &file); + filerr = util::core_file::open(imgfile2.c_str(), OPEN_FLAG_READ, file); if (filerr != FILERR_NONE) { printf("Could not open %s (%d)\n", imgfile2.c_str(), filerr); @@ -105,8 +105,8 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img } /* load the source image */ - pngerr = png_read_bitmap(file, bitmap2); - core_fclose(file); + pngerr = png_read_bitmap(*file, bitmap2); + file.reset(); if (pngerr != PNGERR_NONE) { printf("Could not read %s (%d)\n", imgfile2.c_str(), pngerr); @@ -170,14 +170,14 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img } /* write the final PNG */ - filerr = core_fopen(outfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &file); + filerr = util::core_file::open(outfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file); if (filerr != FILERR_NONE) { printf("Could not open %s (%d)\n", outfilename.c_str(), filerr); goto error; } - pngerr = png_write_bitmap(file, nullptr, finalbitmap, 0, nullptr); - core_fclose(file); + pngerr = png_write_bitmap(*file, nullptr, finalbitmap, 0, nullptr); + file.reset(); if (pngerr != PNGERR_NONE) { printf("Could not write %s (%d)\n", outfilename.c_str(), pngerr); diff --git a/src/tools/regrep.cpp b/src/tools/regrep.cpp index 16eaa21f7de..b0cad2497ae 100644 --- a/src/tools/regrep.cpp +++ b/src/tools/regrep.cpp @@ -148,15 +148,15 @@ static int CLIB_DECL compare_file(const void *file0ptr, const void *file1ptr); static summary_file *sort_file_list(void); /* HTML helpers */ -static core_file *create_file_and_output_header(std::string &filename, std::string &templatefile, std::string &title); -static void output_footer_and_close_file(core_file *file, std::string &templatefile, std::string &title); +static util::core_file::ptr create_file_and_output_header(std::string &filename, std::string &templatefile, std::string &title); +static void output_footer_and_close_file(util::core_file::ptr &&file, std::string &templatefile, std::string &title); /* report generators */ static void output_report(std::string &dirname, std::string &tempheader, std::string &tempfooter, summary_file *filelist); static int compare_screenshots(summary_file *curfile); static int generate_png_diff(const summary_file *curfile, std::string &destdir, const char *destname); static void create_linked_file(std::string &dirname, const summary_file *curfile, const summary_file *prevfile, const summary_file *nextfile, const char *pngfile, std::string &tempheader, std::string &tempfooter); -static void append_driver_list_table(const char *header, std::string &dirname, core_file *indexfile, const summary_file *listhead, std::string &tempheader, std::string &tempfooter); +static void append_driver_list_table(const char *header, std::string &dirname, util::core_file &indexfile, const summary_file *listhead, std::string &tempheader, std::string &tempfooter); @@ -235,7 +235,7 @@ int main(int argc, char *argv[]) /* read the template file into an astring */ std::string tempheader; - if (core_fload(tempfilename.c_str(), &buffer, &bufsize) == FILERR_NONE) + if (util::core_file::load(tempfilename.c_str(), &buffer, bufsize) == FILERR_NONE) { tempheader.assign((const char *)buffer, bufsize); osd_free(buffer); @@ -560,18 +560,18 @@ static summary_file *sort_file_list(void) HTML file with a standard header -------------------------------------------------*/ -static core_file *create_file_and_output_header(std::string &filename, std::string &templatefile, std::string &title) +static util::core_file::ptr create_file_and_output_header(std::string &filename, std::string &templatefile, std::string &title) { - core_file *file; + util::core_file::ptr file; /* create the indexfile */ - if (core_fopen(filename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, &file) != FILERR_NONE) - return nullptr; + if (util::core_file::open(filename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, file) != FILERR_NONE) + return util::core_file::ptr(); /* print a header */ std::string modified(templatefile); strreplace(modified, "<!--TITLE-->", title.c_str()); - core_fwrite(file, modified.c_str(), modified.length()); + file->write(modified.c_str(), modified.length()); /* return the file */ return file; @@ -583,12 +583,12 @@ static core_file *create_file_and_output_header(std::string &filename, std::stri standard footer to an HTML file and close it -------------------------------------------------*/ -static void output_footer_and_close_file(core_file *file, std::string &templatefile, std::string &title) +static void output_footer_and_close_file(util::core_file::ptr &&file, std::string &templatefile, std::string &title) { std::string modified(templatefile); strreplace(modified, "<!--TITLE-->", title.c_str()); - core_fwrite(file, modified.c_str(), modified.length()); - core_fclose(file); + file->write(modified.c_str(), modified.length()); + file.reset(); } @@ -609,7 +609,7 @@ static void output_report(std::string &dirname, std::string &tempheader, std::st std::string title("MAME Regressions"); std::string tempname; int listnum, bucknum; - core_file *indexfile; + util::core_file::ptr indexfile; int count = 0, total; /* initialize the lists */ @@ -688,7 +688,7 @@ static void output_report(std::string &dirname, std::string &tempheader, std::st /* output header */ tempname = string_format("%s" PATH_SEPARATOR "%s", dirname.c_str(), "index.html"); indexfile = create_file_and_output_header(tempname, tempheader, title); - if (indexfile == nullptr) + if (!indexfile) { fprintf(stderr, "Error creating file '%s'\n", tempname.c_str()); return; @@ -702,12 +702,12 @@ static void output_report(std::string &dirname, std::string &tempheader, std::st if (buckethead[curbucket] != nullptr) { fprintf(stderr, "Outputting bucket: %s\n", bucket_name[curbucket]); - append_driver_list_table(bucket_name[curbucket], dirname, indexfile, buckethead[curbucket], tempheader, tempfooter); + append_driver_list_table(bucket_name[curbucket], dirname, *indexfile, buckethead[curbucket], tempheader, tempfooter); } } /* output footer */ - output_footer_and_close_file(indexfile, tempfooter, title); + output_footer_and_close_file(std::move(indexfile), tempfooter, title); } @@ -729,13 +729,13 @@ static int compare_screenshots(summary_file *curfile) { std::string fullname; file_error filerr; - core_file *file; + util::core_file::ptr file; /* get the filename for the image */ fullname = string_format("%s" PATH_SEPARATOR "snap" PATH_SEPARATOR "%s" PATH_SEPARATOR "final.png", lists[listnum].dir, curfile->name); /* open the file */ - filerr = core_fopen(fullname.c_str(), OPEN_FLAG_READ, &file); + filerr = util::core_file::open(fullname.c_str(), OPEN_FLAG_READ, file); /* if that failed, look in the old location */ if (filerr != FILERR_NONE) @@ -744,14 +744,14 @@ 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 = core_fopen(fullname.c_str(), OPEN_FLAG_READ, &file); + filerr = util::core_file::open(fullname.c_str(), OPEN_FLAG_READ, file); } /* if that worked, load the file */ if (filerr == FILERR_NONE) { - png_read_bitmap(file, bitmaps[listnum]); - core_fclose(file); + png_read_bitmap(*file, bitmaps[listnum]); + file.reset(); } } @@ -836,7 +836,7 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir, int width, height, maxwidth; int bitmapcount = 0; int listnum, bmnum; - core_file *file = nullptr; + util::core_file::ptr file; file_error filerr; png_error pngerr; int error = -1; @@ -853,13 +853,13 @@ 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 = core_fopen(tempname.c_str(), OPEN_FLAG_READ, &file); + filerr = util::core_file::open(tempname.c_str(), OPEN_FLAG_READ, file); if (filerr != FILERR_NONE) goto error; /* load the source image */ - pngerr = png_read_bitmap(file, bitmaps[bitmapcount++]); - core_fclose(file); + pngerr = png_read_bitmap(*file, bitmaps[bitmapcount++]); + file.reset(); if (pngerr != PNGERR_NONE) goto error; } @@ -925,11 +925,11 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir, } /* write the final PNG */ - filerr = core_fopen(dstfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &file); + filerr = util::core_file::open(dstfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file); if (filerr != FILERR_NONE) goto error; - pngerr = png_write_bitmap(file, nullptr, finalbitmap, 0, nullptr); - core_fclose(file); + pngerr = png_write_bitmap(*file, nullptr, finalbitmap, 0, nullptr); + file.reset(); if (pngerr != PNGERR_NONE) goto error; @@ -953,7 +953,7 @@ static void create_linked_file(std::string &dirname, const summary_file *curfile std::string linkname; std::string filename; std::string title; - core_file *linkfile; + util::core_file::ptr linkfile; int listnum; /* create the filename */ @@ -970,19 +970,19 @@ static void create_linked_file(std::string &dirname, const summary_file *curfile } /* link to the previous/next entries */ - core_fprintf(linkfile, "\t<p>\n"); - core_fprintf(linkfile, "\t<table width=\"100%%\">\n"); - core_fprintf(linkfile, "\t\t<td align=\"left\" width=\"40%%\" style=\"border:none\">"); + linkfile->printf("\t<p>\n"); + linkfile->printf("\t<table width=\"100%%\">\n"); + linkfile->printf("\t\t<td align=\"left\" width=\"40%%\" style=\"border:none\">"); if (prevfile != nullptr) - core_fprintf(linkfile, "<a href=\"%s.html\"><< %s (%s)</a>", prevfile->name, prevfile->name, prevfile->source); - core_fprintf(linkfile, "</td>\n"); - core_fprintf(linkfile, "\t\t<td align=\"center\" width=\"20%%\" style=\"border:none\"><a href=\"index.html\">Home</a></td>\n"); - core_fprintf(linkfile, "\t\t<td align=\"right\" width=\"40%%\" style=\"border:none\">"); + linkfile->printf("<a href=\"%s.html\"><< %s (%s)</a>", prevfile->name, prevfile->name, prevfile->source); + linkfile->printf("</td>\n"); + linkfile->printf("\t\t<td align=\"center\" width=\"20%%\" style=\"border:none\"><a href=\"index.html\">Home</a></td>\n"); + linkfile->printf("\t\t<td align=\"right\" width=\"40%%\" style=\"border:none\">"); if (nextfile != nullptr) - core_fprintf(linkfile, "<a href=\"%s.html\">%s (%s) >></a>", nextfile->name, nextfile->name, nextfile->source); - core_fprintf(linkfile, "</td>\n"); - core_fprintf(linkfile, "\t</table>\n"); - core_fprintf(linkfile, "\t</p>\n"); + linkfile->printf("<a href=\"%s.html\">%s (%s) >></a>", nextfile->name, nextfile->name, nextfile->source); + linkfile->printf("</td>\n"); + linkfile->printf("\t</table>\n"); + linkfile->printf("\t</p>\n"); /* output data for each one */ for (listnum = 0; listnum < list_count; listnum++) @@ -990,34 +990,34 @@ static void create_linked_file(std::string &dirname, const summary_file *curfile int imageindex = -1; /* generate the HTML */ - core_fprintf(linkfile, "\n\t<h2>%s</h2>\n", lists[listnum].version); - core_fprintf(linkfile, "\t<p>\n"); - core_fprintf(linkfile, "\t<b>Status:</b> %s\n", status_text[curfile->status[listnum]]); + linkfile->printf("\n\t<h2>%s</h2>\n", lists[listnum].version); + linkfile->printf("\t<p>\n"); + linkfile->printf("\t<b>Status:</b> %s\n", status_text[curfile->status[listnum]]); if (pngfile != nullptr) imageindex = get_unique_index(curfile, listnum); if (imageindex != -1) - core_fprintf(linkfile, " [%d]", imageindex); - core_fprintf(linkfile, "\t</p>\n"); + linkfile->printf(" [%d]", imageindex); + linkfile->printf("\t</p>\n"); if (curfile->text[listnum].length() != 0) { - core_fprintf(linkfile, "\t<p>\n"); - core_fprintf(linkfile, "\t<b>Errors:</b>\n"); - core_fprintf(linkfile, "\t<pre>%s</pre>\n", curfile->text[listnum].c_str()); - core_fprintf(linkfile, "\t</p>\n"); + linkfile->printf("\t<p>\n"); + linkfile->printf("\t<b>Errors:</b>\n"); + linkfile->printf("\t<pre>%s</pre>\n", curfile->text[listnum].c_str()); + linkfile->printf("\t</p>\n"); } } /* output link to the image */ if (pngfile != nullptr) { - core_fprintf(linkfile, "\n\t<h2>Screenshot Comparisons</h2>\n"); - core_fprintf(linkfile, "\t<p>\n"); - core_fprintf(linkfile, "\t<img src=\"%s\" />\n", pngfile); - core_fprintf(linkfile, "\t</p>\n"); + linkfile->printf("\n\t<h2>Screenshot Comparisons</h2>\n"); + linkfile->printf("\t<p>\n"); + linkfile->printf("\t<img src=\"%s\" />\n", pngfile); + linkfile->printf("\t</p>\n"); } /* output footer */ - output_footer_and_close_file(linkfile, tempfooter, title); + output_footer_and_close_file(std::move(linkfile), tempfooter, title); } @@ -1026,28 +1026,28 @@ static void create_linked_file(std::string &dirname, const summary_file *curfile of drivers from a list to an HTML file -------------------------------------------------*/ -static void append_driver_list_table(const char *header, std::string &dirname, core_file *indexfile, const summary_file *listhead, std::string &tempheader, std::string &tempfooter) +static void append_driver_list_table(const char *header, std::string &dirname, util::core_file &indexfile, const summary_file *listhead, std::string &tempheader, std::string &tempfooter) { const summary_file *curfile, *prevfile; int width = 100 / (2 + list_count); int listnum; /* output a header */ - core_fprintf(indexfile, "\t<h2>%s</h2>\n", header); + indexfile.printf("\t<h2>%s</h2>\n", header); /* start the table */ - core_fprintf(indexfile, "\t<p><table width=\"90%%\">\n"); - core_fprintf(indexfile, "\t\t<tr>\n\t\t\t<th width=\"%d%%\">Source</th><th width=\"%d%%\">Driver</th>", width, width); + indexfile.printf("\t<p><table width=\"90%%\">\n"); + indexfile.printf("\t\t<tr>\n\t\t\t<th width=\"%d%%\">Source</th><th width=\"%d%%\">Driver</th>", width, width); for (listnum = 0; listnum < list_count; listnum++) - core_fprintf(indexfile, "<th width=\"%d%%\">%s</th>", width, lists[listnum].version); - core_fprintf(indexfile, "\n\t\t</tr>\n"); + indexfile.printf("<th width=\"%d%%\">%s</th>", width, lists[listnum].version); + indexfile.printf("\n\t\t</tr>\n"); /* if nothing, print a default message */ if (listhead == nullptr) { - core_fprintf(indexfile, "\t\t<tr>\n\t\t\t"); - core_fprintf(indexfile, "<td colspan=\"%d\" align=\"center\">(No regressions detected)</td>", list_count + 2); - core_fprintf(indexfile, "\n\t\t</tr>\n"); + indexfile.printf("\t\t<tr>\n\t\t\t"); + indexfile.printf("<td colspan=\"%d\" align=\"center\">(No regressions detected)</td>", list_count + 2); + indexfile.printf("\n\t\t</tr>\n"); } /* iterate over files */ @@ -1083,10 +1083,10 @@ static void append_driver_list_table(const char *header, std::string &dirname, c create_linked_file(dirname, curfile, prevfile, curfile->next, (pngdiffname[0] == 0) ? nullptr : pngdiffname, tempheader, tempfooter); /* create a row */ - core_fprintf(indexfile, "\t\t<tr>\n\t\t\t"); + indexfile.printf("\t\t<tr>\n\t\t\t"); if (rowspan > 0) - core_fprintf(indexfile, "<td rowspan=\"%d\">%s</td>", rowspan, curfile->source); - core_fprintf(indexfile, "<td><a href=\"%s.html\">%s</a></td>", curfile->name, curfile->name); + indexfile.printf("<td rowspan=\"%d\">%s</td>", rowspan, curfile->source); + indexfile.printf("<td><a href=\"%s.html\">%s</a></td>", curfile->name, curfile->name); for (listnum = 0; listnum < list_count; listnum++) { int unique_index = -1; @@ -1094,16 +1094,16 @@ static void append_driver_list_table(const char *header, std::string &dirname, c if (pngdiffname[0] != 0) unique_index = get_unique_index(curfile, listnum); if (unique_index != -1) - core_fprintf(indexfile, "<td><span style=\"%s\"> </span> %s [<a href=\"%s\" target=\"blank\">%d</a>]</td>", status_color[curfile->status[listnum]], status_text[curfile->status[listnum]], pngdiffname, unique_index); + indexfile.printf("<td><span style=\"%s\"> </span> %s [<a href=\"%s\" target=\"blank\">%d</a>]</td>", status_color[curfile->status[listnum]], status_text[curfile->status[listnum]], pngdiffname, unique_index); else - core_fprintf(indexfile, "<td><span style=\"%s\"> </span> %s</td>", status_color[curfile->status[listnum]], status_text[curfile->status[listnum]]); + indexfile.printf("<td><span style=\"%s\"> </span> %s</td>", status_color[curfile->status[listnum]], status_text[curfile->status[listnum]]); } - core_fprintf(indexfile, "\n\t\t</tr>\n"); + indexfile.printf("\n\t\t</tr>\n"); /* also print the name and source file */ printf("%s %s\n", curfile->name, curfile->source); } /* end of table */ - core_fprintf(indexfile, "</table></p>\n"); + indexfile.printf("</table></p>\n"); } diff --git a/src/tools/split.cpp b/src/tools/split.cpp index a6b97e7175d..f942e1481c2 100644 --- a/src/tools/split.cpp +++ b/src/tools/split.cpp @@ -64,7 +64,7 @@ static void compute_hash_as_string(std::string &buffer, void *data, UINT32 lengt static int split_file(const char *filename, const char *basename, UINT32 splitsize) { std::string outfilename, basefilename, splitfilename; - core_file *outfile = nullptr, *infile = nullptr, *splitfile = nullptr; + util::core_file::ptr outfile, infile, splitfile; std::string computedhash; void *splitbuffer = nullptr; int index, partnum; @@ -81,7 +81,7 @@ static int split_file(const char *filename, const char *basename, UINT32 splitsi splitsize *= 1024 * 1024; // open the file for read - filerr = core_fopen(filename, OPEN_FLAG_READ, &infile); + filerr = util::core_file::open(filename, OPEN_FLAG_READ, infile); if (filerr != FILERR_NONE) { fprintf(stderr, "Fatal error: unable to open file '%s'\n", filename); @@ -89,7 +89,7 @@ static int split_file(const char *filename, const char *basename, UINT32 splitsi } // get the total length - totallength = core_fsize(infile); + totallength = infile->size(); if (totallength < splitsize) { fprintf(stderr, "Fatal error: file is smaller than the split size\n"); @@ -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 = core_fopen(splitfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, &splitfile); + filerr = util::core_file::open(splitfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, splitfile); if (filerr != FILERR_NONE) { fprintf(stderr, "Fatal error: unable to create split file '%s'\n", splitfilename.c_str()); @@ -127,8 +127,8 @@ static int split_file(const char *filename, const char *basename, UINT32 splitsi } // write the basics out - core_fprintf(splitfile, "splitfile=%s\n", basefilename.c_str()); - core_fprintf(splitfile, "splitsize=%d\n", splitsize); + splitfile->printf("splitfile=%s\n", basefilename.c_str()); + splitfile->printf("splitsize=%d\n", splitsize); printf("Split file is '%s'\n", splitfilename.c_str()); printf("Splitting file %s into chunks of %dMB...\n", basefilename.c_str(), splitsize / (1024 * 1024)); @@ -141,7 +141,7 @@ static int split_file(const char *filename, const char *basename, UINT32 splitsi printf("Reading part %d...", partnum); // read as much as we can from the file - length = core_fread(infile, splitbuffer, splitsize); + length = infile->read(splitbuffer, splitsize); if (length == 0) break; @@ -149,13 +149,13 @@ static int split_file(const char *filename, const char *basename, UINT32 splitsi compute_hash_as_string(computedhash, splitbuffer, length); // write that info to the split file - core_fprintf(splitfile, "hash=%s file=%s.%03d\n", computedhash.c_str(), basefilename.c_str(), partnum); + splitfile->printf("hash=%s file=%s.%03d\n", computedhash.c_str(), basefilename.c_str(), partnum); // compute the full filename for this guy outfilename = string_format("%s.%03d", basename, partnum); // create it - filerr = core_fopen(outfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &outfile); + filerr = util::core_file::open(outfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile); if (filerr != FILERR_NONE) { printf("\n"); @@ -166,15 +166,14 @@ static int split_file(const char *filename, const char *basename, UINT32 splitsi printf(" writing %s.%03d...", basefilename.c_str(), partnum); // write the data - actual = core_fwrite(outfile, splitbuffer, length); + actual = outfile->write(splitbuffer, length); if (actual != length) { printf("\n"); fprintf(stderr, "Fatal error: Error writing output file (out of space?)\n"); goto cleanup; } - core_fclose(outfile); - outfile = nullptr; + outfile.reset(); printf(" done\n"); @@ -188,17 +187,17 @@ static int split_file(const char *filename, const char *basename, UINT32 splitsi error = 0; cleanup: - if (splitfile != nullptr) + if (splitfile) { - core_fclose(splitfile); + splitfile.reset(); if (error != 0) remove(splitfilename.c_str()); } - if (infile != nullptr) - core_fclose(infile); - if (outfile != nullptr) + if (infile) + infile.reset(); + if (outfile) { - core_fclose(outfile); + outfile.reset(); if (error != 0) remove(outfilename.c_str()); } @@ -218,7 +217,7 @@ static int join_file(const char *filename, const char *outname, int write_output std::string expectedhash, computedhash; std::string outfilename, infilename; std::string basepath; - core_file *outfile = nullptr, *infile = nullptr, *splitfile = nullptr; + util::core_file::ptr outfile, infile, splitfile; void *splitbuffer = nullptr; file_error filerr; UINT32 splitsize; @@ -227,7 +226,7 @@ static int join_file(const char *filename, const char *outname, int write_output int index; // open the file for read - filerr = core_fopen(filename, OPEN_FLAG_READ, &splitfile); + filerr = util::core_file::open(filename, OPEN_FLAG_READ, splitfile); if (filerr != FILERR_NONE) { fprintf(stderr, "Fatal error: unable to open file '%s'\n", filename); @@ -235,7 +234,7 @@ static int join_file(const char *filename, const char *outname, int write_output } // read the first line and verify this is a split file - if (!core_fgets(buffer, sizeof(buffer), splitfile) || strncmp(buffer, "splitfile=", 10) != 0) + if (!splitfile->gets(buffer, sizeof(buffer)) || strncmp(buffer, "splitfile=", 10) != 0) { fprintf(stderr, "Fatal error: corrupt or incomplete split file at line:\n%s\n", buffer); goto cleanup; @@ -258,7 +257,7 @@ static int join_file(const char *filename, const char *outname, int write_output outfilename.insert(0, basepath); // read the split size - if (!core_fgets(buffer, sizeof(buffer), splitfile) || sscanf(buffer, "splitsize=%d", &splitsize) != 1) + if (!splitfile->gets(buffer, sizeof(buffer)) || sscanf(buffer, "splitsize=%d", &splitsize) != 1) { fprintf(stderr, "Fatal error: corrupt or incomplete split file at line:\n%s\n", buffer); goto cleanup; @@ -268,17 +267,16 @@ static int join_file(const char *filename, const char *outname, int write_output if (write_output) { // don't overwrite the original! - filerr = core_fopen(outfilename.c_str(), OPEN_FLAG_READ, &outfile); + filerr = util::core_file::open(outfilename.c_str(), OPEN_FLAG_READ, outfile); if (filerr == FILERR_NONE) { - core_fclose(outfile); - outfile = nullptr; + outfile.reset(); fprintf(stderr, "Fatal error: output file '%s' already exists\n", outfilename.c_str()); goto cleanup; } // open the output for write - filerr = core_fopen(outfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &outfile); + filerr = util::core_file::open(outfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile); if (filerr != FILERR_NONE) { fprintf(stderr, "Fatal error: unable to create file '%s'\n", outfilename.c_str()); @@ -289,7 +287,7 @@ static int join_file(const char *filename, const char *outname, int write_output printf("%s file '%s'...\n", write_output ? "Joining" : "Verifying", outfilename.c_str()); // now iterate through each file - while (core_fgets(buffer, sizeof(buffer), splitfile)) + while (splitfile->gets(buffer, sizeof(buffer))) { UINT32 length, actual; @@ -307,7 +305,7 @@ static int join_file(const char *filename, const char *outname, int write_output // read the file's contents infilename.insert(0, basepath); - filerr = core_fload(infilename.c_str(), &splitbuffer, &length); + filerr = util::core_file::load(infilename.c_str(), &splitbuffer, length); if (filerr != FILERR_NONE) { printf("\n"); @@ -331,7 +329,7 @@ static int join_file(const char *filename, const char *outname, int write_output { printf(" writing..."); - actual = core_fwrite(outfile, splitbuffer, length); + actual = outfile->write(splitbuffer, length); if (actual != length) { printf("\n"); @@ -357,13 +355,13 @@ static int join_file(const char *filename, const char *outname, int write_output error = 0; cleanup: - if (splitfile != nullptr) - core_fclose(splitfile); - if (infile != nullptr) - core_fclose(infile); - if (outfile != nullptr) + if (splitfile) + splitfile.reset(); + if (infile) + infile.reset(); + if (outfile) { - core_fclose(outfile); + outfile.reset(); if (error != 0) remove(outfilename.c_str()); } diff --git a/src/tools/src2html.cpp b/src/tools/src2html.cpp index 557313f1b3e..e95cbe11764 100644 --- a/src/tools/src2html.cpp +++ b/src/tools/src2html.cpp @@ -206,12 +206,12 @@ static int recurse_dir(int srcrootlen, int dstrootlen, std::string &srcdir, std: static int output_file(file_type type, int srcrootlen, int dstrootlen, std::string &srcfile, std::string &dstfile, bool link_to_file, std::string &tempheader, std::string &tempfooter); // HTML helpers -static core_file *create_file_and_output_header(std::string &filename, std::string &templatefile, std::string &path); -static void output_footer_and_close_file(core_file *file, std::string &templatefile, std::string &path); +static util::core_file::ptr create_file_and_output_header(std::string &filename, std::string &templatefile, std::string &path); +static void output_footer_and_close_file(util::core_file::ptr &&file, std::string &templatefile, std::string &path); // path helpers static std::string &normalized_subpath(std::string &dest, std::string &path, int start); -static void output_path_as_links(core_file *file, std::string &path, bool end_is_directory, bool link_to_file); +static void output_path_as_links(util::core_file &file, std::string &path, bool end_is_directory, bool link_to_file); static bool find_include_file(std::string &srcincpath, int srcrootlen, int dstrootlen, std::string &srcfile, std::string &dstfile, std::string &filename); @@ -279,7 +279,7 @@ int main(int argc, char *argv[]) // read the template file into an std::string UINT32 bufsize; void *buffer; - if (core_fload(tempfilename.c_str(), &buffer, &bufsize) == FILERR_NONE) + if (util::core_file::load(tempfilename.c_str(), &buffer, bufsize) == FILERR_NONE) { tempheader.assign((const char *)buffer, bufsize); osd_free(buffer); @@ -333,12 +333,12 @@ static int recurse_dir(int srcrootlen, int dstrootlen, std::string &srcdir, std: // create an index file std::string indexname; indexname = string_format("%s%c%s", dstdir.c_str(), PATH_SEPARATOR[0], "index.html"); - core_file *indexfile = create_file_and_output_header(indexname, tempheader, srcdir_subpath); + util::core_file::ptr indexfile = create_file_and_output_header(indexname, tempheader, srcdir_subpath); // output the directory navigation - core_fprintf(indexfile, "<h3>Viewing Directory: "); - output_path_as_links(indexfile, srcdir_subpath, true, false); - core_fprintf(indexfile, "</h3>"); + indexfile->printf("<h3>Viewing Directory: "); + output_path_as_links(*indexfile, srcdir_subpath, true, false); + indexfile->printf("</h3>"); // iterate first over directories, then over files int result = 0; @@ -398,7 +398,7 @@ static int recurse_dir(int srcrootlen, int dstrootlen, std::string &srcdir, std: { // add a header if (curlist == list) - core_fprintf(indexfile, "\t<h2>%s</h2>\n\t<ul>\n", (entry_type == ENTTYPE_DIR) ? "Directories" : "Files"); + indexfile->printf("\t<h2>%s</h2>\n\t<ul>\n", (entry_type == ENTTYPE_DIR) ? "Directories" : "Files"); // build the source filename std::string srcfile; @@ -422,7 +422,7 @@ static int recurse_dir(int srcrootlen, int dstrootlen, std::string &srcdir, std: { dstfile = string_format("%s%c%s.html", dstdir.c_str(), PATH_SEPARATOR[0], curlist->name.c_str()); if (indexfile != nullptr) - core_fprintf(indexfile, "\t<li><a href=\"%s.html\">%s</a></li>\n", curlist->name.c_str(), curlist->name.c_str()); + indexfile->printf("\t<li><a href=\"%s.html\">%s</a></li>\n", curlist->name.c_str(), curlist->name.c_str()); result = output_file(type, srcrootlen, dstrootlen, srcfile, dstfile, srcdir.compare(dstdir) == 0, tempheader, tempfooter); } } @@ -432,14 +432,14 @@ static int recurse_dir(int srcrootlen, int dstrootlen, std::string &srcdir, std: { dstfile = string_format("%s%c%s", dstdir.c_str(), PATH_SEPARATOR[0], curlist->name.c_str()); if (indexfile != nullptr) - core_fprintf(indexfile, "\t<li><a href=\"%s/index.html\">%s/</a></li>\n", curlist->name.c_str(), curlist->name.c_str()); + indexfile->printf("\t<li><a href=\"%s/index.html\">%s/</a></li>\n", curlist->name.c_str(), curlist->name.c_str()); result = recurse_dir(srcrootlen, dstrootlen, srcfile, dstfile, tempheader, tempfooter); } } // close the list if we found some stuff if (list != nullptr) - core_fprintf(indexfile, "\t</ul>\n"); + indexfile->printf("\t</ul>\n"); // free all the allocated entries while (list != nullptr) @@ -451,7 +451,7 @@ static int recurse_dir(int srcrootlen, int dstrootlen, std::string &srcdir, std: } if (indexfile != nullptr) - output_footer_and_close_file(indexfile, tempfooter, srcdir_subpath); + output_footer_and_close_file(std::move(indexfile), tempfooter, srcdir_subpath); return result; } @@ -516,36 +516,35 @@ static int output_file(file_type type, int srcrootlen, int dstrootlen, std::stri is_token[(UINT8)token_chars[toknum]] = true; // open the source file - core_file *src; - if (core_fopen(srcfile.c_str(), OPEN_FLAG_READ, &src) != FILERR_NONE) + util::core_file::ptr src; + if (util::core_file::open(srcfile.c_str(), OPEN_FLAG_READ, src) != FILERR_NONE) { fprintf(stderr, "Unable to read file '%s'\n", srcfile.c_str()); return 1; } // open the output file - core_file *dst = create_file_and_output_header(dstfile, tempheader, srcfile_subpath); + util::core_file::ptr dst = create_file_and_output_header(dstfile, tempheader, srcfile_subpath); if (dst == nullptr) { fprintf(stderr, "Unable to write file '%s'\n", dstfile.c_str()); - core_fclose(src); return 1; } // output the directory navigation - core_fprintf(dst, "<h3>Viewing File: "); - output_path_as_links(dst, srcfile_subpath, false, link_to_file); - core_fprintf(dst, "</h3>"); + dst->printf("<h3>Viewing File: "); + output_path_as_links(*dst, srcfile_subpath, false, link_to_file); + dst->printf("</h3>"); // start with some tags - core_fprintf(dst, "\t<pre class=\"source\">\n"); + dst->printf("\t<pre class=\"source\">\n"); // iterate over lines in the source file int linenum = 1; bool in_comment = false; char srcline[4096]; std::ostringstream dstline; - while (core_fgets(srcline, ARRAY_LENGTH(srcline), src) != nullptr) + while (src->gets(srcline, ARRAY_LENGTH(srcline)) != nullptr) { // start with the line number dstline.str(""); @@ -707,15 +706,14 @@ static int output_file(file_type type, int srcrootlen, int dstrootlen, std::stri // append a break and move on dstline.put('\n'); - core_fputs(dst, dstline.str().c_str()); + dst->puts(dstline.str().c_str()); } // close tags - core_fprintf(dst, "\t</pre>\n"); + dst->printf("\t</pre>\n"); // close the file - output_footer_and_close_file(dst, tempfooter, srcfile_subpath); - core_fclose(src); + output_footer_and_close_file(std::move(dst), tempfooter, srcfile_subpath); return 0; } @@ -730,17 +728,17 @@ static int output_file(file_type type, int srcrootlen, int dstrootlen, std::stri HTML file with a standard header -------------------------------------------------*/ -static core_file *create_file_and_output_header(std::string &filename, std::string &templatefile, std::string &path) +static util::core_file::ptr create_file_and_output_header(std::string &filename, std::string &templatefile, std::string &path) { // create the indexfile - core_file *file; - if (core_fopen(filename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, &file) != FILERR_NONE) - return nullptr; + 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) != FILERR_NONE) + return util::core_file::ptr(); // print a header std::string modified(templatefile); strreplace(modified, "<!--PATH-->", path.c_str()); - core_fwrite(file, modified.c_str(), modified.length()); + file->write(modified.c_str(), modified.length()); // return the file return file; @@ -752,12 +750,12 @@ static core_file *create_file_and_output_header(std::string &filename, std::stri standard footer to an HTML file and close it -------------------------------------------------*/ -static void output_footer_and_close_file(core_file *file, std::string &templatefile, std::string &path) +static void output_footer_and_close_file(util::core_file::ptr &&file, std::string &templatefile, std::string &path) { std::string modified(templatefile); strreplace(modified, "<!--PATH-->", path.c_str()); - core_fwrite(file, modified.c_str(), modified.length()); - core_fclose(file); + file->write(modified.c_str(), modified.length()); + file.reset(); } @@ -783,7 +781,7 @@ static std::string &normalized_subpath(std::string &dest, std::string &path, int series of links -------------------------------------------------*/ -static void output_path_as_links(core_file *file, std::string &path, bool end_is_directory, bool link_to_file) +static void output_path_as_links(util::core_file &file, std::string &path, bool end_is_directory, bool link_to_file) { // first count how deep we are int srcdepth = 0; @@ -793,10 +791,10 @@ static void output_path_as_links(core_file *file, std::string &path, bool end_is srcdepth++; // output a link to the root - core_fprintf(file, "<a href=\""); + file.printf("<a href=\""); for (int depth = 0; depth < srcdepth; depth++) - core_fprintf(file, "../"); - core_fprintf(file, "index.html\"><root></a>/"); + file.printf("../"); + file.printf("index.html\"><root></a>/"); // now output links to each path up the chain int curdepth = 0; @@ -806,10 +804,10 @@ static void output_path_as_links(core_file *file, std::string &path, bool end_is std::string substr(path, lastslash, slashindex - lastslash); curdepth++; - core_fprintf(file, "<a href=\""); + file.printf("<a href=\""); for (int depth = curdepth; depth < srcdepth; depth++) - core_fprintf(file, "../"); - core_fprintf(file, "index.html\">%s</a>/", substr.c_str()); + file.printf("../"); + file.printf("index.html\">%s</a>/", substr.c_str()); lastslash = slashindex + 1; } @@ -817,11 +815,11 @@ static void output_path_as_links(core_file *file, std::string &path, bool end_is // and a final link to the current directory std::string substr(path, lastslash, -1); if (end_is_directory) - core_fprintf(file, "<a href=\"index.html\">%s</a>", substr.c_str()); + file.printf("<a href=\"index.html\">%s</a>", substr.c_str()); else if (link_to_file) - core_fprintf(file, "<a href=\"%s\">%s</a>", substr.c_str(), substr.c_str()); + file.printf("<a href=\"%s\">%s</a>", substr.c_str(), substr.c_str()); else - core_fprintf(file, "<a href=\"%s.html\">%s</a>", substr.c_str(), substr.c_str()); + file.printf("<a href=\"%s.html\">%s</a>", substr.c_str(), substr.c_str()); } @@ -866,11 +864,11 @@ static bool find_include_file(std::string &srcincpath, int srcrootlen, int dstro srcincpath.append(PATH_SEPARATOR).append(filename.substr(lastsepindex, -1)); // see if we can open it - core_file *testfile; - if (core_fopen(srcincpath.c_str(), OPEN_FLAG_READ, &testfile) == FILERR_NONE) + util::core_file::ptr testfile; + if (util::core_file::open(srcincpath.c_str(), OPEN_FLAG_READ, testfile) == FILERR_NONE) { // close the file - core_fclose(testfile); + testfile.reset(); // find the longest matching directory substring between the include and source file lastsepindex = 0; diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index 13eabe31c59..f69de2b0864 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -512,7 +512,7 @@ int main(int argc, char *argv[]) return 1; // load the file - filerr = core_fload(opts.filename, &data, &length); + filerr = util::core_file::load(opts.filename, &data, length); if (filerr != FILERR_NONE) { fprintf(stderr, "Error opening file '%s'\n", opts.filename); |