summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/bus/a7800/a78_slot.cpp2
-rw-r--r--src/devices/bus/acorn/system/8k.cpp2
-rw-r--r--src/devices/bus/apf/slot.cpp2
-rw-r--r--src/devices/bus/aquarius/slot.cpp2
-rw-r--r--src/devices/bus/ata/idehd.cpp2
-rw-r--r--src/devices/bus/bbc/1mhzbus/datacentre.cpp2
-rw-r--r--src/devices/bus/bbc/rom/slot.cpp2
-rw-r--r--src/devices/bus/c64/exp.cpp2
-rw-r--r--src/devices/bus/cgenie/expansion/floppy.cpp2
-rw-r--r--src/devices/bus/coco/coco_dwsock.cpp41
-rw-r--r--src/devices/bus/crvision/slot.cpp2
-rw-r--r--src/devices/bus/electron/cart/ap5.cpp2
-rw-r--r--src/devices/bus/electron/cart/romp144.cpp2
-rw-r--r--src/devices/bus/electron/cart/slot.cpp4
-rw-r--r--src/devices/bus/electron/plus1.cpp2
-rw-r--r--src/devices/bus/electron/plus2.cpp2
-rw-r--r--src/devices/bus/electron/rombox.cpp2
-rw-r--r--src/devices/bus/electron/romboxp.cpp2
-rw-r--r--src/devices/bus/electron/sidewndr.cpp2
-rw-r--r--src/devices/bus/gamate/slot.cpp2
-rw-r--r--src/devices/bus/gameboy/gb_slot.cpp2
-rw-r--r--src/devices/bus/gba/gba_slot.cpp2
-rw-r--r--src/devices/bus/isa/sc499.cpp25
-rw-r--r--src/devices/bus/m5/slot.cpp2
-rw-r--r--src/devices/bus/mc10/mc10_cart.cpp6
-rw-r--r--src/devices/bus/msx_slot/cartridge.cpp2
-rw-r--r--src/devices/bus/nes/nes_slot.cpp2
-rw-r--r--src/devices/bus/nubus/nubus_image.cpp10
-rw-r--r--src/devices/bus/plus4/exp.cpp2
-rw-r--r--src/devices/bus/scv/slot.cpp2
-rw-r--r--src/devices/bus/sega8/sega8_slot.cpp2
-rw-r--r--src/devices/bus/spectrum/intf2.cpp2
-rw-r--r--src/devices/bus/ti99/gromport/cartridges.cpp55
-rw-r--r--src/devices/bus/ti99/gromport/cartridges.h13
-rw-r--r--src/devices/bus/vboy/slot.cpp6
-rw-r--r--src/devices/bus/vc4000/slot.cpp2
-rw-r--r--src/devices/bus/vcs/vcs_slot.cpp2
-rw-r--r--src/devices/bus/vectrex/slot.cpp4
-rw-r--r--src/devices/bus/vsmile/vsmile_slot.cpp2
-rw-r--r--src/devices/imagedev/cassette.cpp118
-rw-r--r--src/devices/imagedev/chd_cd.cpp23
-rw-r--r--src/devices/imagedev/diablo.cpp42
-rw-r--r--src/devices/imagedev/flopdrv.cpp80
-rw-r--r--src/devices/imagedev/floppy.cpp144
-rw-r--r--src/devices/imagedev/harddriv.cpp52
-rw-r--r--src/devices/imagedev/mfmhd.cpp30
-rw-r--r--src/devices/imagedev/mfmhd.h6
-rw-r--r--src/devices/imagedev/midiin.cpp2
-rw-r--r--src/devices/machine/ataflash.cpp6
-rw-r--r--src/devices/machine/ch376.cpp2
-rw-r--r--src/devices/machine/hp_dc100_tape.cpp47
-rw-r--r--src/devices/machine/laserdsc.cpp27
-rw-r--r--src/devices/machine/laserdsc.h26
-rw-r--r--src/devices/sound/samples.cpp18
-rw-r--r--src/emu/addrmap.h2
-rw-r--r--src/emu/config.cpp20
-rw-r--r--src/emu/crsshair.cpp6
-rw-r--r--src/emu/debug/debugcmd.cpp6
-rw-r--r--src/emu/debug/debugcpu.cpp8
-rw-r--r--src/emu/devcb.h104
-rw-r--r--src/emu/devdelegate.h16
-rw-r--r--src/emu/devfind.h2
-rw-r--r--src/emu/device.h12
-rw-r--r--src/emu/diimage.cpp207
-rw-r--r--src/emu/diimage.h33
-rw-r--r--src/emu/dimemory.h10
-rw-r--r--src/emu/dipty.cpp9
-rw-r--r--src/emu/dipty.h8
-rw-r--r--src/emu/fileio.cpp69
-rw-r--r--src/emu/fileio.h26
-rw-r--r--src/emu/hashfile.cpp4
-rw-r--r--src/emu/http.cpp6
-rw-r--r--src/emu/image.cpp4
-rw-r--r--src/emu/ioport.cpp77
-rw-r--r--src/emu/ioport.h9
-rw-r--r--src/emu/machine.cpp16
-rw-r--r--src/emu/render.cpp5
-rw-r--r--src/emu/rendfont.cpp16
-rw-r--r--src/emu/rendlay.cpp41
-rw-r--r--src/emu/romload.cpp70
-rw-r--r--src/emu/romload.h13
-rw-r--r--src/emu/save.cpp55
-rw-r--r--src/emu/save.h8
-rw-r--r--src/emu/screen.cpp6
-rw-r--r--src/emu/softlist_dev.cpp6
-rw-r--r--src/emu/uiinput.h2
-rw-r--r--src/emu/video.cpp26
-rw-r--r--src/emu/video.h4
-rw-r--r--src/frontend/mame/audit.cpp16
-rw-r--r--src/frontend/mame/cheat.cpp6
-rw-r--r--src/frontend/mame/clifront.cpp6
-rw-r--r--src/frontend/mame/language.cpp2
-rw-r--r--src/frontend/mame/luaengine.cpp52
-rw-r--r--src/frontend/mame/luaengine.ipp8
-rw-r--r--src/frontend/mame/mame.cpp6
-rw-r--r--src/frontend/mame/mameopts.cpp4
-rw-r--r--src/frontend/mame/media_ident.cpp16
-rw-r--r--src/frontend/mame/ui/auditmenu.cpp2
-rw-r--r--src/frontend/mame/ui/filesel.cpp12
-rw-r--r--src/frontend/mame/ui/floppycntrl.cpp5
-rw-r--r--src/frontend/mame/ui/imgcntrl.cpp2
-rw-r--r--src/frontend/mame/ui/inifile.cpp8
-rw-r--r--src/frontend/mame/ui/menu.cpp4
-rw-r--r--src/frontend/mame/ui/miscmenu.cpp18
-rw-r--r--src/frontend/mame/ui/optsmenu.cpp2
-rw-r--r--src/frontend/mame/ui/selgame.cpp12
-rw-r--r--src/frontend/mame/ui/selmenu.cpp30
-rw-r--r--src/frontend/mame/ui/selsoft.cpp8
-rw-r--r--src/frontend/mame/ui/state.cpp10
-rw-r--r--src/frontend/mame/ui/ui.cpp13
-rw-r--r--src/lib/formats/acorn_dsk.cpp216
-rw-r--r--src/lib/formats/acorn_dsk.h30
-rw-r--r--src/lib/formats/afs_dsk.cpp3
-rw-r--r--src/lib/formats/afs_dsk.h2
-rw-r--r--src/lib/formats/aim_dsk.cpp19
-rw-r--r--src/lib/formats/aim_dsk.h11
-rw-r--r--src/lib/formats/ami_dsk.cpp80
-rw-r--r--src/lib/formats/ami_dsk.h6
-rw-r--r--src/lib/formats/ap2_dsk.cpp141
-rw-r--r--src/lib/formats/ap2_dsk.h26
-rw-r--r--src/lib/formats/ap_dsk35.cpp83
-rw-r--r--src/lib/formats/ap_dsk35.h18
-rw-r--r--src/lib/formats/apd_dsk.cpp26
-rw-r--r--src/lib/formats/apd_dsk.h4
-rw-r--r--src/lib/formats/apollo_dsk.cpp14
-rw-r--r--src/lib/formats/apollo_dsk.h2
-rw-r--r--src/lib/formats/apridisk.cpp24
-rw-r--r--src/lib/formats/apridisk.h6
-rw-r--r--src/lib/formats/cassimg.cpp79
-rw-r--r--src/lib/formats/cassimg.h22
-rw-r--r--src/lib/formats/ccvf_dsk.cpp19
-rw-r--r--src/lib/formats/ccvf_dsk.h4
-rw-r--r--src/lib/formats/concept_dsk.cpp49
-rw-r--r--src/lib/formats/concept_dsk.h8
-rw-r--r--src/lib/formats/coupedsk.cpp28
-rw-r--r--src/lib/formats/coupedsk.h6
-rw-r--r--src/lib/formats/cqm_dsk.cpp36
-rw-r--r--src/lib/formats/cqm_dsk.h6
-rw-r--r--src/lib/formats/d64_dsk.cpp33
-rw-r--r--src/lib/formats/d64_dsk.h10
-rw-r--r--src/lib/formats/d80_dsk.cpp5
-rw-r--r--src/lib/formats/d88_dsk.cpp35
-rw-r--r--src/lib/formats/d88_dsk.h6
-rw-r--r--src/lib/formats/dcp_dsk.cpp28
-rw-r--r--src/lib/formats/dcp_dsk.h4
-rw-r--r--src/lib/formats/dfi_dsk.cpp25
-rw-r--r--src/lib/formats/dfi_dsk.h6
-rw-r--r--src/lib/formats/dim_dsk.cpp22
-rw-r--r--src/lib/formats/dim_dsk.h6
-rw-r--r--src/lib/formats/dip_dsk.cpp16
-rw-r--r--src/lib/formats/dip_dsk.h4
-rw-r--r--src/lib/formats/dmk_dsk.cpp27
-rw-r--r--src/lib/formats/dmk_dsk.h6
-rw-r--r--src/lib/formats/ds9_dsk.cpp24
-rw-r--r--src/lib/formats/ds9_dsk.h13
-rw-r--r--src/lib/formats/dsk_dsk.cpp35
-rw-r--r--src/lib/formats/dsk_dsk.h4
-rw-r--r--src/lib/formats/dvk_mx_dsk.cpp25
-rw-r--r--src/lib/formats/dvk_mx_dsk.h13
-rw-r--r--src/lib/formats/esq16_dsk.cpp40
-rw-r--r--src/lib/formats/esq16_dsk.h8
-rw-r--r--src/lib/formats/esq8_dsk.cpp38
-rw-r--r--src/lib/formats/esq8_dsk.h8
-rw-r--r--src/lib/formats/fdd_dsk.cpp18
-rw-r--r--src/lib/formats/fdd_dsk.h4
-rw-r--r--src/lib/formats/flex_dsk.cpp22
-rw-r--r--src/lib/formats/flex_dsk.h4
-rw-r--r--src/lib/formats/flopimg.cpp77
-rw-r--r--src/lib/formats/flopimg.h24
-rw-r--r--src/lib/formats/fsd_dsk.cpp16
-rw-r--r--src/lib/formats/fsd_dsk.h4
-rw-r--r--src/lib/formats/g64_dsk.cpp45
-rw-r--r--src/lib/formats/g64_dsk.h6
-rw-r--r--src/lib/formats/hpi_dsk.cpp23
-rw-r--r--src/lib/formats/hpi_dsk.h6
-rw-r--r--src/lib/formats/hti_tape.cpp52
-rw-r--r--src/lib/formats/hti_tape.h12
-rw-r--r--src/lib/formats/hxchfe_dsk.cpp26
-rw-r--r--src/lib/formats/hxchfe_dsk.h6
-rw-r--r--src/lib/formats/hxcmfm_dsk.cpp28
-rw-r--r--src/lib/formats/hxcmfm_dsk.h6
-rw-r--r--src/lib/formats/ibmxdf_dsk.cpp17
-rw-r--r--src/lib/formats/ibmxdf_dsk.h6
-rw-r--r--src/lib/formats/imd_dsk.cpp76
-rw-r--r--src/lib/formats/imd_dsk.h6
-rw-r--r--src/lib/formats/img_dsk.cpp22
-rw-r--r--src/lib/formats/img_dsk.h6
-rw-r--r--src/lib/formats/ioprocs.cpp214
-rw-r--r--src/lib/formats/ioprocs.h70
-rw-r--r--src/lib/formats/ipf_dsk.cpp21
-rw-r--r--src/lib/formats/ipf_dsk.h4
-rw-r--r--src/lib/formats/jfd_dsk.cpp25
-rw-r--r--src/lib/formats/jfd_dsk.h4
-rw-r--r--src/lib/formats/jvc_dsk.cpp26
-rw-r--r--src/lib/formats/jvc_dsk.h8
-rw-r--r--src/lib/formats/m20_dsk.cpp42
-rw-r--r--src/lib/formats/m20_dsk.h6
-rw-r--r--src/lib/formats/mdos_dsk.cpp22
-rw-r--r--src/lib/formats/mdos_dsk.h4
-rw-r--r--src/lib/formats/mfi_dsk.cpp29
-rw-r--r--src/lib/formats/mfi_dsk.h6
-rw-r--r--src/lib/formats/mfm_hd.cpp17
-rw-r--r--src/lib/formats/mfm_hd.h8
-rw-r--r--src/lib/formats/nfd_dsk.cpp31
-rw-r--r--src/lib/formats/nfd_dsk.h4
-rw-r--r--src/lib/formats/opd_dsk.cpp5
-rw-r--r--src/lib/formats/opd_dsk.h2
-rw-r--r--src/lib/formats/oric_dsk.cpp53
-rw-r--r--src/lib/formats/oric_dsk.h12
-rw-r--r--src/lib/formats/os9_dsk.cpp15
-rw-r--r--src/lib/formats/os9_dsk.h4
-rw-r--r--src/lib/formats/pasti_dsk.cpp16
-rw-r--r--src/lib/formats/pasti_dsk.h4
-rw-r--r--src/lib/formats/pc98fdi_dsk.cpp54
-rw-r--r--src/lib/formats/pc98fdi_dsk.h4
-rw-r--r--src/lib/formats/pc_dsk.cpp13
-rw-r--r--src/lib/formats/pc_dsk.h2
-rw-r--r--src/lib/formats/poly_dsk.cpp31
-rw-r--r--src/lib/formats/poly_dsk.h4
-rw-r--r--src/lib/formats/rx50_dsk.cpp27
-rw-r--r--src/lib/formats/rx50_dsk.h8
-rw-r--r--src/lib/formats/sdd_dsk.cpp5
-rw-r--r--src/lib/formats/sdf_dsk.cpp23
-rw-r--r--src/lib/formats/sdf_dsk.h6
-rw-r--r--src/lib/formats/st_dsk.cpp66
-rw-r--r--src/lib/formats/st_dsk.h16
-rw-r--r--src/lib/formats/svi_dsk.cpp37
-rw-r--r--src/lib/formats/svi_dsk.h6
-rw-r--r--src/lib/formats/td0_dsk.cpp73
-rw-r--r--src/lib/formats/td0_dsk.h6
-rw-r--r--src/lib/formats/ti99_dsk.cpp75
-rw-r--r--src/lib/formats/ti99_dsk.h26
-rw-r--r--src/lib/formats/trd_dsk.cpp17
-rw-r--r--src/lib/formats/trd_dsk.h2
-rw-r--r--src/lib/formats/trs80_dsk.cpp58
-rw-r--r--src/lib/formats/trs80_dsk.h6
-rw-r--r--src/lib/formats/uniflex_dsk.cpp21
-rw-r--r--src/lib/formats/uniflex_dsk.h4
-rw-r--r--src/lib/formats/upd765_dsk.cpp21
-rw-r--r--src/lib/formats/upd765_dsk.h8
-rw-r--r--src/lib/formats/vdk_dsk.cpp42
-rw-r--r--src/lib/formats/vdk_dsk.h6
-rw-r--r--src/lib/formats/victor9k_dsk.cpp32
-rw-r--r--src/lib/formats/victor9k_dsk.h8
-rw-r--r--src/lib/formats/vt_dsk.cpp47
-rw-r--r--src/lib/formats/vt_dsk.h12
-rw-r--r--src/lib/formats/wd177x_dsk.cpp27
-rw-r--r--src/lib/formats/wd177x_dsk.h8
-rw-r--r--src/lib/util/avhuff.cpp4
-rw-r--r--src/lib/util/aviio.cpp84
-rw-r--r--src/lib/util/cdrom.cpp91
-rw-r--r--src/lib/util/cdrom.h14
-rw-r--r--src/lib/util/chd.cpp711
-rw-r--r--src/lib/util/chd.h274
-rw-r--r--src/lib/util/chdcd.cpp186
-rw-r--r--src/lib/util/chdcd.h12
-rw-r--r--src/lib/util/chdcodec.cpp260
-rw-r--r--src/lib/util/chdcodec.h95
-rw-r--r--src/lib/util/corefile.cpp441
-rw-r--r--src/lib/util/corefile.h49
-rw-r--r--src/lib/util/harddisk.cpp18
-rw-r--r--src/lib/util/harddisk.h10
-rw-r--r--src/lib/util/ioprocs.cpp1248
-rw-r--r--src/lib/util/ioprocs.h130
-rw-r--r--src/lib/util/ioprocsfill.h163
-rw-r--r--src/lib/util/ioprocsfilter.cpp598
-rw-r--r--src/lib/util/ioprocsfilter.h31
-rw-r--r--src/lib/util/ioprocsvec.h211
-rw-r--r--src/lib/util/path.cpp0
-rw-r--r--src/lib/util/path.h65
-rw-r--r--src/lib/util/strformat.h54
-rw-r--r--src/lib/util/timeconv.cpp69
-rw-r--r--src/lib/util/timeconv.h39
-rw-r--r--src/lib/util/un7z.cpp467
-rw-r--r--src/lib/util/unzip.cpp1050
-rw-r--r--src/lib/util/unzip.h58
-rw-r--r--src/lib/util/utilfwd.h45
-rw-r--r--src/lib/util/zippath.cpp149
-rw-r--r--src/lib/util/zippath.h5
-rw-r--r--src/mame/drivers/aim65.cpp4
-rw-r--r--src/mame/drivers/alphatro.cpp2
-rw-r--r--src/mame/drivers/atom.cpp2
-rw-r--r--src/mame/drivers/beta.cpp2
-rw-r--r--src/mame/drivers/binbug.cpp10
-rw-r--r--src/mame/drivers/cc40.cpp2
-rw-r--r--src/mame/drivers/cd2650.cpp10
-rw-r--r--src/mame/drivers/d6800.cpp2
-rw-r--r--src/mame/drivers/elan_eu3a05.cpp2
-rw-r--r--src/mame/drivers/eti660.cpp2
-rw-r--r--src/mame/drivers/force68k.cpp2
-rw-r--r--src/mame/drivers/gameking.cpp2
-rw-r--r--src/mame/drivers/hh_tms1k.cpp4
-rw-r--r--src/mame/drivers/homelab.cpp10
-rw-r--r--src/mame/drivers/hx20.cpp2
-rw-r--r--src/mame/drivers/ibmpcjr.cpp2
-rw-r--r--src/mame/drivers/instruct.cpp10
-rw-r--r--src/mame/drivers/jtc.cpp14
-rw-r--r--src/mame/drivers/jupace.cpp4
-rw-r--r--src/mame/drivers/ldplayer.cpp9
-rw-r--r--src/mame/drivers/lynx.cpp4
-rw-r--r--src/mame/drivers/m68705prg.cpp4
-rw-r--r--src/mame/drivers/microvsn.cpp2
-rw-r--r--src/mame/drivers/myvision.cpp2
-rw-r--r--src/mame/drivers/nascom1.cpp4
-rw-r--r--src/mame/drivers/ngp.cpp2
-rw-r--r--src/mame/drivers/pegasus.cpp4
-rw-r--r--src/mame/drivers/phunsy.cpp2
-rw-r--r--src/mame/drivers/pipbug.cpp10
-rw-r--r--src/mame/drivers/pokemini.cpp4
-rw-r--r--src/mame/drivers/pv1000.cpp2
-rw-r--r--src/mame/drivers/pv2000.cpp2
-rw-r--r--src/mame/drivers/ravens.cpp10
-rw-r--r--src/mame/drivers/roland_cm32p.cpp2
-rw-r--r--src/mame/drivers/rx78.cpp2
-rw-r--r--src/mame/drivers/sag.cpp8
-rw-r--r--src/mame/drivers/spg2xx_ican.cpp2
-rw-r--r--src/mame/drivers/spg2xx_smarttv.cpp2
-rw-r--r--src/mame/drivers/spg2xx_telestory.cpp2
-rw-r--r--src/mame/drivers/spg2xx_tvgogo.cpp2
-rw-r--r--src/mame/drivers/spg2xx_vii.cpp2
-rw-r--r--src/mame/drivers/squale.cpp2
-rw-r--r--src/mame/drivers/studio2.cpp8
-rw-r--r--src/mame/drivers/supracan.cpp2
-rw-r--r--src/mame/drivers/sv8000.cpp2
-rw-r--r--src/mame/drivers/svision.cpp2
-rw-r--r--src/mame/drivers/ti74.cpp2
-rw-r--r--src/mame/drivers/timex.cpp8
-rw-r--r--src/mame/drivers/tispeak.cpp2
-rw-r--r--src/mame/drivers/vc4000.cpp16
-rw-r--r--src/mame/drivers/vtech1.cpp4
-rw-r--r--src/mame/drivers/x07.cpp2
-rw-r--r--src/mame/drivers/z1013.cpp4
-rw-r--r--src/mame/machine/amstrad.cpp4
-rw-r--r--src/mame/machine/electron.cpp2
-rw-r--r--src/mame/machine/gamecom.cpp2
-rw-r--r--src/mame/machine/m1comm.cpp10
-rw-r--r--src/mame/machine/m2comm.cpp10
-rw-r--r--src/mame/machine/mbee.cpp8
-rw-r--r--src/mame/machine/mtx.cpp12
-rw-r--r--src/mame/machine/s32comm.cpp10
-rw-r--r--src/mame/machine/sorcerer.cpp2
-rw-r--r--src/mame/machine/thomson.cpp8
-rw-r--r--src/mame/machine/vtech2.cpp2
-rw-r--r--src/mame/machine/z80bin.cpp8
-rw-r--r--src/mame/video/midtunit.cpp4
-rw-r--r--src/osd/modules/debugger/debuggdbstub.cpp4
-rw-r--r--src/osd/modules/debugger/debugimgui.cpp8
-rw-r--r--src/osd/modules/file/posixdomain.cpp208
-rw-r--r--src/osd/modules/file/posixfile.cpp166
-rw-r--r--src/osd/modules/file/posixfile.h18
-rw-r--r--src/osd/modules/file/posixptty.cpp57
-rw-r--r--src/osd/modules/file/posixsocket.cpp187
-rw-r--r--src/osd/modules/file/stdfile.cpp104
-rw-r--r--src/osd/modules/file/winfile.cpp176
-rw-r--r--src/osd/modules/file/winfile.h23
-rw-r--r--src/osd/modules/file/winptty.cpp44
-rw-r--r--src/osd/modules/file/winsocket.cpp130
-rw-r--r--src/osd/modules/font/font_sdl.cpp6
-rw-r--r--src/osd/modules/render/aviwrite.cpp4
-rw-r--r--src/osd/modules/render/bgfx/texturemanager.cpp2
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.cpp10
-rw-r--r--src/osd/osdfile.h66
-rw-r--r--src/tools/castool.cpp15
-rw-r--r--src/tools/chdman.cpp265
-rw-r--r--src/tools/floptool.cpp16
-rw-r--r--src/tools/image_handler.cpp116
-rw-r--r--src/tools/image_handler.h22
-rw-r--r--src/tools/imgtool/iflopimg.cpp83
-rw-r--r--src/tools/imgtool/iflopimg.h11
-rw-r--r--src/tools/imgtool/imghd.cpp57
-rw-r--r--src/tools/imgtool/imghd.h3
-rw-r--r--src/tools/imgtool/imgtool.cpp12
-rw-r--r--src/tools/imgtool/library.h28
-rw-r--r--src/tools/imgtool/main.cpp2
-rw-r--r--src/tools/imgtool/modules/hp85_tape.cpp56
-rw-r--r--src/tools/imgtool/modules/hp9845_tape.cpp57
-rw-r--r--src/tools/imgtool/stream.cpp255
-rw-r--r--src/tools/imgtool/stream.h141
-rw-r--r--src/tools/ldresample.cpp55
-rw-r--r--src/tools/ldverify.cpp29
-rw-r--r--src/tools/pngcmp.cpp14
-rw-r--r--src/tools/regrep.cpp16
-rw-r--r--src/tools/romcmp.cpp743
-rw-r--r--src/tools/split.cpp18
-rw-r--r--src/tools/srcclean.cpp6
-rw-r--r--src/tools/unidasm.cpp6
386 files changed, 8997 insertions, 6549 deletions
diff --git a/src/devices/bus/a7800/a78_slot.cpp b/src/devices/bus/a7800/a78_slot.cpp
index 4a7392fc3f6..d55412058d1 100644
--- a/src/devices/bus/a7800/a78_slot.cpp
+++ b/src/devices/bus/a7800/a78_slot.cpp
@@ -491,7 +491,7 @@ image_verify_result a78_cart_slot_device::verify_header(char *header)
if (strncmp(magic, header + 1, 9))
{
logerror("Not a valid A7800 image\n");
- seterror(IMAGE_ERROR_UNSPECIFIED, "File is not a valid A7800 image");
+ seterror(image_error::INVALIDIMAGE, "File is not a valid A7800 image");
return image_verify_result::FAIL;
}
diff --git a/src/devices/bus/acorn/system/8k.cpp b/src/devices/bus/acorn/system/8k.cpp
index ecbd69c930f..b2e1c7bb3d2 100644
--- a/src/devices/bus/acorn/system/8k.cpp
+++ b/src/devices/bus/acorn/system/8k.cpp
@@ -144,7 +144,7 @@ image_init_result acorn_8k_device::load_rom(device_image_interface &image, gener
// socket accepts 2K and 4K ROM only
if (size != 0x0800 && size != 0x1000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 2K/4K is supported");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 2K/4K is supported");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/apf/slot.cpp b/src/devices/bus/apf/slot.cpp
index 0d44530a8b6..c43738fae2a 100644
--- a/src/devices/bus/apf/slot.cpp
+++ b/src/devices/bus/apf/slot.cpp
@@ -152,7 +152,7 @@ image_init_result apf_cart_slot_device::call_load()
if (size > 0x3800)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Image extends beyond the expected size for an APF cart");
+ seterror(image_error::INVALIDIMAGE, "Image extends beyond the expected size for an APF cart");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/aquarius/slot.cpp b/src/devices/bus/aquarius/slot.cpp
index 825e03f39d5..88be36900f4 100644
--- a/src/devices/bus/aquarius/slot.cpp
+++ b/src/devices/bus/aquarius/slot.cpp
@@ -91,7 +91,7 @@ image_init_result aquarius_cartridge_slot_device::call_load()
if (size % 0x1000)
{
- seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid ROM size");
+ seterror(image_error::INVALIDIMAGE, "Invalid ROM size");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/ata/idehd.cpp b/src/devices/bus/ata/idehd.cpp
index 15a079963de..dd1a8f932ec 100644
--- a/src/devices/bus/ata/idehd.cpp
+++ b/src/devices/bus/ata/idehd.cpp
@@ -838,7 +838,7 @@ void ide_hdd_device::device_reset()
// build the features page
uint32_t metalength;
- if (m_handle && m_handle->read_metadata (HARD_DISK_IDENT_METADATA_TAG, 0, &m_buffer[0], 512, metalength) == CHDERR_NONE)
+ if (m_handle && !m_handle->read_metadata(HARD_DISK_IDENT_METADATA_TAG, 0, &m_buffer[0], 512, metalength))
{
for( int w = 0; w < 256; w++ )
{
diff --git a/src/devices/bus/bbc/1mhzbus/datacentre.cpp b/src/devices/bus/bbc/1mhzbus/datacentre.cpp
index 05ba11a3bab..f21d5af1d54 100644
--- a/src/devices/bus/bbc/1mhzbus/datacentre.cpp
+++ b/src/devices/bus/bbc/1mhzbus/datacentre.cpp
@@ -328,7 +328,7 @@ QUICKLOAD_LOAD_MEMBER(bbc_datacentre_device::quickload_cb)
}
else
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid filetype, must be SSD, DSD, or IMG");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid filetype, must be SSD, DSD, or IMG");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/bbc/rom/slot.cpp b/src/devices/bus/bbc/rom/slot.cpp
index 8a315e12234..65acb920bca 100644
--- a/src/devices/bus/bbc/rom/slot.cpp
+++ b/src/devices/bus/bbc/rom/slot.cpp
@@ -122,7 +122,7 @@ image_init_result bbc_romslot_device::call_load()
if (size % 0x2000)
{
- seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid ROM size");
+ seterror(image_error::INVALIDIMAGE, "Invalid ROM size");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/c64/exp.cpp b/src/devices/bus/c64/exp.cpp
index e4cc42f61d8..cf20f18fe45 100644
--- a/src/devices/bus/c64/exp.cpp
+++ b/src/devices/bus/c64/exp.cpp
@@ -191,7 +191,7 @@ image_init_result c64_expansion_slot_device::call_load()
if ((m_card->m_roml_size & (m_card->m_roml_size - 1)) || (m_card->m_romh_size & (m_card->m_romh_size - 1)))
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "ROM size must be power of 2");
+ seterror(image_error::INVALIDIMAGE, "ROM size must be power of 2");
return image_init_result::FAIL;
}
}
diff --git a/src/devices/bus/cgenie/expansion/floppy.cpp b/src/devices/bus/cgenie/expansion/floppy.cpp
index b6f0a9c30ac..ee914179d10 100644
--- a/src/devices/bus/cgenie/expansion/floppy.cpp
+++ b/src/devices/bus/cgenie/expansion/floppy.cpp
@@ -181,7 +181,7 @@ DEVICE_IMAGE_LOAD_MEMBER( cgenie_fdc_device::socket_load )
if (size > 0x1000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported ROM size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported ROM size");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/coco/coco_dwsock.cpp b/src/devices/bus/coco/coco_dwsock.cpp
index b970458c91c..a69ac57b4c4 100644
--- a/src/devices/bus/coco/coco_dwsock.cpp
+++ b/src/devices/bus/coco/coco_dwsock.cpp
@@ -82,18 +82,14 @@ beckerport_device::~beckerport_device()
void beckerport_device::device_start()
{
- char chAddress[64];
-
- /* format address string for opening the port */
- snprintf(chAddress, sizeof(chAddress), "socket.%s:%d", m_hostname, m_dwtcpport);
-
- osd_printf_verbose("Connecting to Drivewire server on %s:%d... ", m_hostname, m_dwtcpport);
+ osd_printf_verbose("%s: Connecting to Drivewire server on %s:%d... ", tag(), m_hostname, m_dwtcpport);
u64 filesize; // unused
- osd_file::error filerr = osd_file::open(chAddress, 0, m_pSocket, filesize);
- if (filerr != osd_file::error::NONE)
+ /* format address string for opening the port */
+ std::error_condition filerr = osd_file::open(util::string_format("socket.%s:%d", m_hostname, m_dwtcpport), 0, m_pSocket, filesize);
+ if (filerr)
{
- osd_printf_verbose("Error: osd_open returned error %i!\n", (int) filerr);
+ osd_printf_verbose("Error: osd_open returned error %s:%d %s!\n", filerr.category().name(), filerr.value(), filerr.message());
return;
}
@@ -108,7 +104,7 @@ void beckerport_device::device_stop()
{
if (m_pSocket)
{
- printf("Closing connection to Drivewire server\n");
+ printf("%s: Closing connection to Drivewire server\n", tag());
m_pSocket.reset();
}
}
@@ -140,23 +136,24 @@ u8 beckerport_device::read(offs_t offset)
if (!m_rx_pending)
{
/* Try to read from dws */
- osd_file::error filerr = m_pSocket->read(m_buf, 0, sizeof(m_buf), m_rx_pending);
- if (filerr != osd_file::error::NONE && filerr != osd_file::error::FAILURE) // osd_file::error::FAILURE means no data available, so don't throw error message
- fprintf(stderr, "coco_dwsock.c: beckerport_device::read() socket read operation failed with osd_file::error %i\n", int(filerr));
+ std::error_condition filerr = m_pSocket->read(m_buf, 0, sizeof(m_buf), m_rx_pending);
+ if (filerr)
+ osd_printf_error("%s: coco_dwsock.c: beckerport_device::read() socket read operation failed with error %s:%d %s\n", tag(), filerr.category().name(), filerr.value(), filerr.message());
else
m_head = 0;
}
- //printf("beckerport_device: status read. %i bytes remaining.\n", m_rx_pending);
+ //logerror("beckerport_device: status read. %i bytes remaining.\n", m_rx_pending);
data = (m_rx_pending > 0) ? 2 : 0;
break;
case DWS_DATA:
- if (!m_rx_pending) {
- fprintf(stderr, "coco_dwsock.c: beckerport_device::read() buffer underrun\n");
+ if (!m_rx_pending)
+ {
+ osd_printf_error("%s: coco_dwsock.c: beckerport_device::read() buffer underrun\n", tag());
break;
}
data = m_buf[m_head++];
m_rx_pending--;
- //printf("beckerport_device: data read 1 byte (0x%02x). %i bytes remaining.\n", data&0xff, m_rx_pending);
+ //logerror("beckerport_device: data read 1 byte (0x%02x). %i bytes remaining.\n", data&0xff, m_rx_pending);
break;
default:
fprintf(stderr, "%s: read from bad offset %d\n", __FILE__, offset);
@@ -172,7 +169,7 @@ u8 beckerport_device::read(offs_t offset)
void beckerport_device::write(offs_t offset, u8 data)
{
char d = char(data);
- osd_file::error filerr;
+ std::error_condition filerr;
u32 written;
if (!m_pSocket)
@@ -181,13 +178,13 @@ void beckerport_device::write(offs_t offset, u8 data)
switch (offset)
{
case DWS_STATUS:
- //printf("beckerport_write: error: write (0x%02x) to status register\n", d);
+ //logerror("beckerport_write: error: write (0x%02x) to status register\n", d);
break;
case DWS_DATA:
filerr = m_pSocket->write(&d, 0, 1, written);
- if (filerr != osd_file::error::NONE)
- fprintf(stderr, "coco_dwsock.c: beckerport_device::write() socket write operation failed with osd_file::error %i\n", int(filerr));
- //printf("beckerport_write: data write one byte (0x%02x)\n", d & 0xff);
+ if (filerr)
+ osd_printf_error("%s: coco_dwsock.c: beckerport_device::write() socket write operation failed with error %s:%d %s\n", tag(), filerr.category().name(), filerr.value(), filerr.message());
+ //logerror("beckerport_write: data write one byte (0x%02x)\n", d & 0xff);
break;
default:
fprintf(stderr, "%s: write to bad offset %d\n", __FILE__, offset);
diff --git a/src/devices/bus/crvision/slot.cpp b/src/devices/bus/crvision/slot.cpp
index ecab87796e4..ce1e2a5ea1e 100644
--- a/src/devices/bus/crvision/slot.cpp
+++ b/src/devices/bus/crvision/slot.cpp
@@ -145,7 +145,7 @@ image_init_result crvision_cart_slot_device::call_load()
if (size > 0x4800)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Image extends beyond the expected size for an APF cart");
+ seterror(image_error::INVALIDIMAGE, "Image extends beyond the expected size for an APF cart");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/electron/cart/ap5.cpp b/src/devices/bus/electron/cart/ap5.cpp
index cc4c951a154..90c4188d7b1 100644
--- a/src/devices/bus/electron/cart/ap5.cpp
+++ b/src/devices/bus/electron/cart/ap5.cpp
@@ -161,7 +161,7 @@ image_init_result electron_ap5_device::load_rom(device_image_interface &image, g
// socket accepts 8K and 16K ROM only
if (size != 0x2000 && size != 0x4000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/electron/cart/romp144.cpp b/src/devices/bus/electron/cart/romp144.cpp
index de947454fd8..8bdeab7cc34 100644
--- a/src/devices/bus/electron/cart/romp144.cpp
+++ b/src/devices/bus/electron/cart/romp144.cpp
@@ -147,7 +147,7 @@ image_init_result electron_romp144_device::load_rom(device_image_interface &imag
// socket accepts 8K and 16K ROM only
if (size != 0x2000 && size != 0x4000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/electron/cart/slot.cpp b/src/devices/bus/electron/cart/slot.cpp
index 489cb567c4d..342cd3ae4f8 100644
--- a/src/devices/bus/electron/cart/slot.cpp
+++ b/src/devices/bus/electron/cart/slot.cpp
@@ -132,7 +132,7 @@ image_init_result electron_cartslot_device::call_load()
if (size % 0x2000)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
@@ -152,7 +152,7 @@ image_init_result electron_cartslot_device::call_load()
if ((upsize % 0x2000 && upsize != 0) || (losize % 0x2000 && losize != 0) || (romsize % 0x2000 && romsize != 0))
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/electron/plus1.cpp b/src/devices/bus/electron/plus1.cpp
index 5bf61578b2b..4b2c3ba9dad 100644
--- a/src/devices/bus/electron/plus1.cpp
+++ b/src/devices/bus/electron/plus1.cpp
@@ -522,7 +522,7 @@ image_init_result electron_ap6_device::load_rom(device_image_interface &image, g
// socket accepts 8K and 16K ROM only
if (size != 0x2000 && size != 0x4000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/electron/plus2.cpp b/src/devices/bus/electron/plus2.cpp
index d379f053047..82e75bd6030 100644
--- a/src/devices/bus/electron/plus2.cpp
+++ b/src/devices/bus/electron/plus2.cpp
@@ -231,7 +231,7 @@ image_init_result electron_plus2_device::load_rom(device_image_interface &image,
// socket accepts 8K and 16K ROM only
if (size != 0x2000 && size != 0x4000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/electron/rombox.cpp b/src/devices/bus/electron/rombox.cpp
index 920419c2d66..47040271e7f 100644
--- a/src/devices/bus/electron/rombox.cpp
+++ b/src/devices/bus/electron/rombox.cpp
@@ -185,7 +185,7 @@ image_init_result electron_rombox_device::load_rom(device_image_interface &image
// socket accepts 8K and 16K ROM only
if (size != 0x2000 && size != 0x4000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/electron/romboxp.cpp b/src/devices/bus/electron/romboxp.cpp
index e6cfd472989..59d83bc4121 100644
--- a/src/devices/bus/electron/romboxp.cpp
+++ b/src/devices/bus/electron/romboxp.cpp
@@ -328,7 +328,7 @@ image_init_result electron_romboxp_device::load_rom(device_image_interface &imag
// socket accepts 8K and 16K ROM only
if (size != 0x2000 && size != 0x4000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/electron/sidewndr.cpp b/src/devices/bus/electron/sidewndr.cpp
index e66ac800f3c..a2ab8011b09 100644
--- a/src/devices/bus/electron/sidewndr.cpp
+++ b/src/devices/bus/electron/sidewndr.cpp
@@ -174,7 +174,7 @@ image_init_result electron_sidewndr_device::load_rom(device_image_interface &ima
// socket accepts 8K and 16K ROM only
if (size != 0x2000 && size != 0x4000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/gamate/slot.cpp b/src/devices/bus/gamate/slot.cpp
index 625e4103482..3f98a30927d 100644
--- a/src/devices/bus/gamate/slot.cpp
+++ b/src/devices/bus/gamate/slot.cpp
@@ -134,7 +134,7 @@ image_init_result gamate_cart_slot_device::call_load()
if (len > 0x80000)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/gameboy/gb_slot.cpp b/src/devices/bus/gameboy/gb_slot.cpp
index a408b9d15ff..79708f95314 100644
--- a/src/devices/bus/gameboy/gb_slot.cpp
+++ b/src/devices/bus/gameboy/gb_slot.cpp
@@ -267,7 +267,7 @@ image_init_result gb_cart_slot_device_base::call_load()
/* Verify that the file contains 16kb blocks */
if ((len == 0) || ((len % 0x4000) != 0))
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid rom file size\n");
+ seterror(image_error::INVALIDIMAGE, "Invalid ROM file size\n");
return image_init_result::FAIL;
}
}
diff --git a/src/devices/bus/gba/gba_slot.cpp b/src/devices/bus/gba/gba_slot.cpp
index 06ec379cf77..ac036718e2d 100644
--- a/src/devices/bus/gba/gba_slot.cpp
+++ b/src/devices/bus/gba/gba_slot.cpp
@@ -625,7 +625,7 @@ image_init_result gba_cart_slot_device::call_load()
uint32_t size = loaded_through_softlist() ? get_software_region_length("rom") : length();
if (size > 0x4000000)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Attempted loading a cart larger than 64MB");
+ seterror(image_error::INVALIDIMAGE, "Attempted loading a cart larger than 64MB");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/isa/sc499.cpp b/src/devices/bus/isa/sc499.cpp
index c313dd84148..bc942ede9e8 100644
--- a/src/devices/bus/isa/sc499.cpp
+++ b/src/devices/bus/isa/sc499.cpp
@@ -16,7 +16,7 @@
#include "emu.h"
#include "sc499.h"
-#include "formats/ioprocs.h"
+
#define VERBOSE 0
@@ -1310,18 +1310,17 @@ void sc499_ctape_image_device::write_block(int block_num, uint8_t *ptr)
image_init_result sc499_ctape_image_device::call_load()
{
- uint32_t size;
- io_generic io;
- io.file = (device_image_interface *)this;
- io.procs = &image_ioprocs;
- io.filler = 0xff;
-
- size = io_generic_size(&io);
- m_ctape_data.resize(size);
-
- io_generic_read(&io, &m_ctape_data[0], 0, size);
-
- return image_init_result::PASS;
+ try
+ {
+ auto const size = length();
+ m_ctape_data.resize(size);
+ if (!fseek(0, SEEK_SET) && (fread(m_ctape_data.data(), size) == size))
+ return image_init_result::PASS;
+ }
+ catch (...)
+ {
+ }
+ return image_init_result::FAIL;
}
void sc499_ctape_image_device::call_unload()
diff --git a/src/devices/bus/m5/slot.cpp b/src/devices/bus/m5/slot.cpp
index a1b9d551b23..a75599bb807 100644
--- a/src/devices/bus/m5/slot.cpp
+++ b/src/devices/bus/m5/slot.cpp
@@ -166,7 +166,7 @@ image_init_result m5_cart_slot_device::call_load()
if (size > 0x5000 && m_type == M5_STD)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Image extends beyond the expected size for an M5 cart");
+ seterror(image_error::INVALIDIMAGE, "Image extends beyond the expected size for an M5 cart");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/mc10/mc10_cart.cpp b/src/devices/bus/mc10/mc10_cart.cpp
index e8addd9939a..088b3ca8c81 100644
--- a/src/devices/bus/mc10/mc10_cart.cpp
+++ b/src/devices/bus/mc10/mc10_cart.cpp
@@ -96,14 +96,14 @@ image_init_result mc10cart_slot_device::call_load()
memory_region *romregion(loaded_through_softlist() ? memregion("rom") : nullptr);
if (loaded_through_softlist() && !romregion)
{
- seterror(IMAGE_ERROR_INVALIDIMAGE, "Software list item has no 'rom' data area");
+ seterror(image_error::INVALIDIMAGE, "Software list item has no 'rom' data area");
return image_init_result::FAIL;
}
u32 const len(loaded_through_softlist() ? romregion->bytes() : length());
if (len > m_cart->max_rom_length())
{
- seterror(IMAGE_ERROR_UNSUPPORTED, "Unsupported cartridge size");
+ seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
@@ -114,7 +114,7 @@ image_init_result mc10cart_slot_device::call_load()
u32 const cnt(fread(romregion->base(), len));
if (cnt != len)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Error reading cartridge file");
+ seterror(image_error::UNSPECIFIED, "Error reading cartridge file");
return image_init_result::FAIL;
}
}
diff --git a/src/devices/bus/msx_slot/cartridge.cpp b/src/devices/bus/msx_slot/cartridge.cpp
index 87b89f93c78..30c9f0a2b00 100644
--- a/src/devices/bus/msx_slot/cartridge.cpp
+++ b/src/devices/bus/msx_slot/cartridge.cpp
@@ -165,7 +165,7 @@ image_init_result msx_slot_cartridge_device::call_load()
if (fread(m_cartridge->get_rom_base(), length) != length)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Unable to fully read file");
+ seterror(image_error::UNSPECIFIED, "Unable to fully read file");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/nes/nes_slot.cpp b/src/devices/bus/nes/nes_slot.cpp
index 812aa738399..f75694bd041 100644
--- a/src/devices/bus/nes/nes_slot.cpp
+++ b/src/devices/bus/nes/nes_slot.cpp
@@ -887,7 +887,7 @@ image_init_result nes_cart_slot_device::call_load()
else
{
logerror("%s is NOT a file in either iNES or UNIF format.\n", filename());
- seterror(IMAGE_ERROR_UNSPECIFIED, "File is neither iNES or UNIF format");
+ seterror(image_error::INVALIDIMAGE, "File is neither iNES or UNIF format");
return image_init_result::FAIL;
}
}
diff --git a/src/devices/bus/nubus/nubus_image.cpp b/src/devices/bus/nubus/nubus_image.cpp
index 8c94882cd4f..80875c6bd41 100644
--- a/src/devices/bus/nubus/nubus_image.cpp
+++ b/src/devices/bus/nubus/nubus_image.cpp
@@ -295,8 +295,9 @@ void nubus_image_device::file_cmd_w(uint32_t data)
std::string fullpath(filectx.curdir);
fullpath += PATH_SEPARATOR;
fullpath.append(std::begin(filectx.filename), std::find(std::begin(filectx.filename), std::end(filectx.filename), '\0'));
- if (osd_file::open(fullpath, OPEN_FLAG_READ, filectx.fd, filectx.filelen) != osd_file::error::NONE)
- osd_printf_error("Error opening %s\n", fullpath);
+ std::error_condition const filerr = osd_file::open(fullpath, OPEN_FLAG_READ, filectx.fd, filectx.filelen);
+ if (filerr)
+ osd_printf_error("%s: Error opening %s (%s:%d %s)\n", tag(), fullpath, filerr.category().name(), filerr.value(), filerr.message());
filectx.bytecount = 0;
}
break;
@@ -306,8 +307,9 @@ void nubus_image_device::file_cmd_w(uint32_t data)
fullpath += PATH_SEPARATOR;
fullpath.append(std::begin(filectx.filename), std::find(std::begin(filectx.filename), std::end(filectx.filename), '\0'));
uint64_t filesize; // unused, but it's an output from the open call
- if (osd_file::open(fullpath, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, filectx.fd, filesize) != osd_file::error::NONE)
- osd_printf_error("Error opening %s\n", fullpath);
+ std::error_condition const filerr = osd_file::open(fullpath, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, filectx.fd, filesize);
+ if (filerr)
+ osd_printf_error("%s: Error opening %s (%s:%d %s)\n", tag(), fullpath, filerr.category().name(), filerr.value(), filerr.message());
filectx.bytecount = 0;
}
break;
diff --git a/src/devices/bus/plus4/exp.cpp b/src/devices/bus/plus4/exp.cpp
index fb0387908ef..487de7ea3c2 100644
--- a/src/devices/bus/plus4/exp.cpp
+++ b/src/devices/bus/plus4/exp.cpp
@@ -118,7 +118,7 @@ image_init_result plus4_expansion_slot_device::call_load()
if ((m_card->m_c1l_size & (m_card->m_c1l_size - 1)) || (m_card->m_c1h_size & (m_card->m_c1h_size - 1)) || (m_card->m_c2l_size & (m_card->m_c2l_size - 1)) || (m_card->m_c2h_size & (m_card->m_c2h_size - 1)))
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "ROM size must be power of 2");
+ seterror(image_error::INVALIDIMAGE, "ROM size must be power of 2");
return image_init_result::FAIL;
}
}
diff --git a/src/devices/bus/scv/slot.cpp b/src/devices/bus/scv/slot.cpp
index 65081801f30..86dc2d810c1 100644
--- a/src/devices/bus/scv/slot.cpp
+++ b/src/devices/bus/scv/slot.cpp
@@ -157,7 +157,7 @@ image_init_result scv_cart_slot_device::call_load()
if (len > 0x20000)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/sega8/sega8_slot.cpp b/src/devices/bus/sega8/sega8_slot.cpp
index 8330fc68915..8a998e71bf0 100644
--- a/src/devices/bus/sega8/sega8_slot.cpp
+++ b/src/devices/bus/sega8/sega8_slot.cpp
@@ -397,7 +397,7 @@ image_init_result sega8_cart_slot_device::call_load()
if (m_is_card && len > 0x8000)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Attempted loading a card larger than 32KB");
+ seterror(image_error::INVALIDIMAGE, "Attempted loading a card larger than 32KB");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/spectrum/intf2.cpp b/src/devices/bus/spectrum/intf2.cpp
index 7442dfe49a9..afce2005a99 100644
--- a/src/devices/bus/spectrum/intf2.cpp
+++ b/src/devices/bus/spectrum/intf2.cpp
@@ -99,7 +99,7 @@ DEVICE_IMAGE_LOAD_MEMBER(spectrum_intf2_device::cart_load)
if (size != 0x4000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/ti99/gromport/cartridges.cpp b/src/devices/bus/ti99/gromport/cartridges.cpp
index 20831395a0c..2f5a558d29b 100644
--- a/src/devices/bus/ti99/gromport/cartridges.cpp
+++ b/src/devices/bus/ti99/gromport/cartridges.cpp
@@ -16,6 +16,10 @@
#include "cartridges.h"
#include "corestr.h"
+#include "ioprocs.h"
+#include "unzip.h"
+#include "xmlfile.h"
+
#define LOG_WARN (1U<<1) // Warnings
#define LOG_CONFIG (1U<<2) // Configuration
@@ -260,14 +264,14 @@ image_init_result ti99_cartridge_device::call_load()
auto reader = std::make_unique<rpk_reader>(pcbdefs);
try
{
- m_rpk = reader->open(machine().options(), filename(), machine().system().name);
+ m_rpk = reader->open(machine().options(), image_core_file(), machine().system().name);
m_pcbtype = m_rpk->get_type();
}
catch (rpk_exception& err)
{
LOGMASKED(LOG_WARN, "Failed to load cartridge '%s': %s\n", basename(), err.to_string().c_str());
m_rpk = nullptr;
- m_err = IMAGE_ERROR_INVALIDIMAGE;
+ m_err = image_error::INVALIDIMAGE;
return image_init_result::FAIL;
}
}
@@ -1553,8 +1557,8 @@ void ti99_cartridge_device::rpk::close()
throw emu_fatalerror("ti99_cartridge_device::rpk::close: Buffer is null or length is 0");
emu_file file(m_options.nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = file.open(socket.second->get_pathname());
- if (filerr == osd_file::error::NONE)
+ std::error_condition const filerr = file.open(socket.second->get_pathname());
+ if (!filerr)
file.write(socket.second->get_contents(), socket.second->get_content_length());
}
@@ -1641,8 +1645,8 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re
catch (std::bad_alloc const &) { throw rpk_exception(RPK_OUT_OF_MEMORY); }
// and unzip file from the zip file
- util::archive_file::error ziperr = zip.decompress(contents.get(), length);
- if (ziperr != util::archive_file::error::NONE)
+ std::error_condition const ziperr = zip.decompress(contents.get(), length);
+ if (ziperr)
{
if (ziperr == util::archive_file::error::UNSUPPORTED) throw rpk_exception(RPK_ZIP_UNSUPPORTED);
else throw rpk_exception(RPK_ZIP_ERROR);
@@ -1727,9 +1731,9 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re
// try to open the battery file and read it if possible
emu_file file(options.nvram_directory(), OPEN_FLAG_READ);
- osd_file::error filerr = file.open(ram_pname);
+ std::error_condition const filerr = file.open(ram_pname);
int bytes_read = 0;
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
bytes_read = file.read(contents.get(), length);
// fill remaining bytes (if necessary)
@@ -1747,33 +1751,30 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re
system_name - name of the driver (also just for NVRAM handling)
-------------------------------------------------*/
-ti99_cartridge_device::rpk* ti99_cartridge_device::rpk_reader::open(emu_options &options, const char *filename, const char *system_name)
+ti99_cartridge_device::rpk* ti99_cartridge_device::rpk_reader::open(emu_options &options, util::core_file &file, const char *system_name)
{
- util::archive_file::error ziperr;
-
- util::archive_file::ptr zipfile;
-
- std::vector<char> layout_text;
-
- int i;
-
auto newrpk = new rpk(options, system_name);
try
{
- /* open the ZIP file */
- ziperr = util::archive_file::open_zip(filename, zipfile);
- if (ziperr != util::archive_file::error::NONE) throw rpk_exception(RPK_NOT_ZIP_FORMAT);
+ // open the ZIP file
+ auto reader = util::core_file_read(file);
+ if (!reader) throw rpk_exception(RPK_OUT_OF_MEMORY);
+
+ std::error_condition ziperr;
+ util::archive_file::ptr zipfile;
+ ziperr = util::archive_file::open_zip(std::move(reader), zipfile);
+ if (ziperr) throw rpk_exception(RPK_NOT_ZIP_FORMAT);
- /* find the layout.xml file */
+ // find the layout.xml file
if (find_file(*zipfile, "layout.xml", 0) < 0) throw rpk_exception(RPK_MISSING_LAYOUT);
- /* reserve space for the layout file contents (+1 for the termination) */
- layout_text.resize(zipfile->current_uncompressed_length() + 1);
+ // reserve space for the layout file contents (+1 for the termination)
+ std::vector<char> layout_text(zipfile->current_uncompressed_length() + 1);
- /* uncompress the layout text */
+ // uncompress the layout text
ziperr = zipfile->decompress(&layout_text[0], zipfile->current_uncompressed_length());
- if (ziperr != util::archive_file::error::NONE)
+ if (ziperr)
{
if (ziperr == util::archive_file::error::UNSUPPORTED) throw rpk_exception(RPK_ZIP_UNSUPPORTED);
else throw rpk_exception(RPK_ZIP_ERROR);
@@ -1781,7 +1782,7 @@ ti99_cartridge_device::rpk* ti99_cartridge_device::rpk_reader::open(emu_options
layout_text[zipfile->current_uncompressed_length()] = '\0'; // Null-terminate
- /* parse the layout text */
+ // parse the layout text
util::xml::file::ptr const layout_xml = util::xml::file::string_read(&layout_text[0], nullptr);
if (!layout_xml) throw rpk_exception(RPK_XML_ERROR);
@@ -1808,7 +1809,7 @@ ti99_cartridge_device::rpk* ti99_cartridge_device::rpk_reader::open(emu_options
if (!pcb_type) throw rpk_exception(RPK_INVALID_LAYOUT, "<pcb> must have a 'type' attribute");
LOGMASKED(LOG_RPK, "[RPK handler] Cartridge says it has PCB type '%s'\n", *pcb_type);
- i=0;
+ int i=0;
do
{
if (*pcb_type == m_types[i].name)
diff --git a/src/devices/bus/ti99/gromport/cartridges.h b/src/devices/bus/ti99/gromport/cartridges.h
index db2de6b2672..df94321a5f9 100644
--- a/src/devices/bus/ti99/gromport/cartridges.h
+++ b/src/devices/bus/ti99/gromport/cartridges.h
@@ -8,12 +8,15 @@
#pragma once
-#include "emuopts.h"
+#include "gromport.h"
+
#include "machine/tmc0430.h"
+
+#include "emuopts.h"
#include "softlist_dev.h"
-#include "gromport.h"
-#include "unzip.h"
-#include "xmlfile.h"
+
+#include "utilfwd.h"
+
namespace bus::ti99::gromport {
@@ -137,7 +140,7 @@ private:
public:
rpk_reader(const pcb_type *types) : m_types(types) { }
- rpk *open(emu_options &options, const char *filename, const char *system_name);
+ rpk *open(emu_options &options, util::core_file &file, const char *system_name);
private:
int find_file(util::archive_file &zip, const char *filename, uint32_t crc);
diff --git a/src/devices/bus/vboy/slot.cpp b/src/devices/bus/vboy/slot.cpp
index 083c0db745b..70dd9e05063 100644
--- a/src/devices/bus/vboy/slot.cpp
+++ b/src/devices/bus/vboy/slot.cpp
@@ -54,14 +54,14 @@ image_init_result vboy_cart_slot_device::call_load()
memory_region *romregion(loaded_through_softlist() ? memregion("rom") : nullptr);
if (loaded_through_softlist() && !romregion)
{
- seterror(IMAGE_ERROR_INVALIDIMAGE, "Software list item has no 'rom' data area");
+ seterror(image_error::INVALIDIMAGE, "Software list item has no 'rom' data area");
return image_init_result::FAIL;
}
u32 const len(loaded_through_softlist() ? romregion->bytes() : length());
if ((0x0000'0003 & len) || (0x0100'0000 < len))
{
- seterror(IMAGE_ERROR_UNSUPPORTED, "Unsupported cartridge size (must be a multiple of 4 bytes no larger than 16 MiB)");
+ seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size (must be a multiple of 4 bytes no larger than 16 MiB)");
return image_init_result::FAIL;
}
@@ -72,7 +72,7 @@ image_init_result vboy_cart_slot_device::call_load()
u32 const cnt(fread(romregion->base(), len));
if (cnt != len)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Error reading cartridge file");
+ seterror(image_error::UNSPECIFIED, "Error reading cartridge file");
return image_init_result::FAIL;
}
}
diff --git a/src/devices/bus/vc4000/slot.cpp b/src/devices/bus/vc4000/slot.cpp
index f33e5623639..8de01177448 100644
--- a/src/devices/bus/vc4000/slot.cpp
+++ b/src/devices/bus/vc4000/slot.cpp
@@ -176,7 +176,7 @@ image_init_result vc4000_cart_slot_device::call_load()
if (size > 0x1800)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Image extends beyond the expected size for a VC4000 cart");
+ seterror(image_error::INVALIDIMAGE, "Image extends beyond the expected size for a VC4000 cart");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/vcs/vcs_slot.cpp b/src/devices/bus/vcs/vcs_slot.cpp
index 28d402322d5..5efcc4ba32d 100644
--- a/src/devices/bus/vcs/vcs_slot.cpp
+++ b/src/devices/bus/vcs/vcs_slot.cpp
@@ -200,7 +200,7 @@ image_init_result vcs_cart_slot_device::call_load()
break;
default:
- seterror(IMAGE_ERROR_UNSUPPORTED, "Invalid rom file size" );
+ seterror(image_error::INVALIDIMAGE, "Invalid ROM file size" );
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/vectrex/slot.cpp b/src/devices/bus/vectrex/slot.cpp
index 014b6c9516c..9e3ebd14fa6 100644
--- a/src/devices/bus/vectrex/slot.cpp
+++ b/src/devices/bus/vectrex/slot.cpp
@@ -145,7 +145,7 @@ image_init_result vectrex_cart_slot_device::call_load()
if (size > 0x10000)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
@@ -160,7 +160,7 @@ image_init_result vectrex_cart_slot_device::call_load()
// Verify the file is accepted by the Vectrex bios
if (memcmp(ROM, "g GCE", 5))
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid image");
+ seterror(image_error::INVALIDIMAGE, "Invalid image");
return image_init_result::FAIL;
}
diff --git a/src/devices/bus/vsmile/vsmile_slot.cpp b/src/devices/bus/vsmile/vsmile_slot.cpp
index 59f039c685d..9c2906826c9 100644
--- a/src/devices/bus/vsmile/vsmile_slot.cpp
+++ b/src/devices/bus/vsmile/vsmile_slot.cpp
@@ -139,7 +139,7 @@ image_init_result vsmile_cart_slot_device::call_load()
uint32_t size = loaded_through_softlist() ? get_software_region_length("rom") : length();
if (size > 0x1000000)
{
- seterror(IMAGE_ERROR_UNSPECIFIED, "Attempted loading a cart larger than 16MB");
+ seterror(image_error::INVALIDIMAGE, "Attempted loading a cart larger than 16MB");
return image_init_result::FAIL;
}
diff --git a/src/devices/imagedev/cassette.cpp b/src/devices/imagedev/cassette.cpp
index 778b296d63d..52103cb1e7d 100644
--- a/src/devices/imagedev/cassette.cpp
+++ b/src/devices/imagedev/cassette.cpp
@@ -9,9 +9,12 @@
*********************************************************************/
#include "emu.h"
-#include "formats/imageutl.h"
#include "cassette.h"
+#include "formats/imageutl.h"
+
+#include "util/ioprocs.h"
+
#define LOG_WARN (1U<<1) // Warnings
#define LOG_DETAIL (1U<<2) // Details
@@ -19,6 +22,7 @@
#include "logmacro.h"
+
// device type definition
DEFINE_DEVICE_TYPE(CASSETTE, cassette_image_device, "cassette_image", "Cassette")
@@ -253,12 +257,24 @@ image_init_result cassette_image_device::internal_load(bool is_create)
device_image_interface *image = nullptr;
interface(image);
+ check_for_file();
if (is_create || (length()==0)) // empty existing images are fine to write over.
{
- // creating an image
- err = cassette_image::create((void *)image, &image_ioprocs, &cassette_image::wavfile_format, m_create_opts, cassette_image::FLAG_READWRITE|cassette_image::FLAG_SAVEONEXIT, m_cassette);
- if (err != cassette_image::error::SUCCESS)
- goto error;
+ auto io = util::core_file_read_write(image_core_file(), 0x00);
+ if (io)
+ {
+ // creating an image
+ err = cassette_image::create(
+ std::move(io),
+ &cassette_image::wavfile_format,
+ m_create_opts,
+ cassette_image::FLAG_READWRITE|cassette_image::FLAG_SAVEONEXIT,
+ m_cassette);
+ }
+ else
+ {
+ err = cassette_image::error::OUT_OF_MEMORY;
+ }
}
else
{
@@ -269,11 +285,24 @@ image_init_result cassette_image_device::internal_load(bool is_create)
// we probably don't want to retry...
retry = false;
- // try opening the cassette
- int cassette_flags = is_readonly()
- ? cassette_image::FLAG_READONLY
- : (cassette_image::FLAG_READWRITE | cassette_image::FLAG_SAVEONEXIT);
- err = cassette_image::open_choices((void *)image, &image_ioprocs, filetype(), m_formats, cassette_flags, m_cassette);
+ auto io = util::core_file_read_write(image_core_file(), 0x00);
+ if (io)
+ {
+ // try opening the cassette
+ int const cassette_flags = is_readonly()
+ ? cassette_image::FLAG_READONLY
+ : (cassette_image::FLAG_READWRITE | cassette_image::FLAG_SAVEONEXIT);
+ err = cassette_image::open_choices(
+ std::move(io),
+ filetype(),
+ m_formats,
+ cassette_flags,
+ m_cassette);
+ }
+ else
+ {
+ err = cassette_image::error::OUT_OF_MEMORY;
+ }
// special case - if we failed due to readwrite not being supported, make the image be read only and retry
if (err == cassette_image::error::READ_WRITE_UNSUPPORTED)
@@ -283,47 +312,48 @@ image_init_result cassette_image_device::internal_load(bool is_create)
}
}
while(retry);
-
- if (err != cassette_image::error::SUCCESS)
- goto error;
}
- /* set to default state, but only change the UI state */
- change_state(m_default_state, CASSETTE_MASK_UISTATE);
-
- /* reset the position */
- m_position = 0.0;
- m_position_time = machine().time().as_double();
+ if (err == cassette_image::error::SUCCESS)
+ {
+ /* set to default state, but only change the UI state */
+ change_state(m_default_state, CASSETTE_MASK_UISTATE);
- /* default channel to 0, speed multiplier to 1 */
- m_channel = 0;
- m_speed = 1;
- m_direction = 1;
+ /* reset the position */
+ m_position = 0.0;
+ m_position_time = machine().time().as_double();
- return image_init_result::PASS;
+ /* default channel to 0, speed multiplier to 1 */
+ m_channel = 0;
+ m_speed = 1;
+ m_direction = 1;
-error:
- image_error_t imgerr = IMAGE_ERROR_UNSPECIFIED;
- switch(err)
+ return image_init_result::PASS;
+ }
+ else
{
- case cassette_image::error::INTERNAL:
- imgerr = IMAGE_ERROR_INTERNAL;
- break;
- case cassette_image::error::UNSUPPORTED:
- imgerr = IMAGE_ERROR_UNSUPPORTED;
- break;
- case cassette_image::error::OUT_OF_MEMORY:
- imgerr = IMAGE_ERROR_OUTOFMEMORY;
- break;
- case cassette_image::error::INVALID_IMAGE:
- imgerr = IMAGE_ERROR_INVALIDIMAGE;
- break;
- default:
- imgerr = IMAGE_ERROR_UNSPECIFIED;
- break;
+ std::error_condition imgerr = image_error::UNSPECIFIED;
+ switch(err)
+ {
+ case cassette_image::error::INTERNAL:
+ imgerr = image_error::INTERNAL;
+ break;
+ case cassette_image::error::UNSUPPORTED:
+ imgerr = image_error::UNSUPPORTED;
+ break;
+ case cassette_image::error::OUT_OF_MEMORY:
+ imgerr = std::errc::not_enough_memory;
+ break;
+ case cassette_image::error::INVALID_IMAGE:
+ imgerr = image_error::INVALIDIMAGE;
+ break;
+ default:
+ imgerr = image_error::UNSPECIFIED;
+ break;
+ }
+ image->seterror(imgerr, nullptr);
+ return image_init_result::FAIL;
}
- image->seterror(imgerr, "" );
- return image_init_result::FAIL;
}
diff --git a/src/devices/imagedev/chd_cd.cpp b/src/devices/imagedev/chd_cd.cpp
index 5daaba2ed45..4eacb3d3b58 100644
--- a/src/devices/imagedev/chd_cd.cpp
+++ b/src/devices/imagedev/chd_cd.cpp
@@ -83,17 +83,16 @@ void cdrom_image_device::device_stop()
image_init_result cdrom_image_device::call_load()
{
- chd_error err = (chd_error)0;
- chd_file *chd = nullptr;
+ std::error_condition err;
+ chd_file *chd = nullptr;
if (m_cdrom_handle)
cdrom_close(m_cdrom_handle);
- if (!loaded_through_softlist())
- {
+ if (!loaded_through_softlist()) {
if (is_filetype("chd") && is_loaded()) {
- err = m_self_chd.open( image_core_file() ); /* CDs are never writeable */
- if ( err )
+ err = m_self_chd.open(util::core_file_read_write(image_core_file())); // CDs are never writeable
+ if (err)
goto error;
chd = &m_self_chd;
}
@@ -103,20 +102,20 @@ image_init_result cdrom_image_device::call_load()
/* open the CHD file */
if (chd) {
- m_cdrom_handle = cdrom_open( chd );
+ m_cdrom_handle = cdrom_open(chd);
} else {
m_cdrom_handle = cdrom_open(filename());
}
- if ( ! m_cdrom_handle )
+ if (!m_cdrom_handle)
goto error;
return image_init_result::PASS;
error:
- if ( chd && chd == &m_self_chd )
- m_self_chd.close( );
- if ( err )
- seterror( IMAGE_ERROR_UNSPECIFIED, chd_file::error_string( err ) );
+ if (chd && chd == &m_self_chd)
+ m_self_chd.close();
+ if (err)
+ seterror(err, nullptr);
return image_init_result::FAIL;
}
diff --git a/src/devices/imagedev/diablo.cpp b/src/devices/imagedev/diablo.cpp
index 58a34a664f6..be09c263719 100644
--- a/src/devices/imagedev/diablo.cpp
+++ b/src/devices/imagedev/diablo.cpp
@@ -112,8 +112,6 @@ image_init_result diablo_image_device::call_load()
image_init_result diablo_image_device::call_create(int create_format, util::option_resolution *create_args)
{
- int err;
-
if (!create_args)
throw emu_fatalerror("diablo_image_device::call_create: Expected create_args to not be nullptr");
@@ -127,15 +125,15 @@ image_init_result diablo_image_device::call_create(int create_format, util::opti
/* create the CHD file */
chd_codec_type compression[4] = { CHD_CODEC_NONE };
- err = m_origchd.create(image_core_file(), (uint64_t)totalsectors * (uint64_t)sectorsize, hunksize, sectorsize, compression);
- if (err != CHDERR_NONE)
+ std::error_condition err = m_origchd.create(util::core_file_read_write(image_core_file()), uint64_t(totalsectors) * uint64_t(sectorsize), hunksize, sectorsize, compression);
+ if (err)
return image_init_result::FAIL;
/* if we created the image and hence, have metadata to set, set the metadata */
err = m_origchd.write_metadata(HARD_DISK_METADATA_TAG, 0, string_format(HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize));
m_origchd.close();
- if (err != CHDERR_NONE)
+ if (err)
return image_init_result::FAIL;
return internal_load_dsk();
@@ -164,28 +162,28 @@ void diablo_image_device::call_unload()
open_disk_diff - open a DISK diff file
-------------------------------------------------*/
-static chd_error open_disk_diff(emu_options &options, const char *name, chd_file &source, chd_file &diff_chd)
+static std::error_condition open_disk_diff(emu_options &options, const char *name, chd_file &source, chd_file &diff_chd)
{
std::string fname = std::string(name).append(".dif");
/* try to open the diff */
//printf("Opening differencing image file: %s\n", fname.c_str());
emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE);
- osd_file::error filerr = diff_file.open(fname.c_str());
- if (filerr == osd_file::error::NONE)
+ std::error_condition filerr = diff_file.open(fname);
+ if (!filerr)
{
std::string fullpath(diff_file.fullpath());
diff_file.close();
//printf("Opening differencing image file: %s\n", fullpath.c_str());
- return diff_chd.open(fullpath.c_str(), true, &source);
+ return diff_chd.open(fullpath, true, &source);
}
/* didn't work; try creating it instead */
//printf("Creating differencing image: %s\n", fname.c_str());
diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- filerr = diff_file.open(fname.c_str());
- if (filerr == osd_file::error::NONE)
+ filerr = diff_file.open(fname);
+ if (!filerr)
{
std::string fullpath(diff_file.fullpath());
diff_file.close();
@@ -193,19 +191,19 @@ static chd_error open_disk_diff(emu_options &options, const char *name, chd_file
/* create the CHD */
//printf("Creating differencing image file: %s\n", fullpath.c_str());
chd_codec_type compression[4] = { CHD_CODEC_NONE };
- chd_error err = diff_chd.create(fullpath.c_str(), source.logical_bytes(), source.hunk_bytes(), compression, source);
- if (err != CHDERR_NONE)
+ std::error_condition err = diff_chd.create(fullpath, source.logical_bytes(), source.hunk_bytes(), compression, source);
+ if (err)
return err;
return diff_chd.clone_all_metadata(source);
}
- return CHDERR_FILE_NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
}
image_init_result diablo_image_device::internal_load_dsk()
{
- chd_error err = CHDERR_NONE;
+ std::error_condition err;
m_chd = nullptr;
@@ -219,18 +217,18 @@ image_init_result diablo_image_device::internal_load_dsk()
}
else
{
- err = m_origchd.open(image_core_file(), true);
- if (err == CHDERR_NONE)
+ err = m_origchd.open(util::core_file_read_write(image_core_file()), true);
+ if (!err)
{
m_chd = &m_origchd;
}
- else if (err == CHDERR_FILE_NOT_WRITEABLE)
+ else if (err == chd_file::error::FILE_NOT_WRITEABLE)
{
- err = m_origchd.open(image_core_file(), false);
- if (err == CHDERR_NONE)
+ err = m_origchd.open(util::core_file_read_write(image_core_file()), false);
+ if (!err)
{
err = open_disk_diff(device().machine().options(), basename_noext(), m_origchd, m_diffchd);
- if (err == CHDERR_NONE)
+ if (!err)
{
m_chd = &m_diffchd;
}
@@ -250,7 +248,7 @@ image_init_result diablo_image_device::internal_load_dsk()
m_origchd.close();
m_diffchd.close();
m_chd = nullptr;
- seterror(IMAGE_ERROR_UNSPECIFIED, chd_file::error_string(err));
+ seterror(err, nullptr);
return image_init_result::FAIL;
}
diff --git a/src/devices/imagedev/flopdrv.cpp b/src/devices/imagedev/flopdrv.cpp
index 6ab5028f2d8..316b66ef713 100644
--- a/src/devices/imagedev/flopdrv.cpp
+++ b/src/devices/imagedev/flopdrv.cpp
@@ -14,9 +14,13 @@
*/
#include "emu.h"
-#include "formats/imageutl.h"
#include "flopdrv.h"
+#include "formats/imageutl.h"
+
+#include "util/ioprocs.h"
+
+
#define VERBOSE 0
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
@@ -33,7 +37,7 @@
struct floppy_error_map
{
floperr_t ferr;
- image_error_t ierr;
+ std::error_condition ierr;
const char *message;
};
@@ -45,11 +49,11 @@ struct floppy_error_map
static const floppy_error_map errmap[] =
{
- { FLOPPY_ERROR_SUCCESS, IMAGE_ERROR_SUCCESS },
- { FLOPPY_ERROR_INTERNAL, IMAGE_ERROR_INTERNAL },
- { FLOPPY_ERROR_UNSUPPORTED, IMAGE_ERROR_UNSUPPORTED },
- { FLOPPY_ERROR_OUTOFMEMORY, IMAGE_ERROR_OUTOFMEMORY },
- { FLOPPY_ERROR_INVALIDIMAGE, IMAGE_ERROR_INVALIDIMAGE }
+ { FLOPPY_ERROR_SUCCESS, { } },
+ { FLOPPY_ERROR_INTERNAL, { image_error::INTERNAL } },
+ { FLOPPY_ERROR_UNSUPPORTED, { image_error::UNSUPPORTED } },
+ { FLOPPY_ERROR_OUTOFMEMORY, { std::errc::not_enough_memory } },
+ { FLOPPY_ERROR_INVALIDIMAGE, { image_error::INVALIDIMAGE } }
};
/***************************************************************************
@@ -418,50 +422,52 @@ void legacy_floppy_image_device::floppy_drive_set_controller(device_t *controlle
image_init_result legacy_floppy_image_device::internal_floppy_device_load(bool is_create, int create_format, util::option_resolution *create_args)
{
- floperr_t err;
- const struct FloppyFormat *floppy_options;
- int floppy_flags, i;
+ const struct FloppyFormat *floppy_options = m_config->formats;
- device_image_interface *image = nullptr;
- interface(image); /* figure out the floppy options */
- floppy_options = m_config->formats;
-
- if (is_create)
+ floperr_t err;
+ check_for_file();
+ auto io = util::core_file_read_write(image_core_file(), 0xff);
+ if (!io)
+ {
+ err = FLOPPY_ERROR_OUTOFMEMORY;
+ }
+ else if (is_create)
{
/* creating an image */
assert(create_format >= 0);
- err = floppy_create((void *) image, &image_ioprocs, &floppy_options[create_format], create_args, &m_floppy);
- if (err)
- goto error;
+ err = floppy_create(std::move(io), &floppy_options[create_format], create_args, &m_floppy);
}
else
{
/* opening an image */
- floppy_flags = !is_readonly() ? FLOPPY_FLAGS_READWRITE : FLOPPY_FLAGS_READONLY;
- err = floppy_open_choices((void *) image, &image_ioprocs, filetype(), floppy_options, floppy_flags, &m_floppy);
- if (err)
- goto error;
+ int const floppy_flags = !is_readonly() ? FLOPPY_FLAGS_READWRITE : FLOPPY_FLAGS_READONLY;
+ err = floppy_open_choices(std::move(io), filetype(), floppy_options, floppy_flags, &m_floppy);
}
- if (floppy_callbacks(m_floppy)->get_heads_per_disk && floppy_callbacks(m_floppy)->get_tracks_per_disk)
- {
- floppy_drive_set_geometry_absolute(floppy_get_tracks_per_disk(m_floppy),floppy_get_heads_per_disk(m_floppy));
- }
- /* disk changed */
- m_dskchg = CLEAR_LINE;
- // If we have one of our hacky load procs, call it
- if (m_load_proc)
- m_load_proc(*this, is_create);
+ if (!err)
+ {
+ if (floppy_callbacks(m_floppy)->get_heads_per_disk && floppy_callbacks(m_floppy)->get_tracks_per_disk)
+ {
+ floppy_drive_set_geometry_absolute(floppy_get_tracks_per_disk(m_floppy),floppy_get_heads_per_disk(m_floppy));
+ }
+ /* disk changed */
+ m_dskchg = CLEAR_LINE;
- return image_init_result::PASS;
+ // If we have one of our hacky load procs, call it
+ if (m_load_proc)
+ m_load_proc(*this, is_create);
-error:
- for (i = 0; i < std::size(errmap); i++)
+ return image_init_result::PASS;
+ }
+ else
{
- if (err == errmap[i].ferr)
- seterror(errmap[i].ierr, errmap[i].message);
+ for (int i = 0; i < std::size(errmap); i++)
+ {
+ if (err == errmap[i].ferr)
+ seterror(errmap[i].ierr, errmap[i].message);
+ }
+ return image_init_result::FAIL;
}
- return image_init_result::FAIL;
}
TIMER_CALLBACK_MEMBER( legacy_floppy_image_device::set_wpt )
diff --git a/src/devices/imagedev/floppy.cpp b/src/devices/imagedev/floppy.cpp
index 452fde35035..5d3956e2cab 100644
--- a/src/devices/imagedev/floppy.cpp
+++ b/src/devices/imagedev/floppy.cpp
@@ -26,8 +26,11 @@
#include "screen.h"
#include "speaker.h"
+
#include "formats/imageutl.h"
-#include "zippath.h"
+
+#include "util/ioprocs.h"
+#include "util/zippath.h"
/*
Debugging flags. Set to 0 or 1.
@@ -273,7 +276,7 @@ floppy_image_device::floppy_image_device(const machine_config &mconfig, device_t
m_flux_screen(*this, "flux")
{
extension_list[0] = '\0';
- m_err = IMAGE_ERROR_INVALIDIMAGE;
+ m_err = image_error::INVALIDIMAGE;
}
//-------------------------------------------------
@@ -398,17 +401,19 @@ void floppy_image_device::commit_image()
image_dirty = false;
if(!output_format || !output_format->supports_save())
return;
- io_generic io;
- // Do _not_ remove this cast otherwise the pointer will be incorrect when used by the ioprocs.
- io.file = (device_image_interface *)this;
- io.procs = &image_ioprocs;
- io.filler = 0xff;
- osd_file::error err = image_core_file().truncate(0);
- if (err != osd_file::error::NONE)
- popmessage("Error, unable to truncate image: %d", int(err));
+ check_for_file();
+ auto io = util::core_file_read_write(image_core_file(), 0xff);
+ if(!io) {
+ popmessage("Error, out of memory");
+ return;
+ }
+
+ std::error_condition const err = image_core_file().truncate(0);
+ if (err)
+ popmessage("Error, unable to truncate image: %s", err.message());
- output_format->save(&io, variants, image.get());
+ output_format->save(*io, variants, image.get());
}
void floppy_image_device::device_config_complete()
@@ -532,28 +537,28 @@ floppy_image_format_t *floppy_image_device::identify(std::string filename)
{
util::core_file::ptr fd;
std::string revised_path;
+ std::error_condition err = util::zippath_fopen(filename, OPEN_FLAG_READ, fd, revised_path);
+ if(err) {
+ seterror(err, nullptr);
+ return nullptr;
+ }
- osd_file::error err = util::zippath_fopen(filename, OPEN_FLAG_READ, fd, revised_path);
- if(err != osd_file::error::NONE) {
- seterror(IMAGE_ERROR_INVALIDIMAGE, "Unable to open the image file");
+ auto io = util::core_file_read(std::move(fd), 0xff);
+ if(!io) {
+ seterror(std::errc::not_enough_memory, nullptr);
return nullptr;
}
- io_generic io;
- 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)
- {
- int score = format->identify(&io, form_factor, variants);
+ for(floppy_image_format_t *format : fif_list) {
+ int score = format->identify(*io, form_factor, variants);
if(score > best) {
best = score;
best_format = format;
}
}
- fd.reset();
+
return best_format;
}
@@ -585,16 +590,17 @@ void floppy_image_device::init_floppy_load(bool write_supported)
image_init_result floppy_image_device::call_load()
{
- io_generic io;
+ check_for_file();
+ auto io = util::core_file_read(image_core_file(), 0xff);
+ if(!io) {
+ seterror(std::errc::not_enough_memory, nullptr);
+ return image_init_result::FAIL;
+ }
- // Do _not_ remove this cast otherwise the pointer will be incorrect when used by the ioprocs.
- io.file = (device_image_interface *)this;
- io.procs = &image_ioprocs;
- io.filler = 0xff;
int best = 0;
floppy_image_format_t *best_format = nullptr;
for (floppy_image_format_t *format : fif_list) {
- int score = format->identify(&io, form_factor, variants);
+ int score = format->identify(*io, form_factor, variants);
if(score > best) {
best = score;
best_format = format;
@@ -602,13 +608,13 @@ image_init_result floppy_image_device::call_load()
}
if (!best_format) {
- seterror(IMAGE_ERROR_INVALIDIMAGE, "Unable to identify the image format");
+ seterror(image_error::INVALIDIMAGE, "Unable to identify the image format");
return image_init_result::FAIL;
}
image = std::make_unique<floppy_image>(tracks, sides, form_factor);
- if (!best_format->load(&io, form_factor, variants, image.get())) {
- seterror(IMAGE_ERROR_UNSUPPORTED, "Incompatible image format or corrupted data");
+ if (!best_format->load(*io, form_factor, variants, image.get())) {
+ seterror(image_error::UNSUPPORTED, "Incompatible image format or corrupted data");
image.reset();
return image_init_result::FAIL;
}
@@ -822,88 +828,22 @@ image_init_result floppy_image_device::call_create(int format_type, util::option
return image_init_result::PASS;
}
-// Should that go into ioprocs? Should ioprocs be turned into something C++?
-
-struct iofile_ram {
- std::vector<u8> *data;
- int64_t pos;
-};
-
-static void ram_closeproc(void *file)
-{
- auto f = (iofile_ram *)file;
- delete f;
-}
-
-static int ram_seekproc(void *file, int64_t offset, int whence)
-{
- auto f = (iofile_ram *)file;
- switch(whence) {
- case SEEK_SET: f->pos = offset; break;
- case SEEK_CUR: f->pos += offset; break;
- case SEEK_END: f->pos = f->data->size() + offset; break;
- }
-
- f->pos = std::clamp(f->pos, int64_t(0), int64_t(f->data->size()));
- return 0;
-}
-
-static size_t ram_readproc(void *file, void *buffer, size_t length)
-{
- auto f = (iofile_ram *)file;
- size_t l = std::min(length, size_t(f->data->size() - f->pos));
- memcpy(buffer, f->data->data() + f->pos, l);
- return l;
-}
-
-static size_t ram_writeproc(void *file, const void *buffer, size_t length)
-{
- auto f = (iofile_ram *)file;
- size_t l = std::min(length, size_t(f->data->size() - f->pos));
- memcpy(f->data->data() + f->pos, buffer, l);
- return l;
-}
-
-static uint64_t ram_filesizeproc(void *file)
-{
- auto f = (iofile_ram *)file;
- return f->data->size();
-}
-
-
-static const io_procs iop_ram = {
- ram_closeproc,
- ram_seekproc,
- ram_readproc,
- ram_writeproc,
- ram_filesizeproc
-};
-
-static io_generic *ram_open(std::vector<u8> &data)
-{
- iofile_ram *f = new iofile_ram;
- f->data = &data;
- f->pos = 0;
- return new io_generic({ &iop_ram, f });
-}
-
void floppy_image_device::init_fs(const fs_info *fs, const fs_meta_data &meta)
{
assert(image);
- if (fs->m_type)
- {
+ if (fs->m_type) {
std::vector<u8> img(fs->m_image_size);
fsblk_vec_t blockdev(img);
auto cfs = fs->m_manager->mount(blockdev);
cfs->format(meta);
- auto iog = ram_open(img);
auto source_format = fs->m_type();
- source_format->load(iog, floppy_image::FF_UNKNOWN, variants, image.get());
+ auto io = util::ram_read(img.data(), img.size(), 0xff);
+ source_format->load(*io, floppy_image::FF_UNKNOWN, variants, image.get());
delete source_format;
- delete iog;
- } else
+ } else {
fs_unformatted::format(fs->m_key, image.get());
+ }
}
/* write protect, active high
diff --git a/src/devices/imagedev/harddriv.cpp b/src/devices/imagedev/harddriv.cpp
index e6e0c56f896..5a7b9fe8109 100644
--- a/src/devices/imagedev/harddriv.cpp
+++ b/src/devices/imagedev/harddriv.cpp
@@ -133,8 +133,6 @@ image_init_result harddisk_image_device::call_load()
image_init_result harddisk_image_device::call_create(int create_format, util::option_resolution *create_args)
{
- int err;
-
if (!create_args)
throw emu_fatalerror("harddisk_image_device::call_create: Expected create_args to not be nullptr");
@@ -148,15 +146,15 @@ image_init_result harddisk_image_device::call_create(int create_format, util::op
/* create the CHD file */
chd_codec_type compression[4] = { CHD_CODEC_NONE };
- err = m_origchd.create(image_core_file(), (uint64_t)totalsectors * (uint64_t)sectorsize, hunksize, sectorsize, compression);
- if (err != CHDERR_NONE)
+ std::error_condition err = m_origchd.create(util::core_file_read_write(image_core_file()), (uint64_t)totalsectors * (uint64_t)sectorsize, hunksize, sectorsize, compression);
+ if (err)
return image_init_result::FAIL;
/* if we created the image and hence, have metadata to set, set the metadata */
err = m_origchd.write_metadata(HARD_DISK_METADATA_TAG, 0, string_format(HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize));
m_origchd.close();
- if (err != CHDERR_NONE)
+ if (err)
return image_init_result::FAIL;
return internal_load_hd();
@@ -168,7 +166,7 @@ void harddisk_image_device::call_unload()
if (!m_device_image_unload.isnull())
m_device_image_unload(*this);
- if (m_hard_disk_handle != nullptr)
+ if (m_hard_disk_handle)
{
hard_disk_close(m_hard_disk_handle);
m_hard_disk_handle = nullptr;
@@ -186,28 +184,28 @@ void harddisk_image_device::call_unload()
open_disk_diff - open a DISK diff file
-------------------------------------------------*/
-static chd_error open_disk_diff(emu_options &options, const char *name, chd_file &source, chd_file &diff_chd)
+static std::error_condition open_disk_diff(emu_options &options, const char *name, chd_file &source, chd_file &diff_chd)
{
std::string fname = std::string(name).append(".dif");
/* try to open the diff */
//printf("Opening differencing image file: %s\n", fname.c_str());
emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE);
- osd_file::error filerr = diff_file.open(fname.c_str());
- if (filerr == osd_file::error::NONE)
+ std::error_condition filerr = diff_file.open(fname);
+ if (!filerr)
{
std::string fullpath(diff_file.fullpath());
diff_file.close();
//printf("Opening differencing image file: %s\n", fullpath.c_str());
- return diff_chd.open(fullpath.c_str(), true, &source);
+ return diff_chd.open(fullpath, true, &source);
}
/* didn't work; try creating it instead */
//printf("Creating differencing image: %s\n", fname.c_str());
diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- filerr = diff_file.open(fname.c_str());
- if (filerr == osd_file::error::NONE)
+ filerr = diff_file.open(fname);
+ if (!filerr)
{
std::string fullpath(diff_file.fullpath());
diff_file.close();
@@ -215,23 +213,23 @@ static chd_error open_disk_diff(emu_options &options, const char *name, chd_file
/* create the CHD */
//printf("Creating differencing image file: %s\n", fupointllpath.c_str());
chd_codec_type compression[4] = { CHD_CODEC_NONE };
- chd_error err = diff_chd.create(fullpath.c_str(), source.logical_bytes(), source.hunk_bytes(), compression, source);
- if (err != CHDERR_NONE)
+ std::error_condition err = diff_chd.create(fullpath, source.logical_bytes(), source.hunk_bytes(), compression, source);
+ if (err)
return err;
return diff_chd.clone_all_metadata(source);
}
- return CHDERR_FILE_NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
}
image_init_result harddisk_image_device::internal_load_hd()
{
- chd_error err = CHDERR_NONE;
+ std::error_condition err;
m_chd = nullptr;
uint8_t header[64];
- if (m_hard_disk_handle != nullptr)
+ if (m_hard_disk_handle)
{
hard_disk_close(m_hard_disk_handle);
m_hard_disk_handle = nullptr;
@@ -250,19 +248,19 @@ image_init_result harddisk_image_device::internal_load_hd()
if (!memcmp("MComprHD", header, 8))
{
- err = m_origchd.open(image_core_file(), true);
+ err = m_origchd.open(util::core_file_read_write(image_core_file()), true);
- if (err == CHDERR_NONE)
+ if (!err)
{
m_chd = &m_origchd;
}
- else if (err == CHDERR_FILE_NOT_WRITEABLE)
+ else if (err == chd_file::error::FILE_NOT_WRITEABLE)
{
- err = m_origchd.open(image_core_file(), false);
- if (err == CHDERR_NONE)
+ err = m_origchd.open(util::core_file_read_write(image_core_file()), false);
+ if (!err)
{
err = open_disk_diff(device().machine().options(), basename_noext(), m_origchd, m_diffchd);
- if (err == CHDERR_NONE)
+ if (!err)
{
m_chd = &m_diffchd;
}
@@ -271,11 +269,11 @@ image_init_result harddisk_image_device::internal_load_hd()
}
}
- if (m_chd != nullptr)
+ if (m_chd)
{
/* open the hard disk file */
m_hard_disk_handle = hard_disk_open(m_chd);
- if (m_hard_disk_handle != nullptr)
+ if (m_hard_disk_handle)
return image_init_result::PASS;
}
else
@@ -306,7 +304,7 @@ image_init_result harddisk_image_device::internal_load_hd()
}
m_hard_disk_handle = hard_disk_open(image_core_file(), skip);
- if (m_hard_disk_handle != nullptr)
+ if (m_hard_disk_handle)
return image_init_result::PASS;
}
@@ -317,7 +315,7 @@ image_init_result harddisk_image_device::internal_load_hd()
m_origchd.close();
m_diffchd.close();
m_chd = nullptr;
- seterror(IMAGE_ERROR_UNSPECIFIED, chd_file::error_string(err));
+ seterror(err, nullptr);
return image_init_result::FAIL;
}
diff --git a/src/devices/imagedev/mfmhd.cpp b/src/devices/imagedev/mfmhd.cpp
index 61eabb12217..f309b8f0d0f 100644
--- a/src/devices/imagedev/mfmhd.cpp
+++ b/src/devices/imagedev/mfmhd.cpp
@@ -440,8 +440,8 @@ image_init_result mfm_harddisk_device::call_load()
}
// Read the hard disk metadata
- chd_error state = chdfile->read_metadata(HARD_DISK_METADATA_TAG, 0, metadata);
- if (state != CHDERR_NONE)
+ std::error_condition state = chdfile->read_metadata(HARD_DISK_METADATA_TAG, 0, metadata);
+ if (state)
{
LOG("Failed to read CHD metadata\n");
return image_init_result::FAIL;
@@ -475,7 +475,7 @@ image_init_result mfm_harddisk_device::call_load()
param.reduced_wcurr_cylinder = -1;
state = chdfile->read_metadata(MFM_HARD_DISK_METADATA_TAG, 0, metadata);
- if (state != CHDERR_NONE)
+ if (state)
{
LOGMASKED(LOG_WARN, "Failed to read CHD sector arrangement/recording specs, applying defaults\n");
}
@@ -494,7 +494,7 @@ image_init_result mfm_harddisk_device::call_load()
param.interleave, param.cylskew, param.headskew, param.write_precomp_cylinder, param.reduced_wcurr_cylinder);
state = chdfile->read_metadata(MFM_HARD_DISK_METADATA_TAG, 1, metadata);
- if (state != CHDERR_NONE)
+ if (state)
{
LOGMASKED(LOG_WARN, "Failed to read CHD track gap specs, applying defaults\n");
}
@@ -561,8 +561,8 @@ void mfm_harddisk_device::call_unload()
LOGMASKED(LOG_WARN, "MFM HD sector arrangement and recording specs have changed; updating CHD metadata\n");
chd_file* chdfile = get_chd_file();
- chd_error err = chdfile->write_metadata(MFM_HARD_DISK_METADATA_TAG, 0, string_format(MFMHD_REC_METADATA_FORMAT, params->interleave, params->cylskew, params->headskew, params->write_precomp_cylinder, params->reduced_wcurr_cylinder), 0);
- if (err != CHDERR_NONE)
+ std::error_condition err = chdfile->write_metadata(MFM_HARD_DISK_METADATA_TAG, 0, string_format(MFMHD_REC_METADATA_FORMAT, params->interleave, params->cylskew, params->headskew, params->write_precomp_cylinder, params->reduced_wcurr_cylinder), 0);
+ if (err)
{
LOGMASKED(LOG_WARN, "Failed to save MFM HD sector arrangement/recording specs to CHD\n");
}
@@ -573,8 +573,8 @@ void mfm_harddisk_device::call_unload()
LOGMASKED(LOG_WARN, "MFM HD track gap specs have changed; updating CHD metadata\n");
chd_file* chdfile = get_chd_file();
- chd_error err = chdfile->write_metadata(MFM_HARD_DISK_METADATA_TAG, 1, string_format(MFMHD_GAP_METADATA_FORMAT, params->gap1, params->gap2, params->gap3, params->sync, params->headerlen, params->ecctype), 0);
- if (err != CHDERR_NONE)
+ std::error_condition err = chdfile->write_metadata(MFM_HARD_DISK_METADATA_TAG, 1, string_format(MFMHD_GAP_METADATA_FORMAT, params->gap1, params->gap2, params->gap3, params->sync, params->headerlen, params->ecctype), 0);
+ if (err)
{
LOGMASKED(LOG_WARN, "Failed to save MFM HD track gap specs to CHD\n");
}
@@ -919,10 +919,9 @@ bool mfm_harddisk_device::write(attotime &from_when, const attotime &limit, uint
return false;
}
-chd_error mfm_harddisk_device::load_track(uint16_t* data, int cylinder, int head)
+std::error_condition mfm_harddisk_device::load_track(uint16_t* data, int cylinder, int head)
{
- chd_error state = m_format->load(m_chd, data, m_trackimage_size, cylinder, head);
- return state;
+ return m_format->load(m_chd, data, m_trackimage_size, cylinder, head);
}
void mfm_harddisk_device::write_track(uint16_t* data, int cylinder, int head)
@@ -1070,7 +1069,7 @@ void mfmhd_trackimage_cache::init(mfm_harddisk_device* mfmhd, int tracksize, int
{
if (TRACE_CACHE) m_machine.logerror("[%s:cache] MFM HD cache init; cache size is %d tracks\n", mfmhd->tag(), trackslots);
- chd_error state;
+ std::error_condition state;
mfmhd_trackimage* previous;
mfmhd_trackimage* current = nullptr;
@@ -1091,7 +1090,8 @@ void mfmhd_trackimage_cache::init(mfm_harddisk_device* mfmhd, int tracksize, int
// Load the first tracks into the slots
state = m_mfmhd->load_track(current->encdata.get(), cylinder, head);
- if (state != CHDERR_NONE) throw emu_fatalerror("Cannot load (c=%d,h=%d) from hard disk", cylinder, head);
+ if (state)
+ throw emu_fatalerror("Cannot load (c=%d,h=%d) from hard disk", cylinder, head);
current->dirty = false;
current->cylinder = cylinder;
@@ -1128,11 +1128,11 @@ uint16_t* mfmhd_trackimage_cache::get_trackimage(int cylinder, int head)
mfmhd_trackimage* current = m_tracks;
mfmhd_trackimage* previous = nullptr;
- chd_error state = CHDERR_NONE;
+ std::error_condition state;
// Repeat the search. This loop should run at most twice; once for a direct hit,
// and twice on miss, then the second iteration will be a hit.
- while (state == CHDERR_NONE)
+ while (!state)
{
// A simple linear search
while (current != nullptr)
diff --git a/src/devices/imagedev/mfmhd.h b/src/devices/imagedev/mfmhd.h
index 007be4be420..bb5d8493f97 100644
--- a/src/devices/imagedev/mfmhd.h
+++ b/src/devices/imagedev/mfmhd.h
@@ -17,8 +17,12 @@
#pragma once
#include "imagedev/harddriv.h"
+
#include "formats/mfm_hd.h"
+#include <system_error>
+
+
class mfm_harddisk_device;
class mfmhd_trackimage
@@ -94,7 +98,7 @@ public:
attotime track_end_time();
// Access the tracks on the image. Used as a callback from the cache.
- chd_error load_track(uint16_t* data, int cylinder, int head);
+ std::error_condition load_track(uint16_t* data, int cylinder, int head);
void write_track(uint16_t* data, int cylinder, int head);
// Delivers the number of heads according to the loaded image
diff --git a/src/devices/imagedev/midiin.cpp b/src/devices/imagedev/midiin.cpp
index 54a9f1c2297..e2386afb532 100644
--- a/src/devices/imagedev/midiin.cpp
+++ b/src/devices/imagedev/midiin.cpp
@@ -129,7 +129,7 @@ image_init_result midiin_device::call_load()
{
// attempt to load if it's a real file
m_err = load_image_by_path(OPEN_FLAG_READ, filename());
- if (m_err == IMAGE_ERROR_SUCCESS)
+ if (!m_err)
{
// if the parsing succeeds, schedule the start to happen at least
// 10 seconds after starting to allow the keyboards to initialize
diff --git a/src/devices/machine/ataflash.cpp b/src/devices/machine/ataflash.cpp
index 464bd074cdf..155ec34bcd3 100644
--- a/src/devices/machine/ataflash.cpp
+++ b/src/devices/machine/ataflash.cpp
@@ -140,7 +140,7 @@ void taito_pccard1_device::device_reset()
uint32_t metalength;
memset(m_key, 0, sizeof(m_key));
- if (m_handle != nullptr && m_handle->read_metadata(HARD_DISK_KEY_METADATA_TAG, 0, m_key, 5, metalength) == CHDERR_NONE)
+ if (m_handle && !m_handle->read_metadata(HARD_DISK_KEY_METADATA_TAG, 0, m_key, 5, metalength))
{
m_locked = 0x1ff;
}
@@ -231,7 +231,7 @@ void taito_pccard2_device::device_reset()
uint32_t metalength;
memset(m_key, 0, sizeof(m_key));
- if (m_handle != nullptr && m_handle->read_metadata(HARD_DISK_KEY_METADATA_TAG, 0, m_key, 5, metalength) == CHDERR_NONE)
+ if (m_handle && !m_handle->read_metadata(HARD_DISK_KEY_METADATA_TAG, 0, m_key, 5, metalength))
{
m_locked = true;
}
@@ -330,7 +330,7 @@ void taito_compact_flash_device::device_reset()
uint32_t metalength;
memset(m_key, 0, sizeof(m_key));
- if (m_handle != nullptr && m_handle->read_metadata(HARD_DISK_KEY_METADATA_TAG, 0, m_key, 5, metalength) == CHDERR_NONE)
+ if (m_handle && !m_handle->read_metadata(HARD_DISK_KEY_METADATA_TAG, 0, m_key, 5, metalength))
{
m_locked = true;
}
diff --git a/src/devices/machine/ch376.cpp b/src/devices/machine/ch376.cpp
index 8c13833292e..eeca140ec0a 100644
--- a/src/devices/machine/ch376.cpp
+++ b/src/devices/machine/ch376.cpp
@@ -255,7 +255,7 @@ void ch376_device::write(offs_t offset, u8 data)
tmpPath.append(m_file_name);
}
- if (osd_file::open(tmpPath, OPEN_FLAG_READ|OPEN_FLAG_WRITE, m_file, size) == osd_file::error::NONE)
+ if (!osd_file::open(tmpPath, OPEN_FLAG_READ|OPEN_FLAG_WRITE, m_file, size))
{
m_int_status = STATUS_USB_INT_SUCCESS;
m_cur_file_size = size & 0xffffffff;
diff --git a/src/devices/machine/hp_dc100_tape.cpp b/src/devices/machine/hp_dc100_tape.cpp
index 2c4b55e0156..7d068af39d6 100644
--- a/src/devices/machine/hp_dc100_tape.cpp
+++ b/src/devices/machine/hp_dc100_tape.cpp
@@ -30,6 +30,8 @@
#include "emu.h"
#include "hp_dc100_tape.h"
+#include "util/ioprocs.h"
+
// Debugging
#include "logmacro.h"
#define LOG_TMR_MASK (LOG_GENERAL << 1)
@@ -107,12 +109,12 @@ void hp_dc100_tape_device::call_unload()
device_reset();
if (m_image_dirty) {
- io_generic io;
- io.file = (device_image_interface *)this;
- io.procs = &image_ioprocs;
- io.filler = 0;
- m_image.save_tape(&io);
- m_image_dirty = false;
+ check_for_file();
+ auto io = util::core_file_read_write(image_core_file(), 0);
+ if (io) {
+ m_image.save_tape(*io);
+ m_image_dirty = false;
+ }
}
m_image.clear_tape();
@@ -602,18 +604,31 @@ image_init_result hp_dc100_tape_device::internal_load(bool is_create)
device_reset();
- io_generic io;
- io.file = (device_image_interface *)this;
- io.procs = &image_ioprocs;
- io.filler = 0;
+ check_for_file();
if (is_create) {
+ auto io = util::core_file_read_write(image_core_file(), 0);
+ if (!io) {
+ LOG("out of memory\n");
+ seterror(std::errc::not_enough_memory, nullptr);
+ set_tape_present(false);
+ return image_init_result::FAIL;
+ }
m_image.clear_tape();
- m_image.save_tape(&io);
- } else if (!m_image.load_tape(&io)) {
- LOG("load failed\n");
- seterror(IMAGE_ERROR_INVALIDIMAGE , "Wrong format");
- set_tape_present(false);
- return image_init_result::FAIL;
+ m_image.save_tape(*io);
+ } else {
+ auto io = util::core_file_read(image_core_file(), 0);
+ if (!io) {
+ LOG("out of memory\n");
+ seterror(std::errc::not_enough_memory, nullptr);
+ set_tape_present(false);
+ return image_init_result::FAIL;
+ }
+ if (!m_image.load_tape(*io)) {
+ LOG("load failed\n");
+ seterror(image_error::INVALIDIMAGE , "Wrong format");
+ set_tape_present(false);
+ return image_init_result::FAIL;
+ }
}
LOG("load OK\n");
diff --git a/src/devices/machine/laserdsc.cpp b/src/devices/machine/laserdsc.cpp
index 92fad4019fd..6d1ef156bf9 100644
--- a/src/devices/machine/laserdsc.cpp
+++ b/src/devices/machine/laserdsc.cpp
@@ -10,11 +10,11 @@
#include "emu.h"
#include "laserdsc.h"
-#include "avhuff.h"
-#include "vbiparse.h"
+
#include "config.h"
#include "render.h"
#include "romload.h"
+
#include "chd.h"
@@ -73,7 +73,7 @@ laserdisc_device::laserdisc_device(const machine_config &mconfig, device_type ty
m_height(0),
m_fps_times_1million(0),
m_samplerate(0),
- m_readresult(CHDERR_NONE),
+ m_readresult(),
m_chdtracks(0),
m_work_queue(osd_work_queue_alloc(WORK_QUEUE_FLAG_IO)),
m_audiosquelch(0),
@@ -661,8 +661,9 @@ void laserdisc_device::init_disc()
// read the metadata
std::string metadata;
- chd_error err = m_disc->read_metadata(AV_METADATA_TAG, 0, metadata);
- if (err != CHDERR_NONE)
+ std::error_condition err;
+ err = m_disc->read_metadata(AV_METADATA_TAG, 0, metadata);
+ if (err)
throw emu_fatalerror("Non-A/V CHD file specified");
// extract the metadata
@@ -682,7 +683,7 @@ void laserdisc_device::init_disc()
// allocate memory for the precomputed per-frame metadata
err = m_disc->read_metadata(AV_LD_METADATA_TAG, 0, m_vbidata);
- if (err != CHDERR_NONE || m_vbidata.size() != totalhunks * VBI_PACKED_BYTES)
+ if (err || (m_vbidata.size() != totalhunks * VBI_PACKED_BYTES))
throw emu_fatalerror("Precomputed VBI metadata missing or incorrect size");
}
m_maxtrack = std::max(m_maxtrack, VIRTUAL_LEAD_IN_TRACKS + VIRTUAL_LEAD_OUT_TRACKS + m_chdtracks);
@@ -959,14 +960,14 @@ void laserdisc_device::read_track_data()
}
// configure the codec and then read
- m_readresult = CHDERR_FILE_NOT_FOUND;
- if (m_disc != nullptr && !m_videosquelch)
+ m_readresult = std::errc::no_such_file_or_directory;
+ if (m_disc && !m_videosquelch)
{
m_readresult = m_disc->codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &m_avhuff_config);
- if (m_readresult == CHDERR_NONE)
+ if (!m_readresult)
{
m_queued_hunknum = readhunk;
- m_readresult = CHDERR_OPERATION_PENDING;
+ m_readresult = chd_file::error::OPERATION_PENDING;
osd_work_item_queue(m_work_queue, read_async_static, this, WORK_ITEM_FLAG_AUTO_RELEASE);
}
}
@@ -994,12 +995,12 @@ void *laserdisc_device::read_async_static(void *param, int threadid)
void laserdisc_device::process_track_data()
{
// wait for the async operation to complete
- if (m_readresult == CHDERR_OPERATION_PENDING)
+ if (m_readresult == chd_file::error::OPERATION_PENDING)
osd_work_queue_wait(m_work_queue, osd_ticks_per_second() * 10);
- assert(m_readresult != CHDERR_OPERATION_PENDING);
+ assert(m_readresult != chd_file::error::OPERATION_PENDING);
// remove the video if we had an error
- if (m_readresult != CHDERR_NONE)
+ if (m_readresult)
m_avhuff_video.reset();
// count the field as read if we are successful
diff --git a/src/devices/machine/laserdsc.h b/src/devices/machine/laserdsc.h
index 5fcc317a761..5eb06f105ea 100644
--- a/src/devices/machine/laserdsc.h
+++ b/src/devices/machine/laserdsc.h
@@ -18,8 +18,10 @@
#include "vbiparse.h"
#include "avhuff.h"
-#include <type_traits>
+#include <algorithm>
+#include <system_error>
#include <utility>
+#include <vector>
//**************************************************************************
@@ -244,8 +246,8 @@ private:
{
bitmap_yuy16 m_bitmap; // cached bitmap
bitmap_yuy16 m_visbitmap; // wrapper around bitmap with only visible lines
- uint8_t m_numfields; // number of fields in this frame
- int32_t m_lastfield; // last absolute field number
+ uint8_t m_numfields; // number of fields in this frame
+ int32_t m_lastfield; // last absolute field number
};
// internal helpers
@@ -267,19 +269,19 @@ private:
get_disc_delegate m_getdisc_callback;
audio_delegate m_audio_callback; // audio streaming callback
laserdisc_overlay_config m_orig_config; // original overlay configuration
- uint32_t m_overwidth; // overlay screen width
- uint32_t m_overheight; // overlay screen height
+ uint32_t m_overwidth; // overlay screen width
+ uint32_t m_overheight; // overlay screen height
rectangle m_overclip; // overlay visarea
screen_update_rgb32_delegate m_overupdate_rgb32; // overlay update delegate
// disc parameters
chd_file * m_disc; // handle to the disc itself
- std::vector<uint8_t> m_vbidata; // pointer to precomputed VBI data
+ std::vector<uint8_t> m_vbidata; // pointer to precomputed VBI data
int m_width; // width of video
int m_height; // height of video
uint32_t m_fps_times_1million; // frame rate of video
int m_samplerate; // audio samplerate
- int m_readresult; // result of the most recent read
+ std::error_condition m_readresult; // result of the most recent read
uint32_t m_chdtracks; // number of tracks in the CHD
bitmap_yuy16 m_avhuff_video; // decompresed frame buffer
avhuff_decoder::config m_avhuff_config; // decompression configuration
@@ -305,11 +307,11 @@ private:
// audio data
sound_stream * m_stream;
std::vector<int16_t> m_audiobuffer[2]; // buffer for audio samples
- uint32_t m_audiobufsize; // size of buffer
- uint32_t m_audiobufin; // input index
- uint32_t m_audiobufout; // output index
- uint32_t m_audiocursamples; // current samples this track
- uint32_t m_audiomaxsamples; // maximum samples per track
+ uint32_t m_audiobufsize; // size of buffer
+ uint32_t m_audiobufin; // input index
+ uint32_t m_audiobufout; // output index
+ uint32_t m_audiocursamples; // current samples this track
+ uint32_t m_audiomaxsamples; // maximum samples per track
// metadata
vbi_metadata m_metadata[2]; // metadata parsed from the stream, for each field
diff --git a/src/devices/sound/samples.cpp b/src/devices/sound/samples.cpp
index 5c8d129b799..7663d921475 100644
--- a/src/devices/sound/samples.cpp
+++ b/src/devices/sound/samples.cpp
@@ -605,26 +605,28 @@ bool samples_device::load_samples()
// load the samples
int index = 0;
- for (const char *samplename = iter.first(); samplename != nullptr; index++, samplename = iter.next())
+ for (const char *samplename = iter.first(); samplename; index++, samplename = iter.next())
{
// attempt to open as FLAC first
emu_file file(machine().options().sample_path(), OPEN_FLAG_READ);
- osd_file::error filerr = file.open(util::string_format("%s" PATH_SEPARATOR "%s.flac", basename, samplename));
- if (filerr != osd_file::error::NONE && altbasename != nullptr)
+ std::error_condition filerr = file.open(util::string_format("%s" PATH_SEPARATOR "%s.flac", basename, samplename));
+ if (filerr && altbasename)
filerr = file.open(util::string_format("%s" PATH_SEPARATOR "%s.flac", altbasename, samplename));
// if not, try as WAV
- if (filerr != osd_file::error::NONE)
+ if (filerr)
filerr = file.open(util::string_format("%s" PATH_SEPARATOR "%s.wav", basename, samplename));
- if (filerr != osd_file::error::NONE && altbasename != nullptr)
+ if (filerr && altbasename)
filerr = file.open(util::string_format("%s" PATH_SEPARATOR "%s.wav", altbasename, samplename));
// if opened, read it
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
+ {
read_sample(file, m_sample[index]);
- else if (filerr == osd_file::error::NOT_FOUND)
+ }
+ else
{
- logerror("%s: Sample '%s' NOT FOUND\n", tag(), samplename);
+ logerror("Error opening sample '%s' (%s:%d %s)\n", samplename, filerr.category().name(), filerr.value(), filerr.message());
ok = false;
}
}
diff --git a/src/emu/addrmap.h b/src/emu/addrmap.h
index c5a6c17d128..76cdc6aef54 100644
--- a/src/emu/addrmap.h
+++ b/src/emu/addrmap.h
@@ -72,7 +72,7 @@ class address_map_entry
friend class address_map;
template <typename T, typename Ret, typename... Params>
- struct is_addrmap_method { static constexpr bool value = std::is_constructible<address_map_constructor, Ret (T::*)(Params...), const char *, T*>::value; };
+ using is_addrmap_method = std::bool_constant<std::is_constructible_v<address_map_constructor, Ret (T::*)(Params...), const char *, T *> >;
template <typename T, typename Ret, typename... Params>
static std::enable_if_t<is_addrmap_method<T, Ret, Params...>::value, address_map_constructor> make_delegate(Ret (T::*func)(Params...), const char *name, T *obj)
diff --git a/src/emu/config.cpp b/src/emu/config.cpp
index 46bec43c1dd..792da6f255d 100644
--- a/src/emu/config.cpp
+++ b/src/emu/config.cpp
@@ -64,16 +64,16 @@ bool configuration_manager::load_settings()
type.load(config_type::INIT, config_level::DEFAULT, nullptr);
// now load the controller file
- const char *controller = machine().options().ctrlr();
+ char const *const controller = machine().options().ctrlr();
if (controller && *controller)
{
// open the config file
emu_file file(machine().options().ctrlr_path(), OPEN_FLAG_READ);
osd_printf_verbose("Attempting to parse: %s.cfg\n", controller);
- osd_file::error filerr = file.open(std::string(controller) + ".cfg");
+ std::error_condition const filerr = file.open(std::string(controller) + ".cfg");
- if (filerr != osd_file::error::NONE)
- throw emu_fatalerror("Could not open controller file %s.cfg", controller);
+ if (filerr)
+ throw emu_fatalerror("Could not open controller file %s.cfg (%s:%d %s)", controller, filerr.category().name(), filerr.value(), filerr.message());
// load the XML
if (!load_xml(file, config_type::CONTROLLER))
@@ -82,15 +82,15 @@ bool configuration_manager::load_settings()
// next load the defaults file
emu_file file(machine().options().cfg_directory(), OPEN_FLAG_READ);
- osd_file::error filerr = file.open("default.cfg");
+ std::error_condition filerr = file.open("default.cfg");
osd_printf_verbose("Attempting to parse: default.cfg\n");
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
load_xml(file, config_type::DEFAULT);
// finally, load the game-specific file
filerr = file.open(machine().basename() + ".cfg");
osd_printf_verbose("Attempting to parse: %s.cfg\n",machine().basename());
- const bool loaded = (osd_file::error::NONE == filerr) && load_xml(file, config_type::SYSTEM);
+ const bool loaded = !filerr && load_xml(file, config_type::SYSTEM);
// loop over all registrants and call their final function
for (const auto &type : m_typelist)
@@ -110,13 +110,13 @@ void configuration_manager::save_settings()
// save the defaults file
emu_file file(machine().options().cfg_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = file.open("default.cfg");
- if (filerr == osd_file::error::NONE)
+ std::error_condition filerr = file.open("default.cfg");
+ if (!filerr)
save_xml(file, config_type::DEFAULT);
// finally, save the system-specific file
filerr = file.open(machine().basename() + ".cfg");
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
save_xml(file, config_type::SYSTEM);
// loop over all registrants and call their final function
diff --git a/src/emu/crsshair.cpp b/src/emu/crsshair.cpp
index 43eac50587b..3c6a6b807f0 100644
--- a/src/emu/crsshair.cpp
+++ b/src/emu/crsshair.cpp
@@ -189,7 +189,7 @@ void render_crosshair::create_bitmap()
if (!m_name.empty())
{
// look for user specified file
- if (crossfile.open(m_name + ".png") == osd_file::error::NONE)
+ if (!crossfile.open(m_name + ".png"))
{
render_load_png(*m_bitmap, crossfile);
crossfile.close();
@@ -199,14 +199,14 @@ void render_crosshair::create_bitmap()
{
// look for default cross?.png in crsshair/game dir
std::string const filename = string_format("cross%d.png", m_player + 1);
- if (crossfile.open(m_machine.system().name + (PATH_SEPARATOR + filename)) == osd_file::error::NONE)
+ if (!crossfile.open(m_machine.system().name + (PATH_SEPARATOR + filename)))
{
render_load_png(*m_bitmap, crossfile);
crossfile.close();
}
// look for default cross?.png in crsshair dir
- if (!m_bitmap->valid() && (crossfile.open(filename) == osd_file::error::NONE))
+ if (!m_bitmap->valid() && !crossfile.open(filename))
{
render_load_png(*m_bitmap, crossfile);
crossfile.close();
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp
index bd537935851..58cc85f7a86 100644
--- a/src/emu/debug/debugcmd.cpp
+++ b/src/emu/debug/debugcmd.cpp
@@ -3671,11 +3671,11 @@ void debugger_commands::execute_snap(int ref, const std::vector<std::string> &pa
if (fname.find(".png") == -1)
fname.append(".png");
emu_file file(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = file.open(std::move(fname));
+ std::error_condition filerr = file.open(std::move(fname));
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
- m_console.printf("Error creating file '%s'\n", filename);
+ m_console.printf("Error creating file '%s' (%s:%d %s)\n", filename, filerr.category().name(), filerr.value(), filerr.message());
return;
}
diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp
index 1399a6b8ec2..233e369433e 100644
--- a/src/emu/debug/debugcpu.cpp
+++ b/src/emu/debug/debugcpu.cpp
@@ -168,8 +168,8 @@ bool debugger_cpu::comment_save()
if (found_comments)
{
emu_file file(m_machine.options().comment_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = file.open(m_machine.basename() + ".cmt");
- if (filerr == osd_file::error::NONE)
+ std::error_condition const filerr = file.open(m_machine.basename() + ".cmt");
+ if (!filerr)
{
root->write(file);
comments_saved = true;
@@ -194,10 +194,10 @@ bool debugger_cpu::comment_load(bool is_inline)
{
// open the file
emu_file file(m_machine.options().comment_directory(), OPEN_FLAG_READ);
- osd_file::error filerr = file.open(m_machine.basename() + ".cmt");
+ std::error_condition const filerr = file.open(m_machine.basename() + ".cmt");
// if an error, just return false
- if (filerr != osd_file::error::NONE)
+ if (filerr)
return false;
// wrap in a try/catch to handle errors
diff --git a/src/emu/devcb.h b/src/emu/devcb.h
index ec543aa48d6..d27d3beb74d 100644
--- a/src/emu/devcb.h
+++ b/src/emu/devcb.h
@@ -82,16 +82,16 @@ protected:
template <typename T, typename U> using mask_t = std::make_unsigned_t<intermediate_t<T, U> >;
// Detecting candidates for transform functions
- template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form1 { static constexpr bool value = false; };
- template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form2 { static constexpr bool value = false; };
- template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form3 { static constexpr bool value = false; };
- template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form4 { static constexpr bool value = false; };
- template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form5 { static constexpr bool value = false; };
- template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form6 { static constexpr bool value = false; };
- template <typename Input, typename Result, typename Func> struct is_transform_form3<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t &, Input, std::make_unsigned_t<Input> &>, Result>::value> > { static constexpr bool value = true; };
- template <typename Input, typename Result, typename Func> struct is_transform_form4<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t &, Input>, Result>::value> > { static constexpr bool value = true; };
- template <typename Input, typename Result, typename Func> struct is_transform_form6<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, Input>, Result>::value> > { static constexpr bool value = true; };
- template <typename Input, typename Result, typename Func> struct is_transform { static constexpr bool value = is_transform_form1<Input, Result, Func>::value || is_transform_form2<Input, Result, Func>::value || is_transform_form3<Input, Result, Func>::value || is_transform_form4<Input, Result, Func>::value || is_transform_form5<Input, Result, Func>::value || is_transform_form6<Input, Result, Func>::value; };
+ template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form1 : public std::false_type { };
+ template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form2 : public std::false_type { };
+ template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form3 : public std::false_type { };
+ template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form4 : public std::false_type { };
+ template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form5 : public std::false_type { };
+ template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form6 : public std::false_type { };
+ template <typename Input, typename Result, typename Func> struct is_transform_form3<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t &, Input, std::make_unsigned_t<Input> &>, Result>::value> > : public std::true_type { };
+ template <typename Input, typename Result, typename Func> struct is_transform_form4<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t &, Input>, Result>::value> > : public std::true_type { };
+ template <typename Input, typename Result, typename Func> struct is_transform_form6<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, Input>, Result>::value> > : public std::true_type { };
+ template <typename Input, typename Result, typename Func> struct is_transform : public std::bool_constant<is_transform_form1<Input, Result, Func>::value || is_transform_form2<Input, Result, Func>::value || is_transform_form3<Input, Result, Func>::value || is_transform_form4<Input, Result, Func>::value || is_transform_form5<Input, Result, Func>::value || is_transform_form6<Input, Result, Func>::value> { };
// Determining the result type of a transform function
template <typename Input, typename Result, typename Func, typename Enable = void> struct transform_result;
@@ -211,13 +211,13 @@ class devcb_read_base : public devcb_base
{
protected:
// Detecting candidates for read functions
- template <typename Result, typename Func, typename Enable = void> struct is_read_form1 { static constexpr bool value = false; };
- template <typename Result, typename Func, typename Enable = void> struct is_read_form2 { static constexpr bool value = false; };
- template <typename Result, typename Func, typename Enable = void> struct is_read_form3 { static constexpr bool value = false; };
- template <typename Result, typename Func> struct is_read_form1<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t, Result>, Result>::value> > { static constexpr bool value = true; };
- template <typename Result, typename Func> struct is_read_form2<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t>, Result>::value> > { static constexpr bool value = true; };
- template <typename Result, typename Func> struct is_read_form3<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func>, Result>::value> > { static constexpr bool value = true; };
- template <typename Result, typename Func> struct is_read { static constexpr bool value = is_read_form1<Result, Func>::value || is_read_form2<Result, Func>::value || is_read_form3<Result, Func>::value; };
+ template <typename Result, typename Func, typename Enable = void> struct is_read_form1 : public std::false_type { };
+ template <typename Result, typename Func, typename Enable = void> struct is_read_form2 : public std::false_type { };
+ template <typename Result, typename Func, typename Enable = void> struct is_read_form3 : public std::false_type { };
+ template <typename Result, typename Func> struct is_read_form1<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t, Result>, Result>::value> > : public std::true_type { };
+ template <typename Result, typename Func> struct is_read_form2<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t>, Result>::value> > : public std::true_type { };
+ template <typename Result, typename Func> struct is_read_form3<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func>, Result>::value> > : public std::true_type { };
+ template <typename Result, typename Func> struct is_read : public std::bool_constant<is_read_form1<Result, Func>::value || is_read_form2<Result, Func>::value || is_read_form3<Result, Func>::value> { };
// Determining the result type of a read function
template <typename Result, typename Func, typename Enable = void> struct read_result;
@@ -227,20 +227,20 @@ protected:
template <typename Result, typename Func> using read_result_t = typename read_result<Result, Func>::type;
// Detecting candidates for read delegates
- template <typename T, typename Enable = void> struct is_read_method { static constexpr bool value = false; };
- template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read8s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read16s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read32s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read64s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read8sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read16sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read32sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read64sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read8smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read16smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read32smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read64smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read_line_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
+ template <typename T, typename Enable = void> struct is_read_method : public std::false_type { };
+ template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read8s_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read16s_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read32s_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read64s_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read8sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read16sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read32sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read64sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read8smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read16smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read32smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read64smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read_line_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
// Invoking read callbacks
template <typename Result, typename T> static std::enable_if_t<is_read_form1<Result, T>::value, mask_t<read_result_t<Result, T>, Result> > invoke_read(T const &cb, offs_t offset, std::make_unsigned_t<Result> mem_mask) { return std::make_unsigned_t<read_result_t<Result, T> >(cb(offset, mem_mask)); }
@@ -275,29 +275,29 @@ class devcb_write_base : public devcb_base
{
protected:
// Detecting candidates for write functions
- template <typename Input, typename Func, typename Enable = void> struct is_write_form1 { static constexpr bool value = false; };
- template <typename Input, typename Func, typename Enable = void> struct is_write_form2 { static constexpr bool value = false; };
- template <typename Input, typename Func, typename Enable = void> struct is_write_form3 { static constexpr bool value = false; };
- template <typename Input, typename Func> struct is_write_form1<Input, Func, void_t<std::invoke_result_t<Func, offs_t, Input, std::make_unsigned_t<Input>> > > { static constexpr bool value = true; };
- template <typename Input, typename Func> struct is_write_form2<Input, Func, void_t<std::invoke_result_t<Func, offs_t, Input> > > { static constexpr bool value = true; };
- template <typename Input, typename Func> struct is_write_form3<Input, Func, void_t<std::invoke_result_t<Func, Input> > > { static constexpr bool value = true; };
- template <typename Input, typename Func> struct is_write { static constexpr bool value = is_write_form1<Input, Func>::value || is_write_form2<Input, Func>::value || is_write_form3<Input, Func>::value; };
+ template <typename Input, typename Func, typename Enable = void> struct is_write_form1 : public std::false_type { };
+ template <typename Input, typename Func, typename Enable = void> struct is_write_form2 : public std::false_type { };
+ template <typename Input, typename Func, typename Enable = void> struct is_write_form3 : public std::false_type { };
+ template <typename Input, typename Func> struct is_write_form1<Input, Func, void_t<std::invoke_result_t<Func, offs_t, Input, std::make_unsigned_t<Input>> > > : public std::true_type { };
+ template <typename Input, typename Func> struct is_write_form2<Input, Func, void_t<std::invoke_result_t<Func, offs_t, Input> > > : public std::true_type { };
+ template <typename Input, typename Func> struct is_write_form3<Input, Func, void_t<std::invoke_result_t<Func, Input> > > : public std::true_type { };
+ template <typename Input, typename Func> struct is_write : public std::bool_constant<is_write_form1<Input, Func>::value || is_write_form2<Input, Func>::value || is_write_form3<Input, Func>::value> { };
// Detecting candidates for write delegates
- template <typename T, typename Enable = void> struct is_write_method { static constexpr bool value = false; };
- template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write8s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write16s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write32s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write64s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write8sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write16sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write32sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write64sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write8smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write16smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write32smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write64smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
- template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write_line_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; };
+ template <typename T, typename Enable = void> struct is_write_method : public std::false_type { };
+ template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write8s_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write16s_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write32s_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write64s_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write8sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write16sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write32sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write64sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write8smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write16smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write32smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write64smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
+ template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write_line_delegate, std::remove_reference_t<T> > > > : public std::true_type { };
// Invoking write callbacks
template <typename Input, typename T> static std::enable_if_t<is_write_form1<Input, T>::value> invoke_write(T const &cb, offs_t &offset, Input data, std::make_unsigned_t<Input> mem_mask) { return cb(offset, data, mem_mask); }
diff --git a/src/emu/devdelegate.h b/src/emu/devdelegate.h
index 1ba303d3ef3..906e1da9274 100644
--- a/src/emu/devdelegate.h
+++ b/src/emu/devdelegate.h
@@ -111,12 +111,12 @@ class device_delegate<ReturnType (Params...)> : protected named_delegate<ReturnT
private:
using basetype = named_delegate<ReturnType (Params...)>;
- template <class T, class U> struct is_related_device_implementation
- { static constexpr bool value = std::is_base_of<T, U>::value && std::is_base_of<device_t, U>::value; };
- template <class T, class U> struct is_related_device_interface
- { static constexpr bool value = std::is_base_of<T, U>::value && std::is_base_of<device_interface, U>::value && !std::is_base_of<device_t, U>::value; };
- template <class T, class U> struct is_related_device
- { static constexpr bool value = is_related_device_implementation<T, U>::value || is_related_device_interface<T, U>::value; };
+ template <class T, class U>
+ using is_related_device_implementation = std::bool_constant<std::is_base_of_v<T, U> && std::is_base_of_v<device_t, U> >;
+ template <class T, class U>
+ using is_related_device_interface = std::bool_constant<std::is_base_of_v<T, U> && std::is_base_of_v<device_interface, U> && !std::is_base_of_v<device_t, U> >;
+ template <class T, class U>
+ using is_related_device = std::bool_constant<is_related_device_implementation<T, U>::value || is_related_device_interface<T, U>::value>;
template <class T> static std::enable_if_t<is_related_device_implementation<T, T>::value, device_t &> get_device(T &object) { return object; }
template <class T> static std::enable_if_t<is_related_device_interface<T, T>::value, device_t &> get_device(T &object) { return object.device(); }
@@ -124,8 +124,8 @@ private:
public:
template <unsigned Count> using array = device_delegate_array<ReturnType (Params...), Count>;
- template <typename T> struct supports_callback
- { static constexpr bool value = std::is_constructible<device_delegate, device_t &, char const *, T, char const *>::value; };
+ template <typename T>
+ using supports_callback = std::bool_constant<std::is_constructible_v<device_delegate, device_t &, char const *, T, char const *> >;
// construct/assign
explicit device_delegate(device_t &owner) : basetype(), detail::device_delegate_helper(owner) { }
diff --git a/src/emu/devfind.h b/src/emu/devfind.h
index c5f7a04929a..8253fb123f6 100644
--- a/src/emu/devfind.h
+++ b/src/emu/devfind.h
@@ -308,7 +308,7 @@ public:
}
/// \brief Dummy tag always treated as not found
- constexpr static char DUMMY_TAG[17] = "finder_dummy_tag";
+ static constexpr char DUMMY_TAG[17] = "finder_dummy_tag";
protected:
/// \brief Designated constructor
diff --git a/src/emu/device.h b/src/emu/device.h
index 21ac3bcba6e..d5fe81dd305 100644
--- a/src/emu/device.h
+++ b/src/emu/device.h
@@ -69,15 +69,11 @@ namespace emu::detail {
class device_type_impl_base;
-template <typename T> struct is_device_implementation
-{
- static constexpr bool value = std::is_base_of<device_t, T>::value;
-};
+template <typename T>
+using is_device_implementation = std::bool_constant<std::is_base_of_v<device_t, T> >;
-template <typename T> struct is_device_interface
-{
- static constexpr bool value = std::is_base_of<device_interface, T>::value && !is_device_implementation<T>::value;
-};
+template <typename T>
+using is_device_interface = std::bool_constant<std::is_base_of_v<device_interface, T> && !is_device_implementation<T>::value>;
struct device_feature
diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp
index 55a9193f3f1..e38b4939a2b 100644
--- a/src/emu/diimage.cpp
+++ b/src/emu/diimage.cpp
@@ -10,14 +10,15 @@
#include "emu.h"
-#include "corestr.h"
#include "emuopts.h"
#include "romload.h"
-#include "ui/uimain.h"
-#include "zippath.h"
#include "softlist.h"
#include "softlist_dev.h"
-#include "formats/ioprocs.h"
+
+#include "ui/uimain.h"
+
+#include "corestr.h"
+#include "zippath.h"
#include <algorithm>
#include <cctype>
@@ -270,11 +271,8 @@ void device_image_interface::add_format(std::string &&name, std::string &&descri
void device_image_interface::clear_error()
{
- m_err = IMAGE_ERROR_SUCCESS;
- if (!m_err_message.empty())
- {
- m_err_message.clear();
- }
+ m_err.clear();
+ m_err_message.clear();
}
@@ -284,21 +282,38 @@ void device_image_interface::clear_error()
// error
//-------------------------------------------------
-static std::string_view messages[] =
+std::error_category const &image_category() noexcept
{
- "",
- "Internal error",
- "Unsupported operation",
- "Out of memory",
- "File not found",
- "Invalid image",
- "File already open",
- "Unspecified error"
-};
+ class image_category_impl : public std::error_category
+ {
+ public:
+ virtual char const *name() const noexcept override { return "image"; }
+
+ virtual std::string message(int condition) const override
+ {
+ using namespace std::literals;
+ static std::string_view const s_messages[] = {
+ "No error"sv,
+ "Internal error"sv,
+ "Unsupported operation"sv,
+ "Invalid image"sv,
+ "File already open"sv,
+ "Unspecified error"sv };
+ if ((0 <= condition) && (std::size(s_messages) > condition))
+ return std::string(s_messages[condition]);
+ else
+ return "Unknown error"s;
+ }
+ };
+ static image_category_impl const s_image_category_instance;
+ return s_image_category_instance;
+}
std::string_view device_image_interface::error()
{
- return (!m_err_message.empty()) ? m_err_message : messages[m_err];
+ if (m_err && m_err_message.empty())
+ m_err_message = m_err.message();
+ return m_err_message;
}
@@ -307,14 +322,12 @@ std::string_view device_image_interface::error()
// seterror - specifies an error on an image
//-------------------------------------------------
-void device_image_interface::seterror(image_error_t err, const char *message)
+void device_image_interface::seterror(std::error_condition err, const char *message)
{
clear_error();
m_err = err;
- if (message != nullptr)
- {
+ if (message)
m_err_message = message;
- }
}
@@ -544,14 +557,13 @@ void device_image_interface::battery_load(void *buffer, int length, int fill)
if (!buffer || (length <= 0))
throw emu_fatalerror("device_image_interface::battery_load: Must specify sensical buffer/length");
- osd_file::error filerr;
- int bytes_read = 0;
- std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext).append(".nv");
+ std::string const fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext).append(".nv");
/* try to open the battery file and read it in, if possible */
emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_READ);
- filerr = file.open(fname);
- if (filerr == osd_file::error::NONE)
+ std::error_condition const filerr = file.open(fname);
+ int bytes_read = 0;
+ if (!filerr)
bytes_read = file.read(buffer, length);
// fill remaining bytes (if necessary)
@@ -563,14 +575,13 @@ void device_image_interface::battery_load(void *buffer, int length, const void *
if (!buffer || (length <= 0))
throw emu_fatalerror("device_image_interface::battery_load: Must specify sensical buffer/length");
- osd_file::error filerr;
- int bytes_read = 0;
- std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext).append(".nv");
+ std::string const fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext).append(".nv");
// try to open the battery file and read it in, if possible
emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_READ);
- filerr = file.open(fname);
- if (filerr == osd_file::error::NONE)
+ std::error_condition const filerr = file.open(fname);
+ int bytes_read = 0;
+ if (!filerr)
bytes_read = file.read(buffer, length);
// if no file was present, copy the default contents
@@ -598,8 +609,8 @@ void device_image_interface::battery_save(const void *buffer, int length)
// try to open the battery file and write it out, if possible
emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = file.open(fname);
- if (filerr == osd_file::error::NONE)
+ std::error_condition const filerr = file.open(fname);
+ if (!filerr)
file.write(buffer, length);
}
@@ -637,58 +648,30 @@ bool device_image_interface::uses_file_extension(const char *file_extension) con
// ***************************************************************************
//-------------------------------------------------
-// image_error_from_file_error - converts an image
-// error to a file error
-//-------------------------------------------------
-
-image_error_t device_image_interface::image_error_from_file_error(osd_file::error filerr)
-{
- switch (filerr)
- {
- case osd_file::error::NONE:
- return IMAGE_ERROR_SUCCESS;
-
- case osd_file::error::NOT_FOUND:
- case osd_file::error::ACCESS_DENIED:
- // file not found (or otherwise cannot open)
- return IMAGE_ERROR_FILENOTFOUND;
-
- case osd_file::error::OUT_OF_MEMORY:
- // out of memory
- return IMAGE_ERROR_OUTOFMEMORY;
-
- case osd_file::error::ALREADY_OPEN:
- // this shouldn't happen
- return IMAGE_ERROR_ALREADYOPEN;
-
- case osd_file::error::FAILURE:
- case osd_file::error::TOO_MANY_FILES:
- case osd_file::error::INVALID_DATA:
- default:
- // other errors
- return IMAGE_ERROR_INTERNAL;
- }
-}
-
-
-//-------------------------------------------------
// load_image_by_path - loads an image with a
// specific path
//-------------------------------------------------
-image_error_t device_image_interface::load_image_by_path(u32 open_flags, std::string_view path)
+std::error_condition device_image_interface::load_image_by_path(u32 open_flags, std::string_view path)
{
std::string revised_path;
// attempt to read the file
- auto const filerr = util::zippath_fopen(path, open_flags, m_file, revised_path);
- if (filerr != osd_file::error::NONE)
- return image_error_from_file_error(filerr);
+ auto filerr = util::zippath_fopen(path, open_flags, m_file, revised_path);
+ if (filerr)
+ {
+ osd_printf_verbose("%s: error opening image file %s with flags=%08X (%s:%d %s)\n", device().tag(), path, open_flags, filerr.category().name(), filerr.value(), filerr.message());
+ return filerr;
+ }
+ else
+ {
+ osd_printf_verbose("%s: opened image file %s with flags=%08X\n", device().tag(), path, open_flags);
+ }
m_readonly = (open_flags & OPEN_FLAG_WRITE) ? 0 : 1;
m_created = (open_flags & OPEN_FLAG_CREATE) ? 1 : 0;
set_image_filename(revised_path);
- return IMAGE_ERROR_SUCCESS;
+ return std::error_condition();
}
@@ -696,7 +679,7 @@ image_error_t device_image_interface::load_image_by_path(u32 open_flags, std::st
// reopen_for_write
//-------------------------------------------------
-int device_image_interface::reopen_for_write(std::string_view path)
+std::error_condition device_image_interface::reopen_for_write(std::string_view path)
{
m_file.reset();
@@ -704,15 +687,15 @@ int device_image_interface::reopen_for_write(std::string_view path)
// attempt to open the file for writing
auto const filerr = util::zippath_fopen(path, OPEN_FLAG_READ|OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, m_file, revised_path);
- if (filerr != osd_file::error::NONE)
- return image_error_from_file_error(filerr);
+ if (filerr)
+ return filerr;
// success!
m_readonly = 0;
m_created = 1;
set_image_filename(revised_path);
- return IMAGE_ERROR_SUCCESS;
+ return std::error_condition();
}
@@ -823,19 +806,19 @@ bool device_image_interface::load_software(software_list_device &swlist, std::st
// try to load the file
m_mame_file.reset(new emu_file(device().machine().options().media_path(), searchpath, OPEN_FLAG_READ));
m_mame_file->set_restrict_to_mediapath(1);
- osd_file::error filerr;
+ std::error_condition filerr;
if (has_crc)
filerr = m_mame_file->open(romp->name(), crc);
else
filerr = m_mame_file->open(romp->name());
- if (filerr != osd_file::error::NONE)
+ if (filerr)
m_mame_file.reset();
warningcount += verify_length_and_hash(m_mame_file.get(), romp->name(), romp->get_length(), util::hash_collection(romp->hashdata()));
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
filerr = util::core_file::open_proxy(*m_mame_file, m_file);
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
retval = true;
break; // load first item for start
@@ -878,14 +861,14 @@ image_init_result device_image_interface::load_internal(std::string_view path, b
{
// open the file
m_err = load_image_by_path(*iter, path);
- if (m_err && (m_err != IMAGE_ERROR_FILENOTFOUND))
+ if (m_err && (m_err != std::errc::no_such_file_or_directory) && (m_err != std::errc::permission_denied))
goto done;
}
// did we fail to find the file?
if (!m_file)
{
- m_err = IMAGE_ERROR_FILENOTFOUND;
+ m_err = std::errc::no_such_file_or_directory;
goto done;
}
}
@@ -894,15 +877,17 @@ image_init_result device_image_interface::load_internal(std::string_view path, b
m_create_format = create_format;
m_create_args = create_args;
- if (init_phase()==false) {
- m_err = (finish_load() == image_init_result::PASS) ? IMAGE_ERROR_SUCCESS : IMAGE_ERROR_INTERNAL;
+ if (!init_phase())
+ {
+ m_err = (finish_load() == image_init_result::PASS) ? std::error_condition() : image_error::INTERNAL;
if (m_err)
goto done;
}
// success!
done:
- if (m_err!=0) {
+ if (m_err)
+ {
if (!init_phase())
{
if (device().machine().phase() == machine_phase::RUNNING)
@@ -1004,7 +989,7 @@ image_init_result device_image_interface::finish_load()
{
if (!image_checkhash())
{
- m_err = IMAGE_ERROR_INVALIDIMAGE;
+ m_err = image_error::INVALIDIMAGE;
err = image_init_result::FAIL;
}
@@ -1016,7 +1001,7 @@ image_init_result device_image_interface::finish_load()
if (err != image_init_result::PASS)
{
if (!m_err)
- m_err = IMAGE_ERROR_UNSPECIFIED;
+ m_err = image_error::UNSPECIFIED;
}
}
else
@@ -1026,7 +1011,7 @@ image_init_result device_image_interface::finish_load()
if (err != image_init_result::PASS)
{
if (!m_err)
- m_err = IMAGE_ERROR_UNSPECIFIED;
+ m_err = image_error::UNSPECIFIED;
}
}
}
@@ -1354,41 +1339,3 @@ bool device_image_interface::init_phase() const
return !device().has_running_machine()
|| device().machine().phase() == machine_phase::INIT;
}
-
-
-//----------------------------------------------------------------------------
-
-static int image_fseek_thunk(void *file, s64 offset, int whence)
-{
- device_image_interface *image = (device_image_interface *) file;
- return image->fseek(offset, whence);
-}
-
-static size_t image_fread_thunk(void *file, void *buffer, size_t length)
-{
- device_image_interface *image = (device_image_interface *) file;
- return image->fread(buffer, length);
-}
-
-static size_t image_fwrite_thunk(void *file, const void *buffer, size_t length)
-{
- device_image_interface *image = (device_image_interface *) file;
- return image->fwrite(buffer, length);
-}
-
-static u64 image_fsize_thunk(void *file)
-{
- device_image_interface *image = (device_image_interface *) file;
- return image->length();
-}
-
-//----------------------------------------------------------------------------
-
-struct io_procs image_ioprocs =
-{
- nullptr,
- image_fseek_thunk,
- image_fread_thunk,
- image_fwrite_thunk,
- image_fsize_thunk
-};
diff --git a/src/emu/diimage.h b/src/emu/diimage.h
index 507fd34e1d3..05f714f2647 100644
--- a/src/emu/diimage.h
+++ b/src/emu/diimage.h
@@ -19,6 +19,7 @@
#include <memory>
#include <string>
+#include <system_error>
#include <vector>
@@ -26,8 +27,6 @@
// TYPE DEFINITIONS
//**************************************************************************
-extern struct io_procs image_ioprocs;
-
enum iodevice_t
{
/* List of all supported devices. Refer to the device by these names only */
@@ -55,18 +54,19 @@ enum iodevice_t
IO_COUNT /* 21 - Total Number of IO_devices for searching */
};
-enum image_error_t
+enum class image_error : int
{
- IMAGE_ERROR_SUCCESS,
- IMAGE_ERROR_INTERNAL,
- IMAGE_ERROR_UNSUPPORTED,
- IMAGE_ERROR_OUTOFMEMORY,
- IMAGE_ERROR_FILENOTFOUND,
- IMAGE_ERROR_INVALIDIMAGE,
- IMAGE_ERROR_ALREADYOPEN,
- IMAGE_ERROR_UNSPECIFIED
+ INTERNAL = 1,
+ UNSUPPORTED,
+ INVALIDIMAGE,
+ ALREADYOPEN,
+ UNSPECIFIED
};
+const std::error_category &image_category() noexcept;
+inline std::error_condition make_error_condition(image_error e) noexcept { return std::error_condition(int(e), image_category()); }
+namespace std { template <> struct is_error_condition_enum<image_error> : public std::true_type { }; }
+
struct image_device_type_info
{
iodevice_t m_type;
@@ -150,7 +150,7 @@ public:
const util::option_guide &device_get_creation_option_guide() const { return create_option_guide(); }
std::string_view error();
- void seterror(image_error_t err, const char *message);
+ void seterror(std::error_condition err, const char *message);
void message(const char *format, ...) ATTR_PRINTF(2,3);
bool exists() const noexcept { return !m_image_name.empty(); }
@@ -172,7 +172,7 @@ public:
int fgetc() { char ch; if (fread(&ch, 1) != 1) ch = '\0'; return ch; }
char *fgets(char *buffer, u32 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()); }
+ void *ptr() { check_for_file(); return const_cast<void *>(m_file->buffer()); }
// configuration access
const software_info *software_entry() const noexcept;
@@ -217,7 +217,7 @@ public:
image_init_result create(std::string_view path, const image_device_format *create_format, util::option_resolution *create_args);
image_init_result create(std::string_view path);
bool load_software(software_list_device &swlist, std::string_view swname, const rom_entry *entry);
- int reopen_for_write(std::string_view path);
+ std::error_condition reopen_for_write(std::string_view path);
void set_user_loadable(bool user_loadable) { m_user_loadable = user_loadable; }
@@ -233,7 +233,7 @@ protected:
virtual const bool use_software_list_file_extension_for_filetype() const { return false; }
image_init_result load_internal(std::string_view path, bool is_create, int create_format, util::option_resolution *create_args);
- image_error_t load_image_by_path(u32 open_flags, std::string_view path);
+ std::error_condition load_image_by_path(u32 open_flags, std::string_view path);
void clear();
bool is_loaded() const { return m_file != nullptr; }
@@ -260,7 +260,7 @@ protected:
static const image_device_type_info m_device_info_array[];
// error related info
- image_error_t m_err;
+ std::error_condition m_err;
std::string m_err_message;
private:
@@ -277,7 +277,6 @@ private:
const software_part *m_software_part_ptr;
std::string m_software_list_name;
- static image_error_t image_error_from_file_error(osd_file::error filerr);
std::vector<u32> determine_open_plan(bool is_create);
void update_names();
bool load_software_part(std::string_view identifier);
diff --git a/src/emu/dimemory.h b/src/emu/dimemory.h
index f15a04166f4..119ec9bc6f9 100644
--- a/src/emu/dimemory.h
+++ b/src/emu/dimemory.h
@@ -50,11 +50,11 @@ constexpr int TRANSLATE_FETCH_DEBUG = (TRANSLATE_FETCH | TRANSLATE_DEBUG_MAS
class device_memory_interface : public device_interface
{
friend class device_scheduler;
- template <typename T, typename U> struct is_related_class { static constexpr bool value = std::is_convertible<std::add_pointer_t<T>, std::add_pointer_t<U> >::value; };
- template <typename T, typename U> struct is_related_device { static constexpr bool value = emu::detail::is_device_implementation<T>::value && is_related_class<T, U>::value; };
- template <typename T, typename U> struct is_related_interface { static constexpr bool value = emu::detail::is_device_interface<T>::value && is_related_class<T, U>::value; };
- template <typename T, typename U> struct is_unrelated_device { static constexpr bool value = emu::detail::is_device_implementation<T>::value && !is_related_class<T, U>::value; };
- template <typename T, typename U> struct is_unrelated_interface { static constexpr bool value = emu::detail::is_device_interface<T>::value && !is_related_class<T, U>::value; };
+ template <typename T, typename U> using is_related_class = std::bool_constant<std::is_convertible_v<std::add_pointer_t<T>, std::add_pointer_t<U> > >;
+ template <typename T, typename U> using is_related_device = std::bool_constant<emu::detail::is_device_implementation<T>::value && is_related_class<T, U>::value >;
+ template <typename T, typename U> using is_related_interface = std::bool_constant<emu::detail::is_device_interface<T>::value && is_related_class<T, U>::value >;
+ template <typename T, typename U> using is_unrelated_device = std::bool_constant<emu::detail::is_device_implementation<T>::value && !is_related_class<T, U>::value >;
+ template <typename T, typename U> using is_unrelated_interface = std::bool_constant<emu::detail::is_device_interface<T>::value && !is_related_class<T, U>::value >;
public:
// construction/destruction
diff --git a/src/emu/dipty.cpp b/src/emu/dipty.cpp
index 925113edd08..6a323d84e7f 100644
--- a/src/emu/dipty.cpp
+++ b/src/emu/dipty.cpp
@@ -27,7 +27,7 @@ bool device_pty_interface::open()
{
if (!m_opened)
{
- if (osd_file::openpty(m_pty_master, m_slave_name) == osd_file::error::NONE)
+ if (!osd_file::openpty(m_pty_master, m_slave_name))
{
m_opened = true;
}
@@ -54,7 +54,7 @@ bool device_pty_interface::is_open() const
ssize_t device_pty_interface::read(u8 *rx_chars , size_t count) const
{
u32 actual_bytes;
- if (m_opened && m_pty_master->read(rx_chars, 0, count, actual_bytes) == osd_file::error::NONE)
+ if (m_opened && !m_pty_master->read(rx_chars, 0, count, actual_bytes))
return actual_bytes;
else
return -1;
@@ -72,8 +72,3 @@ bool device_pty_interface::is_slave_connected() const
// TODO: really check for slave status
return m_opened;
}
-
-const char *device_pty_interface::slave_name() const
-{
- return m_slave_name.c_str();
-}
diff --git a/src/emu/dipty.h b/src/emu/dipty.h
index 790d4ec39b0..9fc1ddbc7e1 100644
--- a/src/emu/dipty.h
+++ b/src/emu/dipty.h
@@ -7,10 +7,14 @@
Device PTY interface
***************************************************************************/
-
#ifndef MAME_EMU_DIPTY_H
#define MAME_EMU_DIPTY_H
+#pragma once
+
+#include <string>
+
+
class device_pty_interface : public device_interface
{
public:
@@ -28,7 +32,7 @@ public:
bool is_slave_connected() const;
- const char *slave_name() const;
+ const std::string &slave_name() const { return m_slave_name; }
protected:
osd_file::ptr m_pty_master;
diff --git a/src/emu/fileio.cpp b/src/emu/fileio.cpp
index 293c23045b4..0fa41d3cd11 100644
--- a/src/emu/fileio.cpp
+++ b/src/emu/fileio.cpp
@@ -11,7 +11,8 @@
#include "emu.h"
#include "fileio.h"
-#include "unzip.h"
+#include "util/path.h"
+#include "util/unzip.h"
//#define VERBOSE 1
#define LOG_OUTPUT_FUNC osd_printf_verbose
@@ -121,12 +122,7 @@ bool path_iterator::next(std::string &buffer, const char *name)
// append the name if we have one
if (name)
- {
- // compute the full pathname
- if (!buffer.empty() && !util::is_directory_separator(buffer.back()))
- buffer.append(PATH_SEPARATOR);
- buffer.append(name);
- }
+ util::path_append(buffer, name);
// bump the index and return true
m_is_first = false;
@@ -298,7 +294,7 @@ util::hash_collection &emu_file::hashes(std::string_view types)
// open - open a file by searching paths
//-------------------------------------------------
-osd_file::error emu_file::open(std::string &&name)
+std::error_condition emu_file::open(std::string &&name)
{
// remember the filename and CRC info
m_filename = std::move(name);
@@ -310,7 +306,7 @@ osd_file::error emu_file::open(std::string &&name)
return open_next();
}
-osd_file::error emu_file::open(std::string &&name, u32 crc)
+std::error_condition emu_file::open(std::string &&name, u32 crc)
{
// remember the filename and CRC info
m_filename = std::move(name);
@@ -328,7 +324,7 @@ osd_file::error emu_file::open(std::string &&name, u32 crc)
// the filename by iterating over paths
//-------------------------------------------------
-osd_file::error emu_file::open_next()
+std::error_condition emu_file::open_next()
{
// if we're open from a previous attempt, close up now
if (m_file)
@@ -336,8 +332,8 @@ osd_file::error emu_file::open_next()
// loop over paths
LOG("emu_file: open next '%s'\n", m_filename);
- osd_file::error filerr = osd_file::error::NOT_FOUND;
- while (osd_file::error::NONE != filerr)
+ std::error_condition filerr = std::errc::no_such_file_or_directory;
+ while (filerr)
{
if (m_first)
{
@@ -385,7 +381,7 @@ osd_file::error emu_file::open_next()
filerr = util::core_file::open(m_fullpath, m_openflags, m_file);
// if we're opening for read-only we have other options
- if ((osd_file::error::NONE != filerr) && ((m_openflags & (OPEN_FLAG_READ | OPEN_FLAG_WRITE)) == OPEN_FLAG_READ))
+ if (filerr && ((m_openflags & (OPEN_FLAG_READ | OPEN_FLAG_WRITE)) == OPEN_FLAG_READ))
{
LOG("emu_file: attempting to open '%s' from archives\n", m_fullpath);
filerr = attempt_zipped();
@@ -400,7 +396,7 @@ osd_file::error emu_file::open_next()
// just an array of data in RAM
//-------------------------------------------------
-osd_file::error emu_file::open_ram(const void *data, u32 length)
+std::error_condition emu_file::open_ram(const void *data, u32 length)
{
// set a fake filename and CRC
m_filename = "RAM";
@@ -435,29 +431,14 @@ void emu_file::close()
//-------------------------------------------------
-// compress - enable/disable streaming file
-// compression via zlib; level is 0 to disable
-// compression, or up to 9 for max compression
-//-------------------------------------------------
-
-osd_file::error emu_file::compress(int level)
-{
- return m_file->compress(level);
-}
-
-
-//-------------------------------------------------
// compressed_file_ready - ensure our zip is ready
// loading if needed
//-------------------------------------------------
-bool emu_file::compressed_file_ready()
+std::error_condition emu_file::compressed_file_ready()
{
// load the ZIP file now if we haven't yet
- if (m_zipfile && (load_zipped_file() != osd_file::error::NONE))
- return true;
-
- return false;
+ return m_zipfile ? load_zipped_file() : std::error_condition();
}
//-------------------------------------------------
@@ -715,9 +696,9 @@ bool emu_file::part_of_mediapath(const std::string &path)
// attempt_zipped - attempt to open a ZIPped file
//-------------------------------------------------
-osd_file::error emu_file::attempt_zipped()
+std::error_condition emu_file::attempt_zipped()
{
- typedef util::archive_file::error (*open_func)(const std::string &filename, util::archive_file::ptr &result);
+ typedef std::error_condition (*open_func)(std::string_view filename, util::archive_file::ptr &result);
char const *const suffixes[] = { ".zip", ".7z" };
open_func const open_funcs[std::size(suffixes)] = { &util::archive_file::open_zip, &util::archive_file::open_7z };
@@ -750,13 +731,13 @@ osd_file::error emu_file::attempt_zipped()
// attempt to open the archive file
util::archive_file::ptr zip;
- util::archive_file::error ziperr = open_funcs[i](m_fullpath, zip);
+ std::error_condition ziperr = open_funcs[i](m_fullpath, zip);
// chop the archive suffix back off the filename before continuing
m_fullpath = m_fullpath.substr(0, dirsep);
// if we failed to open this file, continue scanning
- if (ziperr != util::archive_file::error::NONE)
+ if (ziperr)
continue;
int header = -1;
@@ -788,14 +769,14 @@ osd_file::error emu_file::attempt_zipped()
m_hashes.reset();
m_hashes.add_crc(m_zipfile->current_crc());
m_fullpath = savepath;
- return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? osd_file::error::NONE : load_zipped_file();
+ return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? std::error_condition() : load_zipped_file();
}
// close up the archive file and try the next level
zip.reset();
}
}
- return osd_file::error::NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
}
@@ -803,7 +784,7 @@ osd_file::error emu_file::attempt_zipped()
// load_zipped_file - load a ZIPped file
//-------------------------------------------------
-osd_file::error emu_file::load_zipped_file()
+std::error_condition emu_file::load_zipped_file()
{
assert(m_file == nullptr);
assert(m_zipdata.empty());
@@ -814,21 +795,21 @@ osd_file::error emu_file::load_zipped_file()
// read the data into our buffer and return
auto const ziperr = m_zipfile->decompress(&m_zipdata[0], m_zipdata.size());
- if (ziperr != util::archive_file::error::NONE)
+ if (ziperr)
{
m_zipdata.clear();
- return osd_file::error::FAILURE;
+ return ziperr;
}
// convert to RAM file
- osd_file::error filerr = util::core_file::open_ram(&m_zipdata[0], m_zipdata.size(), m_openflags, m_file);
- if (filerr != osd_file::error::NONE)
+ std::error_condition const filerr = util::core_file::open_ram(&m_zipdata[0], m_zipdata.size(), m_openflags, m_file);
+ if (filerr)
{
m_zipdata.clear();
- return osd_file::error::FAILURE;
+ return filerr;
}
// close out the ZIP file
m_zipfile.reset();
- return osd_file::error::NONE;
+ return std::error_condition();
}
diff --git a/src/emu/fileio.h b/src/emu/fileio.h
index d05905efa83..f05706dffed 100644
--- a/src/emu/fileio.h
+++ b/src/emu/fileio.h
@@ -18,6 +18,7 @@
#include <iterator>
#include <string>
+#include <system_error>
#include <type_traits>
#include <utility>
#include <vector>
@@ -156,19 +157,16 @@ public:
void set_restrict_to_mediapath(int rtmp) { m_restrict_to_mediapath = rtmp; }
// open/close
- osd_file::error open(std::string &&name);
- osd_file::error open(std::string &&name, u32 crc);
- osd_file::error open(std::string_view name) { return open(std::string(name)); }
- osd_file::error open(std::string_view name, u32 crc) { return open(std::string(name), crc); }
- osd_file::error open(const char *name) { return open(std::string(name)); }
- osd_file::error open(const char *name, u32 crc) { return open(std::string(name), crc); }
- osd_file::error open_next();
- osd_file::error open_ram(const void *data, u32 length);
+ std::error_condition open(std::string &&name);
+ std::error_condition open(std::string &&name, u32 crc);
+ std::error_condition open(std::string_view name) { return open(std::string(name)); }
+ std::error_condition open(std::string_view name, u32 crc) { return open(std::string(name), crc); }
+ std::error_condition open(const char *name) { return open(std::string(name)); }
+ std::error_condition open(const char *name, u32 crc) { return open(std::string(name), crc); }
+ std::error_condition open_next();
+ std::error_condition open_ram(const void *data, u32 length);
void close();
- // control
- osd_file::error compress(int compress);
-
// position
int seek(s64 offset, int whence);
u64 tell();
@@ -213,11 +211,11 @@ private:
}
bool part_of_mediapath(const std::string &path);
- bool compressed_file_ready();
+ std::error_condition compressed_file_ready();
// internal helpers
- osd_file::error attempt_zipped();
- osd_file::error load_zipped_file();
+ std::error_condition attempt_zipped();
+ std::error_condition load_zipped_file();
// internal state
std::string m_filename; // original filename provided
diff --git a/src/emu/hashfile.cpp b/src/emu/hashfile.cpp
index 50a32a60b29..a6107e5e630 100644
--- a/src/emu/hashfile.cpp
+++ b/src/emu/hashfile.cpp
@@ -27,10 +27,8 @@ static bool read_hash_config(const char *hash_path, const util::hash_collection
{
/* open a file */
emu_file file(hash_path, OPEN_FLAG_READ);
- if (file.open(std::string(sysname) + ".hsi") != osd_file::error::NONE)
- {
+ if (file.open(std::string(sysname) + ".hsi"))
return false;
- }
pugi::xml_document doc;
diff --git a/src/emu/http.cpp b/src/emu/http.cpp
index b384049a37f..42d8120d32e 100644
--- a/src/emu/http.cpp
+++ b/src/emu/http.cpp
@@ -422,8 +422,8 @@ bool http_manager::read_file(std::ostream &os, const std::string &path) {
std::ostringstream full_path;
full_path << m_root << path;
util::core_file::ptr f;
- osd_file::error e = util::core_file::open(full_path.str(), OPEN_FLAG_READ, f);
- if (e == osd_file::error::NONE)
+ std::error_condition const e = util::core_file::open(full_path.str(), OPEN_FLAG_READ, f);
+ if (!e)
{
int c;
while ((c = f->getc()) >= 0)
@@ -431,7 +431,7 @@ bool http_manager::read_file(std::ostream &os, const std::string &path) {
os.put(c);
}
}
- return e == osd_file::error::NONE;
+ return !e;
}
void http_manager::serve_document(http_request_ptr request, http_response_ptr response, const std::string &filename) {
diff --git a/src/emu/image.cpp b/src/emu/image.cpp
index c80d9bafde7..02cc25ce80b 100644
--- a/src/emu/image.cpp
+++ b/src/emu/image.cpp
@@ -173,8 +173,8 @@ int image_manager::write_config(emu_options &options, const char *filename, cons
}
emu_file file(options.ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
- osd_file::error filerr = file.open(filename);
- if (filerr == osd_file::error::NONE)
+ std::error_condition const filerr = file.open(filename);
+ if (!filerr)
{
std::string inistring = options.output_ini();
file.puts(inistring);
diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp
index 2e9d115e46e..cae37f28c17 100644
--- a/src/emu/ioport.cpp
+++ b/src/emu/ioport.cpp
@@ -99,9 +99,11 @@
#include "inputdev.h"
#include "natkeyboard.h"
-#include "corestr.h"
+#include "util/corestr.h"
+#include "util/ioprocsfilter.h"
+#include "util/unicode.h"
+
#include "osdepend.h"
-#include "unicode.h"
#include <cctype>
#include <ctime>
@@ -2652,23 +2654,26 @@ template<typename Type>
Type ioport_manager::playback_read(Type &result)
{
// protect against nullptr handles if previous reads fail
- if (!m_playback_file.is_open())
- result = 0;
+ if (!m_playback_stream)
+ return result = Type(0);
// read the value; if we fail, end playback
- else if (m_playback_file.read(&result, sizeof(result)) != sizeof(result))
+ size_t read;
+ m_playback_stream->read(&result, sizeof(result), read);
+ if (sizeof(result) != read)
{
playback_end("End of file");
- result = 0;
+ return result = Type(0);
}
- // return the appropriate value
- else if (sizeof(result) == 8)
+ // normalize byte order
+ if (sizeof(result) == 8)
result = little_endianize_int64(result);
else if (sizeof(result) == 4)
result = little_endianize_int32(result);
else if (sizeof(result) == 2)
result = little_endianize_int16(result);
+
return result;
}
@@ -2693,15 +2698,15 @@ time_t ioport_manager::playback_init()
return 0;
// open the playback file
- osd_file::error filerr = m_playback_file.open(filename);
+ std::error_condition const filerr = m_playback_file.open(filename);
// return an explicit error if file isn't found in given path
- if(filerr == osd_file::error::NOT_FOUND)
+ if (filerr == std::errc::no_such_file_or_directory)
fatalerror("Input file %s not found\n",filename);
// TODO: bail out any other error laconically for now
- if(filerr != osd_file::error::NONE)
- fatalerror("Failed to open file %s for playback (code error=%d)\n",filename,int(filerr));
+ if (filerr)
+ fatalerror("Failed to open file %s for playback (%s:%d %s)\n", filename, filerr.category().name(), filerr.value(), filerr.message());
// read the header and verify that it is a modern version; if not, print an error
inp_header header;
@@ -2725,7 +2730,7 @@ time_t ioport_manager::playback_init()
osd_printf_info("Input file is for machine '%s', not for current machine '%s'\n", sysname, machine().system().name);
// enable compression
- m_playback_file.compress(FCOMPRESS_MEDIUM);
+ m_playback_stream = util::zlib_read(util::core_file_read(m_playback_file), 16386);
return basetime;
}
@@ -2737,9 +2742,10 @@ time_t ioport_manager::playback_init()
void ioport_manager::playback_end(const char *message)
{
// only applies if we have a live file
- if (m_playback_file.is_open())
+ if (m_playback_stream)
{
// close the file
+ m_playback_stream.reset();
m_playback_file.close();
// pop a message
@@ -2753,7 +2759,8 @@ void ioport_manager::playback_end(const char *message)
osd_printf_info("Average recorded speed: %d%%\n", u32((m_playback_accumulated_speed * 200 + 1) >> 21));
// close the program at the end of inp file playback
- if (machine().options().exit_after_playback()) {
+ if (machine().options().exit_after_playback())
+ {
osd_printf_info("Exiting MAME now...\n");
machine().schedule_exit();
}
@@ -2769,7 +2776,7 @@ void ioport_manager::playback_end(const char *message)
void ioport_manager::playback_frame(const attotime &curtime)
{
// if playing back, fetch the information and verify
- if (m_playback_file.is_open())
+ if (m_playback_stream)
{
// first the absolute time
seconds_t seconds_temp;
@@ -2795,7 +2802,7 @@ void ioport_manager::playback_frame(const attotime &curtime)
void ioport_manager::playback_port(ioport_port &port)
{
// if playing back, fetch information about this port
- if (m_playback_file.is_open())
+ if (m_playback_stream)
{
// read the default value and the digital state
playback_read(port.live().defvalue);
@@ -2824,11 +2831,20 @@ template<typename Type>
void ioport_manager::record_write(Type value)
{
// protect against nullptr handles if previous reads fail
- if (!m_record_file.is_open())
+ if (!m_record_stream)
return;
- // read the value; if we fail, end playback
- if (m_record_file.write(&value, sizeof(value)) != sizeof(value))
+ // normalize byte order
+ if (sizeof(value) == 8)
+ value = little_endianize_int64(value);
+ else if (sizeof(value) == 4)
+ value = little_endianize_int32(value);
+ else if (sizeof(value) == 2)
+ value = little_endianize_int16(value);
+
+ // write the value; if we fail, end recording
+ size_t written;
+ if (m_record_stream->write(&value, sizeof(value), written) || (sizeof(value) != written))
record_end("Out of space");
}
@@ -2875,9 +2891,9 @@ void ioport_manager::record_init()
return;
// open the record file
- osd_file::error filerr = m_record_file.open(filename);
- if (filerr != osd_file::error::NONE)
- throw emu_fatalerror("ioport_manager::record_init: Failed to open file for recording");
+ std::error_condition const filerr = m_record_file.open(filename);
+ if (filerr)
+ throw emu_fatalerror("ioport_manager::record_init: Failed to open file for recording (%s:%d %s)", filerr.category().name(), filerr.value(), filerr.message());
// get the base time
system_time systime;
@@ -2895,7 +2911,7 @@ void ioport_manager::record_init()
header.write(m_record_file);
// enable compression
- m_record_file.compress(FCOMPRESS_MEDIUM);
+ m_record_stream = util::zlib_write(util::core_file_read_write(m_record_file), 6, 16384);
}
@@ -2922,9 +2938,9 @@ void ioport_manager::timecode_init()
filename.append(record_filename).append(".timecode");
osd_printf_info("Record input timecode file: %s\n", record_filename);
- osd_file::error filerr = m_timecode_file.open(filename);
- if (filerr != osd_file::error::NONE)
- throw emu_fatalerror("ioport_manager::timecode_init: Failed to open file for input timecode recording");
+ std::error_condition const filerr = m_timecode_file.open(filename);
+ if (filerr)
+ throw emu_fatalerror("ioport_manager::timecode_init: Failed to open file for input timecode recording (%s:%d %s)", filerr.category().name(), filerr.value(), filerr.message());
m_timecode_file.puts("# ==========================================\n");
m_timecode_file.puts("# TIMECODE FILE FOR VIDEO PREVIEW GENERATION\n");
@@ -2948,9 +2964,10 @@ void ioport_manager::timecode_init()
void ioport_manager::record_end(const char *message)
{
// only applies if we have a live file
- if (m_record_file.is_open())
+ if (m_record_stream)
{
// close the file
+ m_record_stream.reset(); // TODO: check for errors flushing the last compressed block before doing this
m_record_file.close();
// pop a message
@@ -2981,7 +2998,7 @@ void ioport_manager::timecode_end(const char *message)
void ioport_manager::record_frame(const attotime &curtime)
{
// if recording, record information about the current frame
- if (m_record_file.is_open())
+ if (m_record_stream)
{
// first the absolute time
record_write(curtime.seconds());
@@ -3091,7 +3108,7 @@ void ioport_manager::record_frame(const attotime &curtime)
void ioport_manager::record_port(ioport_port &port)
{
// if recording, store information about this port
- if (m_record_file.is_open())
+ if (m_record_stream)
{
// store the default value and digital state
record_write(port.live().defvalue);
diff --git a/src/emu/ioport.h b/src/emu/ioport.h
index 11dcf006be9..fdf859b9afd 100644
--- a/src/emu/ioport.h
+++ b/src/emu/ioport.h
@@ -17,11 +17,14 @@
#ifndef MAME_EMU_IOPORT_H
#define MAME_EMU_IOPORT_H
+#include "ioprocs.h"
+
#include <array>
#include <cstdint>
#include <cstring>
#include <ctime>
#include <list>
+#include <memory>
#include <vector>
@@ -1447,8 +1450,10 @@ private:
attoseconds_t m_last_delta_nsec; // nanoseconds that passed since the previous callback
// playback/record information
- emu_file m_record_file; // recording file (nullptr if not recording)
- emu_file m_playback_file; // playback file (nullptr if not recording)
+ emu_file m_record_file; // recording file (closed if not recording)
+ emu_file m_playback_file; // playback file (closed if not recording)
+ util::write_stream::ptr m_record_stream; // recording stream (nullptr if not recording)
+ util::read_stream::ptr m_playback_stream; // playback stream (nullptr if not recording)
u64 m_playback_accumulated_speed; // accumulated speed during playback
u32 m_playback_accumulated_frames; // accumulated frames during playback
emu_file m_timecode_file; // timecode/frames playback file (nullptr if not recording)
diff --git a/src/emu/machine.cpp b/src/emu/machine.cpp
index 5568bb48e85..3721ba9bec8 100644
--- a/src/emu/machine.cpp
+++ b/src/emu/machine.cpp
@@ -313,8 +313,8 @@ int running_machine::run(bool quiet)
if (options().log() && !quiet)
{
m_logfile = std::make_unique<emu_file>(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = m_logfile->open("error.log");
- if (filerr != osd_file::error::NONE)
+ std::error_condition const filerr = m_logfile->open("error.log");
+ if (filerr)
throw emu_fatalerror("running_machine::run: unable to open error.log file");
using namespace std::placeholders;
@@ -324,8 +324,8 @@ int running_machine::run(bool quiet)
if (options().debug() && options().debuglog())
{
m_debuglogfile = std::make_unique<emu_file>(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = m_debuglogfile->open("debug.log");
- if (filerr != osd_file::error::NONE)
+ std::error_condition const filerr = m_debuglogfile->open("debug.log");
+ if (filerr)
throw emu_fatalerror("running_machine::run: unable to open debug.log file");
}
@@ -931,7 +931,7 @@ void running_machine::handle_saveload()
// open the file
emu_file file(m_saveload_searchpath ? m_saveload_searchpath : "", openflags);
auto const filerr = file.open(m_saveload_pending_file);
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
{
const char *const opnamed = (m_saveload_schedule == saveload_schedule::LOAD) ? "loaded" : "saved";
@@ -973,7 +973,7 @@ void running_machine::handle_saveload()
if (saverr != STATERR_NONE && m_saveload_schedule == saveload_schedule::SAVE)
file.remove_on_close();
}
- else if (openflags == OPEN_FLAG_READ && filerr == osd_file::error::NOT_FOUND)
+ else if ((openflags == OPEN_FLAG_READ) && (std::errc::no_such_file_or_directory == filerr))
{
// attempt to load a non-existent savestate, report empty slot
popmessage("Error: No savestate file to load.", opname);
@@ -1174,7 +1174,7 @@ void running_machine::nvram_load()
for (device_nvram_interface &nvram : nvram_interface_enumerator(root_device()))
{
emu_file file(options().nvram_directory(), OPEN_FLAG_READ);
- if (file.open(nvram_filename(nvram.device())) == osd_file::error::NONE)
+ if (!file.open(nvram_filename(nvram.device())))
{
nvram.nvram_load(file);
file.close();
@@ -1196,7 +1196,7 @@ void running_machine::nvram_save()
if (nvram.nvram_can_save())
{
emu_file file(options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(nvram_filename(nvram.device())) == osd_file::error::NONE)
+ if (!file.open(nvram_filename(nvram.device())))
{
nvram.nvram_save(file);
file.close();
diff --git a/src/emu/render.cpp b/src/emu/render.cpp
index 1c176929aad..2c4541cb6b9 100644
--- a/src/emu/render.cpp
+++ b/src/emu/render.cpp
@@ -50,7 +50,8 @@
#include "ui/uimain.h"
-#include "xmlfile.h"
+#include "util/path.h"
+#include "util/xmlfile.h"
#include <zlib.h>
@@ -2186,7 +2187,7 @@ bool render_target::load_layout_file(const char *dirname, const char *filename)
emu_file layoutfile(m_manager.machine().options().art_path(), OPEN_FLAG_READ);
layoutfile.set_restrict_to_mediapath(1);
bool result(false);
- for (osd_file::error filerr = layoutfile.open(fname); osd_file::error::NONE == filerr; filerr = layoutfile.open_next())
+ for (std::error_condition filerr = layoutfile.open(fname); !filerr; filerr = layoutfile.open_next())
{
// read the file and parse as XML
util::xml::file::ptr const rootnode(util::xml::file::read(layoutfile, &parseopt));
diff --git a/src/emu/rendfont.cpp b/src/emu/rendfont.cpp
index c20a7979bbc..ae295e39e2d 100644
--- a/src/emu/rendfont.cpp
+++ b/src/emu/rendfont.cpp
@@ -594,8 +594,8 @@ render_font::render_font(render_manager &manager, const char *filename)
// load the compiled in data instead
emu_file ramfile(OPEN_FLAG_READ);
- osd_file::error const filerr(ramfile.open_ram(font_uismall, sizeof(font_uismall)));
- if (osd_file::error::NONE == filerr)
+ std::error_condition const filerr(ramfile.open_ram(font_uismall, sizeof(font_uismall)));
+ if (!filerr)
load_cached(ramfile, 0, 0);
render_font_command_glyph();
}
@@ -908,14 +908,14 @@ float render_font::utf8string_width(float height, float aspect, std::string_view
bool render_font::load_cached_bdf(const char *filename)
{
- osd_file::error filerr;
+ std::error_condition filerr;
u32 chunk;
u64 bytes;
// first try to open the BDF itself
emu_file file(m_manager.machine().options().font_path(), OPEN_FLAG_READ);
filerr = file.open(filename);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
return false;
// determine the file size and allocate memory
@@ -952,7 +952,7 @@ bool render_font::load_cached_bdf(const char *filename)
{
emu_file cachefile(m_manager.machine().options().font_path(), OPEN_FLAG_READ);
filerr = cachefile.open(cachedname);
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
{
// if we have a cached version, load it
bool const result = load_cached(cachefile, m_rawsize, hash);
@@ -1456,8 +1456,8 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
// attempt to open the file
emu_file file(m_manager.machine().options().font_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
- osd_file::error const filerr = file.open(filename);
- if (osd_file::error::NONE != filerr)
+ std::error_condition const filerr = file.open(filename);
+ if (filerr)
return false;
// count glyphs
@@ -1596,7 +1596,7 @@ void render_font::render_font_command_glyph()
{
// FIXME: this is copy/pasta from the BDC loading, and it shouldn't be injected into every font
emu_file file(OPEN_FLAG_READ);
- if (file.open_ram(font_uicmd14, sizeof(font_uicmd14)) == osd_file::error::NONE)
+ if (!file.open_ram(font_uicmd14, sizeof(font_uicmd14)))
{
// get the file size, read the header, and check that it looks good
u64 const filesize(file.size());
diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp
index 13b2d6e16c1..c3f7a70a2e8 100644
--- a/src/emu/rendlay.cpp
+++ b/src/emu/rendlay.cpp
@@ -17,10 +17,11 @@
#include "rendutil.h"
#include "video/rgbutil.h"
-#include "nanosvg.h"
-#include "unicode.h"
-#include "vecstream.h"
-#include "xmlfile.h"
+#include "util/nanosvg.h"
+#include "util/path.h"
+#include "util/unicode.h"
+#include "util/vecstream.h"
+#include "util/xmlfile.h"
#include <cctype>
#include <algorithm>
@@ -1713,12 +1714,10 @@ private:
std::string filename;
if (!m_searchpath.empty())
filename = m_dirname;
- if (!filename.empty() && !util::is_directory_separator(filename[filename.size() - 1]))
- filename.append(PATH_SEPARATOR);
- filename.append(m_imagefile);
+ util::path_append(filename, m_imagefile);
LOGMASKED(LOG_IMAGE_LOAD, "Image component attempt to load image file '%s'\n", filename);
- osd_file::error const imgerr = file.open(filename);
- if (osd_file::error::NONE == imgerr)
+ std::error_condition const imgerr = file.open(filename);
+ if (!imgerr)
{
if (!load_bitmap(file))
{
@@ -1729,7 +1728,8 @@ private:
}
else
{
- LOGMASKED(LOG_IMAGE_LOAD, "Image component unable to open image file '%s'\n", filename);
+ LOGMASKED(LOG_IMAGE_LOAD, "Image component unable to open image file '%s' (%s:%d %s)\n",
+ filename, imgerr.category().name(), imgerr.value(), imgerr.message());
}
}
else if (!m_data.empty())
@@ -1745,12 +1745,10 @@ private:
std::string filename;
if (!m_searchpath.empty())
filename = m_dirname;
- if (!filename.empty() && !util::is_directory_separator(filename[filename.size() - 1]))
- filename.append(PATH_SEPARATOR);
- filename.append(m_alphafile);
+ util::path_append(filename, m_alphafile);
LOGMASKED(LOG_IMAGE_LOAD, "Image component attempt to load alpha channel from file '%s'\n", filename);
- osd_file::error const alferr = file.open(filename);
- if (osd_file::error::NONE == alferr)
+ std::error_condition const alferr = file.open(filename);
+ if (!alferr)
{
// TODO: no way to detect corner case where we had alpha from the image but the alpha PNG makes it entirely opaque
if (render_load_png(m_bitmap, file, true))
@@ -1759,7 +1757,8 @@ private:
}
else
{
- LOGMASKED(LOG_IMAGE_LOAD, "Image component unable to open alpha channel file '%s'\n", filename);
+ LOGMASKED(LOG_IMAGE_LOAD, "Image component unable to open alpha channel file '%s' (%s:%d %s)\n",
+ filename, alferr.category().name(), alferr.value(), alferr.message());
}
}
else if (m_svg)
@@ -1841,8 +1840,8 @@ private:
// make a file wrapper for the data and see if it looks like a bitmap
util::core_file::ptr file;
- osd_file::error const filerr(util::core_file::open_ram(m_data.c_str(), m_data.size(), OPEN_FLAG_READ, file));
- bool const bitmapdata((osd_file::error::NONE == filerr) && file && load_bitmap(*file));
+ std::error_condition const filerr(util::core_file::open_ram(m_data.c_str(), m_data.size(), OPEN_FLAG_READ, file));
+ bool const bitmapdata(!filerr && file && load_bitmap(*file));
file.reset();
// if it didn't look like a bitmap, see if it looks like it might be XML and hence SVG
@@ -3398,12 +3397,10 @@ private:
std::string filename;
if (!m_searchpath.empty())
filename = m_dirname;
- if (!filename.empty() && !util::is_directory_separator(filename[filename.size() - 1]))
- filename.append(PATH_SEPARATOR);
- filename.append(m_imagefile[number]);
+ util::path_append(filename, m_imagefile[number]);
// load the basic bitmap
- if (file.open(filename) == osd_file::error::NONE)
+ if (!file.open(filename))
render_load_png(m_bitmap[number], file);
// if we can't load the bitmap just use text rendering
diff --git a/src/emu/romload.cpp b/src/emu/romload.cpp
index 36d7896e467..c4c3101bc89 100644
--- a/src/emu/romload.cpp
+++ b/src/emu/romload.cpp
@@ -101,15 +101,15 @@ std::vector<std::string> make_software_searchpath(software_list_device &swlist,
}
-chd_error do_open_disk(const emu_options &options, std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, const rom_entry *romp, chd_file &chd, std::function<const rom_entry * ()> next_parent)
+std::error_condition do_open_disk(const emu_options &options, std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, const rom_entry *romp, chd_file &chd, std::function<const rom_entry * ()> next_parent)
{
// hashes are fixed, but we might need to try multiple filenames
std::set<std::string> tried;
const util::hash_collection hashes(romp->hashdata());
std::string filename, fullpath;
const rom_entry *parent(nullptr);
- chd_error result(CHDERR_FILE_NOT_FOUND);
- while (romp && (CHDERR_NONE != result))
+ std::error_condition result(std::errc::no_such_file_or_directory);
+ while (romp && result)
{
filename = romp->name() + ".chd";
if (tried.insert(filename).second)
@@ -120,8 +120,8 @@ chd_error do_open_disk(const emu_options &options, std::initializer_list<std::re
{
imgfile.reset(new emu_file(options.media_path(), paths, OPEN_FLAG_READ));
imgfile->set_restrict_to_mediapath(1);
- const osd_file::error filerr(imgfile->open(filename, OPEN_FLAG_READ));
- if (osd_file::error::NONE == filerr)
+ const std::error_condition filerr(imgfile->open(filename, OPEN_FLAG_READ));
+ if (!filerr)
break;
else
imgfile.reset();
@@ -132,12 +132,12 @@ chd_error do_open_disk(const emu_options &options, std::initializer_list<std::re
{
fullpath = imgfile->fullpath();
imgfile.reset();
- result = chd.open(fullpath.c_str());
+ result = chd.open(fullpath);
}
}
// walk the parents looking for a CHD with the same hashes but a different name
- if (CHDERR_NONE != result)
+ if (result)
{
while (romp)
{
@@ -345,11 +345,11 @@ chd_file *rom_load_manager::get_disk_handle(std::string_view region)
file associated with the given region
-------------------------------------------------*/
-int rom_load_manager::set_disk_handle(std::string_view region, const char *fullpath)
+std::error_condition rom_load_manager::set_disk_handle(std::string_view region, const char *fullpath)
{
auto chd = std::make_unique<open_chd>(region);
auto err = chd->orig_chd().open(fullpath);
- if (err == CHDERR_NONE)
+ if (!err)
m_chd_list.push_back(std::move(chd));
return err;
}
@@ -439,7 +439,7 @@ void rom_load_manager::fill_random(u8 *base, u32 length)
for missing files
-------------------------------------------------*/
-void rom_load_manager::handle_missing_file(const rom_entry *romp, const std::vector<std::string> &tried_file_names, chd_error chderr)
+void rom_load_manager::handle_missing_file(const rom_entry *romp, const std::vector<std::string> &tried_file_names, std::error_condition chderr)
{
std::string tried;
if (!tried_file_names.empty())
@@ -453,12 +453,12 @@ void rom_load_manager::handle_missing_file(const rom_entry *romp, const std::vec
tried += ')';
}
- const bool is_chd(chderr != CHDERR_NONE);
+ const bool is_chd(chderr);
const std::string name(is_chd ? romp->name() + ".chd" : romp->name());
- const bool is_chd_error(is_chd && chderr != CHDERR_FILE_NOT_FOUND);
+ const bool is_chd_error(is_chd && chderr != std::errc::no_such_file_or_directory);
if (is_chd_error)
- m_errorstring.append(string_format("%s CHD ERROR: %s\n", name, chd_file::error_string(chderr)));
+ m_errorstring.append(string_format("%s CHD ERROR: %s\n", name, chderr.message()));
if (ROM_ISOPTIONAL(romp))
{
@@ -638,7 +638,7 @@ void rom_load_manager::region_post_process(memory_region *region, bool invert)
std::unique_ptr<emu_file> rom_load_manager::open_rom_file(std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, const rom_entry *romp, std::vector<std::string> &tried_file_names, bool from_list)
{
- osd_file::error filerr = osd_file::error::NOT_FOUND;
+ std::error_condition filerr = std::errc::no_such_file_or_directory;
u32 const romsize = rom_file_size(romp);
tried_file_names.clear();
@@ -664,14 +664,14 @@ std::unique_ptr<emu_file> rom_load_manager::open_rom_file(std::initializer_list<
m_romsloadedsize += romsize;
// return the result
- if (osd_file::error::NONE != filerr)
+ if (filerr)
return nullptr;
else
return result;
}
-std::unique_ptr<emu_file> rom_load_manager::open_rom_file(const std::vector<std::string> &paths, std::vector<std::string> &tried, bool has_crc, u32 crc, std::string_view name, osd_file::error &filerr)
+std::unique_ptr<emu_file> rom_load_manager::open_rom_file(const std::vector<std::string> &paths, std::vector<std::string> &tried, bool has_crc, u32 crc, std::string_view name, std::error_condition &filerr)
{
// record the set names we search
tried.insert(tried.end(), paths.begin(), paths.end());
@@ -685,7 +685,7 @@ std::unique_ptr<emu_file> rom_load_manager::open_rom_file(const std::vector<std:
filerr = result->open(name);
// don't return anything if unsuccessful
- if (osd_file::error::NONE != filerr)
+ if (filerr)
return nullptr;
else
return result;
@@ -939,7 +939,7 @@ void rom_load_manager::process_rom_entries(std::initializer_list<std::reference_
{
file = open_rom_file(searchpath, romp, tried_file_names, from_list);
if (!file)
- handle_missing_file(romp, tried_file_names, CHDERR_NONE);
+ handle_missing_file(romp, tried_file_names, std::error_condition());
}
// loop until we run out of reloads
@@ -1000,44 +1000,44 @@ void rom_load_manager::process_rom_entries(std::initializer_list<std::reference_
open_disk_diff - open a DISK diff file
-------------------------------------------------*/
-chd_error rom_load_manager::open_disk_diff(emu_options &options, const rom_entry *romp, chd_file &source, chd_file &diff_chd)
+std::error_condition rom_load_manager::open_disk_diff(emu_options &options, const rom_entry *romp, chd_file &source, chd_file &diff_chd)
{
// TODO: use system name and/or software list name in the path - the current setup doesn't scale
std::string fname = romp->name() + ".dif";
- /* try to open the diff */
+ // try to open the diff
LOG("Opening differencing image file: %s\n", fname.c_str());
emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE);
- osd_file::error filerr = diff_file.open(fname);
- if (filerr == osd_file::error::NONE)
+ std::error_condition filerr = diff_file.open(fname);
+ if (!filerr)
{
std::string fullpath(diff_file.fullpath());
diff_file.close();
LOG("Opening differencing image file: %s\n", fullpath.c_str());
- return diff_chd.open(fullpath.c_str(), true, &source);
+ return diff_chd.open(fullpath, true, &source);
}
- /* didn't work; try creating it instead */
+ // didn't work; try creating it instead
LOG("Creating differencing image: %s\n", fname.c_str());
diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
filerr = diff_file.open(fname);
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
{
std::string fullpath(diff_file.fullpath());
diff_file.close();
- /* create the CHD */
+ // create the CHD
LOG("Creating differencing image file: %s\n", fullpath.c_str());
chd_codec_type compression[4] = { CHD_CODEC_NONE };
- chd_error err = diff_chd.create(fullpath.c_str(), source.logical_bytes(), source.hunk_bytes(), compression, source);
- if (err != CHDERR_NONE)
+ std::error_condition err = diff_chd.create(fullpath, source.logical_bytes(), source.hunk_bytes(), compression, source);
+ if (err)
return err;
return diff_chd.clone_all_metadata(source);
}
- return CHDERR_FILE_NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
}
@@ -1059,7 +1059,7 @@ void rom_load_manager::process_disk_entries(std::initializer_list<std::reference
if (ROMENTRY_ISFILE(romp))
{
auto chd = std::make_unique<open_chd>(regiontag);
- chd_error err;
+ std::error_condition err;
/* make the filename of the source */
const std::string filename = romp->name() + ".chd";
@@ -1068,7 +1068,7 @@ void rom_load_manager::process_disk_entries(std::initializer_list<std::reference
// FIXME: we've lost the ability to search parents here
LOG("Opening disk image: %s\n", filename.c_str());
err = do_open_disk(machine().options(), searchpath, romp, chd->orig_chd(), next_parent);
- if (err != CHDERR_NONE)
+ if (err)
{
handle_missing_file(romp, std::vector<std::string>(), err);
chd = nullptr;
@@ -1098,9 +1098,9 @@ void rom_load_manager::process_disk_entries(std::initializer_list<std::reference
{
/* try to open or create the diff */
err = open_disk_diff(machine().options(), romp, chd->orig_chd(), chd->diff_chd());
- if (err != CHDERR_NONE)
+ if (err)
{
- m_errorstring.append(string_format("%s DIFF CHD ERROR: %s\n", filename, chd_file::error_string(err)));
+ m_errorstring.append(string_format("%s DIFF CHD ERROR: %s\n", filename, err.message()));
m_errors++;
chd = nullptr;
continue;
@@ -1132,7 +1132,7 @@ std::vector<std::string> rom_load_manager::get_software_searchpath(software_list
device
-------------------------------------------------*/
-chd_error rom_load_manager::open_disk_image(const emu_options &options, const device_t &device, const rom_entry *romp, chd_file &image_chd)
+std::error_condition rom_load_manager::open_disk_image(const emu_options &options, const device_t &device, const rom_entry *romp, chd_file &image_chd)
{
const std::vector<std::string> searchpath(device.searchpath());
@@ -1151,7 +1151,7 @@ chd_error rom_load_manager::open_disk_image(const emu_options &options, const de
software item
-------------------------------------------------*/
-chd_error rom_load_manager::open_disk_image(const emu_options &options, software_list_device &swlist, const software_info &swinfo, const rom_entry *romp, chd_file &image_chd)
+std::error_condition rom_load_manager::open_disk_image(const emu_options &options, software_list_device &swlist, const software_info &swinfo, const rom_entry *romp, chd_file &image_chd)
{
std::vector<software_info const *> parents;
std::vector<std::string> searchpath = make_software_searchpath(swlist, swinfo, parents);
diff --git a/src/emu/romload.h b/src/emu/romload.h
index 29caaf8e124..76fdb111cc6 100644
--- a/src/emu/romload.h
+++ b/src/emu/romload.h
@@ -18,6 +18,7 @@
#include <functional>
#include <initializer_list>
#include <string>
+#include <system_error>
#include <type_traits>
#include <vector>
@@ -419,7 +420,7 @@ public:
chd_file *get_disk_handle(std::string_view region);
/* set a pointer to the CHD file associated with the given region */
- int set_disk_handle(std::string_view region, const char *fullpath);
+ std::error_condition set_disk_handle(std::string_view region, const char *fullpath);
void load_software_part_region(device_t &device, software_list_device &swlist, std::string_view swname, const rom_entry *start_region);
@@ -427,27 +428,27 @@ public:
static std::vector<std::string> get_software_searchpath(software_list_device &swlist, const software_info &swinfo);
/* open a disk image, searching up the parent and loading by checksum */
- static chd_error open_disk_image(const emu_options &options, const device_t &device, const rom_entry *romp, chd_file &image_chd);
- static chd_error open_disk_image(const emu_options &options, software_list_device &swlist, const software_info &swinfo, const rom_entry *romp, chd_file &image_chd);
+ static std::error_condition open_disk_image(const emu_options &options, const device_t &device, const rom_entry *romp, chd_file &image_chd);
+ static std::error_condition open_disk_image(const emu_options &options, software_list_device &swlist, const software_info &swinfo, const rom_entry *romp, chd_file &image_chd);
private:
void determine_bios_rom(device_t &device, const char *specbios);
void count_roms();
void fill_random(u8 *base, u32 length);
- void handle_missing_file(const rom_entry *romp, const std::vector<std::string> &tried_file_names, chd_error chderr);
+ void handle_missing_file(const rom_entry *romp, const std::vector<std::string> &tried_file_names, std::error_condition chderr);
void dump_wrong_and_correct_checksums(const util::hash_collection &hashes, const util::hash_collection &acthashes);
void verify_length_and_hash(emu_file *file, std::string_view name, u32 explength, const util::hash_collection &hashes);
void display_loading_rom_message(const char *name, bool from_list);
void display_rom_load_results(bool from_list);
void region_post_process(memory_region *region, bool invert);
std::unique_ptr<emu_file> open_rom_file(std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, const rom_entry *romp, std::vector<std::string> &tried_file_names, bool from_list);
- std::unique_ptr<emu_file> open_rom_file(const std::vector<std::string> &paths, std::vector<std::string> &tried, bool has_crc, u32 crc, std::string_view name, osd_file::error &filerr);
+ std::unique_ptr<emu_file> open_rom_file(const std::vector<std::string> &paths, std::vector<std::string> &tried, bool has_crc, u32 crc, std::string_view name, std::error_condition &filerr);
int rom_fread(emu_file *file, u8 *buffer, int length, const rom_entry *parent_region);
int read_rom_data(emu_file *file, const rom_entry *parent_region, const rom_entry *romp);
void fill_rom_data(const rom_entry *romp);
void copy_rom_data(const rom_entry *romp);
void process_rom_entries(std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, u8 bios, const rom_entry *parent_region, const rom_entry *romp, bool from_list);
- chd_error open_disk_diff(emu_options &options, const rom_entry *romp, chd_file &source, chd_file &diff_chd);
+ std::error_condition open_disk_diff(emu_options &options, const rom_entry *romp, chd_file &source, chd_file &diff_chd);
void process_disk_entries(std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, std::string_view regiontag, const rom_entry *romp, std::function<const rom_entry * ()> next_parent);
void normalize_flags_for_device(std::string_view rgntag, u8 &width, endianness_t &endian);
void process_region_list();
diff --git a/src/emu/save.cpp b/src/emu/save.cpp
index 96fb3429a1c..120fa883655 100644
--- a/src/emu/save.cpp
+++ b/src/emu/save.cpp
@@ -24,7 +24,10 @@
#include "emu.h"
#include "emuopts.h"
-#include "coreutil.h"
+
+#include "util/coreutil.h"
+#include "util/ioprocs.h"
+#include "util/ioprocsfilter.h"
//**************************************************************************
@@ -212,7 +215,6 @@ save_error save_manager::check_file(running_machine &machine, emu_file &file, co
sig = machine.save().signature();
// seek to the beginning and read the header
- file.compress(FCOMPRESS_NONE);
file.seek(0, SEEK_SET);
u8 header[HEADER_SIZE];
if (file.read(header, sizeof(header)) != sizeof(header))
@@ -257,20 +259,28 @@ void save_manager::dispatch_presave()
save_error save_manager::write_file(emu_file &file)
{
- return do_write(
+ util::write_stream::ptr writer;
+ save_error err = do_write(
[] (size_t total_size) { return true; },
- [&file] (const void *data, size_t size) { return file.write(data, size) == size; },
- [&file] ()
+ [&writer] (const void *data, size_t size)
{
- file.compress(FCOMPRESS_NONE);
- file.seek(0, SEEK_SET);
- return true;
+ size_t written;
+ std::error_condition filerr = writer->write(data, size, written);
+ return !filerr && (size == written);
},
- [&file] ()
+ [&file, &writer] ()
{
- file.compress(FCOMPRESS_MEDIUM);
- return true;
+ if (file.seek(0, SEEK_SET))
+ return false;
+ writer = util::core_file_read_write(file);
+ return bool(writer);
+ },
+ [&file, &writer] ()
+ {
+ writer = util::zlib_write(util::core_file_read_write(file), 6, 16384);
+ return bool(writer);
});
+ return (STATERR_NONE != err) ? err : writer->finalize() ? STATERR_WRITE_ERROR : STATERR_NONE;
}
@@ -280,19 +290,26 @@ save_error save_manager::write_file(emu_file &file)
save_error save_manager::read_file(emu_file &file)
{
+ util::read_stream::ptr reader;
return do_read(
[] (size_t total_size) { return true; },
- [&file] (void *data, size_t size) { return file.read(data, size) == size; },
- [&file] ()
+ [&reader] (void *data, size_t size)
{
- file.compress(FCOMPRESS_NONE);
- file.seek(0, SEEK_SET);
- return true;
+ std::size_t read;
+ std::error_condition filerr = reader->read(data, size, read);
+ return !filerr && (read == size);
},
- [&file] ()
+ [&file, &reader] ()
{
- file.compress(FCOMPRESS_MEDIUM);
- return true;
+ if (file.seek(0, SEEK_SET))
+ return false;
+ reader = util::core_file_read(file);
+ return bool(reader);
+ },
+ [&file, &reader] ()
+ {
+ reader = util::zlib_read(util::core_file_read(file), 16384);
+ return bool(reader);
});
}
diff --git a/src/emu/save.h b/src/emu/save.h
index 32ba0526486..cfd674e738e 100644
--- a/src/emu/save.h
+++ b/src/emu/save.h
@@ -55,12 +55,12 @@ typedef named_delegate<void ()> save_prepost_delegate;
// saved; in general, this is intended only to be used for specific enum types
// defined by your device
#define ALLOW_SAVE_TYPE(TYPE) \
- template <> struct save_manager::is_atom<TYPE> { static constexpr bool value = true; };
+ template <> struct save_manager::is_atom<TYPE> : public std::true_type { };
// use this as above, but also to declare that std::vector<TYPE> is safe as well
#define ALLOW_SAVE_TYPE_AND_VECTOR(TYPE) \
ALLOW_SAVE_TYPE(TYPE) \
- template <> struct save_manager::is_vector_safe<TYPE> { static constexpr bool value = true; };
+ template <> struct save_manager::is_vector_safe<TYPE> : public std::true_type { };
// use this for saving members of structures in arrays
#define STRUCT_MEMBER(s, m) s, &save_manager::pointer_unwrap<decltype(s)>::underlying_type::m, #s "." #m
@@ -99,8 +99,8 @@ class save_manager
};
// set of templates to identify valid save types
- template <typename ItemType> struct is_atom { static constexpr bool value = false; };
- template <typename ItemType> struct is_vector_safe { static constexpr bool value = false; };
+ template <typename ItemType> struct is_atom : public std::false_type { };
+ template <typename ItemType> struct is_vector_safe : public std::false_type { };
class state_entry
{
diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp
index 1a1c5dee8ad..0993473de49 100644
--- a/src/emu/screen.cpp
+++ b/src/emu/screen.cpp
@@ -1911,8 +1911,8 @@ void screen_device::finalize_burnin()
// compute the name and create the file
emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = file.open(util::string_format("%s" PATH_SEPARATOR "burnin-%s.png", machine().basename(), tag() + 1));
- if (filerr == osd_file::error::NONE)
+ std::error_condition const filerr = file.open(util::string_format("%s" PATH_SEPARATOR "burnin-%s.png", machine().basename(), tag() + 1));
+ if (!filerr)
{
util::png_info pnginfo;
@@ -1942,7 +1942,7 @@ void screen_device::load_effect_overlay(const char *filename)
// load the file
m_screen_overlay_bitmap.reset();
emu_file file(machine().options().art_path(), OPEN_FLAG_READ);
- if (file.open(fullname) == osd_file::error::NONE)
+ if (!file.open(fullname))
{
render_load_png(m_screen_overlay_bitmap, file);
file.close();
diff --git a/src/emu/softlist_dev.cpp b/src/emu/softlist_dev.cpp
index c48f7820c23..7d25dd17013 100644
--- a/src/emu/softlist_dev.cpp
+++ b/src/emu/softlist_dev.cpp
@@ -288,9 +288,9 @@ void software_list_device::parse()
// attempt to open the file
emu_file file(mconfig().options().hash_path(), OPEN_FLAG_READ);
- const osd_file::error filerr = file.open(m_list_name + ".xml");
+ const std::error_condition filerr = file.open(m_list_name + ".xml");
m_filename = file.filename();
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
{
// parse if no error
std::ostringstream errs;
@@ -298,7 +298,7 @@ void software_list_device::parse()
file.close();
m_errors = errs.str();
}
- else if (filerr == osd_file::error::NOT_FOUND)
+ else if (std::errc::no_such_file_or_directory == filerr)
{
osd_printf_verbose("%s: Software list %s not found\n", tag(), m_filename);
}
diff --git a/src/emu/uiinput.h b/src/emu/uiinput.h
index 29b18d06d30..3fc89d7a4ff 100644
--- a/src/emu/uiinput.h
+++ b/src/emu/uiinput.h
@@ -103,7 +103,7 @@ public:
private:
// constants
- constexpr static unsigned EVENT_QUEUE_SIZE = 128;
+ static constexpr unsigned EVENT_QUEUE_SIZE = 128;
// internal state
running_machine & m_machine; // reference to our machine
diff --git a/src/emu/video.cpp b/src/emu/video.cpp
index b6dada1c0b5..56f877ec8fa 100644
--- a/src/emu/video.cpp
+++ b/src/emu/video.cpp
@@ -359,8 +359,8 @@ void video_manager::save_active_screen_snapshots()
if (machine().render().is_live(screen))
{
emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = open_next(file, "png");
- if (filerr == osd_file::error::NONE)
+ std::error_condition const filerr = open_next(file, "png");
+ if (!filerr)
save_snapshot(&screen, file);
}
}
@@ -368,8 +368,8 @@ void video_manager::save_active_screen_snapshots()
{
// otherwise, just write a single snapshot
emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = open_next(file, "png");
- if (filerr == osd_file::error::NONE)
+ std::error_condition const filerr = open_next(file, "png");
+ if (!filerr)
save_snapshot(nullptr, file);
}
}
@@ -431,12 +431,12 @@ void video_manager::begin_recording_screen(const std::string &filename, uint32_t
OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
// and open the actual file
- osd_file::error filerr = filename.empty()
+ std::error_condition filerr = filename.empty()
? open_next(*movie_file, extension)
: movie_file->open(filename);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
- osd_printf_error("Error creating movie, osd_file::error=%d\n", int(filerr));
+ osd_printf_error("Error creating movie, %s:%d %s\n", filerr.category().name(), filerr.value(), filerr.message());
return;
}
@@ -1007,8 +1007,8 @@ void video_manager::recompute_speed(const attotime &emutime)
{
// create a final screenshot
emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = file.open(machine().basename() + PATH_SEPARATOR "final.png");
- if (filerr == osd_file::error::NONE)
+ std::error_condition filerr = file.open(machine().basename() + PATH_SEPARATOR "final.png");
+ if (!filerr)
save_snapshot(nullptr, file);
//printf("Scheduled exit at %f\n", emutime.as_double());
@@ -1096,7 +1096,7 @@ void video_manager::pixels(u32 *buffer)
// scheme
//-------------------------------------------------
-osd_file::error video_manager::open_next(emu_file &file, const char *extension, uint32_t added_index)
+std::error_condition video_manager::open_next(emu_file &file, const char *extension, uint32_t added_index)
{
u32 origflags = file.openflags();
@@ -1205,11 +1205,9 @@ osd_file::error video_manager::open_next(emu_file &file, const char *extension,
strreplace(fname, "%i", string_format("%04d", seq));
// try to open the file; stop when we fail
- osd_file::error filerr = file.open(fname);
- if (filerr == osd_file::error::NOT_FOUND)
- {
+ std::error_condition const filerr = file.open(fname);
+ if (std::errc::no_such_file_or_directory == filerr)
break;
- }
}
}
diff --git a/src/emu/video.h b/src/emu/video.h
index bd58db9ca1d..3544bf19823 100644
--- a/src/emu/video.h
+++ b/src/emu/video.h
@@ -19,6 +19,8 @@
#include "recording.h"
+#include <system_error>
+
//**************************************************************************
// CONSTANTS
@@ -61,7 +63,7 @@ public:
// misc
void toggle_record_movie(movie_recording::format format);
- osd_file::error open_next(emu_file &file, const char *extension, uint32_t index = 0);
+ std::error_condition open_next(emu_file &file, const char *extension, uint32_t index = 0);
void compute_snapshot_size(s32 &width, s32 &height);
void pixels(u32 *buffer);
diff --git a/src/frontend/mame/audit.cpp b/src/frontend/mame/audit.cpp
index 42ddcdad438..0a37c4a3fff 100644
--- a/src/frontend/mame/audit.cpp
+++ b/src/frontend/mame/audit.cpp
@@ -425,11 +425,11 @@ media_auditor::summary media_auditor::audit_samples()
while (path.next(curpath, samplename))
{
// attempt to access the file (.flac) or (.wav)
- osd_file::error filerr = file.open(curpath + ".flac");
- if (filerr != osd_file::error::NONE)
+ std::error_condition filerr = file.open(curpath + ".flac");
+ if (filerr)
filerr = file.open(curpath + ".wav");
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
{
record.set_status(audit_status::GOOD, audit_substatus::GOOD);
found++;
@@ -589,14 +589,14 @@ media_auditor::audit_record &media_auditor::audit_one_rom(const std::vector<std:
file.set_restrict_to_mediapath(1);
// open the file if we can
- osd_file::error filerr;
+ std::error_condition filerr;
if (has_crc)
filerr = file.open(record.name(), crc);
else
filerr = file.open(record.name());
// if it worked, get the actual length and hashes, then stop
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
record.set_actual(file.hashes(m_validation), file.size());
// compute the final status
@@ -617,10 +617,10 @@ media_auditor::audit_record &media_auditor::audit_one_disk(const rom_entry *rom,
// open the disk
chd_file source;
- const chd_error err = rom_load_manager::open_disk_image(m_enumerator.options(), std::forward<T>(args)..., rom, source);
+ const std::error_condition err = rom_load_manager::open_disk_image(m_enumerator.options(), std::forward<T>(args)..., rom, source);
// if we succeeded, get the hashes
- if (err == CHDERR_NONE)
+ if (!err)
{
util::hash_collection hashes;
@@ -633,7 +633,7 @@ media_auditor::audit_record &media_auditor::audit_one_disk(const rom_entry *rom,
}
// compute the final status
- compute_status(record, rom, err == CHDERR_NONE);
+ compute_status(record, rom, !err);
return record;
}
diff --git a/src/frontend/mame/cheat.cpp b/src/frontend/mame/cheat.cpp
index bc266cc6aae..f4a567db28f 100644
--- a/src/frontend/mame/cheat.cpp
+++ b/src/frontend/mame/cheat.cpp
@@ -1191,10 +1191,10 @@ bool cheat_manager::save_all(std::string const &filename)
{
// open the file with the proper name
emu_file cheatfile(machine().options().cheat_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error const filerr(cheatfile.open(filename + ".xml"));
+ std::error_condition const filerr(cheatfile.open(filename + ".xml"));
// if that failed, return nothing
- if (filerr != osd_file::error::NONE)
+ if (filerr)
return false;
// wrap the rest of catch errors
@@ -1391,7 +1391,7 @@ void cheat_manager::load_cheats(std::string const &filename)
try
{
// loop over all instrances of the files found in our search paths
- for (osd_file::error filerr = cheatfile.open(filename + ".xml"); filerr == osd_file::error::NONE; filerr = cheatfile.open_next())
+ for (std::error_condition filerr = cheatfile.open(filename + ".xml"); !filerr; filerr = cheatfile.open_next())
{
osd_printf_verbose("Loading cheats file from %s\n", cheatfile.fullpath());
diff --git a/src/frontend/mame/clifront.cpp b/src/frontend/mame/clifront.cpp
index 38b61b9755f..eb77ead8e5c 100644
--- a/src/frontend/mame/clifront.cpp
+++ b/src/frontend/mame/clifront.cpp
@@ -1681,7 +1681,7 @@ void cli_frontend::execute_commands(std::string_view exename)
{
// attempt to open the output file
emu_file file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(std::string(emulator_info::get_configname()) + ".ini") != osd_file::error::NONE)
+ if (file.open(std::string(emulator_info::get_configname()) + ".ini"))
throw emu_fatalerror("Unable to create file %s.ini\n",emulator_info::get_configname());
// generate the updated INI
@@ -1689,7 +1689,7 @@ void cli_frontend::execute_commands(std::string_view exename)
ui_options ui_opts;
emu_file file_ui(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file_ui.open("ui.ini") != osd_file::error::NONE)
+ if (file_ui.open("ui.ini"))
throw emu_fatalerror("Unable to create file ui.ini\n");
// generate the updated INI
@@ -1704,7 +1704,7 @@ void cli_frontend::execute_commands(std::string_view exename)
plugin_opts.scan_directory(pluginpath, true);
}
emu_file file_plugin(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file_plugin.open("plugin.ini") != osd_file::error::NONE)
+ if (file_plugin.open("plugin.ini"))
throw emu_fatalerror("Unable to create file plugin.ini\n");
// generate the updated INI
diff --git a/src/frontend/mame/language.cpp b/src/frontend/mame/language.cpp
index 1cd0d1be65e..eae75b3fd6f 100644
--- a/src/frontend/mame/language.cpp
+++ b/src/frontend/mame/language.cpp
@@ -70,7 +70,7 @@ void load_translation(emu_options &m_options)
strreplace(name, "(", "");
strreplace(name, ")", "");
emu_file file(m_options.language_path(), OPEN_FLAG_READ);
- if (file.open(name + PATH_SEPARATOR "strings.mo") != osd_file::error::NONE)
+ if (file.open(name + PATH_SEPARATOR "strings.mo"))
{
osd_printf_error("Error opening translation file %s\n", name);
return;
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp
index 9dfc9aeee0b..54fdd78b01c 100644
--- a/src/frontend/mame/luaengine.cpp
+++ b/src/frontend/mame/luaengine.cpp
@@ -322,48 +322,12 @@ public:
} // namespace sol
-int sol_lua_push(sol::types<osd_file::error>, lua_State *L, osd_file::error &&value)
+int sol_lua_push(sol::types<std::error_condition>, lua_State *L, std::error_condition &&value)
{
- const char *strerror;
- switch(value)
- {
- case osd_file::error::NONE:
- return sol::stack::push(L, sol::lua_nil);
- case osd_file::error::FAILURE:
- strerror = "failure";
- break;
- case osd_file::error::OUT_OF_MEMORY:
- strerror = "out_of_memory";
- break;
- case osd_file::error::NOT_FOUND:
- strerror = "not_found";
- break;
- case osd_file::error::ACCESS_DENIED:
- strerror = "access_denied";
- break;
- case osd_file::error::ALREADY_OPEN:
- strerror = "already_open";
- break;
- case osd_file::error::TOO_MANY_FILES:
- strerror = "too_many_files";
- break;
- case osd_file::error::INVALID_DATA:
- strerror = "invalid_data";
- break;
- case osd_file::error::INVALID_ACCESS:
- strerror = "invalid_access";
- break;
- default:
- strerror = "unknown_error";
- break;
- }
- return sol::stack::push(L, strerror);
-}
-
-template <typename Handler>
-bool sol_lua_check(sol::types<osd_file::error>, lua_State *L, int index, Handler &&handler, sol::stack::record &tracking)
-{
- return sol::stack::check<int>(L, index, std::forward<Handler>(handler));
+ if (!value)
+ return sol::stack::push(L, sol::lua_nil);
+ else
+ return sol::stack::push(L, value.message());
}
@@ -884,7 +848,7 @@ void lua_engine::initialize()
}));
file_type.set("read", [](emu_file &file, sol::buffer *buff) { buff->set_len(file.read(buff->get_ptr(), buff->get_len())); return buff; });
file_type.set("write", [](emu_file &file, const std::string &data) { return file.write(data.data(), data.size()); });
- file_type.set("open", static_cast<osd_file::error (emu_file::*)(std::string_view)>(&emu_file::open));
+ file_type.set("open", static_cast<std::error_condition (emu_file::*)(std::string_view)>(&emu_file::open));
file_type.set("open_next", &emu_file::open_next);
file_type.set("seek", sol::overload(
[](emu_file &file) { return file.tell(); },
@@ -1534,12 +1498,12 @@ void lua_engine::initialize()
// open the file
emu_file file(is_absolute_path ? "" : machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr;
+ std::error_condition filerr;
if (!snapstr.empty())
filerr = file.open(snapstr);
else
filerr = machine().video().open_next(file, "png");
- if (filerr != osd_file::error::NONE)
+ if (filerr)
return sol::make_object(sol(), filerr);
// and save the snapshot
diff --git a/src/frontend/mame/luaengine.ipp b/src/frontend/mame/luaengine.ipp
index d532b8be1b4..f995b0a4a7b 100644
--- a/src/frontend/mame/luaengine.ipp
+++ b/src/frontend/mame/luaengine.ipp
@@ -16,6 +16,8 @@
#include <lua.hpp>
+#include <system_error>
+
template <typename T>
@@ -258,10 +260,8 @@ public:
} // namespace sol
-// osd_file::error customisation
-int sol_lua_push(sol::types<osd_file::error>, lua_State *L, osd_file::error &&value);
-template <typename Handler>
-bool sol_lua_check(sol::types<osd_file::error>, lua_State *L, int index, Handler &&handler, sol::stack::record &tracking);
+// automatically convert std::error_condition to string
+int sol_lua_push(sol::types<std::error_condition>, lua_State &L, std::error_condition &&value);
// enums to automatically convert to strings
int sol_lua_push(sol::types<map_handler_type>, lua_State *L, map_handler_type &&value);
diff --git a/src/frontend/mame/mame.cpp b/src/frontend/mame/mame.cpp
index 1158666ff92..c7bc0879909 100644
--- a/src/frontend/mame/mame.cpp
+++ b/src/frontend/mame/mame.cpp
@@ -152,7 +152,7 @@ void mame_machine_manager::start_luaengine()
// parse the file
// attempt to open the output file
emu_file file(options().ini_path(), OPEN_FLAG_READ);
- if (file.open("plugin.ini") == osd_file::error::NONE)
+ if (!file.open("plugin.ini"))
{
try
{
@@ -198,8 +198,8 @@ void mame_machine_manager::start_luaengine()
{
emu_file file(options().plugins_path(), OPEN_FLAG_READ);
- osd_file::error filerr = file.open("boot.lua");
- if (filerr == osd_file::error::NONE)
+ std::error_condition const filerr = file.open("boot.lua");
+ if (!filerr)
{
std::string exppath;
osd_subst_env(exppath, std::string(file.fullpath()));
diff --git a/src/frontend/mame/mameopts.cpp b/src/frontend/mame/mameopts.cpp
index 0e6c28da23d..a1d370ddb74 100644
--- a/src/frontend/mame/mameopts.cpp
+++ b/src/frontend/mame/mameopts.cpp
@@ -130,8 +130,8 @@ void mame_options::parse_one_ini(emu_options &options, const char *basename, int
// open the file; if we fail, that's ok
emu_file file(options.ini_path(), OPEN_FLAG_READ);
osd_printf_verbose("Attempting load of %s.ini\n", basename);
- osd_file::error filerr = file.open(std::string(basename) + ".ini");
- if (filerr != osd_file::error::NONE)
+ std::error_condition const filerr = file.open(std::string(basename) + ".ini");
+ if (filerr)
return;
// parse the file
diff --git a/src/frontend/mame/media_ident.cpp b/src/frontend/mame/media_ident.cpp
index 690996145b2..08a7381ad3e 100644
--- a/src/frontend/mame/media_ident.cpp
+++ b/src/frontend/mame/media_ident.cpp
@@ -134,13 +134,13 @@ void media_identifier::collect_files(std::vector<file_info> &info, char const *p
{
// first attempt to examine it as a valid zip/7z file
util::archive_file::ptr archive;
- util::archive_file::error err;
+ std::error_condition err;
if (core_filename_ends_with(path, ".7z"))
err = util::archive_file::open_7z(path, archive);
else
err = util::archive_file::open_zip(path, archive);
- if ((util::archive_file::error::NONE == err) && archive)
+ if (!err && archive)
{
std::vector<std::uint8_t> data;
@@ -158,10 +158,10 @@ void media_identifier::collect_files(std::vector<file_info> &info, char const *p
{
data.resize(std::size_t(length));
err = archive->decompress(&data[0], std::uint32_t(length));
- if (util::archive_file::error::NONE == err)
+ if (!err)
digest_data(info, curfile.c_str(), &data[0], length);
else
- osd_printf_error("%s: error decompressing file\n", curfile);
+ osd_printf_error("%s: error decompressing file (%s:%d %s)\n", curfile, err.category().name(), err.value(), err.message());
}
catch (...)
{
@@ -205,9 +205,9 @@ void media_identifier::digest_file(std::vector<file_info> &info, char const *pat
{
// attempt to open as a CHD; fail if not
chd_file chd;
- chd_error const err = chd.open(path);
+ std::error_condition const err = chd.open(path);
m_total++;
- if (err != CHDERR_NONE)
+ if (err)
{
osd_printf_info("%-20s NOT A CHD\n", core_filename_extract_base(path));
m_nonroms++;
@@ -233,7 +233,7 @@ void media_identifier::digest_file(std::vector<file_info> &info, char const *pat
// load the file and process if it opens and has a valid length
uint32_t length;
void *data;
- if (osd_file::error::NONE == util::core_file::load(path, &data, length))
+ if (!util::core_file::load(path, &data, length))
{
jed_data jed;
if (JEDERR_NONE == jed_parse(data, length, &jed))
@@ -260,7 +260,7 @@ void media_identifier::digest_file(std::vector<file_info> &info, char const *pat
// load the file and process if it opens and has a valid length
util::core_file::ptr file;
- if ((osd_file::error::NONE == util::core_file::open(path, OPEN_FLAG_READ, file)) && file)
+ if (!util::core_file::open(path, OPEN_FLAG_READ, file) && file)
{
util::hash_collection hashes;
hashes.begin(util::hash_collection::HASH_TYPES_CRC_SHA1);
diff --git a/src/frontend/mame/ui/auditmenu.cpp b/src/frontend/mame/ui/auditmenu.cpp
index 9cadb5b5d97..66c1aab0597 100644
--- a/src/frontend/mame/ui/auditmenu.cpp
+++ b/src/frontend/mame/ui/auditmenu.cpp
@@ -229,7 +229,7 @@ void menu_audit::save_available_machines()
{
// attempt to open the output file
emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(std::string(emulator_info::get_configname()) + "_avail.ini") == osd_file::error::NONE)
+ if (!file.open(std::string(emulator_info::get_configname()) + "_avail.ini"))
{
// generate header
file.printf("#\n%s%s\n#\n\n", UI_VERSION_TAG, emulator_info::get_bare_build_version());
diff --git a/src/frontend/mame/ui/filesel.cpp b/src/frontend/mame/ui/filesel.cpp
index b722afab60d..bc5c5abbd12 100644
--- a/src/frontend/mame/ui/filesel.cpp
+++ b/src/frontend/mame/ui/filesel.cpp
@@ -316,8 +316,8 @@ void menu_file_selector::select_item(const file_selector_entry &entry)
{
// drive/directory - first check the path
util::zippath_directory::ptr dir;
- osd_file::error const err = util::zippath_directory::open(entry.fullpath, dir);
- if (err != osd_file::error::NONE)
+ std::error_condition const err = util::zippath_directory::open(entry.fullpath, dir);
+ if (err)
{
// this path is problematic; present the user with an error and bail
ui().popup_time(1, _("Error accessing %s"), entry.fullpath);
@@ -399,7 +399,7 @@ void menu_file_selector::populate(float &customtop, float &custombottom)
// open the directory
util::zippath_directory::ptr directory;
- osd_file::error const err = util::zippath_directory::open(m_current_directory, directory);
+ std::error_condition const err = util::zippath_directory::open(m_current_directory, directory);
// add the "[empty slot]" entry if available
if (m_has_empty)
@@ -421,9 +421,11 @@ void menu_file_selector::populate(float &customtop, float &custombottom)
std::size_t const first = m_entrylist.size() + 1;
// build the menu for each item
- if (osd_file::error::NONE != err)
+ if (err)
{
- osd_printf_verbose("menu_file_selector::populate: error opening directory '%s' (%d)\n", m_current_directory, int(err));
+ osd_printf_verbose(
+ "menu_file_selector::populate: error opening directory '%s' (%s:%d %s)\n",
+ m_current_directory, err.category().name(), err.value(), err.message());
}
else
{
diff --git a/src/frontend/mame/ui/floppycntrl.cpp b/src/frontend/mame/ui/floppycntrl.cpp
index 0cfc8ac2333..2f1cc9e0192 100644
--- a/src/frontend/mame/ui/floppycntrl.cpp
+++ b/src/frontend/mame/ui/floppycntrl.cpp
@@ -79,12 +79,11 @@ void menu_control_floppy_image::hook_load(const std::string &filename)
bool can_in_place = input_format->supports_save();
if(can_in_place) {
- osd_file::error filerr;
std::string tmp_path;
util::core_file::ptr tmp_file;
// attempt to open the file for writing but *without* create
- filerr = util::zippath_fopen(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE, tmp_file, tmp_path);
- if(filerr == osd_file::error::NONE)
+ std::error_condition const filerr = util::zippath_fopen(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE, tmp_file, tmp_path);
+ if(!filerr)
tmp_file.reset();
else
can_in_place = false;
diff --git a/src/frontend/mame/ui/imgcntrl.cpp b/src/frontend/mame/ui/imgcntrl.cpp
index 33a71b7354a..43f40603479 100644
--- a/src/frontend/mame/ui/imgcntrl.cpp
+++ b/src/frontend/mame/ui/imgcntrl.cpp
@@ -85,7 +85,7 @@ menu_control_device_image::menu_control_device_image(mame_ui_manager &mui, rende
// check to see if the path exists; if not then set to current directory
util::zippath_directory::ptr dir;
- if (util::zippath_directory::open(m_current_directory, dir) != osd_file::error::NONE)
+ if (util::zippath_directory::open(m_current_directory, dir))
osd_get_full_path(m_current_directory, ".");
}
}
diff --git a/src/frontend/mame/ui/inifile.cpp b/src/frontend/mame/ui/inifile.cpp
index f1e0346769a..000ea922a4a 100644
--- a/src/frontend/mame/ui/inifile.cpp
+++ b/src/frontend/mame/ui/inifile.cpp
@@ -45,7 +45,7 @@ inifile_manager::inifile_manager(ui_options &options)
if (core_filename_ends_with(name, ".ini"))
{
emu_file file(m_options.categoryini_path(), OPEN_FLAG_READ);
- if (file.open(name) == osd_file::error::NONE)
+ if (!file.open(name))
{
init_category(std::move(name), file);
file.close();
@@ -63,7 +63,7 @@ void inifile_manager::load_ini_category(size_t file, size_t category, std::unord
{
std::string const &filename(m_ini_index[file].first);
emu_file fp(m_options.categoryini_path(), OPEN_FLAG_READ);
- if (fp.open(filename) != osd_file::error::NONE)
+ if (fp.open(filename))
{
osd_printf_error("Failed to open category file %s for reading\n", filename);
return;
@@ -216,7 +216,7 @@ favorite_manager::favorite_manager(ui_options &options)
, m_need_sort(true)
{
emu_file file(m_options.ui_path(), OPEN_FLAG_READ);
- if (file.open(FAVORITE_FILENAME) == osd_file::error::NONE)
+ if (!file.open(FAVORITE_FILENAME))
{
char readbuf[1024];
file.gets(readbuf, 1024);
@@ -537,7 +537,7 @@ void favorite_manager::save_favorites()
{
// attempt to open the output file
emu_file file(m_options.ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(FAVORITE_FILENAME) == osd_file::error::NONE)
+ if (!file.open(FAVORITE_FILENAME))
{
if (m_favorites.empty())
{
diff --git a/src/frontend/mame/ui/menu.cpp b/src/frontend/mame/ui/menu.cpp
index 8eb1eab47c9..923a0fae6df 100644
--- a/src/frontend/mame/ui/menu.cpp
+++ b/src/frontend/mame/ui/menu.cpp
@@ -92,13 +92,13 @@ menu::global_state::global_state(running_machine &machine, ui_options const &opt
{
m_bgrnd_bitmap = std::make_unique<bitmap_argb32>(0, 0);
emu_file backgroundfile(".", OPEN_FLAG_READ);
- if (backgroundfile.open("background.jpg") == osd_file::error::NONE)
+ if (!backgroundfile.open("background.jpg"))
{
render_load_jpeg(*m_bgrnd_bitmap, backgroundfile);
backgroundfile.close();
}
- if (!m_bgrnd_bitmap->valid() && (backgroundfile.open("background.png") == osd_file::error::NONE))
+ if (!m_bgrnd_bitmap->valid() && !backgroundfile.open("background.png"))
{
render_load_png(*m_bgrnd_bitmap, backgroundfile);
backgroundfile.close();
diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp
index bf1754481dc..da7989e6e3b 100644
--- a/src/frontend/mame/ui/miscmenu.cpp
+++ b/src/frontend/mame/ui/miscmenu.cpp
@@ -599,11 +599,11 @@ void menu_export::handle()
{
std::string filename("exported");
emu_file infile(ui().options().ui_path(), OPEN_FLAG_READ);
- if (infile.open(filename + ".xml") == osd_file::error::NONE)
+ if (!infile.open(filename + ".xml"))
for (int seq = 0; ; ++seq)
{
const std::string seqtext = string_format("%s_%04d", filename, seq);
- if (infile.open(seqtext + ".xml") != osd_file::error::NONE)
+ if (infile.open(seqtext + ".xml"))
{
filename = seqtext;
break;
@@ -612,7 +612,7 @@ void menu_export::handle()
// attempt to open the output file
emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(filename + ".xml") == osd_file::error::NONE)
+ if (!file.open(filename + ".xml"))
{
const std::string fullpath(file.fullpath());
file.close();
@@ -644,11 +644,11 @@ void menu_export::handle()
{
std::string filename("exported");
emu_file infile(ui().options().ui_path(), OPEN_FLAG_READ);
- if (infile.open(filename + ".txt") == osd_file::error::NONE)
+ if (!infile.open(filename + ".txt"))
for (int seq = 0; ; ++seq)
{
const std::string seqtext = string_format("%s_%04d", filename, seq);
- if (infile.open(seqtext + ".txt") != osd_file::error::NONE)
+ if (infile.open(seqtext + ".txt"))
{
filename = seqtext;
break;
@@ -657,7 +657,7 @@ void menu_export::handle()
// attempt to open the output file
emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(filename + ".txt") == osd_file::error::NONE)
+ if (!file.open(filename + ".txt"))
{
// print the header
std::ostringstream buffer;
@@ -754,8 +754,8 @@ void menu_machine_configure::handle()
{
const std::string filename(m_drv.name);
emu_file file(machine().options().ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
- osd_file::error filerr = file.open(filename + ".ini");
- if (filerr == osd_file::error::NONE)
+ std::error_condition const filerr = file.open(filename + ".ini");
+ if (!filerr)
{
std::string inistring = m_opts.output_ini();
file.puts(inistring);
@@ -891,7 +891,7 @@ menu_plugins_configure::menu_plugins_configure(mame_ui_manager &mui, render_cont
menu_plugins_configure::~menu_plugins_configure()
{
emu_file file_plugin(machine().options().ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file_plugin.open("plugin.ini") != osd_file::error::NONE)
+ if (file_plugin.open("plugin.ini"))
// Can't throw in a destructor, so let's ignore silently for
// now. We shouldn't write files in a destructor in any case.
//
diff --git a/src/frontend/mame/ui/optsmenu.cpp b/src/frontend/mame/ui/optsmenu.cpp
index 0ceeca25ce2..922bbb5b6fa 100644
--- a/src/frontend/mame/ui/optsmenu.cpp
+++ b/src/frontend/mame/ui/optsmenu.cpp
@@ -265,7 +265,7 @@ void menu_game_options::handle_item_event(event const &menu_event)
if (machine_filter::CUSTOM == filter.get_type())
{
emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(util::string_format("custom_%s_filter.ini", emulator_info::get_configname())) == osd_file::error::NONE)
+ if (!file.open(util::string_format("custom_%s_filter.ini", emulator_info::get_configname())))
{
filter.save_ini(file, 0);
file.close();
diff --git a/src/frontend/mame/ui/selgame.cpp b/src/frontend/mame/ui/selgame.cpp
index 338f98c42d0..ece205a8ef4 100644
--- a/src/frontend/mame/ui/selgame.cpp
+++ b/src/frontend/mame/ui/selgame.cpp
@@ -266,7 +266,7 @@ menu_select_game::menu_select_game(mame_ui_manager &mui, render_container &conta
}
emu_file file(ui().options().ui_path(), OPEN_FLAG_READ);
- if (file.open_ram(fake_ini.c_str(), fake_ini.size()) == osd_file::error::NONE)
+ if (!file.open_ram(fake_ini.c_str(), fake_ini.size()))
{
m_persistent_data.filter_data().load_ini(file);
file.close();
@@ -1259,12 +1259,12 @@ render_texture *menu_select_game::get_icon_texture(int linenum, void *selectedre
bitmap_argb32 tmp;
emu_file snapfile(std::string(m_icon_paths), OPEN_FLAG_READ);
- if (snapfile.open(std::string(driver->name) + ".ico") == osd_file::error::NONE)
+ if (!snapfile.open(std::string(driver->name) + ".ico"))
{
render_load_ico_highest_detail(snapfile, tmp);
snapfile.close();
}
- if (!tmp.valid() && cloneof && (snapfile.open(std::string(driver->parent) + ".ico") == osd_file::error::NONE))
+ if (!tmp.valid() && cloneof && !snapfile.open(std::string(driver->parent) + ".ico"))
{
render_load_ico_highest_detail(snapfile, tmp);
snapfile.close();
@@ -1309,7 +1309,7 @@ bool menu_select_game::load_available_machines()
{
// try to load available drivers from file
emu_file file(ui().options().ui_path(), OPEN_FLAG_READ);
- if (file.open(std::string(emulator_info::get_configname()) + "_avail.ini") != osd_file::error::NONE)
+ if (file.open(std::string(emulator_info::get_configname()) + "_avail.ini"))
return false;
char rbuf[MAX_CHAR_INFO];
@@ -1361,7 +1361,7 @@ bool menu_select_game::load_available_machines()
void menu_select_game::load_custom_filters()
{
emu_file file(ui().options().ui_path(), OPEN_FLAG_READ);
- if (file.open(util::string_format("custom_%s_filter.ini", emulator_info::get_configname())) == osd_file::error::NONE)
+ if (!file.open(util::string_format("custom_%s_filter.ini", emulator_info::get_configname())))
{
machine_filter::ptr flt(machine_filter::create(file, m_persistent_data.filter_data()));
if (flt)
@@ -1456,7 +1456,7 @@ void menu_select_game::filter_selected()
if (machine_filter::CUSTOM == new_type)
{
emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(util::string_format("custom_%s_filter.ini", emulator_info::get_configname())) == osd_file::error::NONE)
+ if (!file.open(util::string_format("custom_%s_filter.ini", emulator_info::get_configname())))
{
filter.save_ini(file, 0);
file.close();
diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp
index fb3f7087e27..15c7e1c3364 100644
--- a/src/frontend/mame/ui/selmenu.cpp
+++ b/src/frontend/mame/ui/selmenu.cpp
@@ -36,6 +36,8 @@
#include "uiinput.h"
#include "luaengine.h"
+#include "util/path.h"
+
#include <algorithm>
#include <cmath>
#include <cstring>
@@ -99,19 +101,19 @@ char const *const hover_msg[] = {
void load_image(bitmap_argb32 &bitmap, emu_file &file, std::string const &base)
{
- if (file.open(base + ".png") == osd_file::error::NONE)
+ if (!file.open(base + ".png"))
{
render_load_png(bitmap, file);
file.close();
}
- if (!bitmap.valid() && (file.open(base + ".jpg") == osd_file::error::NONE))
+ if (!bitmap.valid() && !file.open(base + ".jpg"))
{
render_load_jpeg(bitmap, file);
file.close();
}
- if (!bitmap.valid() && (file.open(base + ".bmp") == osd_file::error::NONE))
+ if (!bitmap.valid() && !file.open(base + ".bmp"))
{
render_load_msdib(bitmap, file);
file.close();
@@ -123,7 +125,7 @@ void load_driver_image(bitmap_argb32 &bitmap, emu_file &file, game_driver const
{
// try to load snapshot first from saved "0000.png" file
std::string fullname = driver.name;
- load_image(bitmap, file, fullname + PATH_SEPARATOR + "0000");
+ load_image(bitmap, file, util::path_concat(fullname, "0000"));
// if fail, attempt to load from standard file
if (!bitmap.valid())
@@ -144,7 +146,7 @@ void load_driver_image(bitmap_argb32 &bitmap, emu_file &file, game_driver const
if (isclone)
{
fullname = driver.parent;
- load_image(bitmap, file, fullname + PATH_SEPARATOR + "0000");
+ load_image(bitmap, file, util::path_concat(fullname, "0000"));
if (!bitmap.valid())
load_image(bitmap, file, fullname);
@@ -621,7 +623,7 @@ void menu_select_launch::launch_system(mame_ui_manager &mui, game_driver const &
else
moptions.set_value(OPTION_SOFTWARENAME, util::string_format("%s:%s", swinfo->listname, swinfo->shortname), OPTION_PRIORITY_CMDLINE);
- moptions.set_value(OPTION_SNAPNAME, util::string_format("%s%s%s", swinfo->listname, PATH_SEPARATOR, swinfo->shortname), OPTION_PRIORITY_CMDLINE);
+ moptions.set_value(OPTION_SNAPNAME, util::path_concat(swinfo->listname, swinfo->shortname), OPTION_PRIORITY_CMDLINE);
}
reselect_last::set_software(driver, *swinfo);
}
@@ -1087,11 +1089,7 @@ void menu_select_launch::check_for_icons(char const *listname)
{
// if we're doing a software list, append it to the configured path
if (listname)
- {
- if (!current.empty() && !util::is_directory_separator(current.back()))
- current.append(PATH_SEPARATOR);
- current.append(listname);
- }
+ util::path_append(current, listname);
osd_printf_verbose("Checking for icons in directory %s\n", current);
// open and walk the directory
@@ -1136,11 +1134,7 @@ std::string menu_select_launch::make_icon_paths(char const *listname) const
{
// if we're doing a software list, append it to the configured path
if (listname)
- {
- if (!current.empty() && !util::is_directory_separator(current.back()))
- current.append(PATH_SEPARATOR);
- current.append(listname);
- }
+ util::path_append(current, listname);
// append the configured path
if (!result.empty())
@@ -2286,11 +2280,11 @@ void menu_select_launch::arts_render(float origx1, float origy1, float origx2, f
else
{
// First attempt from name list
- load_image(tmp_bitmap, snapfile, software->listname + PATH_SEPARATOR + software->shortname);
+ load_image(tmp_bitmap, snapfile, util::path_concat(software->listname, software->shortname));
// Second attempt from driver name + part name
if (!tmp_bitmap.valid())
- load_image(tmp_bitmap, snapfile, software->driver->name + software->part + PATH_SEPARATOR + software->shortname);
+ load_image(tmp_bitmap, snapfile, util::path_concat(software->driver->name + software->part, software->shortname));
}
m_cache->set_snapx_software(software);
diff --git a/src/frontend/mame/ui/selsoft.cpp b/src/frontend/mame/ui/selsoft.cpp
index 2ac32cce987..95c02a9d853 100644
--- a/src/frontend/mame/ui/selsoft.cpp
+++ b/src/frontend/mame/ui/selsoft.cpp
@@ -517,7 +517,7 @@ void menu_select_software::load_sw_custom_filters()
{
// attempt to open the output file
emu_file file(ui().options().ui_path(), OPEN_FLAG_READ);
- if (file.open(util::string_format("custom_%s_filter.ini", m_driver.name)) == osd_file::error::NONE)
+ if (!file.open(util::string_format("custom_%s_filter.ini", m_driver.name)))
{
software_filter::ptr flt(software_filter::create(file, m_filter_data));
if (flt)
@@ -593,12 +593,12 @@ render_texture *menu_select_software::get_icon_texture(int linenum, void *select
bitmap_argb32 tmp;
emu_file snapfile(std::string(paths->second), OPEN_FLAG_READ);
- if (snapfile.open(std::string(swinfo->shortname) + ".ico") == osd_file::error::NONE)
+ if (!snapfile.open(std::string(swinfo->shortname) + ".ico"))
{
render_load_ico_highest_detail(snapfile, tmp);
snapfile.close();
}
- if (!tmp.valid() && !swinfo->parentname.empty() && (snapfile.open(std::string(swinfo->parentname) + ".ico") == osd_file::error::NONE))
+ if (!tmp.valid() && !swinfo->parentname.empty() && !snapfile.open(std::string(swinfo->parentname) + ".ico"))
{
render_load_ico_highest_detail(snapfile, tmp);
snapfile.close();
@@ -668,7 +668,7 @@ void menu_select_software::filter_selected()
if (software_filter::CUSTOM == new_type)
{
emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(util::string_format("custom_%s_filter.ini", m_driver.name)) == osd_file::error::NONE)
+ if (!file.open(util::string_format("custom_%s_filter.ini", m_driver.name)))
{
filter.save_ini(file, 0);
file.close();
diff --git a/src/frontend/mame/ui/state.cpp b/src/frontend/mame/ui/state.cpp
index 8f911b8f15b..6bb0b9ccdc5 100644
--- a/src/frontend/mame/ui/state.cpp
+++ b/src/frontend/mame/ui/state.cpp
@@ -365,14 +365,16 @@ void menu_load_save_state_base::handle_keys(uint32_t flags, int &iptkey)
machine().options().state_directory(),
machine().get_statename(machine().options().state_name()),
m_confirm_delete->file_name()));
- osd_file::error const err(osd_file::remove(filename));
- if (osd_file::error::NONE != err)
+ std::error_condition const err(osd_file::remove(filename));
+ if (err)
{
osd_printf_error(
- "Error removing file %s for state %s (%d)\n",
+ "Error removing file %s for state %s (%s:%d %s)\n",
filename,
m_confirm_delete->visible_name(),
- std::underlying_type_t<osd_file::error>(err));
+ err.category().name(),
+ err.value(),
+ err.message());
machine().popmessage(_("Error removing saved state file %1$s"), filename);
}
diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp
index 9f176cca141..22404f32364 100644
--- a/src/frontend/mame/ui/ui.cpp
+++ b/src/frontend/mame/ui/ui.cpp
@@ -2136,7 +2136,7 @@ void mame_ui_manager::load_ui_options()
// parse the file
// attempt to open the output file
emu_file file(machine().options().ini_path(), OPEN_FLAG_READ);
- if (file.open("ui.ini") == osd_file::error::NONE)
+ if (!file.open("ui.ini"))
{
try
{
@@ -2157,7 +2157,7 @@ void mame_ui_manager::save_ui_options()
{
// attempt to open the output file
emu_file file(machine().options().ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open("ui.ini") == osd_file::error::NONE)
+ if (!file.open("ui.ini"))
{
// generate the updated INI
file.puts(options().output_ini());
@@ -2185,13 +2185,13 @@ void mame_ui_manager::save_main_option()
// attempt to open the main ini file
{
emu_file file(machine().options().ini_path(), OPEN_FLAG_READ);
- if (file.open(std::string(emulator_info::get_configname()) + ".ini") == osd_file::error::NONE)
+ if (!file.open(std::string(emulator_info::get_configname()) + ".ini"))
{
try
{
options.parse_ini_file((util::core_file&)file, OPTION_PRIORITY_MAME_INI, OPTION_PRIORITY_MAME_INI < OPTION_PRIORITY_DRIVER_INI, true);
}
- catch(options_error_exception &)
+ catch (options_error_exception &)
{
osd_printf_error("**Error loading %s.ini**\n", emulator_info::get_configname());
return;
@@ -2215,13 +2215,14 @@ void mame_ui_manager::save_main_option()
// attempt to open the output file
{
emu_file file(machine().options().ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(std::string(emulator_info::get_configname()) + ".ini") == osd_file::error::NONE)
+ if (!file.open(std::string(emulator_info::get_configname()) + ".ini"))
{
// generate the updated INI
file.puts(options.output_ini());
file.close();
}
- else {
+ else
+ {
machine().popmessage(_("**Error saving %s.ini**"), emulator_info::get_configname());
return;
}
diff --git a/src/lib/formats/acorn_dsk.cpp b/src/lib/formats/acorn_dsk.cpp
index c4668478b05..40ab6eb1029 100644
--- a/src/lib/formats/acorn_dsk.cpp
+++ b/src/lib/formats/acorn_dsk.cpp
@@ -10,6 +10,9 @@
#include "acorn_dsk.h"
+#include "ioprocs.h"
+
+
acorn_ssd_format::acorn_ssd_format() : wd177x_format(formats)
{
}
@@ -29,29 +32,36 @@ const char *acorn_ssd_format::extensions() const
return "ssd,bbc,img";
}
-int acorn_ssd_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int acorn_ssd_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t cat[8];
uint32_t sectors0, sectors2;
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ {
+ LOG_FORMATS("ssd: error getting image size\n");
+ return -1;
+ }
- for(int i=0; formats[i].form_factor; i++) {
+ for (int i=0; formats[i].form_factor; i++)
+ {
+ size_t actual;
const format &f = formats[i];
- if(form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
+ if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
continue;
// test for Torch CPN - test pattern at sector &0018
- io_generic_read(io, cat, 0x32800, 8);
+ io.read_at(0x32800, cat, 8, actual);
if (memcmp(cat, "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd", 4) == 0 && size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count)
return i;
// test for HADFS - test pattern at sector 70
- io_generic_read(io, cat, 0x04610, 8);
+ io.read_at(0x04610, cat, 8, actual);
if (memcmp(cat, "\x00\x28\x43\x29\x4a\x47\x48\x00", 4) == 0 && size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count)
return i;
// test for Kenda SD - offset &0962 = 0 SD/1 DD, offset &0963 = disk size blocks / 4 (block size = 1K, ie. 0x400 bytes), reserved tracks = 3, ie. 0x1e00 bytes, soft stagger = 2 sectors, ie. 0x200 bytes
- io_generic_read(io, cat, 0x0960, 8);
+ io.read_at(0x0960, cat, 8, actual);
if (cat[2] == 0 && ((uint64_t)cat[3] * 4 * 0x400 + 0x2000) == size && size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count)
{
// valid blocks for single sided
@@ -63,20 +73,22 @@ int acorn_ssd_format::find_size(io_generic *io, uint32_t form_factor, const std:
}
// read sector count from side 0 catalogue
- io_generic_read(io, cat, 0x100, 8);
+ io.read_at(0x100, cat, 8, actual);
sectors0 = ((cat[6] & 3) << 8) + cat[7];
LOG_FORMATS("ssd: sector count 0: %d %s\n", sectors0, sectors0 % 10 != 0 ? "invalid" : "");
- if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (sectors0 <= f.track_count * f.sector_count)) {
+ if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (sectors0 <= f.track_count * f.sector_count))
+ {
if (f.head_count == 2)
{
// read sector count from side 2 catalogue
- io_generic_read(io, cat, (uint64_t)compute_track_size(f) * f.track_count + 0x100, 8); // sequential
+ io.read_at((uint64_t)compute_track_size(f) * f.track_count + 0x100, cat, 8, actual); // sequential
sectors2 = ((cat[6] & 3) << 8) + cat[7];
// exception case for Acorn CP/M System Disc 1
- io_generic_read(io, cat, 0x367ec, 8);
- if (memcmp(cat, "/M ", 4) == 0) sectors2 = ((cat[6] & 3) << 8) + cat[7];
+ io.read_at(0x367ec, cat, 8, actual);
+ if (memcmp(cat, "/M ", 4) == 0)
+ sectors2 = ((cat[6] & 3) << 8) + cat[7];
LOG_FORMATS("ssd: sector count 2: %d %s\n", sectors2, sectors2 % 10 != 0 ? "invalid" : "");
}
@@ -93,12 +105,13 @@ int acorn_ssd_format::find_size(io_generic *io, uint32_t form_factor, const std:
return -1;
}
-int acorn_ssd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int acorn_ssd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int type = find_size(io, form_factor, variants);
- if(type != -1)
+ if (type != -1)
return 90;
+
return 0;
}
@@ -171,40 +184,49 @@ const char *acorn_dsd_format::extensions() const
return "dsd";
}
-int acorn_dsd_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int acorn_dsd_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t cat[8];
uint32_t sectors0, sectors2;
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ {
+ LOG_FORMATS("dsd: error getting image size\n");
+ return -1;
+ }
- for (int i = 0; formats[i].form_factor; i++) {
+ for (int i = 0; formats[i].form_factor; i++)
+ {
+ size_t actual;
const format &f = formats[i];
if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
continue;
// test for Torch CPN - test pattern at sector &0018
- io_generic_read(io, cat, 0x1200, 8);
+ io.read_at(0x1200, cat, 8, actual);
if (memcmp(cat, "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd", 4) == 0 && size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count)
return i;
// test for HADFS - test pattern at sector 70
- io_generic_read(io, cat, 0x08c10, 8);
+ io.read_at(0x08c10, cat, 8, actual);
if (memcmp(cat, "\x00\x28\x43\x29\x4a\x47\x48\x00", 4) == 0 && size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count)
return i;
// read sector count from side 0 catalogue
- io_generic_read(io, cat, 0x100, 8);
+ io.read_at(0x100, cat, 8, actual);
sectors0 = ((cat[6] & 3) << 8) + cat[7];
LOG_FORMATS("dsd: sector count 0: %d %s\n", sectors0, sectors0 % 10 != 0 ? "invalid" : "");
- if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (sectors0 <= f.track_count * f.sector_count)) {
+ if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (sectors0 <= f.track_count * f.sector_count))
+ {
// read sector count from side 2 catalogue
- io_generic_read(io, cat, 0xb00, 8); // interleaved
+ io.read_at(0xb00, cat, 8, actual); // interleaved
sectors2 = ((cat[6] & 3) << 8) + cat[7];
// exception case for Acorn CP/M System Disc 1
- io_generic_read(io, cat, 0x97ec, 8);
- if (memcmp(cat, "/M ", 4) == 0) sectors2 = ((cat[6] & 3) << 8) + cat[7];
+ io.read_at(0x97ec, cat, 8, actual);
+ if (memcmp(cat, "/M ", 4) == 0)
+ sectors2 = ((cat[6] & 3) << 8) + cat[7];
LOG_FORMATS("dsd: sector count 2: %d %s\n", sectors2, sectors2 % 10 != 0 ? "invalid" : "");
@@ -216,12 +238,13 @@ int acorn_dsd_format::find_size(io_generic *io, uint32_t form_factor, const std:
return -1;
}
-int acorn_dsd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int acorn_dsd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int type = find_size(io, form_factor, variants);
if (type != -1)
return 90;
+
return 0;
}
@@ -274,27 +297,36 @@ const char *opus_ddos_format::extensions() const
return "dds";
}
-int opus_ddos_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int opus_ddos_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
+ size_t actual;
uint8_t cat[8];
uint32_t sectors0, sectors2;
// read sector count from side 0 catalogue
- io_generic_read(io, cat, 0x1000, 8);
+ io.read_at(0x1000, cat, 8, actual);
sectors0 = (cat[1] << 8) + cat[2];
LOG_FORMATS("ddos: sector count 0: %d %s\n", sectors0, sectors0 % 18 != 0 ? "invalid" : "");
- uint64_t size = io_generic_size(io);
- for (int i = 0; formats[i].form_factor; i++) {
+ uint64_t size;
+ if (io.length(size))
+ {
+ LOG_FORMATS("ddos: error getting image size\n");
+ return -1;
+ }
+
+ for (int i = 0; formats[i].form_factor; i++)
+ {
const format &f = formats[i];
if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
continue;
- if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (sectors0 <= f.track_count * f.sector_count)) {
+ if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (sectors0 <= f.track_count * f.sector_count))
+ {
if (f.head_count == 2)
{
// read sector count from side 2 catalogue
- io_generic_read(io, cat, (uint64_t)compute_track_size(f) * f.track_count + 0x1000, 8); // sequential
+ io.read_at((uint64_t)compute_track_size(f) * f.track_count + 0x1000, cat, 8, actual); // sequential
sectors2 = (cat[1] << 8) + cat[2];
LOG_FORMATS("ddos: sector count 2: %d %s\n", sectors2, sectors2 % 18 != 0 ? "invalid" : "");
}
@@ -311,12 +343,13 @@ int opus_ddos_format::find_size(io_generic *io, uint32_t form_factor, const std:
return -1;
}
-int opus_ddos_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int opus_ddos_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int type = find_size(io, form_factor, variants);
if (type != -1)
return 90;
+
return 0;
}
@@ -369,25 +402,33 @@ const char *acorn_adfs_old_format::extensions() const
return "adf,ads,adm,adl";
}
-int acorn_adfs_old_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int acorn_adfs_old_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
+ size_t actual;
uint8_t map[3];
uint32_t sectors;
uint8_t oldmap[4];
// read sector count from free space map
- io_generic_read(io, map, 0xfc, 3);
+ io.read_at(0xfc, map, 3, actual);
sectors = map[0] + (map[1] << 8) + (map[2] << 16);
LOG_FORMATS("adfs_o: sector count %d %s\n", sectors, sectors % 16 != 0 ? "invalid" : "");
// read map identifier
- io_generic_read(io, oldmap, 0x201, 4);
+ io.read_at(0x201, oldmap, 4, actual);
LOG_FORMATS("adfs_o: map identifier %s %s\n", oldmap, memcmp(oldmap, "Hugo", 4) != 0 ? "invalid" : "");
- uint64_t size = io_generic_size(io);
- for(int i=0; formats[i].form_factor; i++) {
+ uint64_t size;
+ if (io.length(size))
+ {
+ LOG_FORMATS("adfs_o: error getting image size\n");
+ return -1;
+ }
+
+ for (int i=0; formats[i].form_factor; i++)
+ {
const format &f = formats[i];
- if(form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
+ if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
continue;
// valid images will have map identifier 'Hugo' and sector counts adfs-s = 0x280; adfs-m = 0x500; adfs-l = 0xa00; adfs-dos = 0xaa0; though many adfs-s images are incorrect
@@ -399,12 +440,13 @@ int acorn_adfs_old_format::find_size(io_generic *io, uint32_t form_factor, const
return -1;
}
-int acorn_adfs_old_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int acorn_adfs_old_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int type = find_size(io, form_factor, variants);
if(type != -1)
return 100;
+
return 0;
}
@@ -465,43 +507,50 @@ const char *acorn_adfs_new_format::extensions() const
return "adf";
}
-int acorn_adfs_new_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int acorn_adfs_new_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
+ size_t actual;
uint8_t dform[4];
uint8_t eform[4];
// read map identifiers for D and E formats
- io_generic_read(io, dform, 0x401, 4);
+ io.read_at(0x401, dform, 4, actual);
LOG_FORMATS("adfs_n: map identifier (D format) %s %s\n", dform, (memcmp(dform, "Hugo", 4) != 0 && memcmp(dform, "Nick", 4) != 0) ? "invalid" : "");
- io_generic_read(io, eform, 0x801, 4);
+ io.read_at(0x801, eform, 4, actual);
LOG_FORMATS("adfs_n: map identifier (E format) %s %s\n", eform, memcmp(eform, "Nick", 4) != 0 ? "invalid" : "");
- uint64_t size = io_generic_size(io);
- for (int i = 0; formats[i].form_factor; i++) {
+ uint64_t size;
+ if (io.length(size))
+ {
+ LOG_FORMATS("adfs_n: error getting image size\n");
+ return -1;
+ }
+
+ for (int i = 0; formats[i].form_factor; i++)
+ {
const format &f = formats[i];
if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
continue;
// no further checks for 1600K images
- if ((size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && size == 0x190000) {
+ if ((size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && size == 0x190000)
return i;
- }
// valid 800K images will have map identifier Nick, Arthur D format still use Hugo
- if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (memcmp(dform, "Hugo", 4) == 0 || memcmp(dform, "Nick", 4) == 0 || memcmp(eform, "Nick", 4) == 0)) {
+ if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (memcmp(dform, "Hugo", 4) == 0 || memcmp(dform, "Nick", 4) == 0 || memcmp(eform, "Nick", 4) == 0))
return i;
- }
}
LOG_FORMATS("adfs_n: no match\n");
return -1;
}
-int acorn_adfs_new_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int acorn_adfs_new_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int type = find_size(io, form_factor, variants);
if (type != -1)
return 100;
+
return 0;
}
@@ -546,33 +595,43 @@ const char *acorn_dos_format::extensions() const
return "img";
}
-int acorn_dos_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int acorn_dos_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint8_t type;
+ uint64_t size;
+ if (io.length(size))
+ {
+ LOG_FORMATS("dos: error getting image size\n");
+ return -1;
+ }
- uint64_t size = io_generic_size(io);
- for(int i=0; formats[i].form_factor; i++) {
+ for (int i=0; formats[i].form_factor; i++)
+ {
const format &f = formats[i];
- if(form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
+ if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
continue;
- if (size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) {
+ if (size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count)
+ {
// read media type ID from FAT - Acorn DOS = 0xfd
- io_generic_read(io, &type, 0, 1);
+ size_t actual;
+ uint8_t type;
+ io.read_at(0, &type, 1, actual);
LOG_FORMATS("dos: 800k media type id %02X %s\n", type, type != 0xfd ? "invalid" : "");
- if (type == 0xfd) return i;
+ if (type == 0xfd)
+ return i;
}
}
LOG_FORMATS("dos: no match\n");
return -1;
}
-int acorn_dos_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int acorn_dos_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int type = find_size(io, form_factor, variants);
- if(type != -1)
+ if (type != -1)
return 90;
+
return 0;
}
@@ -618,19 +677,28 @@ bool opus_ddcpm_format::supports_save() const
return false;
}
-int opus_ddcpm_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int opus_ddcpm_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
+ size_t actual;
uint8_t h[8];
- io_generic_read(io, h, 0, 8);
+ io.read_at(0, h, 8, actual);
+
+ uint64_t size;
+ if (io.length(size))
+ {
+ LOG_FORMATS("ddcpm: error getting image size\n");
+ return -1;
+ }
- if (io_generic_size(io) == 819200 && memcmp(h, "Slogger ", 8) == 0)
+ if (size == 819200 && memcmp(h, "Slogger ", 8) == 0)
return 100;
+
LOG_FORMATS("ddcpm: no match\n");
return 0;
}
-bool opus_ddcpm_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool opus_ddcpm_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
// Double density discs formatted with DDCPM :
//
@@ -644,19 +712,21 @@ bool opus_ddcpm_format::load(io_generic *io, uint32_t form_factor, const std::ve
// Sector skew of 1
// Sector interleave of 2
//
- int spt, bps;
-
- for (int head = 0; head < 2; head++) {
- for (int track = 0; track < 80; track++) {
- bool mfm = track > 2 || head;
- bps = mfm ? 512 : 256;
- spt = 10;
+ for (int head = 0; head < 2; head++)
+ {
+ for (int track = 0; track < 80; track++)
+ {
+ bool const mfm = track > 2 || head;
+ int const bps = mfm ? 512 : 256;
+ int const spt = 10;
desc_pc_sector sects[10];
uint8_t sectdata[10*512];
- io_generic_read(io, sectdata, head * 80 * spt * 512 + track * spt * 512, spt * 512);
+ size_t actual;
+ io.read_at(head * 80 * spt * 512 + track * spt * 512, sectdata, spt * 512, actual);
- for (int i = 0; i < spt; i++) {
+ for (int i = 0; i < spt; i++)
+ {
sects[i].track = track;
sects[i].head = head;
sects[i].sector = i;
@@ -677,7 +747,7 @@ bool opus_ddcpm_format::load(io_generic *io, uint32_t form_factor, const std::ve
return true;
}
-bool opus_ddcpm_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool opus_ddcpm_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
return false;
}
diff --git a/src/lib/formats/acorn_dsk.h b/src/lib/formats/acorn_dsk.h
index 1428212cfaa..de07e8b9fed 100644
--- a/src/lib/formats/acorn_dsk.h
+++ b/src/lib/formats/acorn_dsk.h
@@ -20,8 +20,8 @@ class acorn_ssd_format : public wd177x_format
public:
acorn_ssd_format();
- virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual int get_image_offset(const format &f, int head, int track) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -36,8 +36,8 @@ class acorn_dsd_format : public wd177x_format
public:
acorn_dsd_format();
- virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual int get_image_offset(const format &f, int head, int track) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -52,8 +52,8 @@ class opus_ddos_format : public wd177x_format
public:
opus_ddos_format();
- virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual int get_image_offset(const format &f, int head, int track) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -68,8 +68,8 @@ class acorn_adfs_old_format : public wd177x_format
public:
acorn_adfs_old_format();
- virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual int get_image_offset(const format &f, int head, int track) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -84,8 +84,8 @@ class acorn_adfs_new_format : public wd177x_format
public:
acorn_adfs_new_format();
- virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual int get_image_offset(const format &f, int head, int track) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -100,8 +100,8 @@ class acorn_dos_format : public wd177x_format
public:
acorn_dos_format();
- virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual int get_image_offset(const format &f, int head, int track) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -116,9 +116,9 @@ class opus_ddcpm_format : public floppy_image_format_t
public:
opus_ddcpm_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/afs_dsk.cpp b/src/lib/formats/afs_dsk.cpp
index d6b275240de..000daf62df7 100644
--- a/src/lib/formats/afs_dsk.cpp
+++ b/src/lib/formats/afs_dsk.cpp
@@ -30,12 +30,13 @@ const char *afs_format::extensions() const
return "adl,img";
}
-int afs_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int afs_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int type = find_size(io, form_factor, variants);
if (type != -1)
return 50;
+
return 0;
}
diff --git a/src/lib/formats/afs_dsk.h b/src/lib/formats/afs_dsk.h
index 1a15e54d90d..f56b2dcb1f4 100644
--- a/src/lib/formats/afs_dsk.h
+++ b/src/lib/formats/afs_dsk.h
@@ -20,7 +20,7 @@ class afs_format : public wd177x_format
public:
afs_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual int get_image_offset(const format &f, int head, int track) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/aim_dsk.cpp b/src/lib/formats/aim_dsk.cpp
index 489ec1752e4..6ad49b22969 100644
--- a/src/lib/formats/aim_dsk.cpp
+++ b/src/lib/formats/aim_dsk.cpp
@@ -12,10 +12,10 @@
*********************************************************************/
-#include <cassert>
-
#include "aim_dsk.h"
+#include "ioprocs.h"
+
aim_format::aim_format()
{
@@ -40,18 +40,20 @@ const char *aim_format::extensions() const
}
-int aim_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int aim_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- if (io_generic_size(io) == 2068480)
- {
+ uint64_t size;
+ if (io.length(size))
+ return 0;
+
+ if (size == 2068480)
return 100;
- }
return 0;
}
-bool aim_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool aim_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
image->set_variant(floppy_image::DSQD);
@@ -70,7 +72,8 @@ bool aim_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
bool header = false;
// Read track
- io_generic_read(io, &track_data[0], ( heads * track + head ) * track_size, track_size);
+ size_t actual;
+ io.read_at((heads * track + head) * track_size, &track_data[0], track_size, actual);
// Find first sector header or index mark
for (int offset = 0; offset < track_size; offset += 2)
diff --git a/src/lib/formats/aim_dsk.h b/src/lib/formats/aim_dsk.h
index c4737efc7e6..560943be30c 100644
--- a/src/lib/formats/aim_dsk.h
+++ b/src/lib/formats/aim_dsk.h
@@ -7,9 +7,10 @@
AIM disk images
*********************************************************************/
+#ifndef MAME_FORMATS_AIM_DSK_H
+#define MAME_FORMATS_AIM_DSK_H
-#ifndef AIM_DSK_H
-#define AIM_DSK_H
+#pragma once
#include "flopimg.h"
@@ -20,8 +21,8 @@ class aim_format : public floppy_image_format_t
public:
aim_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -31,4 +32,4 @@ public:
extern const floppy_format_type FLOPPY_AIM_FORMAT;
-#endif /* AIM_DSK_H */
+#endif // MAME_FORMATS_AIM_DSK_H
diff --git a/src/lib/formats/ami_dsk.cpp b/src/lib/formats/ami_dsk.cpp
index 5973bc69dab..eb96b01377d 100644
--- a/src/lib/formats/ami_dsk.cpp
+++ b/src/lib/formats/ami_dsk.cpp
@@ -8,10 +8,11 @@
*********************************************************************/
-#include <cassert>
-
#include "formats/ami_dsk.h"
+#include "ioprocs.h"
+
+
adf_format::adf_format() : floppy_image_format_t()
{
}
@@ -36,59 +37,61 @@ bool adf_format::supports_save() const
return true;
}
-int adf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int adf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return 0;
+
if ((size == 901120) || (size == 912384) || (size == 1802240))
- {
return 50;
- }
+
return 0;
}
-bool adf_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool adf_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
desc_s sectors[22];
uint8_t sectdata[512*22];
bool is_hd = false;
int tracks = 80;
- for(int i=0; i<22; i++) {
+ for (int i=0; i<22; i++) {
sectors[i].data = sectdata + 512*i;
sectors[i].size = 512;
sectors[i].sector_id = i;
}
- uint64_t size = io_generic_size(io);
- if(size == 901120)
- {
+ uint64_t size;
+ if (io.length(size))
+ return false;
+
+ if (size == 901120) {
is_hd = false;
tracks = 80;
- }
- else if (size == 912384)
- {
+ } else if (size == 912384) {
is_hd = false;
tracks = 81;
- }
- else
- {
+ } else {
is_hd = true;
tracks = 80;
}
if (!is_hd) {
image->set_variant(floppy_image::DSDD);
- for(int track=0; track < tracks; track++) {
- for(int side=0; side < 2; side++) {
- io_generic_read(io, sectdata, (track*2 + side)*512*11, 512*11);
+ for (int track=0; track < tracks; track++) {
+ for (int side=0; side < 2; side++) {
+ size_t actual;
+ io.read_at((track*2 + side)*512*11, sectdata, 512*11, actual);
generate_track(amiga_11, track, side, sectors, 11, 100000, image);
}
}
} else {
image->set_variant(floppy_image::DSHD);
- for(int track=0; track < tracks; track++) {
- for(int side=0; side < 2; side++) {
- io_generic_read(io, sectdata, (track*2 + side)*512*22, 512*22);
+ for (int track=0; track < tracks; track++) {
+ for (int side=0; side < 2; side++) {
+ size_t actual;
+ io.read_at((track*2 + side)*512*22, sectdata, 512*22, actual);
generate_track(amiga_22, track, side, sectors, 22, 200000, image);
}
}
@@ -100,11 +103,11 @@ bool adf_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
uint32_t adf_format::g32(const std::vector<bool> &trackbuf, uint32_t pos)
{
uint32_t res = 0;
- for(int i=0; i != 32; i++) {
- if(trackbuf[pos])
+ for (int i=0; i != 32; i++) {
+ if (trackbuf[pos])
res |= 0x80000000 >> i;
- pos ++;
- if(pos == trackbuf.size())
+ pos++;
+ if (pos == trackbuf.size())
pos = 0;
}
return res;
@@ -113,34 +116,34 @@ uint32_t adf_format::g32(const std::vector<bool> &trackbuf, uint32_t pos)
uint32_t adf_format::checksum(const std::vector<bool> &trackbuf, uint32_t pos, int long_count)
{
uint32_t check = 0;
- for(int i=0; i<long_count; i++)
+ for (int i=0; i<long_count; i++)
check ^= g32(trackbuf, pos+32*i);
return check & 0x55555555;
}
-bool adf_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool adf_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint8_t sectdata[512*22];
- bool hd = image->get_variant() == floppy_image::DSHD;
+ bool const hd = image->get_variant() == floppy_image::DSHD;
- int data_track_size = hd ? 512*22 : 512*11;
+ int const data_track_size = hd ? 512*22 : 512*11;
- for(int track=0; track < 80; track++) {
- for(int side=0; side < 2; side++) {
+ for (int track=0; track < 80; track++) {
+ for (int side=0; side < 2; side++) {
auto trackbuf = generate_bitstream_from_track(track, side, hd ? 1000 : 2000, image);
- for(uint32_t i=0; i<trackbuf.size(); i++)
- if(g32(trackbuf, i) == 0x44894489 &&
+ for (uint32_t i=0; i<trackbuf.size(); i++)
+ if (g32(trackbuf, i) == 0x44894489 &&
(g32(trackbuf, i+384) & 0x55555555) == checksum(trackbuf, i+32, 10) &&
(g32(trackbuf, i+448) & 0x55555555) == checksum(trackbuf, i+480, 256)) {
uint32_t head = ((g32(trackbuf, i+32) & 0x55555555) << 1) | (g32(trackbuf, i+64) & 0x55555555);
int sect = (head >> 8) & 0xff;
- if(sect > (hd ? 22 : 11))
+ if (sect > (hd ? 22 : 11))
continue;
uint8_t *dest = sectdata + 512*sect;
- for(int j=0; j<128; j++) {
+ for (int j=0; j<128; j++) {
uint32_t val = ((g32(trackbuf, i+480+32*j) & 0x55555555) << 1) | (g32(trackbuf, i+4576+32*j) & 0x55555555);
*dest++ = val >> 24;
*dest++ = val >> 16;
@@ -148,7 +151,8 @@ bool adf_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
*dest++ = val;
}
- io_generic_write(io, sectdata, (track*2 + side)*data_track_size, data_track_size);
+ size_t actual;
+ io.write_at((track*2 + side) * data_track_size, sectdata, data_track_size, actual);
}
}
}
diff --git a/src/lib/formats/ami_dsk.h b/src/lib/formats/ami_dsk.h
index d25fd45a210..595beb1bcd3 100644
--- a/src/lib/formats/ami_dsk.h
+++ b/src/lib/formats/ami_dsk.h
@@ -19,9 +19,9 @@ class adf_format : public floppy_image_format_t
public:
adf_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/ap2_dsk.cpp b/src/lib/formats/ap2_dsk.cpp
index 50b071d6432..8adc13d69d3 100644
--- a/src/lib/formats/ap2_dsk.cpp
+++ b/src/lib/formats/ap2_dsk.cpp
@@ -8,13 +8,15 @@
*********************************************************************/
-#include <cstdlib>
-#include <cstring>
-#include <cassert>
-
#include "ap2_dsk.h"
#include "basicdsk.h"
+#include "ioprocs.h"
+
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+
#define APPLE2_IMAGE_DO 0
#define APPLE2_IMAGE_PO 1
@@ -559,9 +561,12 @@ bool a2_16sect_format::supports_save() const
return true;
}
-int a2_16sect_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int a2_16sect_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return 0;
+
//uint32_t expected_size = 35 * 16 * 256;
uint32_t expected_size = APPLE2_TRACK_COUNT * 16 * 256;
@@ -574,9 +579,11 @@ int a2_16sect_format::identify(io_generic *io, uint32_t form_factor, const std::
return 0;
}
-bool a2_16sect_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool a2_16sect_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return false;
image->set_form_variant(floppy_image::FF_525, floppy_image::SSSD);
@@ -595,7 +602,8 @@ bool a2_16sect_format::load(io_generic *io, uint32_t form_factor, const std::vec
static const unsigned char cpm22_block1[8] = { 0xa2, 0x55, 0xa9, 0x00, 0x9d, 0x00, 0x0d, 0xca };
static const unsigned char subnod_block1[8] = { 0x63, 0xaa, 0xf0, 0x76, 0x8d, 0x63, 0xaa, 0x8e };
- io_generic_read(io, sector_data, fpos, 256*16);
+ size_t actual;
+ io.read_at(fpos, sector_data, 256*16, actual);
if (track == 0 && fpos == 0)
{
@@ -740,7 +748,7 @@ void a2_16sect_format::update_chk(const uint8_t *data, int size, uint32_t &chk)
//#define VERBOSE_SAVE
-bool a2_16sect_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool a2_16sect_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int g_tracks, g_heads;
int visualgrid[16][APPLE2_TRACK_COUNT]; // visualizer grid, cleared/initialized below
@@ -938,8 +946,9 @@ bool a2_16sect_format::save(io_generic *io, const std::vector<uint32_t> &variant
}
for(int i=0; i<nsect; i++) {
//if(nsect>0) printf("t%d,", track);
- uint8_t *data = sectdata + (256)*i;
- io_generic_write(io, data, pos_data, 256);
+ uint8_t const *const data = sectdata + (256)*i;
+ size_t actual;
+ io.write_at(pos_data, data, 256, actual);
pos_data += 256;
}
//printf("\n");
@@ -952,11 +961,11 @@ bool a2_16sect_format::save(io_generic *io, const std::vector<uint32_t> &variant
for (int i = 0; i < 16; i++) {
if (visualgrid[i][j] == NOTFOUND) printf("-NF- ");
else {
- if (visualgrid[i][j] & ADDRFOUND) printf("a"); else printf(" ");
- if (visualgrid[i][j] & ADDRGOOD) printf("A"); else printf(" ");
- if (visualgrid[i][j] & DATAFOUND) printf("d"); else printf(" ");
- if (visualgrid[i][j] & DATAGOOD) { printf("D"); total_good++; } else printf(" ");
- if (visualgrid[i][j] & DATAPOST) printf("."); else printf(" ");
+ if (visualgrid[i][j] & ADDRFOUND) printf("a"); else printf(" ");
+ if (visualgrid[i][j] & ADDRGOOD) printf("A"); else printf(" ");
+ if (visualgrid[i][j] & DATAFOUND) printf("d"); else printf(" ");
+ if (visualgrid[i][j] & DATAGOOD) { printf("D"); total_good++; } else printf(" ");
+ if (visualgrid[i][j] & DATAPOST) printf("."); else printf(" ");
}
}
printf("\n");
@@ -1019,14 +1028,16 @@ bool a2_rwts18_format::supports_save() const
return true;
}
-int a2_rwts18_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int a2_rwts18_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
- uint32_t expected_size = APPLE2_TRACK_COUNT * 16 * 256;
+ uint64_t size;
+ if(io.length(size))
+ return 0;
+ uint32_t const expected_size = APPLE2_TRACK_COUNT * 16 * 256;
return size == expected_size;
}
-bool a2_rwts18_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool a2_rwts18_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
/* TODO: rewrite me properly
uint8_t sector_data[(256)*16];
@@ -1046,7 +1057,8 @@ bool a2_rwts18_format::load(io_generic *io, uint32_t form_factor, const std::vec
sectors[si].size = 256;
sectors[si].sector_id = si;
sectors[si].sector_info = format;
- io_generic_read(io, data, pos_data, 256);
+ size_t actual;
+ io.read_at(pos_data, data, 256, actual);
pos_data += 256;
}
generate_track(mac_gcr, track, head, sectors, 16, 3104*16, image);
@@ -1075,7 +1087,7 @@ void a2_rwts18_format::update_chk(const uint8_t *data, int size, uint32_t &chk)
{
}
-bool a2_rwts18_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool a2_rwts18_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int g_tracks, g_heads;
int visualgrid[18][APPLE2_TRACK_COUNT]; // visualizer grid, cleared/initialized below
@@ -1266,8 +1278,9 @@ bool a2_rwts18_format::save(io_generic *io, const std::vector<uint32_t> &variant
}
for(int i=0; i<nsect; i++) {
//if(nsect>0) printf("t%d,", track);
- uint8_t *data = sectdata + (256)*i;
- io_generic_write(io, data, pos_data, 256);
+ uint8_t const *const data = sectdata + (256)*i;
+ size_t actual;
+ io.write_at(pos_data, data, 256, actual);
pos_data += 256;
}
@@ -1447,8 +1460,9 @@ bool a2_rwts18_format::save(io_generic *io, const std::vector<uint32_t> &variant
}
for(int i=0; i<nsect; i++) {
//if(nsect>0) printf("t%d,", track);
- uint8_t *data = sectdata + (256)*i;
- io_generic_write(io, data, pos_data, 256);
+ uint8_t const *const data = sectdata + (256)*i;
+ size_t actual;
+ io.write_at(pos_data, data, 256, actual);
pos_data += 256;
}
//printf("\n");
@@ -1500,9 +1514,12 @@ bool a2_edd_format::supports_save() const
return false;
}
-int a2_edd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int a2_edd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- return ((io_generic_size(io) == 2244608) || (io_generic_size(io) == 2310144)) ? 50 : 0;
+ uint64_t size;
+ if (io.length(size))
+ return 0;
+ return ((size == 2244608) || (size == 2310144)) ? 50 : 0;
}
uint8_t a2_edd_format::pick(const uint8_t *data, int pos)
@@ -1510,23 +1527,20 @@ uint8_t a2_edd_format::pick(const uint8_t *data, int pos)
return ((data[pos>>3] << 8) | data[(pos>>3)+1]) >> (8-(pos & 7));
}
-bool a2_edd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool a2_edd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint8_t *img;
uint8_t nibble[16384], stream[16384];
int npos[16384];
- img = (uint8_t *) malloc(2244608);
-
+ std::unique_ptr<uint8_t []> img(new (std::nothrow) uint8_t[2244608]);
if (!img)
- {
return false;
- }
- io_generic_read(io, img, 0, 2244608);
+ size_t actual;
+ io.read_at(0, img.get(), 2244608, actual);
for(int i=0; i<137; i++) {
- const uint8_t *trk = img + 16384*i;
+ uint8_t const *const trk = &img[16384*i];
int pos = 0;
int wpos = 0;
while(pos < 16383*8) {
@@ -1590,7 +1604,7 @@ bool a2_edd_format::load(io_generic *io, uint32_t form_factor, const std::vector
generate_track_from_bitstream(i >> 2, 0, stream, len, image, i & 3);
image->set_write_splice_position(i >> 2, 0, uint32_t(uint64_t(200'000'000)*splice/len), i & 3);
}
- free(img);
+ img.reset();
image->set_form_variant(floppy_image::FF_525, floppy_image::SSSD);
@@ -1627,26 +1641,31 @@ bool a2_woz_format::supports_save() const
const uint8_t a2_woz_format::signature[8] = { 0x57, 0x4f, 0x5a, 0x31, 0xff, 0x0a, 0x0d, 0x0a };
const uint8_t a2_woz_format::signature2[8] = { 0x57, 0x4f, 0x5a, 0x32, 0xff, 0x0a, 0x0d, 0x0a };
-int a2_woz_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int a2_woz_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t header[8];
- io_generic_read(io, header, 0, 8);
+ size_t actual;
+ io.read_at(0, header, 8, actual);
if (!memcmp(header, signature, 8)) return 100;
if (!memcmp(header, signature2, 8)) return 100;
return 0;
}
-bool a2_woz_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool a2_woz_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- std::vector<uint8_t> img(io_generic_size(io));
- io_generic_read(io, &img[0], 0, img.size());
+ uint64_t image_size;
+ if(io.length(image_size))
+ return false;
+ std::vector<uint8_t> img(image_size);
+ size_t actual;
+ io.read_at(0, &img[0], img.size(), actual);
// Check signature
- if ((memcmp(&img[0], signature, 8)) && (memcmp(&img[0], signature2, 8)))
+ if((memcmp(&img[0], signature, 8)) && (memcmp(&img[0], signature2, 8)))
return false;
uint32_t woz_vers = 1;
- if (!memcmp(&img[0], signature2, 8)) woz_vers = 2;
+ if(!memcmp(&img[0], signature2, 8)) woz_vers = 2;
// Check integrity
uint32_t crc = crc32r(&img[12], img.size() - 12);
@@ -1663,7 +1682,7 @@ bool a2_woz_format::load(io_generic *io, uint32_t form_factor, const std::vector
uint32_t info_vers = r8(img, off_info + 0);
- if ((info_vers != 1) && (info_vers != 2))
+ if((info_vers != 1) && (info_vers != 2))
return false;
bool is_35 = r8(img, off_info + 1) == 2;
@@ -1721,7 +1740,7 @@ bool a2_woz_format::load(io_generic *io, uint32_t form_factor, const std::vector
return true;
}
-bool a2_woz_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool a2_woz_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
std::vector<std::vector<bool>> tracks(160);
bool twosided = false;
@@ -1823,7 +1842,8 @@ bool a2_woz_format::save(io_generic *io, const std::vector<uint32_t> &variants,
w32(data, 8, crc32r(&data[12], data.size() - 12));
- io_generic_write(io, data.data(), 0, data.size());
+ size_t actual;
+ io.write_at(0, data.data(), data.size(), actual);
return true;
}
@@ -1911,12 +1931,15 @@ bool a2_nib_format::supports_save() const
return false;
}
-int a2_nib_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int a2_nib_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- const auto size = io_generic_size(io);
- if (size == expected_size_35t || size == expected_size_40t) {
+ uint64_t size;
+ if (io.length(size))
+ return 0;
+
+ if (size == expected_size_35t || size == expected_size_40t)
return 50;
- }
+
return 0;
}
@@ -2031,18 +2054,20 @@ std::vector<uint32_t> a2_nib_format::generate_levels_from_nibbles(const std::vec
return levels;
}
-bool a2_nib_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool a2_nib_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- auto size = io_generic_size(io);
- if (size != expected_size_35t && size != expected_size_40t) {
+ uint64_t size;
+ if (io.length(size))
return false;
- }
+ if (size != expected_size_35t && size != expected_size_40t)
+ return false;
+
const auto nr_tracks = size == expected_size_35t? 35 : 40;
std::vector<uint8_t> nibbles(nibbles_per_track);
for (unsigned track = 0; track < nr_tracks; ++track) {
- io_generic_read(io, &nibbles[0],
- track * nibbles_per_track, nibbles_per_track);
+ size_t actual;
+ io.read_at(track * nibbles_per_track, &nibbles[0], nibbles_per_track, actual);
auto levels = generate_levels_from_nibbles(nibbles);
generate_track_from_levels(track, 0,
levels,
diff --git a/src/lib/formats/ap2_dsk.h b/src/lib/formats/ap2_dsk.h
index 7420d72d818..bab61cf96b8 100644
--- a/src/lib/formats/ap2_dsk.h
+++ b/src/lib/formats/ap2_dsk.h
@@ -41,9 +41,9 @@ class a2_16sect_format : public floppy_image_format_t
public:
a2_16sect_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -68,9 +68,9 @@ class a2_rwts18_format : public floppy_image_format_t
public:
a2_rwts18_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -92,8 +92,8 @@ class a2_edd_format : public floppy_image_format_t
public:
a2_edd_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override;
virtual const char *name() const override;
@@ -111,9 +111,9 @@ class a2_woz_format : public floppy_image_format_t
public:
a2_woz_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override;
virtual const char *name() const override;
@@ -141,8 +141,8 @@ class a2_nib_format : public floppy_image_format_t
public:
a2_nib_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override;
virtual const char *name() const override;
diff --git a/src/lib/formats/ap_dsk35.cpp b/src/lib/formats/ap_dsk35.cpp
index 9819406183c..6a3fa5d742b 100644
--- a/src/lib/formats/ap_dsk35.cpp
+++ b/src/lib/formats/ap_dsk35.cpp
@@ -100,6 +100,8 @@
#include "ap_dsk35.h"
+#include "ioprocs.h"
+
#include <cassert>
#include <cstdio>
@@ -1233,14 +1235,15 @@ bool dc42_format::supports_save() const
return true;
}
-int dc42_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int dc42_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint8_t h[0x54];
- uint64_t size = io_generic_size(io);
- if(size < 0x54)
+ uint64_t size;
+ if(io.length(size) || (size < 0x54))
return 0;
- io_generic_read(io, h, 0, 0x54);
+ uint8_t h[0x54];
+ size_t actual;
+ io.read_at(0, h, 0x54, actual);
uint32_t dsize = (h[0x40] << 24) | (h[0x41] << 16) | (h[0x42] << 8) | h[0x43];
uint32_t tsize = (h[0x44] << 24) | (h[0x45] << 16) | (h[0x46] << 8) | h[0x47];
@@ -1252,13 +1255,14 @@ int dc42_format::identify(io_generic *io, uint32_t form_factor, const std::vecto
return 0;
}
- return size == 0x54+tsize+dsize && h[0] < 64 && h[0x52] == 1 && h[0x53] == 0 ? 100 : 0;
+ return (size == 0x54+tsize+dsize && h[0] < 64 && h[0x52] == 1 && h[0x53] == 0) ? 100 : 0;
}
-bool dc42_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool dc42_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
uint8_t h[0x54];
- io_generic_read(io, h, 0, 0x54);
+ io.read_at(0, h, 0x54, actual);
int dsize = (h[0x40] << 24) | (h[0x41] << 16) | (h[0x42] << 8) | h[0x43];
int tsize = (h[0x44] << 24) | (h[0x45] << 16) | (h[0x46] << 8) | h[0x47];
@@ -1270,8 +1274,7 @@ bool dc42_format::load(io_generic *io, uint32_t form_factor, const std::vector<u
return false;
}
- switch (dsize)
- {
+ switch(dsize) {
case 409600: // Mac 400K
image->set_form_variant(floppy_image::FF_35, floppy_image::SSDD);
break;
@@ -1315,13 +1318,14 @@ bool dc42_format::load(io_generic *io, uint32_t form_factor, const std::vector<u
sectors[si].sector = i;
sectors[si].info = format;
if(tsize) {
- io_generic_read(io, data, pos_tag, 12);
+ io.read_at(pos_tag, data, 12, actual);
sectors[si].tag = data;
pos_tag += 12;
- } else
+ } else {
sectors[si].tag = nullptr;
+ }
sectors[si].data = data+12;
- io_generic_read(io, data+12, pos_data, 512);
+ io.read_at(pos_data, data+12, 512, actual);
pos_data += 512;
si = (si + 2) % ns;
if(si == 0)
@@ -1341,7 +1345,7 @@ void dc42_format::update_chk(const uint8_t *data, int size, uint32_t &chk)
}
}
-bool dc42_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool dc42_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int g_tracks, g_heads;
image->get_actual_geometry(g_tracks, g_heads);
@@ -1381,8 +1385,9 @@ bool dc42_format::save(io_generic *io, const std::vector<uint32_t> &variants, fl
for(unsigned int i=0; i < sectors.size(); i++) {
auto &sdata = sectors[i];
sdata.resize(512+12);
- io_generic_write(io, &sdata[0], pos_tag, 12);
- io_generic_write(io, &sdata[12], pos_data, 512);
+ size_t actual;
+ io.write_at(pos_tag, &sdata[0], 12, actual);
+ io.write_at(pos_data, &sdata[12], 512, actual);
pos_tag += 12;
pos_data += 512;
if(track || head || i)
@@ -1401,7 +1406,8 @@ bool dc42_format::save(io_generic *io, const std::vector<uint32_t> &variants, fl
h[0x4e] = tchk >> 8;
h[0x4f] = tchk;
- io_generic_write(io, h, 0, 0x54);
+ size_t actual;
+ io.write_at(0, h, 0x54, actual);
return true;
}
@@ -1432,26 +1438,32 @@ bool apple_gcr_format::supports_save() const
return true;
}
-int apple_gcr_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int apple_gcr_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return 0;
+
if(size == 409600 || (size == 819200 && (variants.empty() || has_variant(variants, floppy_image::DSDD))))
return 50;
return 0;
}
-bool apple_gcr_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool apple_gcr_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
desc_gcr_sector sectors[12];
uint8_t sdata[512*12];
int pos_data = 0;
uint8_t header[64];
- io_generic_read(io, header, 0, 64);
+ io.read_at(0, header, 64, actual);
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return false;
int head_count = size == 409600 ? 1 : size == 819200 ? 2 : 0;
image->set_form_variant(floppy_image::FF_35, head_count == 2 ? floppy_image::DSDD : floppy_image::SSDD);
@@ -1461,7 +1473,7 @@ bool apple_gcr_format::load(io_generic *io, uint32_t form_factor, const std::vec
for(int track=0; track < 80; track++) {
for(int head=0; head < head_count; head++) {
int ns = 12 - (track/16);
- io_generic_read(io, sdata, pos_data, 512*ns);
+ io.read_at(pos_data, sdata, 512*ns, actual);
pos_data += 512*ns;
int si = 0;
@@ -1482,7 +1494,7 @@ bool apple_gcr_format::load(io_generic *io, uint32_t form_factor, const std::vec
return true;
}
-bool apple_gcr_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool apple_gcr_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int g_tracks, g_heads;
image->get_actual_geometry(g_tracks, g_heads);
@@ -1498,7 +1510,8 @@ bool apple_gcr_format::save(io_generic *io, const std::vector<uint32_t> &variant
for(unsigned int i=0; i < sectors.size(); i++) {
auto &sdata = sectors[i];
sdata.resize(512+12);
- io_generic_write(io, &sdata[12], pos_data, 512);
+ size_t actual;
+ io.write_at(pos_data, &sdata[12], 512, actual);
pos_data += 512;
}
}
@@ -1534,10 +1547,11 @@ bool apple_2mg_format::supports_save() const
return true;
}
-int apple_2mg_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int apple_2mg_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t signature[4];
- io_generic_read(io, signature, 0, 4);
+ size_t actual;
+ io.read_at(0, signature, 4, actual);
if (!strncmp(reinterpret_cast<char *>(signature), "2IMG", 4))
{
return 100;
@@ -1552,11 +1566,12 @@ int apple_2mg_format::identify(io_generic *io, uint32_t form_factor, const std::
return 0;
}
-bool apple_2mg_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool apple_2mg_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
desc_gcr_sector sectors[12];
uint8_t sdata[512*12], header[64];
- io_generic_read(io, header, 0, 64);
+ io.read_at(0, header, 64, actual);
uint32_t blocks = header[0x14] | (header[0x15] << 8) | (header[0x16] << 16) | (header[0x17] << 24);
uint32_t pos_data = header[0x18] | (header[0x19] << 8) | (header[0x1a] << 16) | (header[0x1b] << 24);
@@ -1568,7 +1583,7 @@ bool apple_2mg_format::load(io_generic *io, uint32_t form_factor, const std::vec
for(int track=0; track < 80; track++) {
for(int head=0; head < 2; head++) {
int ns = 12 - (track/16);
- io_generic_read(io, sdata, pos_data, 512*ns);
+ io.read_at(pos_data, sdata, 512*ns, actual);
pos_data += 512*ns;
int si = 0;
@@ -1589,8 +1604,10 @@ bool apple_2mg_format::load(io_generic *io, uint32_t form_factor, const std::vec
return true;
}
-bool apple_2mg_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool apple_2mg_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
+
uint8_t header[0x40];
int pos_data = 0x40;
@@ -1611,7 +1628,7 @@ bool apple_2mg_format::save(io_generic *io, const std::vector<uint32_t> &variant
header[0x18] = 0x40;
// bytes of disk data
header[0x1c] = 0x00; header[0x1d] = 0x80; header[0x1e] = 0x0c; // 0xC8000 (819200)
- io_generic_write(io, header, 0, 0x40);
+ io.write_at(0, header, 0x40, actual);
for(int track=0; track < 80; track++) {
for(int head=0; head < 2; head++) {
@@ -1619,7 +1636,7 @@ bool apple_2mg_format::save(io_generic *io, const std::vector<uint32_t> &variant
for(unsigned int i=0; i < sectors.size(); i++) {
auto &sdata = sectors[i];
sdata.resize(512+12);
- io_generic_write(io, &sdata[12], pos_data, 512);
+ io.write_at(pos_data, &sdata[12], 512, actual);
pos_data += 512;
}
}
diff --git a/src/lib/formats/ap_dsk35.h b/src/lib/formats/ap_dsk35.h
index def1cb86856..f4a8ec7bff8 100644
--- a/src/lib/formats/ap_dsk35.h
+++ b/src/lib/formats/ap_dsk35.h
@@ -29,9 +29,9 @@ class dc42_format : public floppy_image_format_t
public:
dc42_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -49,9 +49,9 @@ class apple_gcr_format : public floppy_image_format_t
public:
apple_gcr_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -66,9 +66,9 @@ class apple_2mg_format : public floppy_image_format_t
public:
apple_2mg_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/apd_dsk.cpp b/src/lib/formats/apd_dsk.cpp
index 45d385a0800..f882d90fe23 100644
--- a/src/lib/formats/apd_dsk.cpp
+++ b/src/lib/formats/apd_dsk.cpp
@@ -60,9 +60,13 @@
*********************************************************************/
-#include <zlib.h>
#include "formats/apd_dsk.h"
+#include "ioprocs.h"
+
+#include <zlib.h>
+
+
static const uint8_t APD_HEADER[8] = { 'A', 'P', 'D', 'X', '0', '0', '0', '1' };
static const uint8_t GZ_HEADER[2] = { 0x1f, 0x8b };
@@ -85,11 +89,15 @@ const char *apd_format::extensions() const
return "apd";
}
-int apd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int apd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return 0;
+
std::vector<uint8_t> img(size);
- io_generic_read(io, &img[0], 0, size);
+ size_t actual;
+ io.read_at(0, &img[0], size, actual);
int err;
std::vector<uint8_t> gz_ptr(8);
@@ -123,11 +131,15 @@ int apd_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool apd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool apd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return false;
+
std::vector<uint8_t> img(size);
- io_generic_read(io, &img[0], 0, size);
+ size_t actual;
+ io.read_at(0, &img[0], size, actual);
int err;
std::vector<uint8_t> gz_ptr;
diff --git a/src/lib/formats/apd_dsk.h b/src/lib/formats/apd_dsk.h
index bc551973c4a..8c3ac6f0d42 100644
--- a/src/lib/formats/apd_dsk.h
+++ b/src/lib/formats/apd_dsk.h
@@ -23,8 +23,8 @@ public:
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override;
};
diff --git a/src/lib/formats/apollo_dsk.cpp b/src/lib/formats/apollo_dsk.cpp
index 75c31cfe7f8..a1159ac68c8 100644
--- a/src/lib/formats/apollo_dsk.cpp
+++ b/src/lib/formats/apollo_dsk.cpp
@@ -8,10 +8,11 @@
*********************************************************************/
-#include <cassert>
-
#include "formats/apollo_dsk.h"
+#include "ioprocs.h"
+
+
apollo_format::apollo_format() : upd765_format(formats)
{
}
@@ -46,10 +47,13 @@ const apollo_format::format apollo_format::formats[] = {
const floppy_format_type FLOPPY_APOLLO_FORMAT = &floppy_image_format_creator<apollo_format>;
-int apollo_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int apollo_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
- uint32_t expected_size = 77*2*8*1024;
+ uint64_t size;
+ if (io.length(size))
+ return 0;
+
+ constexpr uint32_t expected_size = 77*2*8*1024;
return ((size == expected_size) || (size == 0)) ? 1 : 0;
}
diff --git a/src/lib/formats/apollo_dsk.h b/src/lib/formats/apollo_dsk.h
index 6376c77b067..1c2c6d81030 100644
--- a/src/lib/formats/apollo_dsk.h
+++ b/src/lib/formats/apollo_dsk.h
@@ -19,7 +19,7 @@ class apollo_format : public upd765_format
public:
apollo_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual const char *name() const override;
virtual const char *description() const override;
virtual const char *extensions() const override;
diff --git a/src/lib/formats/apridisk.cpp b/src/lib/formats/apridisk.cpp
index 388d358f6f8..1560c199149 100644
--- a/src/lib/formats/apridisk.cpp
+++ b/src/lib/formats/apridisk.cpp
@@ -12,6 +12,8 @@
#include "imageutl.h"
+#include "ioprocs.h"
+
apridisk_format::apridisk_format()
{
@@ -32,10 +34,11 @@ const char *apridisk_format::extensions() const
return "dsk";
}
-int apridisk_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int apridisk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t header[APR_HEADER_SIZE];
- io_generic_read(io, header, 0, APR_HEADER_SIZE);
+ size_t actual;
+ io.read_at(0, header, APR_HEADER_SIZE, actual);
const char magic[] = "ACT Apricot disk image\x1a\x04";
@@ -45,21 +48,26 @@ int apridisk_format::identify(io_generic *io, uint32_t form_factor, const std::v
return 0;
}
-bool apridisk_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool apridisk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
desc_pc_sector sectors[80][2][18];
std::unique_ptr<uint8_t []> sector_data(new uint8_t [MAX_SECTORS * SECTOR_SIZE]);
uint8_t *data_ptr = sector_data.get();
int track_count = 0, head_count = 0, sector_count = 0;
- uint64_t file_size = io_generic_size(io);
+ uint64_t file_size;
+ if (io.length(file_size))
+ return false;
+
uint64_t file_offset = APR_HEADER_SIZE;
while (file_offset < file_size)
{
+ size_t actual;
+
// read sector header
uint8_t sector_header[16];
- io_generic_read(io, sector_header, file_offset, 16);
+ io.read_at(file_offset, sector_header, 16, actual);
uint32_t type = pick_integer_le(&sector_header, 0, 4);
uint16_t compression = pick_integer_le(&sector_header, 4, 2);
@@ -94,7 +102,7 @@ bool apridisk_format::load(io_generic *io, uint32_t form_factor, const std::vect
case APR_COMPRESSED:
{
uint8_t comp[3];
- io_generic_read(io, comp, file_offset, 3);
+ io.read_at(file_offset, comp, 3, actual);
uint16_t length = pick_integer_le(comp, 0, 2);
if (length != SECTOR_SIZE)
@@ -108,7 +116,7 @@ bool apridisk_format::load(io_generic *io, uint32_t form_factor, const std::vect
break;
case APR_UNCOMPRESSED:
- io_generic_read(io, data_ptr, file_offset, SECTOR_SIZE);
+ io.read_at(file_offset, data_ptr, SECTOR_SIZE, actual);
break;
default:
@@ -140,7 +148,7 @@ bool apridisk_format::load(io_generic *io, uint32_t form_factor, const std::vect
return true;
}
-bool apridisk_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool apridisk_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
return false;
}
diff --git a/src/lib/formats/apridisk.h b/src/lib/formats/apridisk.h
index 3e751f8d6ec..5cc8a1403fb 100644
--- a/src/lib/formats/apridisk.h
+++ b/src/lib/formats/apridisk.h
@@ -23,9 +23,9 @@ public:
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override;
private:
diff --git a/src/lib/formats/cassimg.cpp b/src/lib/formats/cassimg.cpp
index cf5812c67c1..2fab4a1ec8b 100644
--- a/src/lib/formats/cassimg.cpp
+++ b/src/lib/formats/cassimg.cpp
@@ -199,12 +199,15 @@ cassette_image::error cassette_image::lookup_sample(int channel, size_t sample,
-cassette_image::cassette_image(const Format *format, void *file, const io_procs *procs, int flags)
+cassette_image::cassette_image(const Format *format, util::random_read_write::ptr &&io, int flags) :
+ m_format(format),
+ m_io(std::move(io)),
+ m_channels(0),
+ m_flags(flags),
+ m_sample_frequency(0),
+ m_blocks(),
+ m_sample_count(0)
{
- m_format = format;
- m_io.file = file;
- m_io.procs = procs;
- m_flags = flags;
}
@@ -217,17 +220,24 @@ cassette_image::~cassette_image()
-cassette_image::error cassette_image::open(void *file, const io_procs *procs,
- const Format *format, int flags, ptr &outcassette)
+cassette_image::error cassette_image::open(
+ util::random_read_write::ptr &&io,
+ const Format *format,
+ int flags,
+ ptr &outcassette)
{
const Format *const formats[2] = { format, nullptr };
- return open_choices(file, procs, {}, formats, flags, outcassette);
+ return open_choices(std::move(io), { }, formats, flags, outcassette);
}
-cassette_image::error cassette_image::open_choices(void *file, const io_procs *procs, const std::string &extension,
- const Format *const *formats, int flags, ptr &outcassette)
+cassette_image::error cassette_image::open_choices(
+ util::random_read_write::ptr &&io,
+ const std::string &extension,
+ const Format *const *formats,
+ int flags,
+ ptr &outcassette)
{
// if not specified, use the dummy arguments
if (!formats)
@@ -235,7 +245,7 @@ cassette_image::error cassette_image::open_choices(void *file, const io_procs *p
// create the cassette object
ptr cassette;
- try { cassette.reset(new cassette_image(nullptr, file, procs, flags)); }
+ try { cassette.reset(new cassette_image(nullptr, std::move(io), flags)); }
catch (std::bad_alloc const &) { return error::OUT_OF_MEMORY; }
// identify the image
@@ -275,8 +285,12 @@ cassette_image::error cassette_image::open_choices(void *file, const io_procs *p
-cassette_image::error cassette_image::create(void *file, const io_procs *procs, const Format *format,
- const Options *opts, int flags, ptr &outcassette)
+cassette_image::error cassette_image::create(
+ util::random_read_write::ptr &&io,
+ const Format *format,
+ const Options *opts,
+ int flags,
+ ptr &outcassette)
{
static const Options default_options = { 1, 16, 44100 };
@@ -294,7 +308,7 @@ cassette_image::error cassette_image::create(void *file, const io_procs *procs,
// create the cassette object
ptr cassette;
- try { cassette.reset(new cassette_image(format, file, procs, flags)); }
+ try { cassette.reset(new cassette_image(format, std::move(io), flags)); }
catch (std::bad_alloc const &) { return error::OUT_OF_MEMORY; }
// read the options
@@ -334,13 +348,13 @@ cassette_image::Info cassette_image::get_info() const
-void cassette_image::change(void *file, const io_procs *procs, const Format *format, int flags)
+void cassette_image::change(util::random_read_write::ptr &&io, const Format *format, int flags)
{
- if ((flags & FLAG_READONLY) == 0)
+ if (!(flags & FLAG_READONLY))
flags |= CASSETTE_FLAG_DIRTY;
- m_io.file = file;
- m_io.procs = procs;
+
m_format = format;
+ m_io = std::move(io);
m_flags = flags;
}
@@ -352,7 +366,8 @@ void cassette_image::change(void *file, const io_procs *procs, const Format *for
void cassette_image::image_read(void *buffer, uint64_t offset, size_t length)
{
- io_generic_read(&m_io, buffer, offset, length);
+ size_t actual;
+ m_io->read_at(offset, buffer, length, actual);
}
@@ -360,7 +375,7 @@ void cassette_image::image_read(void *buffer, uint64_t offset, size_t length)
uint8_t cassette_image::image_read_byte(uint64_t offset)
{
uint8_t data;
- io_generic_read(&m_io, &data, offset, 1);
+ image_read(&data, offset, 1);
return data;
}
@@ -368,14 +383,17 @@ uint8_t cassette_image::image_read_byte(uint64_t offset)
void cassette_image::image_write(const void *buffer, uint64_t offset, size_t length)
{
- io_generic_write(&m_io, buffer, offset, length);
+ size_t actual;
+ m_io->write_at(offset, buffer, length, actual);
}
uint64_t cassette_image::image_size()
{
- return io_generic_size(&m_io);
+ uint64_t size = 0;
+ m_io->length(size);
+ return size;
}
@@ -900,20 +918,19 @@ done:
void cassette_image::dump(const char *filename)
{
- FILE *f = fopen(filename, "wb");
- if (!f)
+ util::random_read_write::ptr saved_io = util::stdio_read_write(fopen(filename, "wb"), 0);
+ if (!saved_io)
return;
- io_generic saved_io = m_io;
- const Format *saved_format = m_format;
+ Format const *const saved_format = m_format;
- m_io.file = f;
- m_io.procs = &stdio_ioprocs_noclose;
+ using std::swap;
+
+ swap(m_io, saved_io);
m_format = &wavfile_format;
+
perform_save();
- m_io = saved_io;
+ swap(m_io, saved_io);
m_format = saved_format;
-
- fclose(f);
}
diff --git a/src/lib/formats/cassimg.h b/src/lib/formats/cassimg.h
index 3a59870571a..765b860b659 100644
--- a/src/lib/formats/cassimg.h
+++ b/src/lib/formats/cassimg.h
@@ -185,14 +185,14 @@ public:
void dump(const char *filename);
error save();
- void change(void *file, const io_procs *procs, const Format *format, int flags);
+ void change(util::random_read_write::ptr &&io, const Format *format, int flags);
Info get_info() const;
- static error open(void *file, const io_procs *procs,
+ static error open(util::random_read_write::ptr &&io,
const Format *format, int flags, ptr &outcassette);
- static error open_choices(void *file, const io_procs *procs, const std::string &extension,
+ static error open_choices(util::random_read_write::ptr &&io, const std::string &extension,
const Format *const *formats, int flags, ptr &outcassette);
- static error create(void *file, const io_procs *procs, const cassette_image::Format *format,
+ static error create(util::random_read_write::ptr &&io, const cassette_image::Format *format,
const cassette_image::Options *opts, int flags, ptr &outcassette);
// builtin formats
@@ -201,7 +201,7 @@ public:
private:
struct manipulation_ranges;
- cassette_image(const Format *format, void *file, const io_procs *procs, int flags);
+ cassette_image(const Format *format, util::random_read_write::ptr &&io, int flags);
cassette_image(const cassette_image &) = delete;
cassette_image(cassette_image &&) = delete;
cassette_image &operator=(const cassette_image &) = delete;
@@ -212,15 +212,15 @@ private:
error compute_manipulation_ranges(int channel, double time_index, double sample_period, manipulation_ranges &ranges) const;
error lookup_sample(int channel, size_t sample, int32_t *&ptr);
- const Format *m_format = nullptr;
- io_generic m_io;
+ const Format *m_format;
+ util::random_read_write::ptr m_io;
- int m_channels = 0;
- int m_flags = 0;
- uint32_t m_sample_frequency = 0;
+ int m_channels;
+ int m_flags;
+ uint32_t m_sample_frequency;
std::vector<std::unique_ptr<int32_t []> > m_blocks;
- size_t m_sample_count = 0;
+ size_t m_sample_count;
};
/* macros for specifying format lists */
diff --git a/src/lib/formats/ccvf_dsk.cpp b/src/lib/formats/ccvf_dsk.cpp
index bba52d3922a..6ed0c14038a 100644
--- a/src/lib/formats/ccvf_dsk.cpp
+++ b/src/lib/formats/ccvf_dsk.cpp
@@ -11,6 +11,7 @@
#include "formats/ccvf_dsk.h"
#include "coretmpl.h" // BIT
+#include "ioprocs.h"
ccvf_format::ccvf_format()
@@ -46,12 +47,12 @@ const ccvf_format::format ccvf_format::file_formats[] = {
{}
};
-int ccvf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int ccvf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
char h[36];
-
- io_generic_read(io, h, 0, 36);
- if(!memcmp(h, "Compucolor Virtual Floppy Disk Image", 36))
+ size_t actual;
+ io.read_at(0, h, 36, actual);
+ if (!memcmp(h, "Compucolor Virtual Floppy Disk Image", 36))
return 100;
return 0;
@@ -87,13 +88,17 @@ floppy_image_format_t::desc_e* ccvf_format::get_desc_8n1(const format &f, int &c
return desc;
}
-bool ccvf_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool ccvf_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
const format &f = formats[0];
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return false;
+
std::vector<uint8_t> img(size);
- io_generic_read(io, &img[0], 0, size);
+ size_t actual;
+ io.read_at(0, &img[0], size, actual);
std::string ccvf = std::string((const char *)&img[0], size);
std::vector<uint8_t> bytes(78720);
diff --git a/src/lib/formats/ccvf_dsk.h b/src/lib/formats/ccvf_dsk.h
index 5895a882550..92f04e03ddd 100644
--- a/src/lib/formats/ccvf_dsk.h
+++ b/src/lib/formats/ccvf_dsk.h
@@ -39,8 +39,8 @@ public:
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override;
protected:
diff --git a/src/lib/formats/concept_dsk.cpp b/src/lib/formats/concept_dsk.cpp
index 67c8562e1c3..7f5edce3363 100644
--- a/src/lib/formats/concept_dsk.cpp
+++ b/src/lib/formats/concept_dsk.cpp
@@ -10,11 +10,11 @@
*********************************************************************/
-#include <cassert>
-
-#include "flopimg.h"
#include "formats/concept_dsk.h"
+#include "ioprocs.h"
+
+
/* 9 sectors / track, 512 bytes per sector */
const floppy_image_format_t::desc_e cc525dsdd_format::cc_9_desc[] = {
{ MFM, 0x4e, 80 },
@@ -72,50 +72,50 @@ bool cc525dsdd_format::supports_save() const
return true;
}
-void cc525dsdd_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
+void cc525dsdd_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
{
- uint64_t size = io_generic_size(io);
-
track_count = 77;
head_count = 2;
sector_count = 9;
- uint32_t expected_size = 512 * track_count*head_count*sector_count;
- if (size == expected_size)
- {
+ uint32_t const expected_size = 512 * track_count*head_count*sector_count;
+
+ uint64_t size;
+ if (!io.length(size) && (size == expected_size))
return;
- }
track_count = head_count = sector_count = 0;
}
-int cc525dsdd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int cc525dsdd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t track_count, head_count, sector_count;
find_size(io, track_count, head_count, sector_count);
- if(track_count)
+ if (track_count)
return 50;
+
return 0;
}
-bool cc525dsdd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool cc525dsdd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint8_t track_count, head_count, sector_count;
find_size(io, track_count, head_count, sector_count);
uint8_t sectdata[10*512];
desc_s sectors[10];
- for(int i=0; i<sector_count; i++) {
+ for (int i=0; i<sector_count; i++) {
sectors[i+1].data = sectdata + 512*i;
sectors[i+1].size = 512;
sectors[i+1].sector_id = i+1;
}
int track_size = sector_count*512;
- for(int track=0; track < track_count; track++) {
- for(int head=0; head < head_count; head++) {
- io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size);
+ for (int track=0; track < track_count; track++) {
+ for (int head=0; head < head_count; head++) {
+ size_t actual;
+ io.read_at((track*head_count + head) * track_size, sectdata, track_size, actual);
generate_track(cc_9_desc, track, head, sectors, sector_count, 100000, image);
}
}
@@ -125,28 +125,29 @@ bool cc525dsdd_format::load(io_generic *io, uint32_t form_factor, const std::vec
return true;
}
-bool cc525dsdd_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool cc525dsdd_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int track_count, head_count, sector_count;
get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);
- if(track_count != 77)
+ if (track_count != 77)
track_count = 77;
// Happens for a fully unformatted floppy
- if(!head_count)
+ if (!head_count)
head_count = 2;
- if(sector_count != 9)
+ if (sector_count != 9)
sector_count = 9;
uint8_t sectdata[9*512];
int track_size = sector_count*512;
- for(int track=0; track < track_count; track++) {
- for(int head=0; head < head_count; head++) {
+ for (int track=0; track < track_count; track++) {
+ for (int head=0; head < head_count; head++) {
get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
- io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size);
+ size_t actual;
+ io.write_at((track*head_count + head)*track_size, sectdata, track_size, actual);
}
}
diff --git a/src/lib/formats/concept_dsk.h b/src/lib/formats/concept_dsk.h
index 58d4e1c52b3..36e3f790a84 100644
--- a/src/lib/formats/concept_dsk.h
+++ b/src/lib/formats/concept_dsk.h
@@ -17,9 +17,9 @@ class cc525dsdd_format : public floppy_image_format_t
public:
cc525dsdd_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -29,7 +29,7 @@ public:
static const desc_e cc_9_desc[];
private:
- void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
+ void find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
};
extern const floppy_format_type FLOPPY_CONCEPT_525DSDD_FORMAT;
diff --git a/src/lib/formats/coupedsk.cpp b/src/lib/formats/coupedsk.cpp
index 16842583855..9400cd41bb6 100644
--- a/src/lib/formats/coupedsk.cpp
+++ b/src/lib/formats/coupedsk.cpp
@@ -8,10 +8,10 @@
**************************************************************************/
-#include <cassert>
+#include "coupedsk.h"
+
+#include "ioprocs.h"
-#include "formats/coupedsk.h"
-#include "flopimg.h"
const floppy_image_format_t::desc_e mgt_format::desc_10[] = {
{ MFM, 0x4e, 60 },
@@ -64,9 +64,11 @@ bool mgt_format::supports_save() const
return true;
}
-int mgt_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int mgt_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return 0;
if(/*size == 737280 || */ size == 819200)
return 50;
@@ -74,10 +76,12 @@ int mgt_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool mgt_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool mgt_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint64_t size = io_generic_size(io);
- int sector_count = size == 737280 ? 9 : 10;
+ uint64_t size;
+ if(io.length(size))
+ return false;
+ int const sector_count = (size == 737280) ? 9 : 10;
uint8_t sectdata[10*512];
desc_s sectors[10];
@@ -90,7 +94,8 @@ bool mgt_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
int track_size = sector_count*512;
for(int head=0; head < 2; head++) {
for(int track=0; track < 80; track++) {
- io_generic_read(io, sectdata, (track*2+head)*track_size, track_size);
+ size_t actual;
+ io.read_at((track*2+head)*track_size, sectdata, track_size, actual);
generate_track(desc_10, track, head, sectors, sector_count+1, 100000, image);
}
}
@@ -99,7 +104,7 @@ bool mgt_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return true;
}
-bool mgt_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool mgt_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int track_count, head_count, sector_count;
get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);
@@ -115,7 +120,8 @@ bool mgt_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
for(int head=0; head < 2; head++) {
for(int track=0; track < 80; track++) {
get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
- io_generic_write(io, sectdata, (track*2+head)*track_size, track_size);
+ size_t actual;
+ io.write_at((track*2+head)*track_size, sectdata, track_size, actual);
}
}
diff --git a/src/lib/formats/coupedsk.h b/src/lib/formats/coupedsk.h
index 3700d3e9974..e9ef4b118ca 100644
--- a/src/lib/formats/coupedsk.h
+++ b/src/lib/formats/coupedsk.h
@@ -19,9 +19,9 @@ class mgt_format : public floppy_image_format_t
public:
mgt_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/cqm_dsk.cpp b/src/lib/formats/cqm_dsk.cpp
index 5f79a4d3694..6639e50f801 100644
--- a/src/lib/formats/cqm_dsk.cpp
+++ b/src/lib/formats/cqm_dsk.cpp
@@ -8,9 +8,12 @@
*********************************************************************/
+#include "cqm_dsk.h"
+
+#include "ioprocs.h"
+
#include <cstring>
-#include <cassert>
-#include "flopimg.h"
+
#define CQM_HEADER_SIZE 133
@@ -231,17 +234,6 @@ FLOPPY_CONSTRUCT( cqm_dsk_construct )
-
-/*********************************************************************
-
- formats/cqm_dsk.c
-
- CopyQM disk images
-
-*********************************************************************/
-
-#include "cqm_dsk.h"
-
cqm_format::cqm_format()
{
}
@@ -261,10 +253,11 @@ const char *cqm_format::extensions() const
return "cqm,cqi,dsk";
}
-int cqm_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int cqm_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t h[3];
- io_generic_read(io, h, 0, 3);
+ size_t actual;
+ io.read_at(0, h, 3, actual);
if (h[0] == 'C' && h[1] == 'Q' && h[2] == 0x14)
return 100;
@@ -272,12 +265,13 @@ int cqm_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool cqm_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool cqm_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
const int max_size = 4*1024*1024; // 4MB ought to be large enough for any floppy
std::vector<uint8_t> imagebuf(max_size);
uint8_t header[CQM_HEADER_SIZE];
- io_generic_read(io, header, 0, CQM_HEADER_SIZE);
+ io.read_at(0, header, CQM_HEADER_SIZE, actual);
int sector_size = (header[0x04] << 8) | header[0x03];
int sector_per_track = (header[0x11] << 8) | header[0x10];
@@ -318,9 +312,11 @@ bool cqm_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
int rpm = form_factor == floppy_image::FF_8 || (form_factor == floppy_image::FF_525 && rate >= 300000) ? 360 : 300;
int base_cell_count = rate*60/rpm;
- int cqm_size = io_generic_size(io);
+ uint64_t cqm_size;
+ if (io.length(cqm_size))
+ return false;
std::vector<uint8_t> cqmbuf(cqm_size);
- io_generic_read(io, &cqmbuf[0], 0, cqm_size);
+ io.read_at(0, &cqmbuf[0], cqm_size, actual);
// decode the RLE data
for (int s = 0, pos = CQM_HEADER_SIZE + comment_size; pos < cqm_size; )
@@ -369,7 +365,7 @@ bool cqm_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return true;
}
-bool cqm_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool cqm_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
return false;
}
diff --git a/src/lib/formats/cqm_dsk.h b/src/lib/formats/cqm_dsk.h
index 183c0b83e68..fc8376a2b85 100644
--- a/src/lib/formats/cqm_dsk.h
+++ b/src/lib/formats/cqm_dsk.h
@@ -19,9 +19,9 @@ class cqm_format : public floppy_image_format_t
public:
cqm_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/d64_dsk.cpp b/src/lib/formats/d64_dsk.cpp
index 4819ecc68d2..149130f0b3c 100644
--- a/src/lib/formats/d64_dsk.cpp
+++ b/src/lib/formats/d64_dsk.cpp
@@ -12,6 +12,8 @@
#include "formats/d64_dsk.h"
+#include "ioprocs.h"
+
d64_format::d64_format()
{
@@ -79,9 +81,12 @@ const int d64_format::speed_zone[] =
0, 0 // 41-42
};
-int d64_format::find_size(io_generic *io, uint32_t form_factor) const
+int d64_format::find_size(util::random_read &io, uint32_t form_factor) const
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return 0;
+
for(int i=0; formats[i].sector_count; i++) {
const format &f = formats[i];
if(size == (uint32_t) f.sector_count*f.sector_base_size*f.head_count)
@@ -89,12 +94,13 @@ int d64_format::find_size(io_generic *io, uint32_t form_factor) const
if(size == (uint32_t) (f.sector_count*f.sector_base_size*f.head_count) + f.sector_count)
return i;
}
+
return -1;
}
-int d64_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int d64_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- int type = find_size(io, form_factor);
+ const int type = find_size(io, form_factor);
if (type != -1)
return 50;
@@ -114,10 +120,11 @@ int d64_format::get_disk_id_offset(const format &f)
return 0x165a2;
}
-void d64_format::get_disk_id(const format &f, io_generic *io, uint8_t &id1, uint8_t &id2)
+void d64_format::get_disk_id(const format &f, util::random_read &io, uint8_t &id1, uint8_t &id2)
{
uint8_t id[2];
- io_generic_read(io, id, get_disk_id_offset(f), 2);
+ size_t actual;
+ io.read_at(get_disk_id_offset(f), id, 2, actual);
id1 = id[0];
id2 = id[1];
}
@@ -206,7 +213,7 @@ void d64_format::fix_end_gap(floppy_image_format_t::desc_e* desc, int remaining_
desc[22].p1 >>= remaining_size & 0x01;
}
-bool d64_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool d64_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
int type = find_size(io, form_factor);
if(type == -1)
@@ -214,7 +221,9 @@ bool d64_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
const format &f = formats[type];
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return false;
std::vector<uint8_t> img;
if(size == (uint32_t)f.sector_count*f.sector_base_size) {
@@ -225,7 +234,8 @@ bool d64_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
img.resize(size);
}
- io_generic_read(io, &img[0], 0, size);
+ size_t actual;
+ io.read_at(0, &img[0], size, actual);
int track_offset = 0, error_offset = f.sector_count*f.sector_base_size;
@@ -266,7 +276,7 @@ bool d64_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return true;
}
-bool d64_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool d64_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
const format &f = formats[0];
@@ -280,7 +290,8 @@ bool d64_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
build_sector_description(f, sectdata, 0, 0, sectors, sector_count);
extract_sectors(image, f, sectors, track, head, sector_count);
- io_generic_write(io, sectdata, offset, track_size);
+ size_t actual;
+ io.write_at(offset, sectdata, track_size, actual);
}
}
diff --git a/src/lib/formats/d64_dsk.h b/src/lib/formats/d64_dsk.h
index 665f6489a81..13f1bd4e91c 100644
--- a/src/lib/formats/d64_dsk.h
+++ b/src/lib/formats/d64_dsk.h
@@ -37,9 +37,9 @@ public:
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override { return true; }
protected:
@@ -61,12 +61,12 @@ protected:
const format *formats;
- int find_size(io_generic *io, uint32_t form_factor) const;
+ int find_size(util::random_read &io, uint32_t form_factor) const;
virtual int get_physical_track(const format &f, int head, int track);
virtual uint32_t get_cell_size(const format &f, int track);
virtual int get_sectors_per_track(const format &f, int track);
virtual int get_disk_id_offset(const format &f);
- void get_disk_id(const format &f, io_generic *io, uint8_t &id1, uint8_t &id2);
+ void get_disk_id(const format &f, util::random_read &io, uint8_t &id1, uint8_t &id2);
virtual int get_image_offset(const format &f, int head, int track);
int compute_track_size(const format &f, int track);
virtual int get_gap2(const format &f, int head, int track) { return f.gap_2; }
diff --git a/src/lib/formats/d80_dsk.cpp b/src/lib/formats/d80_dsk.cpp
index d350411b159..338f00292a9 100644
--- a/src/lib/formats/d80_dsk.cpp
+++ b/src/lib/formats/d80_dsk.cpp
@@ -8,10 +8,11 @@
*********************************************************************/
-#include <cassert>
-
#include "formats/d80_dsk.h"
+#include "ioprocs.h"
+
+
d80_format::d80_format() : d64_format(file_formats), formats(nullptr)
{
}
diff --git a/src/lib/formats/d88_dsk.cpp b/src/lib/formats/d88_dsk.cpp
index 7c4eaa079dc..6e29f10df6a 100644
--- a/src/lib/formats/d88_dsk.cpp
+++ b/src/lib/formats/d88_dsk.cpp
@@ -29,11 +29,12 @@
*
*/
- #include <cassert>
-
#include "flopimg.h"
#include "imageutl.h"
+#include "ioprocs.h"
+
+
#define D88_HEADER_LEN 0x2b0
struct d88_tag
@@ -414,12 +415,15 @@ const char *d88_format::extensions() const
return "d77,d88,1dd";
}
-int d88_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int d88_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
- uint8_t h[32];
+ uint64_t size;
+ if(io.length(size))
+ return 0;
- io_generic_read(io, h, 0, 32);
+ uint8_t h[32];
+ size_t actual;
+ io.read_at(0, h, 32, actual);
if((little_endianize_int32(*(uint32_t *)(h+0x1c)) == size) &&
(h[0x1b] == 0x00 || h[0x1b] == 0x10 || h[0x1b] == 0x20 || h[0x1b] == 0x30 || h[0x1b] == 0x40))
return 100;
@@ -427,11 +431,12 @@ int d88_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool d88_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool d88_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint8_t h[32];
+ size_t actual;
- io_generic_read(io, h, 0, 32);
+ uint8_t h[32];
+ io.read_at(0, h, 32, actual);
int cell_count = 0;
int track_count = 0;
@@ -477,9 +482,11 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return false;
uint32_t track_pos[164];
- io_generic_read(io, track_pos, 32, 164*4);
+ io.read_at(32, track_pos, 164*4, actual);
- uint64_t file_size = io_generic_size(io);
+ uint64_t file_size;
+ if(io.length(file_size))
+ return false;
for(int track=0; track < track_count; track++)
for(int head=0; head < head_count; head++) {
@@ -496,7 +503,7 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return true;
uint8_t hs[16];
- io_generic_read(io, hs, pos, 16);
+ io.read_at(pos, hs, 16, actual);
pos += 16;
uint16_t size = little_endianize_int16(*(uint16_t *)(hs+14));
@@ -521,7 +528,7 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
if(size) {
sects[i].data = sect_data + sdatapos;
- io_generic_read(io, sects[i].data, pos, size);
+ io.read_at(pos, sects[i].data, size, actual);
pos += size;
sdatapos += size;
@@ -536,7 +543,7 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
}
-bool d88_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool d88_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
return false;
}
diff --git a/src/lib/formats/d88_dsk.h b/src/lib/formats/d88_dsk.h
index c7c85fc1949..aeed5ed16e8 100644
--- a/src/lib/formats/d88_dsk.h
+++ b/src/lib/formats/d88_dsk.h
@@ -20,9 +20,9 @@ class d88_format : public floppy_image_format_t
public:
d88_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/dcp_dsk.cpp b/src/lib/formats/dcp_dsk.cpp
index b3beb40404f..7d419628bdc 100644
--- a/src/lib/formats/dcp_dsk.cpp
+++ b/src/lib/formats/dcp_dsk.cpp
@@ -20,10 +20,11 @@
*********************************************************************/
-#include <cassert>
-
#include "dcp_dsk.h"
+#include "ioprocs.h"
+
+
dcp_format::dcp_format()
{
}
@@ -43,14 +44,18 @@ const char *dcp_format::extensions() const
return "dcp,dcu";
}
-int dcp_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int dcp_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return 0;
+
uint8_t h[0xa2];
int heads, tracks, spt, bps, count_tracks = 0;
bool is_hdb = false;
- io_generic_read(io, h, 0, 0xa2);
+ size_t actual;
+ io.read_at(0, h, 0xa2, actual);
// First byte is the disk format (see below in load() for details)
switch (h[0])
@@ -112,13 +117,14 @@ int dcp_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool dcp_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool dcp_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
uint8_t h[0xa2];
int heads, tracks, spt, bps;
bool is_hdb = false;
- io_generic_read(io, h, 0, 0xa2);
+ io.read_at(0, h, 0xa2, actual);
// First byte is the disk format:
switch (h[0])
@@ -215,7 +221,7 @@ bool dcp_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
for (int track = 0; track < tracks; track++)
for (int head = 0; head < heads; head++)
{
- io_generic_read(io, sect_data, 0xa2 + bps * spt * (track * heads + head), bps * spt);
+ io.read_at(0xa2 + bps * spt * (track * heads + head), sect_data, bps * spt, actual);
for (int i = 0; i < spt; i++)
{
@@ -235,7 +241,7 @@ bool dcp_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
else // FIXME: the code below is untested, because no image was found... there might be some silly mistake in the disk geometry!
{
// Read Head 0 Track 0 is FM with 26 sectors of 128bytes instead of 256
- io_generic_read(io, sect_data, 0xa2, 128 * spt);
+ io.read_at(0xa2, sect_data, 128 * spt, actual);
for (int i = 0; i < spt; i++)
{
@@ -252,7 +258,7 @@ bool dcp_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
build_pc_track_fm(0, 0, image, cell_count, spt, sects, calc_default_pc_gap3_size(form_factor, 128));
// Read Head 1 Track 0 is MFM with 26 sectors of 256bytes
- io_generic_read(io, sect_data, 0xa2 + 128 * spt, bps * spt);
+ io.read_at(0xa2 + 128 * spt, sect_data, bps * spt, actual);
for (int i = 0; i < spt; i++)
{
@@ -273,7 +279,7 @@ bool dcp_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
for (int track = 1; track < tracks; track++)
for (int head = 0; head < heads; head++)
{
- io_generic_read(io, sect_data, data_offs + bps * spt * ((track - 1) * heads + head), bps * spt);
+ io.read_at(data_offs + bps * spt * ((track - 1) * heads + head), sect_data, bps * spt, actual);
for (int i = 0; i < spt; i++)
{
diff --git a/src/lib/formats/dcp_dsk.h b/src/lib/formats/dcp_dsk.h
index c06396d527e..716814ffd48 100644
--- a/src/lib/formats/dcp_dsk.h
+++ b/src/lib/formats/dcp_dsk.h
@@ -20,8 +20,8 @@ class dcp_format : public floppy_image_format_t
public:
dcp_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/dfi_dsk.cpp b/src/lib/formats/dfi_dsk.cpp
index 409797e9583..607be56f741 100644
--- a/src/lib/formats/dfi_dsk.cpp
+++ b/src/lib/formats/dfi_dsk.cpp
@@ -13,7 +13,8 @@
#include "dfi_dsk.h"
-#include <zlib.h>
+#include "ioprocs.h"
+
#define NUMBER_OF_MULTIREADS 3
// thresholds for brickwall windowing
@@ -56,24 +57,28 @@ bool dfi_format::supports_save() const
return false;
}
-int dfi_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int dfi_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
char sign[4];
- io_generic_read(io, sign, 0, 4);
+ size_t actual;
+ io.read_at(0, sign, 4, actual);
return memcmp(sign, "DFE2", 4) ? 0 : 100;
}
-bool dfi_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool dfi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
char sign[4];
- io_generic_read(io, sign, 0, 4);
- if (memcmp(sign, "DFER", 4) == 0)
- {
+ io.read_at(0, sign, 4, actual);
+ if(memcmp(sign, "DFER", 4) == 0) {
osd_printf_error("dfi_dsk: Old type Discferret image detected; the mess Discferret decoder will not handle this properly, bailing out!\n");
return false;
}
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return false;
+
uint64_t pos = 4;
std::vector<uint8_t> data;
int onerev_time = 0; // time for one revolution, used to guess clock and rpm for DFE2 files
@@ -81,7 +86,7 @@ bool dfi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
int rpm=360; // drive rpm
while(pos < size) {
uint8_t h[10];
- io_generic_read(io, h, pos, 10);
+ io.read_at(pos, h, 10, actual);
uint16_t track = (h[0] << 8) | h[1];
uint16_t head = (h[2] << 8) | h[3];
// Ignore sector
@@ -97,7 +102,7 @@ bool dfi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
data.resize(tsize);
pos += 10; // skip the header, we already read it
- io_generic_read(io, &data[0], pos, tsize);
+ io.read_at(pos, &data[0], tsize, actual);
pos += tsize; // for next time we read, increment to the beginning of next header
int index_time = 0; // what point the last index happened
diff --git a/src/lib/formats/dfi_dsk.h b/src/lib/formats/dfi_dsk.h
index d727f1d3c06..71b69c43d70 100644
--- a/src/lib/formats/dfi_dsk.h
+++ b/src/lib/formats/dfi_dsk.h
@@ -12,9 +12,9 @@ class dfi_format : public floppy_image_format_t
public:
dfi_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- // virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image);
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ // virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image);
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/dim_dsk.cpp b/src/lib/formats/dim_dsk.cpp
index 964f19ce028..04f6e3b8995 100644
--- a/src/lib/formats/dim_dsk.cpp
+++ b/src/lib/formats/dim_dsk.cpp
@@ -8,12 +8,14 @@
*********************************************************************/
-#include <cstring>
-#include <cassert>
-
#include "dim_dsk.h"
#include "basicdsk.h"
+#include "ioprocs.h"
+
+#include <cstring>
+
+
FLOPPY_IDENTIFY(dim_dsk_identify)
{
uint8_t dim_header[16];
@@ -132,11 +134,12 @@ const char *dim_format::extensions() const
return "dim";
}
-int dim_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int dim_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t h[16];
- io_generic_read(io, h, 0xab, 16);
+ size_t actual;
+ io.read_at(0xab, h, 16, actual);
if(strncmp((const char *)h, "DIFC HEADER", 11) == 0)
return 100;
@@ -144,14 +147,15 @@ int dim_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool dim_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool dim_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
int offset = 0x100;
uint8_t h;
uint8_t track_total = 77;
int cell_count = form_factor == floppy_image::FF_35 ? 200000 : 166666;
- io_generic_read(io, &h, 0, 1);
+ io.read_at(0, &h, 1, actual);
int spt, gap3, bps, size;
switch(h) {
@@ -211,7 +215,7 @@ bool dim_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
sects[i].deleted = false;
sects[i].bad_crc = false;
sects[i].data = &sect_data[sdatapos];
- io_generic_read(io, sects[i].data, offset, bps);
+ io.read_at(offset, sects[i].data, bps, actual);
offset += bps;
sdatapos += bps;
}
@@ -223,7 +227,7 @@ bool dim_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
}
-bool dim_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool dim_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
return false;
}
diff --git a/src/lib/formats/dim_dsk.h b/src/lib/formats/dim_dsk.h
index e0227e2e221..5c84f329cb6 100644
--- a/src/lib/formats/dim_dsk.h
+++ b/src/lib/formats/dim_dsk.h
@@ -25,9 +25,9 @@ class dim_format : public floppy_image_format_t
public:
dim_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/dip_dsk.cpp b/src/lib/formats/dip_dsk.cpp
index a33d6fe35d6..17a7f856efe 100644
--- a/src/lib/formats/dip_dsk.cpp
+++ b/src/lib/formats/dip_dsk.cpp
@@ -14,10 +14,11 @@
*********************************************************************/
-#include <cassert>
-
#include "dip_dsk.h"
+#include "ioprocs.h"
+
+
dip_format::dip_format()
{
}
@@ -37,9 +38,11 @@ const char *dip_format::extensions() const
return "dip";
}
-int dip_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int dip_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return 0;
if (size == 0x134000 + 0x100)
return 100;
@@ -47,7 +50,7 @@ int dip_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool dip_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool dip_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
int heads, tracks, spt, bps;
@@ -69,7 +72,8 @@ bool dip_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
for (int track = 0; track < tracks; track++)
for (int head = 0; head < heads; head++)
{
- io_generic_read(io, sect_data, 0x100 + bps * spt * (track * heads + head), bps * spt);
+ size_t actual;
+ io.read_at(0x100 + bps * spt * (track * heads + head), sect_data, bps * spt, actual);
for (int i = 0; i < spt; i++)
{
diff --git a/src/lib/formats/dip_dsk.h b/src/lib/formats/dip_dsk.h
index 255e4e6c8a1..e310ef3f655 100644
--- a/src/lib/formats/dip_dsk.h
+++ b/src/lib/formats/dip_dsk.h
@@ -20,8 +20,8 @@ class dip_format : public floppy_image_format_t
public:
dip_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/dmk_dsk.cpp b/src/lib/formats/dmk_dsk.cpp
index 39c23223ec5..6a9e1dc0f0b 100644
--- a/src/lib/formats/dmk_dsk.cpp
+++ b/src/lib/formats/dmk_dsk.cpp
@@ -13,10 +13,10 @@ TODO:
*********************************************************************/
-#include <cassert>
-
#include "dmk_dsk.h"
+#include "ioprocs.h"
+
dmk_format::dmk_format()
{
@@ -41,14 +41,16 @@ const char *dmk_format::extensions() const
}
-int dmk_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int dmk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
+ uint64_t size;
+ if (io.length(size))
+ return 0;
+
const int header_size = 16;
uint8_t header[header_size];
-
- uint64_t size = io_generic_size(io);
-
- io_generic_read(io, header, 0, header_size);
+ size_t actual;
+ io.read_at(0, header, header_size, actual);
int tracks = header[1];
int track_size = ( header[3] << 8 ) | header[2];
@@ -81,12 +83,13 @@ int dmk_format::identify(io_generic *io, uint32_t form_factor, const std::vector
}
-bool dmk_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool dmk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
+
const int header_size = 16;
uint8_t header[header_size];
-
- io_generic_read(io, header, 0, header_size);
+ io.read_at(0, header, header_size, actual);
const int tracks = header[1];
const int track_size = ( header[3] << 8 ) | header[2];
@@ -128,7 +131,7 @@ bool dmk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
int dam_location[64];
// Read track
- io_generic_read(io, &track_data[0], header_size + ( heads * track + head ) * track_size, track_size);
+ io.read_at(header_size + (heads * track + head) * track_size, &track_data[0], track_size, actual);
for (int i = 0; i < 64; i++)
{
@@ -213,7 +216,7 @@ bool dmk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
}
-bool dmk_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool dmk_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
return false;
}
diff --git a/src/lib/formats/dmk_dsk.h b/src/lib/formats/dmk_dsk.h
index a2e7898dece..5485869b5b6 100644
--- a/src/lib/formats/dmk_dsk.h
+++ b/src/lib/formats/dmk_dsk.h
@@ -21,9 +21,9 @@ class dmk_format : public floppy_image_format_t
public:
dmk_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/ds9_dsk.cpp b/src/lib/formats/ds9_dsk.cpp
index fdf4f5e2299..c97a2cced51 100644
--- a/src/lib/formats/ds9_dsk.cpp
+++ b/src/lib/formats/ds9_dsk.cpp
@@ -14,10 +14,10 @@
************************************************************************/
-#include <cassert>
-
#include "formats/ds9_dsk.h"
+#include "ioprocs.h"
+
static FLOPPY_IDENTIFY(ds9_dsk_identify)
{
@@ -97,33 +97,32 @@ const char *ds9_format::extensions() const
return "ds9";
}
-void ds9_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
+void ds9_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
{
- uint32_t expected_size = 0;
- uint64_t size = io_generic_size(io);
-
head_count = 2;
track_count = 80;
sector_count = 21;
- expected_size = 256 * track_count * head_count * sector_count;
+ uint32_t const expected_size = 256 * track_count * head_count * sector_count;
- if (size >= expected_size) // standard format has 860160 bytes
+ uint64_t size;
+ if (!io.length(size) && (size >= expected_size)) // standard format has 860160 bytes
return;
track_count = head_count = sector_count = 0;
}
-int ds9_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int ds9_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t track_count, head_count, sector_count;
find_size(io, track_count, head_count, sector_count);
- if (track_count) return 50;
+ if (track_count)
+ return 50;
return 0;
}
-bool ds9_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool ds9_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint8_t track_count, head_count, sector_count;
find_size(io, track_count, head_count, sector_count);
@@ -143,7 +142,8 @@ bool ds9_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
{
for (int head = 0; head < head_count; head++)
{
- io_generic_read(io, sectdata, (track * head_count + head) * track_size, track_size);
+ size_t actual;
+ io.read_at((track * head_count + head) * track_size, sectdata, track_size, actual);
generate_track(ds9_desc, track, head, sectors, sector_count, 104000, image);
}
}
diff --git a/src/lib/formats/ds9_dsk.h b/src/lib/formats/ds9_dsk.h
index 317134eab87..abdf152b2b3 100644
--- a/src/lib/formats/ds9_dsk.h
+++ b/src/lib/formats/ds9_dsk.h
@@ -5,9 +5,10 @@
formats/ds9_dsk.h
*********************************************************************/
+#ifndef MAME_FORMATS_DS9_DSK_H
+#define MAME_FORMATS_DS9_DSK_H
-#ifndef DS9_DSK_H_
-#define DS9_DSK_H_
+#pragma once
#include "flopimg.h"
#include "formats/basicdsk.h"
@@ -19,8 +20,8 @@ class ds9_format : public floppy_image_format_t
public:
ds9_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -30,9 +31,9 @@ public:
static const desc_e ds9_desc[];
private:
- void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
+ void find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
};
extern const floppy_format_type FLOPPY_DS9_FORMAT;
-#endif /* DS9_DSK_H_ */
+#endif // MAME_FORMATS_DS9_DSK_H
diff --git a/src/lib/formats/dsk_dsk.cpp b/src/lib/formats/dsk_dsk.cpp
index dba11347887..fcf967edcb1 100644
--- a/src/lib/formats/dsk_dsk.cpp
+++ b/src/lib/formats/dsk_dsk.cpp
@@ -8,11 +8,12 @@
*********************************************************************/
-#include <cstring>
-#include <cassert>
-
+#include "dsk_dsk.h"
#include "imageutl.h"
-#include "flopimg.h"
+
+#include "ioprocs.h"
+
+#include <cstring>
#define MV_CPC "MV - CPC"
#define EXTENDED "EXTENDED"
@@ -270,7 +271,8 @@ FLOPPY_CONSTRUCT( dsk_dsk_construct )
return FLOPPY_ERROR_SUCCESS;
}
-#include "dsk_dsk.h"
+
+
#define DSK_FORMAT_HEADER "MV - CPC"
#define EXT_FORMAT_HEADER "EXTENDED CPC DSK"
@@ -299,11 +301,12 @@ bool dsk_format::supports_save() const
return false;
}
-int dsk_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int dsk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t header[16];
- io_generic_read(io, &header, 0, sizeof(header));
+ size_t actual;
+ io.read_at(0, &header, sizeof(header), actual);
if ( memcmp( header, DSK_FORMAT_HEADER, 8 ) ==0) {
return 100;
}
@@ -344,14 +347,18 @@ struct sector_header
#pragma pack()
-bool dsk_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool dsk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
+
uint8_t header[0x100];
bool extendformat = false;
- uint64_t image_size = io_generic_size(io);
+ uint64_t image_size;
+ if (io.length(image_size))
+ return false;
- io_generic_read(io, &header, 0, sizeof(header));
+ io.read_at(0, &header, sizeof(header), actual);
if ( memcmp( header, EXT_FORMAT_HEADER, 16 ) ==0) {
extendformat = true;
}
@@ -418,7 +425,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
if(track_offsets[(track<<1)+side] >= image_size)
continue;
track_header tr;
- io_generic_read(io, &tr,track_offsets[(track<<1)+side],sizeof(tr));
+ io.read_at(track_offsets[(track<<1)+side], &tr, sizeof(tr), actual);
// skip if there are no sectors in this track
if (tr.number_of_sector == 0)
@@ -428,7 +435,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
int first_sector_code = -1;
for(int j=0;j<tr.number_of_sector;j++) {
sector_header sector;
- io_generic_read(io, &sector,track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j),sizeof(sector));
+ io.read_at(track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j), &sector, sizeof(sector), actual);
if (j == 0)
first_sector_code = sector.sector_size_code;
@@ -447,7 +454,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
for(int j=0;j<tr.number_of_sector;j++) {
sector_header sector;
- io_generic_read(io, &sector,track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j),sizeof(sector));
+ io.read_at(track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j), &sector, sizeof(sector), actual);
sects[j].track = sector.track;
sects[j].head = sector.side;
@@ -470,7 +477,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
if(!(sector.fdc_status_reg1 & 0x04)) {
sects[j].data = sect_data + sdatapos;
- io_generic_read(io, sects[j].data, pos, sects[j].actual_size);
+ io.read_at(pos, sects[j].data, sects[j].actual_size, actual);
sdatapos += sects[j].actual_size;
} else
diff --git a/src/lib/formats/dsk_dsk.h b/src/lib/formats/dsk_dsk.h
index a08e3955888..7d6b3bc43dc 100644
--- a/src/lib/formats/dsk_dsk.h
+++ b/src/lib/formats/dsk_dsk.h
@@ -19,8 +19,8 @@ class dsk_format : public floppy_image_format_t
public:
dsk_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/dvk_mx_dsk.cpp b/src/lib/formats/dvk_mx_dsk.cpp
index 07d7a38cf95..08156d29e9c 100644
--- a/src/lib/formats/dvk_mx_dsk.cpp
+++ b/src/lib/formats/dvk_mx_dsk.cpp
@@ -18,11 +18,11 @@
************************************************************************/
-#include <cassert>
-
-#include "flopimg.h"
#include "formats/dvk_mx_dsk.h"
+#include "ioprocs.h"
+
+
const floppy_image_format_t::desc_e dvk_mx_format::dvk_mx_new_desc[] = {
/* 01 */ { FM, 0x00, 8*2 }, // eight 0x0000 words
/* 03 */ { FM, 0x00, 1 },
@@ -81,9 +81,14 @@ bool dvk_mx_format::supports_save() const
return false;
}
-void dvk_mx_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
+void dvk_mx_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ {
+ track_count = head_count = sector_count = 0;
+ return;
+ }
switch (size)
{
@@ -108,7 +113,7 @@ void dvk_mx_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &hea
}
}
-int dvk_mx_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int dvk_mx_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t track_count, head_count, sector_count;
@@ -117,7 +122,8 @@ int dvk_mx_format::identify(io_generic *io, uint32_t form_factor, const std::vec
if (track_count)
{
uint8_t sectdata[512];
- io_generic_read(io, sectdata, 512, 512);
+ size_t actual;
+ io.read_at(512, sectdata, 512, actual);
// check value in RT-11 home block. see src/tools/imgtool/modules/rt11.cpp
if (pick_integer_le(sectdata, 0724, 2) == 6)
return 100;
@@ -129,7 +135,7 @@ int dvk_mx_format::identify(io_generic *io, uint32_t form_factor, const std::vec
return 0;
}
-bool dvk_mx_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool dvk_mx_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint8_t track_count, head_count, sector_count;
@@ -150,7 +156,8 @@ bool dvk_mx_format::load(io_generic *io, uint32_t form_factor, const std::vector
{
for (int head = 0; head < head_count; head++)
{
- io_generic_read(io, sectdata, (track * head_count + head) * track_size, track_size);
+ size_t actual;
+ io.read_at((track * head_count + head) * track_size, sectdata, track_size, actual);
generate_track(dvk_mx_new_desc, track, head, sectors, sector_count, 45824, image);
}
}
diff --git a/src/lib/formats/dvk_mx_dsk.h b/src/lib/formats/dvk_mx_dsk.h
index 38fd895d154..e20066fc3ec 100644
--- a/src/lib/formats/dvk_mx_dsk.h
+++ b/src/lib/formats/dvk_mx_dsk.h
@@ -5,9 +5,8 @@
formats/dvk_mx_dsk.h
*********************************************************************/
-
-#ifndef DVK_MX_DSK_H_
-#define DVK_MX_DSK_H_
+#ifndef MAME_FORMATS_DVK_MX_DSK_H
+#define MAME_FORMATS_DVK_MX_DSK_H
#pragma once
@@ -19,8 +18,8 @@ class dvk_mx_format : public floppy_image_format_t
public:
dvk_mx_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -31,9 +30,9 @@ public:
static const desc_e dvk_mx_new_desc[];
private:
- void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
+ void find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
};
extern const floppy_format_type FLOPPY_DVK_MX_FORMAT;
-#endif /* DVK_MX_DSK_H_ */
+#endif // MAME_FORMATS_DVK_MX_DSK_H
diff --git a/src/lib/formats/esq16_dsk.cpp b/src/lib/formats/esq16_dsk.cpp
index 10802d26495..b33e529fef2 100644
--- a/src/lib/formats/esq16_dsk.cpp
+++ b/src/lib/formats/esq16_dsk.cpp
@@ -10,10 +10,10 @@
*********************************************************************/
-#include <cassert>
+#include "esq16_dsk.h"
+
+#include "ioprocs.h"
-#include "flopimg.h"
-#include "formats/esq16_dsk.h"
const floppy_image_format_t::desc_e esqimg_format::esq_10_desc[] = {
{ MFM, 0x4e, 80 },
@@ -71,23 +71,23 @@ bool esqimg_format::supports_save() const
return true;
}
-void esqimg_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
+void esqimg_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
{
- uint64_t size = io_generic_size(io);
- track_count = 80;
- head_count = 2;
- sector_count = 10;
-
- uint32_t expected_size = 512 * track_count*head_count*sector_count;
- if (size == expected_size)
- {
- return;
- }
+ uint64_t size;
+ if(!io.length(size)) {
+ track_count = 80;
+ head_count = 2;
+ sector_count = 10;
+ uint32_t expected_size = 512 * track_count*head_count*sector_count;
+ if(size == expected_size) {
+ return;
+ }
+ }
track_count = head_count = sector_count = 0;
}
-int esqimg_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int esqimg_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t track_count, head_count, sector_count;
find_size(io, track_count, head_count, sector_count);
@@ -97,7 +97,7 @@ int esqimg_format::identify(io_generic *io, uint32_t form_factor, const std::vec
return 0;
}
-bool esqimg_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool esqimg_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint8_t track_count, head_count, sector_count;
find_size(io, track_count, head_count, sector_count);
@@ -113,7 +113,8 @@ bool esqimg_format::load(io_generic *io, uint32_t form_factor, const std::vector
int track_size = sector_count*512;
for(int track=0; track < track_count; track++) {
for(int head=0; head < head_count; head++) {
- io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size);
+ size_t actual;
+ io.read_at((track*head_count + head)*track_size, sectdata, track_size, actual);
generate_track(esq_10_desc, track, head, sectors, sector_count, 110528, image);
}
}
@@ -123,7 +124,7 @@ bool esqimg_format::load(io_generic *io, uint32_t form_factor, const std::vector
return true;
}
-bool esqimg_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool esqimg_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int track_count, head_count, sector_count;
get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);
@@ -144,7 +145,8 @@ bool esqimg_format::save(io_generic *io, const std::vector<uint32_t> &variants,
for(int track=0; track < track_count; track++) {
for(int head=0; head < head_count; head++) {
get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
- io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size);
+ size_t actual;
+ io.write_at((track*head_count + head)*track_size, sectdata, track_size, actual);
}
}
diff --git a/src/lib/formats/esq16_dsk.h b/src/lib/formats/esq16_dsk.h
index 8cc49150d2c..2347d64f59c 100644
--- a/src/lib/formats/esq16_dsk.h
+++ b/src/lib/formats/esq16_dsk.h
@@ -21,9 +21,9 @@ class esqimg_format : public floppy_image_format_t
public:
esqimg_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -33,7 +33,7 @@ public:
static const desc_e esq_10_desc[];
private:
- void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
+ void find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
};
extern const floppy_format_type FLOPPY_ESQIMG_FORMAT;
diff --git a/src/lib/formats/esq8_dsk.cpp b/src/lib/formats/esq8_dsk.cpp
index f9dcb3d0727..952dd16edbd 100644
--- a/src/lib/formats/esq8_dsk.cpp
+++ b/src/lib/formats/esq8_dsk.cpp
@@ -12,10 +12,10 @@
*********************************************************************/
-#include <cassert>
+#include "esq8_dsk.h"
+
+#include "ioprocs.h"
-#include "flopimg.h"
-#include "formats/esq8_dsk.h"
const floppy_image_format_t::desc_e esq8img_format::esq_6_desc[] = {
{ MFM, 0x4e, 80 },
@@ -73,22 +73,24 @@ bool esq8img_format::supports_save() const
return true;
}
-void esq8img_format::find_size(io_generic *io, int &track_count, int &head_count, int &sector_count)
+void esq8img_format::find_size(util::random_read &io, int &track_count, int &head_count, int &sector_count)
{
- uint64_t size = io_generic_size(io);
- track_count = 80;
- head_count = 1;
- sector_count = 6;
-
- if(size == 5632 * 80)
+ uint64_t size;
+ if(!io.length(size))
{
- return;
- }
+ track_count = 80;
+ head_count = 1;
+ sector_count = 6;
+ if(size == 5632 * 80)
+ {
+ return;
+ }
+ }
track_count = head_count = sector_count = 0;
}
-int esq8img_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int esq8img_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int track_count, head_count, sector_count;
find_size(io, track_count, head_count, sector_count);
@@ -99,7 +101,7 @@ int esq8img_format::identify(io_generic *io, uint32_t form_factor, const std::ve
return 0;
}
-bool esq8img_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool esq8img_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
int track_count, head_count, sector_count;
find_size(io, track_count, head_count, sector_count);
@@ -128,7 +130,8 @@ bool esq8img_format::load(io_generic *io, uint32_t form_factor, const std::vecto
{
for(int head=0; head < head_count; head++)
{
- io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size);
+ size_t actual;
+ io.read_at((track*head_count + head)*track_size, sectdata, track_size, actual);
generate_track(esq_6_desc, track, head, sectors, sector_count, 109376, image);
}
}
@@ -138,7 +141,7 @@ bool esq8img_format::load(io_generic *io, uint32_t form_factor, const std::vecto
return true;
}
-bool esq8img_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool esq8img_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint64_t file_offset = 0;
int track_count, head_count, sector_count;
@@ -175,7 +178,8 @@ bool esq8img_format::save(io_generic *io, const std::vector<uint32_t> &variants,
return false;
}
- io_generic_write(io, sectors[sector].data(), file_offset, sector_expected_size);
+ size_t actual;
+ io.write_at(file_offset, sectors[sector].data(), sector_expected_size, actual);
file_offset += sector_expected_size;
}
}
diff --git a/src/lib/formats/esq8_dsk.h b/src/lib/formats/esq8_dsk.h
index c4fe5a74f1b..aa09fd278a7 100644
--- a/src/lib/formats/esq8_dsk.h
+++ b/src/lib/formats/esq8_dsk.h
@@ -23,9 +23,9 @@ class esq8img_format : public floppy_image_format_t
public:
esq8img_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -35,7 +35,7 @@ public:
static const desc_e esq_6_desc[];
private:
- void find_size(io_generic *io, int &track_count, int &head_count, int &sector_count);
+ void find_size(util::random_read &io, int &track_count, int &head_count, int &sector_count);
};
extern const floppy_format_type FLOPPY_ESQ8IMG_FORMAT;
diff --git a/src/lib/formats/fdd_dsk.cpp b/src/lib/formats/fdd_dsk.cpp
index df5fd3caa8c..8c8249c9452 100644
--- a/src/lib/formats/fdd_dsk.cpp
+++ b/src/lib/formats/fdd_dsk.cpp
@@ -31,10 +31,11 @@
*********************************************************************/
-#include <cassert>
-
#include "fdd_dsk.h"
+#include "ioprocs.h"
+
+
fdd_format::fdd_format()
{
}
@@ -54,10 +55,11 @@ const char *fdd_format::extensions() const
return "fdd";
}
-int fdd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int fdd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t h[7];
- io_generic_read(io, h, 0, 7);
+ size_t actual;
+ io.read_at(0, h, 7, actual);
if (strncmp((const char *)h, "VFD1.0", 6) == 0)
return 100;
@@ -65,7 +67,7 @@ int fdd_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool fdd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool fdd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint8_t hsec[0x0c];
@@ -86,7 +88,8 @@ bool fdd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
for (int sect = 0; sect < 26; sect++)
{
// read sector map for this sector
- io_generic_read(io, hsec, pos, 0x0c);
+ size_t actual;
+ io.read_at(pos, hsec, 0x0c, actual);
pos += 0x0c;
if (hsec[0] == 0xff) // unformatted/unused sector
@@ -118,10 +121,11 @@ bool fdd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
cur_sec_map = track * 26 + i;
sector_size = 128 << sec_sizes[cur_sec_map];
+ size_t actual;
if (sec_offs[cur_sec_map] == 0xffffffff)
memset(sect_data + cur_pos, fill_vals[cur_sec_map], sector_size);
else
- io_generic_read(io, sect_data + cur_pos, sec_offs[cur_sec_map], sector_size);
+ io.read_at(sec_offs[cur_sec_map], sect_data + cur_pos, sector_size, actual);
sects[i].track = tracks[cur_sec_map];
sects[i].head = heads[cur_sec_map];
diff --git a/src/lib/formats/fdd_dsk.h b/src/lib/formats/fdd_dsk.h
index ec013c58571..c1a3ae8a29b 100644
--- a/src/lib/formats/fdd_dsk.h
+++ b/src/lib/formats/fdd_dsk.h
@@ -20,8 +20,8 @@ class fdd_format : public floppy_image_format_t
public:
fdd_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/flex_dsk.cpp b/src/lib/formats/flex_dsk.cpp
index 692cc4bdc9d..4989a25e707 100644
--- a/src/lib/formats/flex_dsk.cpp
+++ b/src/lib/formats/flex_dsk.cpp
@@ -50,7 +50,11 @@
*/
#include "flex_dsk.h"
-#include "formats/imageutl.h"
+
+#include "imageutl.h"
+
+#include "ioprocs.h"
+
flex_format::flex_format() : wd177x_format(formats)
{
@@ -71,7 +75,7 @@ const char *flex_format::extensions() const
return "dsk";
}
-int flex_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int flex_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int type = find_size(io, form_factor, variants);
@@ -80,17 +84,21 @@ int flex_format::identify(io_generic *io, uint32_t form_factor, const std::vecto
return 0;
}
-int flex_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int flex_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return -1;
+
uint8_t boot0[256], boot1[256];
+ size_t actual;
// Look at the boot sector.
// Density, sides, link??
- io_generic_read(io, &boot0, 256 * 0, sizeof(boot0));
- io_generic_read(io, &boot1, 256 * 1, sizeof(boot1));
+ io.read_at(256 * 0, &boot0, sizeof(boot0), actual);
+ io.read_at(256 * 1, &boot1, sizeof(boot1), actual);
// Look at the system information sector.
- io_generic_read(io, &info, 256 * 2, sizeof(struct sysinfo_sector));
+ io.read_at(256 * 2, &info, sizeof(struct sysinfo_sector), actual);
LOG_FORMATS("FLEX floppy dsk: size %d bytes, %d total sectors, %d remaining bytes, expected form factor %x\n", (uint32_t)size, (uint32_t)size / 256, (uint32_t)size % 256, form_factor);
diff --git a/src/lib/formats/flex_dsk.h b/src/lib/formats/flex_dsk.h
index 094c6854b24..0048e4e088f 100644
--- a/src/lib/formats/flex_dsk.h
+++ b/src/lib/formats/flex_dsk.h
@@ -21,8 +21,8 @@ public:
virtual const char *name() const override;
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual const wd177x_format::format &get_track_format(const format &f, int head, int track) override;
private:
diff --git a/src/lib/formats/flopimg.cpp b/src/lib/formats/flopimg.cpp
index 48c2fa1b610..55d00d1bb83 100644
--- a/src/lib/formats/flopimg.cpp
+++ b/src/lib/formats/flopimg.cpp
@@ -11,9 +11,10 @@
#include "flopimg.h"
#include "imageutl.h"
-#include "osdcore.h"
#include "ioprocs.h"
+#include "osdcore.h"
+
#include <cassert>
#include <cctype>
#include <climits>
@@ -30,7 +31,7 @@ using util::BIT;
struct floppy_image_legacy
{
- struct io_generic io = { 0 };
+ util::random_read_write::ptr io = nullptr;
const struct FloppyFormat *floppy_option = nullptr;
struct FloppyCallbacks format = { 0 };
@@ -69,22 +70,20 @@ OPTION_GUIDE_START(floppy_option_guide)
OPTION_GUIDE_END
-static void floppy_close_internal(floppy_image_legacy *floppy, bool close_file);
+static void floppy_close_internal(floppy_image_legacy *floppy);
/*********************************************************************
opening, closing and creating of floppy images
*********************************************************************/
/* basic floppy_image_legacy initialization common to floppy_open() and floppy_create() */
-static floppy_image_legacy *floppy_init(void *fp, const struct io_procs *procs, int flags)
+static floppy_image_legacy *floppy_init(util::random_read_write::ptr &&io, int flags)
{
floppy_image_legacy *floppy;
floppy = new floppy_image_legacy;
- floppy->io.file = fp;
- floppy->io.procs = procs;
- floppy->io.filler = 0xFF;
+ floppy->io = std::move(io);
floppy->flags = (uint8_t) flags;
return floppy;
}
@@ -93,7 +92,7 @@ static floppy_image_legacy *floppy_init(void *fp, const struct io_procs *procs,
/* main code for identifying and maybe opening a disk image; not exposed
* directly because this function is big and hideous */
-static floperr_t floppy_open_internal(void *fp, const struct io_procs *procs, const std::string &extension,
+static floperr_t floppy_open_internal(util::random_read_write::ptr &&io, const std::string &extension,
const struct FloppyFormat *floppy_options, int max_options, int flags, floppy_image_legacy **outfloppy,
int *outoption)
{
@@ -104,7 +103,7 @@ static floperr_t floppy_open_internal(void *fp, const struct io_procs *procs, co
int vote;
size_t i;
- floppy = floppy_init(fp, procs, flags);
+ floppy = floppy_init(std::move(io), flags);
if (!floppy)
{
err = FLOPPY_ERROR_OUTOFMEMORY;
@@ -163,7 +162,7 @@ done:
/* if we have a floppy disk and we either errored or are not keeping it, close it */
if (floppy && (!outfloppy || err))
{
- floppy_close_internal(floppy, false);
+ floppy_close_internal(floppy);
floppy = nullptr;
}
@@ -176,31 +175,31 @@ done:
-floperr_t floppy_identify(void *fp, const struct io_procs *procs, const char *extension,
+floperr_t floppy_identify(util::random_read_write::ptr &&io, const char *extension,
const struct FloppyFormat *formats, int *identified_format)
{
- return floppy_open_internal(fp, procs, extension, formats, INT_MAX, FLOPPY_FLAGS_READONLY, nullptr, identified_format);
+ return floppy_open_internal(std::move(io), extension, formats, INT_MAX, FLOPPY_FLAGS_READONLY, nullptr, identified_format);
}
-floperr_t floppy_open(void *fp, const struct io_procs *procs, const std::string &extension,
+floperr_t floppy_open(util::random_read_write::ptr &&io, const std::string &extension,
const struct FloppyFormat *format, int flags, floppy_image_legacy **outfloppy)
{
- return floppy_open_internal(fp, procs, extension, format, 1, flags, outfloppy, nullptr);
+ return floppy_open_internal(std::move(io), extension, format, 1, flags, outfloppy, nullptr);
}
-floperr_t floppy_open_choices(void *fp, const struct io_procs *procs, const std::string &extension,
+floperr_t floppy_open_choices(util::random_read_write::ptr &&io, const std::string &extension,
const struct FloppyFormat *formats, int flags, floppy_image_legacy **outfloppy)
{
- return floppy_open_internal(fp, procs, extension, formats, INT_MAX, flags, outfloppy, nullptr);
+ return floppy_open_internal(std::move(io), extension, formats, INT_MAX, flags, outfloppy, nullptr);
}
-floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct FloppyFormat *format, util::option_resolution *parameters, floppy_image_legacy **outfloppy)
+floperr_t floppy_create(util::random_read_write::ptr &&io, const struct FloppyFormat *format, util::option_resolution *parameters, floppy_image_legacy **outfloppy)
{
floppy_image_legacy *floppy = nullptr;
floperr_t err;
@@ -210,7 +209,7 @@ floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct Flo
assert(format);
/* create the new image */
- floppy = floppy_init(fp, procs, 0);
+ floppy = floppy_init(std::move(io), 0);
if (!floppy)
{
err = FLOPPY_ERROR_OUTOFMEMORY;
@@ -266,28 +265,26 @@ floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct Flo
done:
if (err && floppy)
{
- floppy_close_internal(floppy, false);
+ floppy_close_internal(floppy);
floppy = nullptr;
}
if (outfloppy)
*outfloppy = floppy;
else if (floppy)
- floppy_close_internal(floppy, false);
+ floppy_close_internal(floppy);
return err;
}
-static void floppy_close_internal(floppy_image_legacy *floppy, bool close_file)
+static void floppy_close_internal(floppy_image_legacy *floppy)
{
if (floppy) {
floppy_track_unload(floppy);
if(floppy->floppy_option && floppy->floppy_option->destruct)
floppy->floppy_option->destruct(floppy, floppy->floppy_option);
- if (close_file)
- io_generic_close(&floppy->io);
delete floppy;
}
@@ -297,7 +294,7 @@ static void floppy_close_internal(floppy_image_legacy *floppy, bool close_file)
void floppy_close(floppy_image_legacy *floppy)
{
- floppy_close_internal(floppy, true);
+ floppy_close_internal(floppy);
}
@@ -332,14 +329,16 @@ void *floppy_create_tag(floppy_image_legacy *floppy, size_t tagsize)
uint8_t floppy_get_filler(floppy_image_legacy *floppy)
{
- return floppy->io.filler;
+ // FIXME: remove this function, it's here for legacy reasons
+ // the caller actually sets the filler byte - in practice it's always 0xff but there's no actual guarantee
+ return 0xff;
}
-void floppy_set_filler(floppy_image_legacy *floppy, uint8_t filler)
+util::random_read_write &floppy_get_io(floppy_image_legacy *floppy)
{
- floppy->io.filler = filler;
+ return *floppy->io;
}
@@ -350,28 +349,42 @@ void floppy_set_filler(floppy_image_legacy *floppy, uint8_t filler)
void floppy_image_read(floppy_image_legacy *floppy, void *buffer, uint64_t offset, size_t length)
{
- io_generic_read(&floppy->io, buffer, offset, length);
+ size_t actual;
+ floppy->io->read_at(offset, buffer, length, actual);
}
void floppy_image_write(floppy_image_legacy *floppy, const void *buffer, uint64_t offset, size_t length)
{
- io_generic_write(&floppy->io, buffer, offset, length);
+ size_t actual;
+ floppy->io->write_at(offset, buffer, length, actual);
}
void floppy_image_write_filler(floppy_image_legacy *floppy, uint8_t filler, uint64_t offset, size_t length)
{
- io_generic_write_filler(&floppy->io, filler, offset, length);
+ uint8_t buffer[512];
+ memset(buffer, filler, std::min(sizeof(buffer), length));
+
+ while (length)
+ {
+ size_t const block = std::min(sizeof(buffer), length);
+ size_t actual;
+ floppy->io->write_at(offset, buffer, block, actual);
+ offset += block;
+ length -= block;
+ }
}
uint64_t floppy_image_size(floppy_image_legacy *floppy)
{
- return io_generic_size(&floppy->io);
+ uint64_t result;
+ floppy->io->length(result);
+ return result;
}
@@ -976,7 +989,7 @@ bool floppy_image_format_t::has_variant(const std::vector<uint32_t> &variants, u
return false;
}
-bool floppy_image_format_t::save(io_generic *, const std::vector<uint32_t> &, floppy_image *)
+bool floppy_image_format_t::save(util::random_read_write &io, const std::vector<uint32_t> &, floppy_image *)
{
return false;
}
diff --git a/src/lib/formats/flopimg.h b/src/lib/formats/flopimg.h
index 101d9bd86bd..6279def82f8 100644
--- a/src/lib/formats/flopimg.h
+++ b/src/lib/formats/flopimg.h
@@ -12,11 +12,13 @@
#pragma once
-#include "osdcore.h"
-#include "ioprocs.h"
-#include "opresolv.h"
#include "coretmpl.h"
+#include "opresolv.h"
+#include "utilfwd.h"
+
+#include "osdcore.h"
+#include <memory>
#include <vector>
#ifndef LOG_FORMATS
@@ -166,20 +168,20 @@ LEGACY_FLOPPY_OPTIONS_EXTERN(default);
OPTION_GUIDE_EXTERN(floppy_option_guide);
/* opening, closing and creating of floppy images */
-floperr_t floppy_open(void *fp, const struct io_procs *procs, const std::string &extension, const struct FloppyFormat *format, int flags, floppy_image_legacy **outfloppy);
-floperr_t floppy_open_choices(void *fp, const struct io_procs *procs, const std::string &extension, const struct FloppyFormat *formats, int flags, floppy_image_legacy **outfloppy);
-floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct FloppyFormat *format, util::option_resolution *parameters, floppy_image_legacy **outfloppy);
+floperr_t floppy_open(std::unique_ptr<util::random_read_write> &&io, const std::string &extension, const struct FloppyFormat *format, int flags, floppy_image_legacy **outfloppy);
+floperr_t floppy_open_choices(std::unique_ptr<util::random_read_write> &&io, const std::string &extension, const struct FloppyFormat *formats, int flags, floppy_image_legacy **outfloppy);
+floperr_t floppy_create(std::unique_ptr<util::random_read_write> &&io, const struct FloppyFormat *format, util::option_resolution *parameters, floppy_image_legacy **outfloppy);
void floppy_close(floppy_image_legacy *floppy);
/* useful for identifying a floppy image */
-floperr_t floppy_identify(void *fp, const struct io_procs *procs, const char *extension, const struct FloppyFormat *formats, int *identified_format);
+floperr_t floppy_identify(std::unique_ptr<util::random_read_write> &&io, const char *extension, const struct FloppyFormat *formats, int *identified_format);
/* functions useful within format constructors */
void *floppy_tag(floppy_image_legacy *floppy);
void *floppy_create_tag(floppy_image_legacy *floppy, size_t tagsize);
struct FloppyCallbacks *floppy_callbacks(floppy_image_legacy *floppy);
uint8_t floppy_get_filler(floppy_image_legacy *floppy);
-void floppy_set_filler(floppy_image_legacy *floppy, uint8_t filler);
+util::random_read_write &floppy_get_io(floppy_image_legacy *floppy);
/* calls for accessing disk image data */
floperr_t floppy_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, int offset, void *buffer, size_t buffer_len);
@@ -235,7 +237,7 @@ public:
@param variants the variants from floppy_image the drive can handle
@return 1 if image valid, 0 otherwise.
*/
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) = 0;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) = 0;
/*! @brief Load an image.
The load function opens an image file and converts it to the
@@ -247,7 +249,7 @@ public:
@param image output buffer for data in MESS internal format.
@return true on success, false otherwise.
*/
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) = 0;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) = 0;
/*! @brief Save an image.
The save function writes back an image from the MESS internal
@@ -257,7 +259,7 @@ public:
@param image source buffer containing data in MESS internal format.
@return true on success, false otherwise.
*/
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image);
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image);
//! @returns string containing name of format.
virtual const char *name() const = 0;
diff --git a/src/lib/formats/fsd_dsk.cpp b/src/lib/formats/fsd_dsk.cpp
index c5ebd243875..ffb23035420 100644
--- a/src/lib/formats/fsd_dsk.cpp
+++ b/src/lib/formats/fsd_dsk.cpp
@@ -10,6 +10,8 @@
#include "fsd_dsk.h"
+#include "ioprocs.h"
+
/*********************************************************************
@@ -83,11 +85,12 @@ bool fsd_format::supports_save() const
return false;
}
-int fsd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int fsd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t h[3];
- io_generic_read(io, h, 0, 3);
+ size_t actual;
+ io.read_at(0, h, 3, actual);
if (memcmp(h, "FSD", 3) == 0) {
return 100;
}
@@ -95,16 +98,19 @@ int fsd_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool fsd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool fsd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
const char* result[255];
result[0x00] = "OK";
result[0x0e] = "Data CRC Error";
result[0x20] = "Deleted Data";
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return false;
std::vector<uint8_t> img(size);
- io_generic_read(io, &img[0], 0, size);
+ size_t actual;
+ io.read_at(0, &img[0], size, actual);
uint64_t pos;
std::string title;
diff --git a/src/lib/formats/fsd_dsk.h b/src/lib/formats/fsd_dsk.h
index ee2c4aa466c..779ee28ec02 100644
--- a/src/lib/formats/fsd_dsk.h
+++ b/src/lib/formats/fsd_dsk.h
@@ -33,8 +33,8 @@ public:
virtual const char *extensions() const override;
virtual bool supports_save() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
};
extern const floppy_format_type FLOPPY_FSD_FORMAT;
diff --git a/src/lib/formats/g64_dsk.cpp b/src/lib/formats/g64_dsk.cpp
index 02098db88e0..8e6b9c75e44 100644
--- a/src/lib/formats/g64_dsk.cpp
+++ b/src/lib/formats/g64_dsk.cpp
@@ -12,6 +12,8 @@
#include "formats/g64_dsk.h"
+#include "ioprocs.h"
+
#define G64_FORMAT_HEADER "GCR-1541"
@@ -27,22 +29,27 @@ const uint32_t g64_format::c1541_cell_size[] =
3250 // 16MHz/13/4
};
-int g64_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int g64_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
char h[8];
- io_generic_read(io, h, 0, 8);
+ size_t actual;
+ io.read_at(0, h, 8, actual);
if (!memcmp(h, G64_FORMAT_HEADER, 8))
return 100;
return 0;
}
-bool g64_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool g64_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return false;
+
std::vector<uint8_t> img(size);
- io_generic_read(io, &img[0], 0, size);
+ size_t actual;
+ io.read_at(0, &img[0], size, actual);
if (img[POS_VERSION])
{
@@ -109,15 +116,19 @@ int g64_format::generate_bitstream(int track, int head, int speed_zone, std::vec
return ((actual_cell_size >= cell_size-10) && (actual_cell_size <= cell_size+10)) ? speed_zone : -1;
}
-bool g64_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool g64_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ uint8_t const zerofill[] = { 0x00, 0x00, 0x00, 0x00 };
+ std::vector<uint8_t> const prefill(TRACK_LENGTH, 0xff);
+ size_t actual;
+
int tracks, heads;
image->get_actual_geometry(tracks, heads);
tracks = TRACK_COUNT * heads;
// write header
uint8_t header[] = { 'G', 'C', 'R', '-', '1', '5', '4', '1', 0x00, static_cast<uint8_t>(tracks), TRACK_LENGTH & 0xff, TRACK_LENGTH >> 8 };
- io_generic_write(io, header, POS_SIGNATURE, sizeof(header));
+ io.write_at(POS_SIGNATURE, header, sizeof(header), actual);
// write tracks
for (int head = 0; head < heads; head++) {
@@ -126,12 +137,12 @@ bool g64_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
std::vector<bool> trackbuf;
for (int track = 0; track < TRACK_COUNT; track++) {
- uint32_t tpos = POS_TRACK_OFFSET + (track * 4);
- uint32_t spos = tpos + (tracks * 4);
- uint32_t dpos = POS_TRACK_OFFSET + (tracks * 4 * 2) + (tracks_written * TRACK_LENGTH);
+ uint32_t const tpos = POS_TRACK_OFFSET + (track * 4);
+ uint32_t const spos = tpos + (tracks * 4);
+ uint32_t const dpos = POS_TRACK_OFFSET + (tracks * 4 * 2) + (tracks_written * TRACK_LENGTH);
- io_generic_write_filler(io, 0x00, tpos, 4);
- io_generic_write_filler(io, 0x00, spos, 4);
+ io.write_at(tpos, zerofill, 4, actual);
+ io.write_at(spos, zerofill, 4, actual);
if (image->get_buffer(track, head).size() <= 1)
continue;
@@ -163,11 +174,11 @@ bool g64_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
place_integer_le(speed_offset, 0, 4, speed_zone);
place_integer_le(track_length, 0, 2, packed.size());
- io_generic_write(io, track_offset, tpos, 4);
- io_generic_write(io, speed_offset, spos, 4);
- io_generic_write_filler(io, 0xff, dpos, TRACK_LENGTH);
- io_generic_write(io, track_length, dpos, 2);
- io_generic_write(io, packed.data(), dpos + 2, packed.size());
+ io.write_at(tpos, track_offset, 4, actual);
+ io.write_at(spos, speed_offset, 4, actual);
+ io.write_at(dpos, prefill.data(), TRACK_LENGTH, actual);
+ io.write_at(dpos, track_length, 2, actual);
+ io.write_at(dpos + 2, packed.data(), packed.size(), actual);
tracks_written++;
}
diff --git a/src/lib/formats/g64_dsk.h b/src/lib/formats/g64_dsk.h
index 6691146c70e..fcd48d96796 100644
--- a/src/lib/formats/g64_dsk.h
+++ b/src/lib/formats/g64_dsk.h
@@ -20,9 +20,9 @@ class g64_format : public floppy_image_format_t
public:
g64_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/hpi_dsk.cpp b/src/lib/formats/hpi_dsk.cpp
index d9fc788fd45..bdccc66803d 100644
--- a/src/lib/formats/hpi_dsk.cpp
+++ b/src/lib/formats/hpi_dsk.cpp
@@ -48,6 +48,7 @@
#include "hpi_dsk.h"
#include "coretmpl.h" // BIT
+#include "ioprocs.h"
// Debugging
@@ -78,9 +79,12 @@ hpi_format::hpi_format()
(void)HPI_RED_IMAGE_SIZE;
}
-int hpi_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int hpi_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size)) {
+ return 0;
+ }
// we try to stay back and give only 50 points, since another image
// format may also have images of the same size (there is no header and no
@@ -142,12 +146,15 @@ bool hpi_format::geometry_from_size(uint64_t image_size , unsigned& heads , unsi
}
}
-bool hpi_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool hpi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
unsigned heads;
unsigned cylinders;
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size)) {
+ return false;
+ }
if (!geometry_from_size(size, heads, cylinders)) {
return false;
}
@@ -161,7 +168,8 @@ bool hpi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
// Suck in the whole image
std::vector<uint8_t> image_data(size);
- io_generic_read(io, (void *)image_data.data(), 0, size);
+ size_t actual;
+ io.read_at(0, image_data.data(), size, actual);
// Get interleave factor from image
unsigned il = (unsigned)image_data[ IL_OFFSET ] * 256 + image_data[ IL_OFFSET + 1 ];
@@ -191,7 +199,7 @@ bool hpi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return true;
}
-bool hpi_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool hpi_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int tracks;
int heads;
@@ -206,7 +214,8 @@ bool hpi_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
while (get_next_sector(bitstream , pos , track_no , head_no , sector_no , sector_data)) {
if (track_no == cyl && head_no == head && sector_no < HPI_SECTORS) {
unsigned offset_in_image = chs_to_lba(cyl, head, sector_no, heads) * HPI_SECTOR_SIZE;
- io_generic_write(io, sector_data, offset_in_image, HPI_SECTOR_SIZE);
+ size_t actual;
+ io.write_at(offset_in_image, sector_data, HPI_SECTOR_SIZE, actual);
}
}
}
diff --git a/src/lib/formats/hpi_dsk.h b/src/lib/formats/hpi_dsk.h
index 38c70e91c33..ca8aa1ffe11 100644
--- a/src/lib/formats/hpi_dsk.h
+++ b/src/lib/formats/hpi_dsk.h
@@ -28,9 +28,9 @@ class hpi_format : public floppy_image_format_t
public:
hpi_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
virtual const char *extensions() const override;
diff --git a/src/lib/formats/hti_tape.cpp b/src/lib/formats/hti_tape.cpp
index 7f77e3f99df..8fbaeef91cc 100644
--- a/src/lib/formats/hti_tape.cpp
+++ b/src/lib/formats/hti_tape.cpp
@@ -10,6 +10,8 @@
#include "imageutl.h"
+#include "ioprocs.h"
+
static constexpr uint32_t OLD_FILE_MAGIC = 0x5441434f; // Magic value at start of old-format image file: "TACO"
static constexpr uint32_t FILE_MAGIC_DELTA = 0x48544930; // Magic value at start of delta-modulation image file: "HTI0"
@@ -47,22 +49,25 @@ hti_format_t::hti_format_t()
clear_tape();
}
-bool hti_format_t::load_tape(io_generic *io)
+bool hti_format_t::load_tape(util::random_read &io)
{
+ if (io.seek(0, SEEK_SET)) {
+ return false;
+ }
+
+ size_t actual;
uint8_t tmp[ 4 ];
- io_generic_read(io, tmp, 0, 4);
+ io.read(tmp, 4, actual);
auto magic = pick_integer_be(tmp , 0 , 4);
if (((m_img_format == HTI_DELTA_MOD_16_BITS || m_img_format == HTI_DELTA_MOD_17_BITS) && magic != FILE_MAGIC_DELTA && magic != OLD_FILE_MAGIC) ||
(m_img_format == HTI_MANCHESTER_MOD && magic != FILE_MAGIC_MANCHESTER)) {
return false;
}
- uint64_t offset = 4;
-
for (unsigned i = 0; i < no_of_tracks(); i++) {
tape_track_t& track = m_tracks[ i ];
- if (!load_track(io , offset , track , magic == OLD_FILE_MAGIC)) {
+ if (!load_track(io, track, magic == OLD_FILE_MAGIC)) {
clear_tape();
return false;
}
@@ -71,14 +76,15 @@ bool hti_format_t::load_tape(io_generic *io)
return true;
}
-void hti_format_t::save_tape(io_generic *io)
+void hti_format_t::save_tape(util::random_read_write &io)
{
+ io.seek(0, SEEK_SET);
+
+ size_t actual;
uint8_t tmp[ 4 ];
place_integer_be(tmp, 0, 4, m_img_format == HTI_MANCHESTER_MOD ? FILE_MAGIC_MANCHESTER : FILE_MAGIC_DELTA);
- io_generic_write(io, tmp, 0, 4);
-
- uint64_t offset = 4;
+ io.write(tmp, 4, actual);
for (unsigned i = 0; i < no_of_tracks(); i++) {
const tape_track_t& track = m_tracks[ i ];
@@ -87,18 +93,17 @@ void hti_format_t::save_tape(io_generic *io)
tape_track_t::const_iterator it_start;
for (tape_track_t::const_iterator it = track.cbegin(); it != track.cend(); ++it) {
if (it->first != next_pos) {
- dump_sequence(io , offset , it_start , n_words);
+ dump_sequence(io, it_start, n_words);
it_start = it;
n_words = 0;
}
next_pos = it->first + word_length(it->second);
n_words++;
}
- dump_sequence(io , offset , it_start , n_words);
+ dump_sequence(io, it_start, n_words);
// End of track
place_integer_le(tmp, 0, 4, (uint32_t)-1);
- io_generic_write(io, tmp, offset, 4);
- offset += 4;
+ io.write(tmp, 4, actual);
}
}
@@ -374,8 +379,9 @@ bool hti_format_t::next_gap(unsigned track_no , tape_pos_t& pos , bool forward ,
return n_gaps == 0;
}
-bool hti_format_t::load_track(io_generic *io , uint64_t& offset , tape_track_t& track , bool old_format)
+bool hti_format_t::load_track(util::random_read &io , tape_track_t& track , bool old_format)
{
+ size_t actual;
uint8_t tmp[ 4 ];
uint32_t tmp32;
tape_pos_t delta_pos = 0;
@@ -385,8 +391,7 @@ bool hti_format_t::load_track(io_generic *io , uint64_t& offset , tape_track_t&
while (1) {
// Read no. of words to follow
- io_generic_read(io, tmp, offset, 4);
- offset += 4;
+ io.read(tmp, 4, actual);
tmp32 = pick_integer_le(tmp, 0, 4);
@@ -398,8 +403,7 @@ bool hti_format_t::load_track(io_generic *io , uint64_t& offset , tape_track_t&
unsigned n_words = tmp32;
// Read tape position of block
- io_generic_read(io, tmp, offset, 4);
- offset += 4;
+ io.read(tmp, 4, actual);
tmp32 = pick_integer_le(tmp, 0, 4);
@@ -411,8 +415,7 @@ bool hti_format_t::load_track(io_generic *io , uint64_t& offset , tape_track_t&
for (unsigned i = 0; i < n_words; i++) {
uint16_t tmp16;
- io_generic_read(io, tmp, offset, 2);
- offset += 2;
+ io.read(tmp, 2, actual);
tmp16 = pick_integer_le(tmp, 0, 2);
if (!old_format) {
@@ -469,19 +472,18 @@ bool hti_format_t::load_track(io_generic *io , uint64_t& offset , tape_track_t&
}
}
-void hti_format_t::dump_sequence(io_generic *io , uint64_t& offset , tape_track_t::const_iterator it_start , unsigned n_words)
+void hti_format_t::dump_sequence(util::random_read_write &io , tape_track_t::const_iterator it_start , unsigned n_words)
{
if (n_words) {
+ size_t actual;
uint8_t tmp[ 8 ];
place_integer_le(tmp, 0, 4, n_words);
place_integer_le(tmp, 4, 4, it_start->first);
- io_generic_write(io, tmp, offset, 8);
- offset += 8;
+ io.write(tmp, 8, actual);
for (unsigned i = 0; i < n_words; i++) {
place_integer_le(tmp, 0, 2, it_start->second);
- io_generic_write(io, tmp, offset, 2);
- offset += 2;
+ io.write(tmp, 2, actual);
++it_start;
}
}
diff --git a/src/lib/formats/hti_tape.h b/src/lib/formats/hti_tape.h
index 7725b87fa2a..373c971d174 100644
--- a/src/lib/formats/hti_tape.h
+++ b/src/lib/formats/hti_tape.h
@@ -13,10 +13,12 @@
#pragma once
-#include "ioprocs.h"
+#include "utilfwd.h"
+#include <cstdint>
#include <map>
+
class hti_format_t
{
public:
@@ -71,8 +73,8 @@ public:
// Return number of tracks
unsigned no_of_tracks() const { return m_img_format == HTI_MANCHESTER_MOD ? 1 : 2; }
- bool load_tape(io_generic *io);
- void save_tape(io_generic *io);
+ bool load_tape(util::random_read &io);
+ void save_tape(util::random_read_write &io);
void clear_tape();
// Return physical length of a bit on tape
@@ -127,8 +129,8 @@ private:
// Image format
image_format_t m_img_format;
- bool load_track(io_generic *io , uint64_t& offset , tape_track_t& track , bool old_format);
- static void dump_sequence(io_generic *io , uint64_t& offset , tape_track_t::const_iterator it_start , unsigned n_words);
+ bool load_track(util::random_read &io , tape_track_t& track , bool old_format);
+ static void dump_sequence(util::random_read_write &io , tape_track_t::const_iterator it_start , unsigned n_words);
tape_pos_t word_end_pos(const track_iterator_t& it) const;
void adjust_it(tape_track_t& track , track_iterator_t& it , tape_pos_t pos) const;
diff --git a/src/lib/formats/hxchfe_dsk.cpp b/src/lib/formats/hxchfe_dsk.cpp
index 68360f4e9bb..15598bbd746 100644
--- a/src/lib/formats/hxchfe_dsk.cpp
+++ b/src/lib/formats/hxchfe_dsk.cpp
@@ -101,6 +101,9 @@
#include "hxchfe_dsk.h"
+#include "ioprocs.h"
+
+
#define HFE_FORMAT_HEADER "HXCPICFE"
#define HEADER_LENGTH 512
@@ -144,19 +147,21 @@ bool hfe_format::supports_save() const
return true;
}
-int hfe_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int hfe_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t header[8];
- io_generic_read(io, &header, 0, sizeof(header));
+ size_t actual;
+ io.read_at(0, &header, sizeof(header), actual);
if ( memcmp( header, HFE_FORMAT_HEADER, 8 ) ==0) {
return 100;
}
return 0;
}
-bool hfe_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool hfe_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
uint8_t header[HEADER_LENGTH];
uint8_t track_table[TRACK_TABLE_LENGTH];
@@ -164,7 +169,7 @@ bool hfe_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
image->get_maximal_geometry(drivecyl, driveheads);
// read header
- io_generic_read(io, header, 0, HEADER_LENGTH);
+ io.read_at(0, header, HEADER_LENGTH, actual);
// get values
// Format revision must be 0
@@ -236,7 +241,7 @@ bool hfe_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
// read track lookup table (multiple of 512)
int table_offset = (header[18] & 0xff) | ((header[19] & 0xff)<<8);
- io_generic_read(io, track_table, table_offset<<9, TRACK_TABLE_LENGTH);
+ io.read_at(table_offset<<9, track_table, TRACK_TABLE_LENGTH, actual);
for (int i=0; i < m_cylinders; i++)
{
@@ -252,7 +257,7 @@ bool hfe_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
// The HFE format defines an interleave of the two sides per cylinder
// at every 256 bytes
cylinder_buffer.resize(m_cyl_length[cyl]);
- io_generic_read(io, &cylinder_buffer[0], m_cyl_offset[cyl]<<9, m_cyl_length[cyl]);
+ io.read_at(m_cyl_offset[cyl]<<9, &cylinder_buffer[0], m_cyl_length[cyl], actual);
generate_track_from_hfe_bitstream(cyl, 0, samplelength, &cylinder_buffer[0], m_cyl_length[cyl], image);
if (m_heads == 2)
@@ -412,8 +417,9 @@ void hfe_format::generate_track_from_hfe_bitstream(int cyl, int head, int sample
image->set_write_splice_position(cyl, head, 0, 0);
}
-bool hfe_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool hfe_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
std::vector<uint8_t> cylbuf;
// Create a buffer that is big enough to handle HD formats. We don't
@@ -484,7 +490,7 @@ bool hfe_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
header[13] = (m_bit_rate >> 8) & 0xff;
// Now write the header
- io_generic_write(io, header, 0, HEADER_LENGTH);
+ io.write_at(0, header, HEADER_LENGTH, actual);
// Set up the track lookup table
// We need the encoding value to be sure about the track length
@@ -505,10 +511,10 @@ bool hfe_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
for (int i=m_cylinders*4; i < TRACK_TABLE_LENGTH; i++)
track_table[i] = 0xff;
- io_generic_write(io, track_table, 0x200, TRACK_TABLE_LENGTH);
+ io.write_at(0x200, track_table, TRACK_TABLE_LENGTH, actual);
}
// Write the current cylinder
- io_generic_write(io, &cylbuf[0], m_cyl_offset[cyl]<<9, (m_cyl_length[cyl] + 0x1ff) & 0xfe00);
+ io.write_at(m_cyl_offset[cyl]<<9, &cylbuf[0], (m_cyl_length[cyl] + 0x1ff) & 0xfe00, actual);
}
return true;
}
diff --git a/src/lib/formats/hxchfe_dsk.h b/src/lib/formats/hxchfe_dsk.h
index 9d2dbdeae77..4ea98ed861c 100644
--- a/src/lib/formats/hxchfe_dsk.h
+++ b/src/lib/formats/hxchfe_dsk.h
@@ -47,9 +47,9 @@ public:
hfe_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/hxcmfm_dsk.cpp b/src/lib/formats/hxcmfm_dsk.cpp
index b6845b28e4a..e7bf03acd2f 100644
--- a/src/lib/formats/hxcmfm_dsk.cpp
+++ b/src/lib/formats/hxcmfm_dsk.cpp
@@ -1,10 +1,11 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
-#include <cassert>
-
#include "hxcmfm_dsk.h"
+#include "ioprocs.h"
+
+
#define MFM_FORMAT_HEADER "HXCMFM"
#pragma pack(1)
@@ -57,24 +58,26 @@ bool mfm_format::supports_save() const
return true;
}
-int mfm_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int mfm_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t header[7];
- io_generic_read(io, &header, 0, sizeof(header));
+ size_t actual;
+ io.read_at(0, &header, sizeof(header), actual);
if ( memcmp( header, MFM_FORMAT_HEADER, 6 ) ==0) {
return 100;
}
return 0;
}
-bool mfm_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool mfm_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
MFMIMG header;
MFMTRACKIMG trackdesc;
// read header
- io_generic_read(io, &header, 0, sizeof(header));
+ io.read_at(0, &header, sizeof(header), actual);
int drivecyl, driveheads;
image->get_maximal_geometry(drivecyl, driveheads);
@@ -86,12 +89,12 @@ bool mfm_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
for(int side=0; side < header.number_of_side; side++) {
if (!skip_odd || track%2 == 0) {
// read location of
- io_generic_read(io, &trackdesc,(header.mfmtracklistoffset)+( counter *sizeof(trackdesc)),sizeof(trackdesc));
+ io.read_at((header.mfmtracklistoffset)+( counter *sizeof(trackdesc)), &trackdesc, sizeof(trackdesc), actual);
trackbuf.resize(trackdesc.mfmtracksize);
// actual data read
- io_generic_read(io, &trackbuf[0], trackdesc.mfmtrackoffset, trackdesc.mfmtracksize);
+ io.read_at(trackdesc.mfmtrackoffset, &trackbuf[0], trackdesc.mfmtracksize, actual);
if (skip_odd) {
generate_track_from_bitstream(track/2, side, &trackbuf[0], trackdesc.mfmtracksize*8, image);
@@ -109,9 +112,10 @@ bool mfm_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return true;
}
-bool mfm_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool mfm_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
// TODO: HD support
+ size_t actual;
MFMIMG header;
int track_count, head_count;
image->get_actual_geometry(track_count, head_count);
@@ -124,7 +128,7 @@ bool mfm_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
header.floppyiftype = 4;
header.mfmtracklistoffset = sizeof(MFMIMG);
- io_generic_write(io, &header, 0, sizeof(MFMIMG));
+ io.write_at(0, &header, sizeof(MFMIMG), actual);
int tpos = sizeof(MFMIMG);
int dpos = tpos + track_count*head_count*sizeof(MFMTRACKIMG);
@@ -143,8 +147,8 @@ bool mfm_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
trackdesc.mfmtracksize = packed.size();
trackdesc.mfmtrackoffset = dpos;
- io_generic_write(io, &trackdesc, tpos, sizeof(MFMTRACKIMG));
- io_generic_write(io, packed.data(), dpos, packed.size());
+ io.write_at(tpos, &trackdesc, sizeof(MFMTRACKIMG), actual);
+ io.write_at(dpos, packed.data(), packed.size(), actual);
tpos += sizeof(MFMTRACKIMG);
dpos += packed.size();
diff --git a/src/lib/formats/hxcmfm_dsk.h b/src/lib/formats/hxcmfm_dsk.h
index a6f884ab03e..c42190f3aae 100644
--- a/src/lib/formats/hxcmfm_dsk.h
+++ b/src/lib/formats/hxcmfm_dsk.h
@@ -19,9 +19,9 @@ class mfm_format : public floppy_image_format_t
public:
mfm_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/ibmxdf_dsk.cpp b/src/lib/formats/ibmxdf_dsk.cpp
index b18ffad63dc..5a44290a337 100644
--- a/src/lib/formats/ibmxdf_dsk.cpp
+++ b/src/lib/formats/ibmxdf_dsk.cpp
@@ -32,6 +32,8 @@
#include "ibmxdf_dsk.h"
+#include "ioprocs.h"
+
ibmxdf_format::ibmxdf_format() : wd177x_format(formats)
{
@@ -52,7 +54,7 @@ const char *ibmxdf_format::extensions() const
return "xdf,img";
}
-int ibmxdf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int ibmxdf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int type = find_size(io, form_factor, variants);
@@ -61,9 +63,11 @@ int ibmxdf_format::identify(io_generic *io, uint32_t form_factor, const std::vec
return 0;
}
-int ibmxdf_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int ibmxdf_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return -1;
if (size != 1884160)
return -1;
@@ -173,7 +177,7 @@ const ibmxdf_format::format ibmxdf_format::formats_head1_track0[] = {
{}
};
-bool ibmxdf_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool ibmxdf_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
int type = find_size(io, form_factor, variants);
if(type == -1)
@@ -207,8 +211,9 @@ bool ibmxdf_format::load(io_generic *io, uint32_t form_factor, const std::vector
desc[16].p1 = get_track_dam_mfm(tf, head, track);
build_sector_description(tf, sectdata, sectors, track, head);
- int track_size = compute_track_size(f) * 2; // read both sides at once
- io_generic_read(io, sectdata, get_image_offset(f, head, track), track_size);
+ int const track_size = compute_track_size(f) * 2; // read both sides at once
+ size_t actual;
+ io.read_at(get_image_offset(f, head, track), sectdata, track_size, actual);
generate_track(desc, track, head, sectors, tf.sector_count, total_size, image);
}
diff --git a/src/lib/formats/ibmxdf_dsk.h b/src/lib/formats/ibmxdf_dsk.h
index 6d37142ac30..dbb448f8ad3 100644
--- a/src/lib/formats/ibmxdf_dsk.h
+++ b/src/lib/formats/ibmxdf_dsk.h
@@ -23,11 +23,11 @@ public:
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override { return false; }
- virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual int get_image_offset(const format &f, int head, int track) override;
virtual const wd177x_format::format &get_track_format(const format &f, int head, int track) override;
diff --git a/src/lib/formats/imd_dsk.cpp b/src/lib/formats/imd_dsk.cpp
index b3d4eac8229..b0e9a4159d9 100644
--- a/src/lib/formats/imd_dsk.cpp
+++ b/src/lib/formats/imd_dsk.cpp
@@ -10,7 +10,8 @@
#include "imd_dsk.h"
-#include <cassert>
+#include "ioprocs.h"
+
#include <cstring>
@@ -409,25 +410,29 @@ void imd_format::fixnum(char *start, char *end) const
};
}
-int imd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int imd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
char h[4];
- io_generic_read(io, h, 0, 4);
+ size_t actual;
+ io.read_at(0, h, 4, actual);
if(!memcmp(h, "IMD ", 4))
return 100;
return 0;
}
-bool imd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool imd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return false;
std::vector<uint8_t> img(size);
- io_generic_read(io, &img[0], 0, size);
+ size_t actual;
+ io.read_at(0, &img[0], size, actual);
uint64_t pos, savepos;
- for(pos=0; pos < size && img[pos] != 0x1a; pos++) {};
+ for(pos=0; pos < size && img[pos] != 0x1a; pos++) { }
pos++;
m_comment.resize(pos);
@@ -627,39 +632,34 @@ bool can_compress(const uint8_t* buffer, uint8_t ptrn, uint64_t size)
return true;
}
-bool imd_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool imd_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint64_t pos = 0;
- io_generic_write(io, &m_comment[0], pos, m_comment.size());
- pos += m_comment.size();
+ if(io.seek(0, SEEK_SET))
+ return false;
+
+ size_t written;
+ io.write(&m_comment[0], m_comment.size(), written);
for (int i = 0; i < m_mode.size(); i++)
{
- io_generic_write(io, &m_mode[i], pos++, 1);
- io_generic_write(io, &m_track[i], pos++, 1);
- io_generic_write(io, &m_head[i], pos++, 1);
- io_generic_write(io, &m_sector_count[i], pos++, 1);
- io_generic_write(io, &m_ssize[i], pos++, 1);
+ io.write(&m_mode[i], 1, written);
+ io.write(&m_track[i], 1, written);
+ io.write(&m_head[i], 1, written);
+ io.write(&m_sector_count[i], 1, written);
+ io.write(&m_ssize[i], 1, written);
- io_generic_write(io, &m_snum[i][0], pos, m_sector_count[i]);
- pos += m_sector_count[i];
+ io.write(&m_snum[i][0], m_sector_count[i], written);
if (m_tnum[i].size())
- {
- io_generic_write(io, &m_tnum[i][0], pos, m_sector_count[i]);
- pos += m_sector_count[i];
- }
+ io.write(&m_tnum[i][0], m_sector_count[i], written);
if (m_hnum[i].size())
- {
- io_generic_write(io, &m_hnum[i][0], pos, m_sector_count[i]);
- pos += m_sector_count[i];
- }
+ io.write(&m_hnum[i][0], m_sector_count[i], written);
- uint32_t actual_size = m_ssize[i] < 7 ? 128 << m_ssize[i] : 8192;
- uint8_t head = m_head[i] & 0x3f;
+ uint32_t const actual_size = m_ssize[i] < 7 ? 128 << m_ssize[i] : 8192;
+ uint8_t const head = m_head[i] & 0x3f;
- bool fm = m_mode[i]< 3;
+ bool const fm = m_mode[i]< 3;
auto bitstream = generate_bitstream_from_track(m_track[i]*m_trackmult, head, fm ? 4000 : 2000, image);
std::vector<std::vector<uint8_t>> sectors;
@@ -674,11 +674,10 @@ bool imd_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
const auto &data = sectors[m_snum[i][j]];
- uint8_t mode;
if (data.empty())
{
- mode = 0;
- io_generic_write(io, &mode, pos++, 1);
+ uint8_t const mode = 0;
+ io.write(&mode, 1, written);
continue;
}
else if (data.size() < actual_size) {
@@ -690,16 +689,15 @@ bool imd_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
if (can_compress(sdata, sdata[0], actual_size))
{
- mode = 2;
- io_generic_write(io, &mode, pos++, 1);
- io_generic_write(io, &sdata[0], pos++, 1);
+ uint8_t const mode = 2;
+ io.write(&mode, 1, written);
+ io.write(&sdata[0], 1, written);
}
else
{
- mode = 1;
- io_generic_write(io, &mode, pos++, 1);
- io_generic_write(io, &sdata, pos, actual_size);
- pos += actual_size;
+ uint8_t const mode = 1;
+ io.write(&mode, 1, written);
+ io.write(&sdata, actual_size, written);
}
}
}
diff --git a/src/lib/formats/imd_dsk.h b/src/lib/formats/imd_dsk.h
index ba04a0c09e7..acf7da9b892 100644
--- a/src/lib/formats/imd_dsk.h
+++ b/src/lib/formats/imd_dsk.h
@@ -17,9 +17,9 @@ class imd_format : public floppy_image_format_t
public:
imd_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image* image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image* image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/img_dsk.cpp b/src/lib/formats/img_dsk.cpp
index 757f695d923..73ae499c764 100644
--- a/src/lib/formats/img_dsk.cpp
+++ b/src/lib/formats/img_dsk.cpp
@@ -17,6 +17,7 @@
#include "img_dsk.h"
#include "coretmpl.h" // BIT
+#include "ioprocs.h"
// Debugging
@@ -40,9 +41,12 @@ img_format::img_format()
{
}
-int img_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int img_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size)) {
+ return 0;
+ }
if (((form_factor == floppy_image::FF_8) || (form_factor == floppy_image::FF_UNKNOWN)) &&
size == IMG_IMAGE_SIZE) {
@@ -52,17 +56,18 @@ int img_format::identify(io_generic *io, uint32_t form_factor, const std::vector
}
}
-bool img_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool img_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint64_t size = io_generic_size(io);
- if (size != IMG_IMAGE_SIZE) {
+ uint64_t size;
+ if (io.length(size) || (size != IMG_IMAGE_SIZE)) {
return false;
}
image->set_variant(floppy_image::SSDD);
// Suck in the whole image
std::vector<uint8_t> image_data(size);
- io_generic_read(io, (void *)image_data.data(), 0, size);
+ size_t actual;
+ io.read_at(0, image_data.data(), size, actual);
for (unsigned cyl = 0; cyl < TRACKS; cyl++) {
std::vector<uint32_t> track_data;
@@ -96,7 +101,7 @@ bool img_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return true;
}
-bool img_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool img_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
for (int cyl = 0; cyl < TRACKS; cyl++) {
auto bitstream = generate_bitstream_from_track(cyl , 0 , CELL_SIZE , image , 0);
@@ -106,7 +111,8 @@ bool img_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
while (get_next_sector(bitstream , pos , track_no , sector_no , sector_data)) {
if (track_no == cyl && sector_no >= 1 && sector_no <= SECTORS) {
unsigned offset_in_image = (cyl * SECTORS + sector_no - 1) * SECTOR_SIZE;
- io_generic_write(io, sector_data, offset_in_image, SECTOR_SIZE);
+ size_t actual;
+ io.write_at(offset_in_image, sector_data, SECTOR_SIZE, actual);
}
}
}
diff --git a/src/lib/formats/img_dsk.h b/src/lib/formats/img_dsk.h
index af9a2d62466..bbd7a0fc03e 100644
--- a/src/lib/formats/img_dsk.h
+++ b/src/lib/formats/img_dsk.h
@@ -27,9 +27,9 @@ public:
img_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
virtual const char *extensions() const override;
diff --git a/src/lib/formats/ioprocs.cpp b/src/lib/formats/ioprocs.cpp
deleted file mode 100644
index 78e009aa112..00000000000
--- a/src/lib/formats/ioprocs.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Nathan Woods
-#include <cstdio>
-#include <cstring>
-#include <cassert>
-#include "ioprocs.h"
-#include "corefile.h"
-
-
-/*********************************************************************
- ioprocs implementation on stdio
-*********************************************************************/
-
-static void stdio_closeproc(void *file)
-{
- fclose((FILE*)file);
-}
-
-static int stdio_seekproc(void *file, int64_t offset, int whence)
-{
- return fseek((FILE*)file, (long) offset, whence);
-}
-
-static size_t stdio_readproc(void *file, void *buffer, size_t length)
-{
- return fread(buffer, 1, length, (FILE*)file);
-}
-
-static size_t stdio_writeproc(void *file, const void *buffer, size_t length)
-{
- return fwrite(buffer, 1, length, (FILE*)file);
-}
-
-static uint64_t stdio_filesizeproc(void *file)
-{
- long l, sz;
- l = ftell((FILE*)file);
- if (fseek((FILE*)file, 0, SEEK_END))
- return (size_t) -1;
- sz = ftell((FILE*)file);
- if (fseek((FILE*)file, l, SEEK_SET))
- return (size_t) -1;
- return (size_t) sz;
-}
-
-const struct io_procs stdio_ioprocs =
-{
- stdio_closeproc,
- stdio_seekproc,
- stdio_readproc,
- stdio_writeproc,
- stdio_filesizeproc
-};
-
-const struct io_procs stdio_ioprocs_noclose =
-{
- nullptr,
- stdio_seekproc,
- stdio_readproc,
- stdio_writeproc,
- stdio_filesizeproc
-};
-
-/*********************************************************************
- ioprocs implementation on corefile
-*********************************************************************/
-
-static void corefile_closeproc(void *file)
-{
- delete (util::core_file*)file;
-}
-
-static int corefile_seekproc(void *file, int64_t offset, int whence)
-{
- return ((util::core_file*)file)->seek(offset, whence);
-}
-
-static size_t corefile_readproc(void *file, void *buffer, size_t length)
-{
- return ((util::core_file*)file)->read(buffer, length);
-}
-
-static size_t corefile_writeproc(void *file, const void *buffer, size_t length)
-{
- return ((util::core_file*)file)->write(buffer, length);
-}
-
-static uint64_t corefile_filesizeproc(void *file)
-{
- const auto l = ((util::core_file*)file)->tell();
- if (((util::core_file*)file)->seek(0, SEEK_END))
- return (size_t) -1;
- const auto sz = ((util::core_file*)file)->tell();
- if (((util::core_file*)file)->seek(l, SEEK_SET))
- return uint64_t(-1);
- return uint64_t(sz);
-}
-
-const struct io_procs corefile_ioprocs =
-{
- corefile_closeproc,
- corefile_seekproc,
- corefile_readproc,
- corefile_writeproc,
- corefile_filesizeproc
-};
-
-const struct io_procs corefile_ioprocs_noclose =
-{
- nullptr,
- corefile_seekproc,
- corefile_readproc,
- corefile_writeproc,
- corefile_filesizeproc
-};
-
-
-
-/*********************************************************************
- calls for accessing generic IO
-*********************************************************************/
-
-static void io_generic_seek(struct io_generic *genio, uint64_t offset)
-{
- genio->procs->seekproc(genio->file, offset, SEEK_SET);
-}
-
-
-
-void io_generic_close(struct io_generic *genio)
-{
- if (genio->procs->closeproc)
- genio->procs->closeproc(genio->file);
-}
-
-
-
-void io_generic_read(struct io_generic *genio, void *buffer, uint64_t offset, size_t length)
-{
- uint64_t size;
- size_t bytes_read;
-
- size = io_generic_size(genio);
- if (size <= offset)
- {
- bytes_read = 0;
- }
- else
- {
- io_generic_seek(genio, offset);
- bytes_read = genio->procs->readproc(genio->file, buffer, length);
- }
- memset(((uint8_t *) buffer) + bytes_read, genio->filler, length - bytes_read);
-}
-
-
-
-void io_generic_write(struct io_generic *genio, const void *buffer, uint64_t offset, size_t length)
-{
- uint64_t filler_size = 0;
- char filler_buffer[1024];
- size_t bytes_to_write;
- uint64_t size;
-
- size = io_generic_size(genio);
-
- if (size < offset)
- {
- filler_size = offset - size;
- offset = size;
- }
-
- io_generic_seek(genio, offset);
-
- if (filler_size)
- {
- memset(filler_buffer, genio->filler, sizeof(filler_buffer));
- do
- {
- bytes_to_write = (filler_size > sizeof(filler_buffer)) ? sizeof(filler_buffer) : (size_t) filler_size;
- genio->procs->writeproc(genio->file, filler_buffer, bytes_to_write);
- filler_size -= bytes_to_write;
- }
- while(filler_size > 0);
- }
-
- if (length > 0)
- genio->procs->writeproc(genio->file, buffer, length);
-}
-
-
-
-void io_generic_write_filler(struct io_generic *genio, uint8_t filler, uint64_t offset, size_t length)
-{
- uint8_t buffer[512];
- size_t this_length;
-
- memset(buffer, filler, std::min(length, sizeof(buffer)));
-
- while(length > 0)
- {
- this_length = std::min(length, sizeof(buffer));
- io_generic_write(genio, buffer, offset, this_length);
- offset += this_length;
- length -= this_length;
- }
-}
-
-
-
-uint64_t io_generic_size(struct io_generic *genio)
-{
- return genio->procs->filesizeproc(genio->file);
-}
diff --git a/src/lib/formats/ioprocs.h b/src/lib/formats/ioprocs.h
deleted file mode 100644
index 1244873f14c..00000000000
--- a/src/lib/formats/ioprocs.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Nathan Woods
-/*********************************************************************
-
- ioprocs.h
-
- File IO abstraction layer
-
-*********************************************************************/
-#ifndef MAME_FORMATS_IOPROCS_H
-#define MAME_FORMATS_IOPROCS_H
-
-#pragma once
-
-#include <cstdint>
-#include <cstdlib>
-
-
-
-/***************************************************************************
-
- Type definitions
-
-***************************************************************************/
-
-struct io_procs
-{
- void (*closeproc)(void *file) = nullptr;
- int (*seekproc)(void *file, int64_t offset, int whence) = nullptr;
- size_t (*readproc)(void *file, void *buffer, size_t length) = nullptr;
- size_t (*writeproc)(void *file, const void *buffer, size_t length) = nullptr;
- uint64_t (*filesizeproc)(void *file) = nullptr;
-};
-
-
-
-struct io_generic
-{
- const struct io_procs *procs = nullptr;
- void *file = nullptr;
- uint8_t filler = 0;
-};
-
-
-/***************************************************************************
-
- Globals
-
-***************************************************************************/
-
-extern const io_procs stdio_ioprocs;
-extern const io_procs stdio_ioprocs_noclose;
-extern const io_procs corefile_ioprocs;
-extern const io_procs corefile_ioprocs_noclose;
-
-
-
-/***************************************************************************
-
- Prototypes
-
-***************************************************************************/
-
-void io_generic_close(struct io_generic *genio);
-void io_generic_read(struct io_generic *genio, void *buffer, uint64_t offset, size_t length);
-void io_generic_write(struct io_generic *genio, const void *buffer, uint64_t offset, size_t length);
-void io_generic_write_filler(struct io_generic *genio, uint8_t filler, uint64_t offset, size_t length);
-uint64_t io_generic_size(struct io_generic *genio);
-
-#endif // MAME_FORMATS_IOPROCS_H
diff --git a/src/lib/formats/ipf_dsk.cpp b/src/lib/formats/ipf_dsk.cpp
index 0f1725f5c14..10c9ba2c4a9 100644
--- a/src/lib/formats/ipf_dsk.cpp
+++ b/src/lib/formats/ipf_dsk.cpp
@@ -2,6 +2,8 @@
// copyright-holders:Olivier Galibert
#include "ipf_dsk.h"
+#include "ioprocs.h"
+
#include <cassert>
@@ -27,11 +29,12 @@ bool ipf_format::supports_save() const
return false;
}
-int ipf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int ipf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
static const uint8_t refh[12] = { 0x43, 0x41, 0x50, 0x53, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0xd5, 0x73, 0xba };
uint8_t h[12];
- io_generic_read(io, h, 0, 12);
+ size_t actual;
+ io.read_at(0, h, 12, actual);
if(!memcmp(h, refh, 12))
return 100;
@@ -39,14 +42,16 @@ int ipf_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool ipf_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool ipf_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- ipf_decode dec;
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return false;
std::vector<uint8_t> data(size);
- io_generic_read(io, &data[0], 0, size);
- bool res = dec.parse(data, image);
- return res;
+ size_t actual;
+ io.read_at(0, &data[0], size, actual);
+ ipf_decode dec;
+ return dec.parse(data, image);
}
uint32_t ipf_format::ipf_decode::r32(const uint8_t *p)
diff --git a/src/lib/formats/ipf_dsk.h b/src/lib/formats/ipf_dsk.h
index d848a5bb3a0..28d552d5812 100644
--- a/src/lib/formats/ipf_dsk.h
+++ b/src/lib/formats/ipf_dsk.h
@@ -12,8 +12,8 @@
class ipf_format : public floppy_image_format_t
{
public:
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/jfd_dsk.cpp b/src/lib/formats/jfd_dsk.cpp
index 947d6ba4022..7a1da472356 100644
--- a/src/lib/formats/jfd_dsk.cpp
+++ b/src/lib/formats/jfd_dsk.cpp
@@ -158,9 +158,13 @@
*********************************************************************/
-#include <zlib.h>
#include "formats/jfd_dsk.h"
+#include "ioprocs.h"
+
+#include <zlib.h>
+
+
static const uint8_t JFD_HEADER[4] = { 'J', 'F', 'D', 'I' };
static const uint8_t GZ_HEADER[2] = { 0x1f, 0x8b };
@@ -183,11 +187,14 @@ const char *jfd_format::extensions() const
return "jfd";
}
-int jfd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int jfd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return 0;
std::vector<uint8_t> img(size);
- io_generic_read(io, &img[0], 0, size);
+ size_t actual;
+ io.read_at(0, &img[0], size, actual);
int err;
std::vector<uint8_t> gz_ptr(4);
@@ -221,11 +228,15 @@ int jfd_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool jfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool jfd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return false;
+
std::vector<uint8_t> img(size);
- io_generic_read(io, &img[0], 0, size);
+ size_t actual;
+ io.read_at(0, &img[0], size, actual);
int err;
std::vector<uint8_t> gz_ptr;
diff --git a/src/lib/formats/jfd_dsk.h b/src/lib/formats/jfd_dsk.h
index 75b9910c426..7231ccf3460 100644
--- a/src/lib/formats/jfd_dsk.h
+++ b/src/lib/formats/jfd_dsk.h
@@ -23,8 +23,8 @@ public:
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override;
};
diff --git a/src/lib/formats/jvc_dsk.cpp b/src/lib/formats/jvc_dsk.cpp
index 8332f86bace..c71f2c3be06 100644
--- a/src/lib/formats/jvc_dsk.cpp
+++ b/src/lib/formats/jvc_dsk.cpp
@@ -106,6 +106,8 @@
#include "jvc_dsk.h"
+#include "ioprocs.h"
+
jvc_format::jvc_format()
{
@@ -126,19 +128,22 @@ const char *jvc_format::extensions() const
return "jvc,dsk";
}
-bool jvc_format::parse_header(io_generic *io, int &header_size, int &tracks, int &heads, int &sectors, int &sector_size, int &base_sector_id)
+bool jvc_format::parse_header(util::random_read &io, int &header_size, int &tracks, int &heads, int &sectors, int &sector_size, int &base_sector_id)
{
// The JVC format has a header whose size is the size of the image modulo 256. Currently, we only
// handle up to five header bytes
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return false;
header_size = size % 256;
uint8_t header[5];
// if we know that this is a header of a bad size, we can fail immediately; otherwise read the header
+ size_t actual;
if (header_size >= sizeof(header))
return false;
if (header_size > 0)
- io_generic_read(io, header, 0, header_size);
+ io.read_at(0, header, header_size, actual);
// default values
heads = 1;
@@ -168,13 +173,13 @@ bool jvc_format::parse_header(io_generic *io, int &header_size, int &tracks, int
return tracks * heads * sectors * sector_size == (size - header_size);
}
-int jvc_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int jvc_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int header_size, tracks, heads, sectors, sector_size, sector_base_id;
return parse_header(io, header_size, tracks, heads, sectors, sector_size, sector_base_id) ? 50 : 0;
}
-bool jvc_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool jvc_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
int header_size, track_count, head_count, sector_count, sector_size, sector_base_id;
@@ -210,7 +215,8 @@ bool jvc_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
sectors[interleave[i]].bad_crc = false;
sectors[interleave[i]].data = &sector_data[sector_offset];
- io_generic_read(io, sectors[interleave[i]].data, file_offset, sector_size);
+ size_t actual;
+ io.read_at(file_offset, sectors[interleave[i]].data, sector_size, actual);
sector_offset += sector_size;
file_offset += sector_size;
@@ -223,7 +229,7 @@ bool jvc_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return true;
}
-bool jvc_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool jvc_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint64_t file_offset = 0;
@@ -236,7 +242,8 @@ bool jvc_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
uint8_t header[2];
header[0] = 18;
header[1] = 2;
- io_generic_write(io, header, file_offset, sizeof(header));
+ size_t actual;
+ io.write_at(file_offset, header, sizeof(header), actual);
file_offset += sizeof(header);
}
@@ -256,7 +263,8 @@ bool jvc_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
return false;
}
- io_generic_write(io, sectors[1 + i].data(), file_offset, 256);
+ size_t actual;
+ io.write_at(file_offset, sectors[1 + i].data(), 256, actual);
file_offset += 256;
}
}
diff --git a/src/lib/formats/jvc_dsk.h b/src/lib/formats/jvc_dsk.h
index 7c744a0acb5..1b8b59c725f 100644
--- a/src/lib/formats/jvc_dsk.h
+++ b/src/lib/formats/jvc_dsk.h
@@ -35,13 +35,13 @@ public:
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override;
private:
- bool parse_header(io_generic *io, int &header_size, int &tracks, int &heads, int &sectors, int &sector_size, int &base_sector_id);
+ bool parse_header(util::random_read &io, int &header_size, int &tracks, int &heads, int &sectors, int &sector_size, int &base_sector_id);
};
extern const floppy_format_type FLOPPY_JVC_FORMAT;
diff --git a/src/lib/formats/m20_dsk.cpp b/src/lib/formats/m20_dsk.cpp
index 60b2ae58176..05c52c2f211 100644
--- a/src/lib/formats/m20_dsk.cpp
+++ b/src/lib/formats/m20_dsk.cpp
@@ -16,6 +16,9 @@
#include "m20_dsk.h"
+#include "ioprocs.h"
+
+
m20_format::m20_format()
{
}
@@ -40,21 +43,27 @@ bool m20_format::supports_save() const
return true;
}
-int m20_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int m20_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- if(io_generic_size(io) == 286720)
+ uint64_t size;
+ if (io.length(size))
+ return 0;
+
+ if (size == 286720)
return 50;
+
return 0;
}
-bool m20_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool m20_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
for (int track = 0; track < 35; track++)
for (int head = 0; head < 2; head ++) {
bool mfm = track || head;
desc_pc_sector sects[16];
uint8_t sectdata[16*256];
- io_generic_read(io, sectdata, 16*256*(track*2+head), 16*256);
+ size_t actual;
+ io.read_at(16*256*(track*2+head), sectdata, 16*256, actual);
for (int i = 0; i < 16; i++) {
int j = i/2 + (i & 1 ? 0 : 8);
sects[i].track = track;
@@ -76,7 +85,7 @@ bool m20_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return true;
}
-bool m20_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool m20_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint64_t file_offset = 0;
@@ -87,26 +96,27 @@ bool m20_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
auto bitstream = generate_bitstream_from_track(0, 0, 4000, image);
auto sectors = extract_sectors_from_bitstream_fm_pc(bitstream);
- for (int i = 0; i < 16; i++)
- {
- io_generic_write(io, sectors[i + 1].data(), file_offset, 128);
+ for (int i = 0; i < 16; i++) {
+ size_t actual;
+ io.write_at(file_offset, sectors[i + 1].data(), 128, actual);
file_offset += 256; //128;
}
// rest are mfm tracks
- for (int track = 0; track < track_count; track++)
- {
- for (int head = 0; head < head_count; head++)
- {
+ for (int track = 0; track < track_count; track++) {
+ for (int head = 0; head < head_count; head++) {
// skip track 0, head 0
- if (track == 0) { if (head_count == 1) break; else head++; }
+ if (track == 0) {
+ if (head_count == 1) break;
+ else head++;
+ }
bitstream = generate_bitstream_from_track(track, head, 2000, image);
sectors = extract_sectors_from_bitstream_mfm_pc(bitstream);
- for (int i = 0; i < 16; i++)
- {
- io_generic_write(io, sectors[i + 1].data(), file_offset, 256);
+ for (int i = 0; i < 16; i++) {
+ size_t actual;
+ io.write_at(file_offset, sectors[i + 1].data(), 256, actual);
file_offset += 256;
}
}
diff --git a/src/lib/formats/m20_dsk.h b/src/lib/formats/m20_dsk.h
index ed8a7bc4517..d9bd7a45425 100644
--- a/src/lib/formats/m20_dsk.h
+++ b/src/lib/formats/m20_dsk.h
@@ -18,9 +18,9 @@ class m20_format : public floppy_image_format_t {
public:
m20_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/mdos_dsk.cpp b/src/lib/formats/mdos_dsk.cpp
index b96be2f327e..e49d825ea9a 100644
--- a/src/lib/formats/mdos_dsk.cpp
+++ b/src/lib/formats/mdos_dsk.cpp
@@ -50,7 +50,9 @@
*/
#include "mdos_dsk.h"
-#include "formats/imageutl.h"
+#include "imageutl.h"
+
+#include "ioprocs.h"
mdos_format::mdos_format() : wd177x_format(formats)
@@ -72,12 +74,13 @@ const char *mdos_format::extensions() const
return "dsk";
}
-int mdos_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int mdos_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- int type = find_size(io, form_factor, variants);
+ int type = find_size(io, form_factor, variants);
if (type != -1)
return 75;
+
return 0;
}
@@ -109,12 +112,15 @@ int mdos_format::parse_date_field(uint8_t *str)
return (high - 0x30) * 10 + (low - 0x30);
}
-int mdos_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int mdos_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ size_t actual;
+ uint64_t size;
+ if (io.length(size))
+ return -1;
// Look at the disk id sector.
- io_generic_read(io, &info, 0, sizeof(struct disk_id_sector));
+ io.read_at(0, &info, sizeof(struct disk_id_sector), actual);
LOG_FORMATS("MDOS floppy dsk: size %d bytes, %d total sectors, %d remaining bytes, expected form factor %x\n", (uint32_t)size, (uint32_t)size / 128, (uint32_t)size % 128, form_factor);
@@ -176,8 +182,8 @@ int mdos_format::find_size(io_generic *io, uint32_t form_factor, const std::vect
// the extent of the disk are free or available.
uint8_t cluster_allocation[128], cluster_available[128];
- io_generic_read(io, &cluster_allocation, 1 * 128, sizeof(cluster_allocation));
- io_generic_read(io, &cluster_available, 2 * 128, sizeof(cluster_available));
+ io.read_at(1 * 128, &cluster_allocation, sizeof(cluster_allocation), actual);
+ io.read_at(2 * 128, &cluster_available, sizeof(cluster_available), actual);
for (int cluster = 0; cluster < sizeof(cluster_allocation) * 8; cluster++) {
if (cluster * 4 * 128 + 4 * 128 > size) {
diff --git a/src/lib/formats/mdos_dsk.h b/src/lib/formats/mdos_dsk.h
index 65e7bca9f14..56dd29c9954 100644
--- a/src/lib/formats/mdos_dsk.h
+++ b/src/lib/formats/mdos_dsk.h
@@ -19,8 +19,8 @@ public:
virtual const char *name() const override;
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual const wd177x_format::format &get_track_format(const format &f, int head, int track) override;
private:
diff --git a/src/lib/formats/mfi_dsk.cpp b/src/lib/formats/mfi_dsk.cpp
index 7670bf6bfb9..8272253c36a 100644
--- a/src/lib/formats/mfi_dsk.cpp
+++ b/src/lib/formats/mfi_dsk.cpp
@@ -1,10 +1,12 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
-#include <cassert>
-
#include "mfi_dsk.h"
+
+#include "ioprocs.h"
+
#include <zlib.h>
+
/*
Mess floppy image structure:
@@ -94,11 +96,12 @@ bool mfi_format::supports_save() const
return true;
}
-int mfi_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int mfi_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
header h;
- io_generic_read(io, &h, 0, sizeof(header));
+ size_t actual;
+ io.read_at(0, &h, sizeof(header), actual);
if(memcmp( h.sign, sign, 16 ) == 0 &&
(h.cyl_count & CYLINDER_MASK) <= 84 &&
(h.cyl_count >> RESOLUTION_SHIFT) < 3 &&
@@ -108,15 +111,16 @@ int mfi_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool mfi_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool mfi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
header h;
entry entries[84*2*4];
- io_generic_read(io, &h, 0, sizeof(header));
+ io.read_at(0, &h, sizeof(header), actual);
int resolution = h.cyl_count >> RESOLUTION_SHIFT;
h.cyl_count &= CYLINDER_MASK;
- io_generic_read(io, &entries, sizeof(header), (h.cyl_count << resolution)*h.head_count*sizeof(entry));
+ io.read_at(sizeof(header), &entries, (h.cyl_count << resolution)*h.head_count*sizeof(entry), actual);
image->set_form_variant(h.form_factor, h.variant);
@@ -139,7 +143,7 @@ bool mfi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
compressed.resize(ent->compressed_size);
- io_generic_read(io, &compressed[0], ent->offset, ent->compressed_size);
+ io.read_at(ent->offset, &compressed[0], ent->compressed_size, actual);
unsigned int cell_count = ent->uncompressed_size/4;
std::vector<uint32_t> &trackbuf = image->get_buffer(cyl >> 2, head, cyl & 3);;
@@ -169,8 +173,9 @@ bool mfi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return true;
}
-bool mfi_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool mfi_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
int tracks, heads;
image->get_actual_geometry(tracks, heads);
int resolution = image->get_resolution();
@@ -190,7 +195,7 @@ bool mfi_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
h.form_factor = image->get_form_factor();
h.variant = image->get_variant();
- io_generic_write(io, &h, 0, sizeof(header));
+ io.write_at(0, &h, sizeof(header), actual);
memset(entries, 0, sizeof(entries));
@@ -226,11 +231,11 @@ bool mfi_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
entries[epos].write_splice = image->get_write_splice_position(track >> 2, head, track & 3);
epos++;
- io_generic_write(io, postcomp.get(), pos, csize);
+ io.write_at(pos, postcomp.get(), csize, actual);
pos += csize;
}
- io_generic_write(io, entries, sizeof(header), (tracks << resolution)*heads*sizeof(entry));
+ io.write_at(sizeof(header), entries, (tracks << resolution)*heads*sizeof(entry), actual);
return true;
}
diff --git a/src/lib/formats/mfi_dsk.h b/src/lib/formats/mfi_dsk.h
index 129a9ee599e..d0dd36c3d68 100644
--- a/src/lib/formats/mfi_dsk.h
+++ b/src/lib/formats/mfi_dsk.h
@@ -12,9 +12,9 @@ class mfi_format : public floppy_image_format_t
public:
mfi_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/mfm_hd.cpp b/src/lib/formats/mfm_hd.cpp
index 98d8079443c..738f0999863 100644
--- a/src/lib/formats/mfm_hd.cpp
+++ b/src/lib/formats/mfm_hd.cpp
@@ -294,9 +294,9 @@ int mfmhd_generic_format::chs_to_lba(int cylinder, int head, int sector)
else return -1;
}
-chd_error mfmhd_generic_format::load(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head)
+std::error_condition mfmhd_generic_format::load(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head)
{
- chd_error state = CHDERR_NONE;
+ std::error_condition state;
uint8_t sector_content[16384];
int sectorcount = m_param.sectors_per_track;
@@ -382,8 +382,9 @@ chd_error mfmhd_generic_format::load(chd_file* chdfile, uint16_t* trackimage, in
int lbaposition = chs_to_lba(cylinder, head, sec_number);
if (lbaposition>=0)
{
- chd_error state = chdfile->read_units(lbaposition, sector_content);
- if (state != CHDERR_NONE) break;
+ state = chdfile->read_units(lbaposition, sector_content);
+ if (state)
+ break;
}
else
{
@@ -413,7 +414,7 @@ chd_error mfmhd_generic_format::load(chd_file* chdfile, uint16_t* trackimage, in
if (TRACE_LAYOUT) osd_printf_verbose("\n");
// Gap 4
- if (state == CHDERR_NONE)
+ if (!state)
{
// Fill the rest with 0x4e
mfm_encode(trackimage, position, 0x4e, tracksize-position);
@@ -433,7 +434,7 @@ enum
CHECK_CRC
};
-chd_error mfmhd_generic_format::save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int current_cylinder, int current_head)
+std::error_condition mfmhd_generic_format::save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int current_cylinder, int current_head)
{
if (TRACE_RWTRACK) osd_printf_verbose("%s: write back (c=%d,h=%d) to CHD\n", tag(), current_cylinder, current_head);
@@ -490,7 +491,7 @@ chd_error mfmhd_generic_format::save(chd_file* chdfile, uint16_t* trackimage, in
bool countgap3 = false;
bool countsync = false;
- chd_error chdstate = CHDERR_NONE;
+ std::error_condition chdstate;
if (TRACE_IMAGE)
{
@@ -643,7 +644,7 @@ chd_error mfmhd_generic_format::save(chd_file* chdfile, uint16_t* trackimage, in
if (TRACE_DETAIL) osd_printf_verbose("%s: Writing sector chs=(%d,%d,%d) to CHD\n", tag(), current_cylinder, current_head, sector);
chdstate = chdfile->write_units(chs_to_lba(current_cylinder, current_head, sector), buffer);
- if (chdstate != CHDERR_NONE)
+ if (chdstate)
{
osd_printf_verbose("%s: Write error while writing sector chs=(%d,%d,%d)\n", tag(), cylinder, head, sector);
}
diff --git a/src/lib/formats/mfm_hd.h b/src/lib/formats/mfm_hd.h
index 7d28adc518d..472062d1440 100644
--- a/src/lib/formats/mfm_hd.h
+++ b/src/lib/formats/mfm_hd.h
@@ -151,10 +151,10 @@ public:
virtual ~mfmhd_image_format_t() {};
// Load the image.
- virtual chd_error load(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) = 0;
+ virtual std::error_condition load(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) = 0;
// Save the image.
- virtual chd_error save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) = 0;
+ virtual std::error_condition save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) = 0;
// Return the original parameters of the image
mfmhd_layout_params* get_initial_params() { return &m_param_old; }
@@ -196,8 +196,8 @@ class mfmhd_generic_format : public mfmhd_image_format_t
{
public:
mfmhd_generic_format() { m_devtag = std::string("mfmhd_generic_format"); };
- chd_error load(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) override;
- chd_error save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) override;
+ std::error_condition load(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) override;
+ std::error_condition save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) override;
// Yes, we want to save all parameters
virtual bool save_param(mfmhd_param_t type) override { return true; }
diff --git a/src/lib/formats/nfd_dsk.cpp b/src/lib/formats/nfd_dsk.cpp
index 1a0430f9af1..4a51e0db54c 100644
--- a/src/lib/formats/nfd_dsk.cpp
+++ b/src/lib/formats/nfd_dsk.cpp
@@ -77,10 +77,11 @@
*********************************************************************/
- #include <cassert>
-
#include "nfd_dsk.h"
+#include "ioprocs.h"
+
+
nfd_format::nfd_format()
{
}
@@ -100,10 +101,11 @@ const char *nfd_format::extensions() const
return "nfd";
}
-int nfd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int nfd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t h[16];
- io_generic_read(io, h, 0, 16);
+ size_t actual;
+ io.read_at(0, h, 16, actual);
if (strncmp((const char *)h, "T98FDDIMAGE.R0", 14) == 0 || strncmp((const char *)h, "T98FDDIMAGE.R1", 14) == 0)
return 100;
@@ -111,11 +113,14 @@ int nfd_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool nfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool nfd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint64_t size = io_generic_size(io);
+ size_t actual;
+ uint64_t size;
+ if (io.length(size))
+ return false;
uint8_t h[0x120], hsec[0x10];
- io_generic_read(io, h, 0, 0x120);
+ io.read_at(0, h, 0x120, actual);
int format_version = !strncmp((const char *)h, "T98FDDIMAGE.R0", 14) ? 0 : 1;
// sector map (the 164th entry is only used by rev.1 format, loops with track < 163 are correct for rev.0)
@@ -140,7 +145,7 @@ bool nfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
{
int curr_track_size = 0;
// read sector map absolute location
- io_generic_read(io, hsec, pos, 4);
+ io.read_at(pos, hsec, 4, actual);
pos += 4;
uint32_t secmap_addr = little_endianize_int32(*(uint32_t *)(hsec));
@@ -149,14 +154,14 @@ bool nfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
// read actual sector map for the sectors of this track
// for rev.1 format the first 0x10 are a track summary:
// first WORD is # of sectors, second WORD is # of special data sectors
- io_generic_read(io, hsec, secmap_addr, 0x10);
+ io.read_at(secmap_addr, hsec, 0x10, actual);
secmap_addr += 0x10;
num_secs[track] = little_endianize_int16(*(uint16_t *)(hsec));
num_specials[track] = little_endianize_int16(*(uint16_t *)(hsec + 0x2));
for (int sect = 0; sect < num_secs[track]; sect++)
{
- io_generic_read(io, hsec, secmap_addr, 0x10);
+ io.read_at(secmap_addr, hsec, 0x10, actual);
if (track == 0 && sect == 0)
disk_type = hsec[0xb]; // can this change across the disk? I don't think so...
@@ -175,7 +180,7 @@ bool nfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
{
for (int sect = 0; sect < num_specials[track]; sect++)
{
- io_generic_read(io, hsec, secmap_addr, 0x10);
+ io.read_at(secmap_addr, hsec, 0x10, actual);
secmap_addr += 0x10;
curr_track_size += (hsec[9] + 1) * little_endianize_int32(*(uint32_t *)(hsec + 0x0a));
}
@@ -198,7 +203,7 @@ bool nfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
{
// read sector map for this sector
// for rev.0 format each sector uses 0x10 bytes
- io_generic_read(io, hsec, pos, 0x10);
+ io.read_at(pos, hsec, 0x10, actual);
if (track == 0 && sect == 0)
disk_type = hsec[0xa]; // can this change across the disk? I don't think so...
@@ -245,7 +250,7 @@ bool nfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
for (int track = 0; track < 163 && pos < size; track++)
{
- io_generic_read(io, sect_data, pos, track_sizes[track]);
+ io.read_at(pos, sect_data, track_sizes[track], actual);
for (int i = 0; i < num_secs[track]; i++)
{
diff --git a/src/lib/formats/nfd_dsk.h b/src/lib/formats/nfd_dsk.h
index 5eb41893c5f..c0030b073a5 100644
--- a/src/lib/formats/nfd_dsk.h
+++ b/src/lib/formats/nfd_dsk.h
@@ -20,8 +20,8 @@ class nfd_format : public floppy_image_format_t
public:
nfd_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/opd_dsk.cpp b/src/lib/formats/opd_dsk.cpp
index e105d53d678..964b30b75a0 100644
--- a/src/lib/formats/opd_dsk.cpp
+++ b/src/lib/formats/opd_dsk.cpp
@@ -30,12 +30,13 @@ const char *opd_format::extensions() const
return "opd,opu";
}
-int opd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int opd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- int type = find_size(io, form_factor, variants);
+ int const type = find_size(io, form_factor, variants);
if (type != -1)
return 90;
+
return 0;
}
diff --git a/src/lib/formats/opd_dsk.h b/src/lib/formats/opd_dsk.h
index 9a4205314ec..9236320f154 100644
--- a/src/lib/formats/opd_dsk.h
+++ b/src/lib/formats/opd_dsk.h
@@ -21,7 +21,7 @@ class opd_format : public wd177x_format
public:
opd_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual int get_image_offset(const format &f, int head, int track) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/oric_dsk.cpp b/src/lib/formats/oric_dsk.cpp
index 22d70124572..f5b0783a112 100644
--- a/src/lib/formats/oric_dsk.cpp
+++ b/src/lib/formats/oric_dsk.cpp
@@ -8,7 +8,9 @@
*********************************************************************/
-#include "formats/oric_dsk.h"
+#include "oric_dsk.h"
+
+#include "ioprocs.h"
const char *oric_dsk_format::name() const
@@ -31,10 +33,11 @@ bool oric_dsk_format::supports_save() const
return true;
}
-int oric_dsk_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int oric_dsk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t h[256];
- io_generic_read(io, h, 0, 256);
+ size_t actual;
+ io.read_at(0, h, 256, actual);
if(memcmp(h, "MFM_DISK", 8))
return 0;
@@ -43,27 +46,30 @@ int oric_dsk_format::identify(io_generic *io, uint32_t form_factor, const std::v
int tracks = (h[15] << 24) | (h[14] << 16) | (h[13] << 8) | h[12];
int geom = (h[19] << 24) | (h[18] << 16) | (h[17] << 8) | h[16];
- int size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return 0;
if(sides < 0 || sides > 2 || geom != 1 || size != 256+6400*sides*tracks)
return 0;
return 100;
}
-bool oric_dsk_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool oric_dsk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
uint8_t h[256];
uint8_t t[6250+3];
t[6250] = t[6251] = t[6252] = 0;
- io_generic_read(io, h, 0, 256);
+ io.read_at(0, h, 256, actual);
int sides = (h[11] << 24) | (h[10] << 16) | (h[ 9] << 8) | h[ 8];
int tracks = (h[15] << 24) | (h[14] << 16) | (h[13] << 8) | h[12];
for(int side=0; side<sides; side++)
for(int track=0; track<tracks; track++) {
- io_generic_read(io, t, 256+6400*(tracks*side + track), 6250);
+ io.read_at(256+6400*(tracks*side + track), t, 6250, actual);
std::vector<uint32_t> stream;
int sector_size = 128;
for(int i=0; i<6250; i++) {
@@ -99,8 +105,9 @@ bool oric_dsk_format::load(io_generic *io, uint32_t form_factor, const std::vect
return true;
}
-bool oric_dsk_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool oric_dsk_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ // FIXME: surely this should return false, since it does't actually save anything?
return true;
}
@@ -127,28 +134,35 @@ bool oric_jasmin_format::supports_save() const
return true;
}
-int oric_jasmin_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int oric_jasmin_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- int size = io_generic_size(io);
- bool can_ds = variants.empty() || has_variant(variants, floppy_image::DSDD);
+ uint64_t size;
+ if(io.length(size))
+ return 0;
+
+ bool const can_ds = variants.empty() || has_variant(variants, floppy_image::DSDD);
if(size == 41*17*256 || (can_ds && size == 41*17*256*2))
return 50;
return 0;
}
-bool oric_jasmin_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool oric_jasmin_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- int size = io_generic_size(io);
- bool can_ds = variants.empty() || has_variant(variants, floppy_image::DSDD);
+ uint64_t size;
+ if(io.length(size))
+ return false;
+
+ bool const can_ds = variants.empty() || has_variant(variants, floppy_image::DSDD);
if(size != 41*17*256 && (!can_ds || size != 41*17*256*2))
return false;
- int heads = size == 41*17*256 ? 1 : 2;
+ int const heads = size == 41*17*256 ? 1 : 2;
std::vector<uint8_t> data(size);
- io_generic_read(io, data.data(), 0, size);
+ size_t actual;
+ io.read_at(0, data.data(), size, actual);
for(int head = 0; head != heads; head++)
for(int track = 0; track != 41; track++) {
@@ -173,7 +187,7 @@ bool oric_jasmin_format::load(io_generic *io, uint32_t form_factor, const std::v
return true;
}
-bool oric_jasmin_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool oric_jasmin_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int tracks, heads;
image->get_actual_geometry(tracks, heads);
@@ -191,8 +205,9 @@ bool oric_jasmin_format::save(io_generic *io, const std::vector<uint32_t> &varia
for(int track = 0; track != 41; track++) {
auto sectors = extract_sectors_from_bitstream_mfm_pc(generate_bitstream_from_track(track, head, 2000, image));
for(unsigned int sector = 0; sector != 17; sector ++) {
- const uint8_t *data = sector+1 < sectors.size() && !sectors[sector+1].empty() ? sectors[sector+1].data() : zero;
- io_generic_write(io, data, 256 * (sector + track*17 + head*17*41), 256);
+ uint8_t const *const data = (sector+1 < sectors.size() && !sectors[sector+1].empty()) ? sectors[sector+1].data() : zero;
+ size_t actual;
+ io.write_at(256 * (sector + track*17 + head*17*41), data, 256, actual);
}
}
return true;
diff --git a/src/lib/formats/oric_dsk.h b/src/lib/formats/oric_dsk.h
index e42b876e52f..6fd1021384b 100644
--- a/src/lib/formats/oric_dsk.h
+++ b/src/lib/formats/oric_dsk.h
@@ -18,9 +18,9 @@ class oric_dsk_format : public floppy_image_format_t
{
public:
oric_dsk_format() = default;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -35,9 +35,9 @@ class oric_jasmin_format : public floppy_image_format_t
public:
oric_jasmin_format() = default;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/os9_dsk.cpp b/src/lib/formats/os9_dsk.cpp
index b28e4f8d293..ba1b2427811 100644
--- a/src/lib/formats/os9_dsk.cpp
+++ b/src/lib/formats/os9_dsk.cpp
@@ -48,6 +48,7 @@
#include "imageutl.h"
#include "coretmpl.h" // BIT
+#include "ioprocs.h"
os9_format::os9_format() : wd177x_format(formats)
@@ -69,21 +70,25 @@ const char *os9_format::extensions() const
return "dsk,os9";
}
-int os9_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int os9_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- int type = find_size(io, form_factor, variants);
+ int const type = find_size(io, form_factor, variants);
if (type != -1)
return 75;
+
return 0;
}
-int os9_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int os9_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return -1;
uint8_t os9_header[0x60];
- io_generic_read(io, os9_header, 0, sizeof(os9_header));
+ size_t actual;
+ io.read_at(0, os9_header, sizeof(os9_header), actual);
int os9_total_sectors = pick_integer_be(os9_header, 0x00, 3);
int os9_heads = util::BIT(os9_header[0x10], 0) ? 2 : 1;
diff --git a/src/lib/formats/os9_dsk.h b/src/lib/formats/os9_dsk.h
index 57dfbfc9ab5..124c019d155 100644
--- a/src/lib/formats/os9_dsk.h
+++ b/src/lib/formats/os9_dsk.h
@@ -21,8 +21,8 @@ public:
virtual const char *name() const override;
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual const wd177x_format::format &get_track_format(const format &f, int head, int track) override;
private:
diff --git a/src/lib/formats/pasti_dsk.cpp b/src/lib/formats/pasti_dsk.cpp
index 0ab6dc2f064..1a418096cd3 100644
--- a/src/lib/formats/pasti_dsk.cpp
+++ b/src/lib/formats/pasti_dsk.cpp
@@ -2,6 +2,8 @@
// copyright-holders:Olivier Galibert
#include "pasti_dsk.h"
+#include "ioprocs.h"
+
// Pasti format supported using the documentation at
// http://www.sarnau.info/atari:pasti_file_format
@@ -36,10 +38,11 @@ bool pasti_format::supports_save() const
return false;
}
-int pasti_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int pasti_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t h[16];
- io_generic_read(io, h, 0, 16);
+ size_t actual;
+ io.read_at(0, h, 16, actual);
if(!memcmp(h, "RSY\0\3\0", 6) &&
(1 || (h[10] >= 80 && h[10] <= 82) || (h[10] >= 160 && h[10] <= 164)))
@@ -58,10 +61,11 @@ static void hexdump(const uint8_t *d, int s)
}
}
-bool pasti_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool pasti_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
uint8_t fh[16];
- io_generic_read(io, fh, 0, 16);
+ io.read_at(0, fh, 16, actual);
std::vector<uint8_t> raw_track;
@@ -76,7 +80,7 @@ bool pasti_format::load(io_generic *io, uint32_t form_factor, const std::vector<
for(int track=0; track < tracks; track++) {
for(int head=0; head < heads; head++) {
uint8_t th[16];
- io_generic_read(io, th, pos, 16);
+ io.read_at(pos, th, 16, actual);
int entry_len = th[0] | (th[1] << 8) | (th[2] << 16) | (th[3] << 24);
int fuzz_len = th[4] | (th[5] << 8) | (th[6] << 16) | (th[7] << 24);
int sect = th[8] | (th[9] << 8);
@@ -87,7 +91,7 @@ bool pasti_format::load(io_generic *io, uint32_t form_factor, const std::vector<
raw_track.resize(entry_len-16);
- io_generic_read(io, &raw_track[0], pos+16, entry_len-16);
+ io.read_at(pos+16, &raw_track[0], entry_len-16, actual);
uint8_t *fuzz = fuzz_len ? &raw_track[16*sect] : nullptr;
uint8_t *bdata = fuzz ? fuzz+fuzz_len : &raw_track[16*sect];
diff --git a/src/lib/formats/pasti_dsk.h b/src/lib/formats/pasti_dsk.h
index b3fc869da4d..2575c12eeb4 100644
--- a/src/lib/formats/pasti_dsk.h
+++ b/src/lib/formats/pasti_dsk.h
@@ -12,8 +12,8 @@ class pasti_format : public floppy_image_format_t
public:
pasti_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/pc98fdi_dsk.cpp b/src/lib/formats/pc98fdi_dsk.cpp
index 2d503acebe4..61fb8fb8fe3 100644
--- a/src/lib/formats/pc98fdi_dsk.cpp
+++ b/src/lib/formats/pc98fdi_dsk.cpp
@@ -8,9 +8,11 @@
*********************************************************************/
-#include <cassert>
#include "pc98fdi_dsk.h"
+#include "ioprocs.h"
+
+
pc98fdi_format::pc98fdi_format()
{
}
@@ -30,47 +32,53 @@ const char *pc98fdi_format::extensions() const
return "fdi";
}
-int pc98fdi_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int pc98fdi_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
- uint8_t h[32];
+ uint64_t size;
+ if(io.length(size))
+ return 0;
- io_generic_read(io, h, 0, 32);
- uint32_t hsize = little_endianize_int32(*(uint32_t *) (h + 0x8));
- uint32_t psize = little_endianize_int32(*(uint32_t *) (h + 0xc));
- uint32_t ssize = little_endianize_int32(*(uint32_t *) (h + 0x10));
- uint32_t scnt = little_endianize_int32(*(uint32_t *) (h + 0x14));
- uint32_t sides = little_endianize_int32(*(uint32_t *) (h + 0x18));
- uint32_t ntrk = little_endianize_int32(*(uint32_t *) (h + 0x1c));
+ uint8_t h[32];
+ size_t actual;
+ io.read_at(0, h, 32, actual);
+
+ uint32_t const hsize = little_endianize_int32(*(uint32_t *) (h + 0x8));
+ uint32_t const psize = little_endianize_int32(*(uint32_t *) (h + 0xc));
+ uint32_t const ssize = little_endianize_int32(*(uint32_t *) (h + 0x10));
+ uint32_t const scnt = little_endianize_int32(*(uint32_t *) (h + 0x14));
+ uint32_t const sides = little_endianize_int32(*(uint32_t *) (h + 0x18));
+ uint32_t const ntrk = little_endianize_int32(*(uint32_t *) (h + 0x1c));
if(size == hsize + psize && psize == ssize*scnt*sides*ntrk)
return 100;
return 0;
}
-bool pc98fdi_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool pc98fdi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint8_t h[32];
+ size_t actual;
- io_generic_read(io, h, 0, 32);
+ uint8_t h[32];
+ io.read_at(0, h, 32, actual);
- uint32_t hsize = little_endianize_int32(*(uint32_t *)(h+0x8));
- uint32_t sector_size = little_endianize_int32(*(uint32_t *)(h+0x10));
- uint32_t sector_count = little_endianize_int32(*(uint32_t *)(h+0x14));
- uint32_t head_count = little_endianize_int32(*(uint32_t *)(h+0x18));
- uint32_t track_count = little_endianize_int32(*(uint32_t *)(h+0x1c));
+ uint32_t const hsize = little_endianize_int32(*(uint32_t *)(h+0x8));
+ uint32_t const sector_size = little_endianize_int32(*(uint32_t *)(h+0x10));
+ uint32_t const sector_count = little_endianize_int32(*(uint32_t *)(h+0x14));
+ uint32_t const head_count = little_endianize_int32(*(uint32_t *)(h+0x18));
+ uint32_t const track_count = little_endianize_int32(*(uint32_t *)(h+0x1c));
- int cell_count = form_factor == floppy_image::FF_35 ? 200000 : 166666;
+ int const cell_count = form_factor == floppy_image::FF_35 ? 200000 : 166666;
- int ssize;
- for(ssize=0; (128 << ssize) < sector_size; ssize++) {};
+ int ssize = 0;
+ while ((128 << ssize) < sector_size)
+ ssize++;
desc_pc_sector sects[256];
uint8_t sect_data[65536];
for(int track=0; track < track_count; track++)
for(int head=0; head < head_count; head++) {
- io_generic_read(io, sect_data, hsize + sector_size*sector_count*(track*head_count + head), sector_size*sector_count);
+ io.read_at(hsize + sector_size*sector_count*(track*head_count + head), sect_data, sector_size*sector_count, actual);
for(int i=0; i<sector_count; i++) {
sects[i].track = track;
diff --git a/src/lib/formats/pc98fdi_dsk.h b/src/lib/formats/pc98fdi_dsk.h
index 1c60f059cbe..1c539f06094 100644
--- a/src/lib/formats/pc98fdi_dsk.h
+++ b/src/lib/formats/pc98fdi_dsk.h
@@ -20,8 +20,8 @@ class pc98fdi_format : public floppy_image_format_t
public:
pc98fdi_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/pc_dsk.cpp b/src/lib/formats/pc_dsk.cpp
index c814afbe6dc..6fe2a82196a 100644
--- a/src/lib/formats/pc_dsk.cpp
+++ b/src/lib/formats/pc_dsk.cpp
@@ -8,10 +8,12 @@
*********************************************************************/
+#include "formats/pc_dsk.h"
+
+#include "ioprocs.h"
+
#include <cstring>
-#include <cassert>
-#include "formats/pc_dsk.h"
pc_format::pc_format() : upd765_format(formats)
{
@@ -32,9 +34,12 @@ const char *pc_format::extensions() const
return "dsk,ima,img,ufi,360";
}
-int pc_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int pc_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size)) {
+ return 0;
+ }
/* some 360K images have a 512-byte header */
if (size == 368640 + 0x200) {
diff --git a/src/lib/formats/pc_dsk.h b/src/lib/formats/pc_dsk.h
index d53879611b9..8c99a35457f 100644
--- a/src/lib/formats/pc_dsk.h
+++ b/src/lib/formats/pc_dsk.h
@@ -20,7 +20,7 @@ class pc_format : public upd765_format
public:
pc_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/poly_dsk.cpp b/src/lib/formats/poly_dsk.cpp
index a865729864e..8845643eb72 100644
--- a/src/lib/formats/poly_dsk.cpp
+++ b/src/lib/formats/poly_dsk.cpp
@@ -10,6 +10,9 @@
#include "poly_dsk.h"
+#include "ioprocs.h"
+
+
poly_cpm_format::poly_cpm_format()
{
}
@@ -34,30 +37,35 @@ bool poly_cpm_format::supports_save() const
return true;
}
-int poly_cpm_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int poly_cpm_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint8_t boot[16];
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return 0;
// check for valid sizes
if (size == 630784 || size == 622592 || size == 256256)
{
// check for Poly CP/M boot sector
- io_generic_read(io, boot, 0, 16);
+ uint8_t boot[16];
+ size_t actual;
+ io.read_at(0, boot, 16, actual);
if (memcmp(boot, "\x86\xc3\xb7\x00\x00\x8e\x10\xc0\xbf\x00\x01\xbf\xe0\x60\x00\x00", 16) == 0)
{
return 100;
}
}
+
return 0;
}
-bool poly_cpm_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool poly_cpm_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- int total_tracks, spt, bps, head_num;
-
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size) || io.seek(0, SEEK_SET))
+ return false;
+ int total_tracks, spt, bps, head_num;
switch (size)
{
case 622592:
@@ -83,8 +91,7 @@ bool poly_cpm_format::load(io_generic *io, uint32_t form_factor, const std::vect
break;
}
- int cell_count = (form_factor == floppy_image::FF_525) ? 50000 : 100000;
- int offset = 0;
+ int const cell_count = (form_factor == floppy_image::FF_525) ? 50000 : 100000;
for (int track = 0; track < total_tracks; track++)
for (int head = 0; head < head_num; head++)
@@ -105,8 +112,8 @@ bool poly_cpm_format::load(io_generic *io, uint32_t form_factor, const std::vect
sects[i].deleted = false;
sects[i].bad_crc = false;
sects[i].data = &sect_data[sdatapos];
- io_generic_read(io, sects[i].data, offset, bps);
- offset += bps;
+ size_t actual;
+ io.read(sects[i].data, bps, actual);
sdatapos += bps;
}
// gap sizes unverified
diff --git a/src/lib/formats/poly_dsk.h b/src/lib/formats/poly_dsk.h
index 8fd3c9be4a5..8afb6836302 100644
--- a/src/lib/formats/poly_dsk.h
+++ b/src/lib/formats/poly_dsk.h
@@ -20,8 +20,8 @@ public:
virtual const char *name() const override;
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override;
};
diff --git a/src/lib/formats/rx50_dsk.cpp b/src/lib/formats/rx50_dsk.cpp
index d0d8f270c56..f81e2fa5b67 100644
--- a/src/lib/formats/rx50_dsk.cpp
+++ b/src/lib/formats/rx50_dsk.cpp
@@ -29,11 +29,11 @@
FORMAT A: /F:160 on DOS; turn MEDIACHK ON
************************************************************************/
-#include <cassert>
-
-#include "flopimg.h"
#include "formats/rx50_dsk.h"
+#include "ioprocs.h"
+
+
// Controller: WD1793
// TRACK LAYOUT IS UNVERIFED. SEE SOURCES:
// - 'esq_dsk16' (uses WD 1772)
@@ -95,12 +95,17 @@ bool rx50img_format::supports_save() const
return true;
}
-void rx50img_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
+void rx50img_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
{
head_count = 1;
uint32_t expected_size = 0;
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ {
+ track_count = head_count = sector_count = 0;
+ return;
+ }
track_count = 80;
sector_count = 10;
@@ -124,7 +129,7 @@ void rx50img_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &he
track_count = head_count = sector_count = 0;
}
-int rx50img_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int rx50img_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t track_count, head_count, sector_count;
find_size(io, track_count, head_count, sector_count);
@@ -135,7 +140,7 @@ int rx50img_format::identify(io_generic *io, uint32_t form_factor, const std::ve
}
// /* Sectors are numbered 1 to 10 */
-bool rx50img_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool rx50img_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint8_t track_count, head_count, sector_count;
find_size(io, track_count, head_count, sector_count);
@@ -153,7 +158,8 @@ bool rx50img_format::load(io_generic *io, uint32_t form_factor, const std::vecto
int track_size = sector_count*512;
for(int track=0; track < track_count; track++) {
for(int head=0; head < head_count; head++) {
- io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size);
+ size_t actual;
+ io.read_at((track*head_count + head)*track_size, sectdata, track_size, actual);
generate_track(rx50_10_desc, track, head, sectors, sector_count, 102064, image); // 98480
}
}
@@ -163,7 +169,7 @@ bool rx50img_format::load(io_generic *io, uint32_t form_factor, const std::vecto
return true;
}
-bool rx50img_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool rx50img_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int track_count, head_count, sector_count;
get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);
@@ -199,7 +205,8 @@ bool rx50img_format::save(io_generic *io, const std::vector<uint32_t> &variants,
for(int track=0; track < track_count; track++) {
for(int head=0; head < head_count; head++) {
get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
- io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size);
+ size_t actual;
+ io.write_at((track*head_count + head)*track_size, sectdata, track_size, actual);
}
}
return true;
diff --git a/src/lib/formats/rx50_dsk.h b/src/lib/formats/rx50_dsk.h
index 9cac83bd67f..d28ea398d30 100644
--- a/src/lib/formats/rx50_dsk.h
+++ b/src/lib/formats/rx50_dsk.h
@@ -23,9 +23,9 @@ class rx50img_format : public floppy_image_format_t
public:
rx50img_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -35,7 +35,7 @@ public:
static const desc_e rx50_10_desc[];
private:
- void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
+ void find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
};
extern const floppy_format_type FLOPPY_RX50IMG_FORMAT;
diff --git a/src/lib/formats/sdd_dsk.cpp b/src/lib/formats/sdd_dsk.cpp
index cac33948db0..f3e8df51bda 100644
--- a/src/lib/formats/sdd_dsk.cpp
+++ b/src/lib/formats/sdd_dsk.cpp
@@ -8,10 +8,11 @@
*********************************************************************/
-#include <cassert>
-
#include "formats/sdd_dsk.h"
+#include "ioprocs.h"
+
+
sdd_format::sdd_format() : wd177x_format(formats)
{
}
diff --git a/src/lib/formats/sdf_dsk.cpp b/src/lib/formats/sdf_dsk.cpp
index 223b6dc8d8a..f57540f3c35 100644
--- a/src/lib/formats/sdf_dsk.cpp
+++ b/src/lib/formats/sdf_dsk.cpp
@@ -12,7 +12,9 @@
*********************************************************************/
#include "sdf_dsk.h"
-#include <cassert>
+
+#include "ioprocs.h"
+
sdf_format::sdf_format()
{
@@ -37,18 +39,18 @@ const char *sdf_format::extensions() const
}
-int sdf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int sdf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t header[HEADER_SIZE];
- uint64_t size = io_generic_size(io);
-
- if (size < HEADER_SIZE)
+ uint64_t size;
+ if (io.length(size) || (size < HEADER_SIZE))
{
return 0;
}
- io_generic_read(io, header, 0, HEADER_SIZE);
+ size_t actual;
+ io.read_at(0, header, HEADER_SIZE, actual);
int tracks = header[4];
int heads = header[5];
@@ -74,13 +76,14 @@ int sdf_format::identify(io_generic *io, uint32_t form_factor, const std::vector
}
-bool sdf_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool sdf_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
uint8_t header[HEADER_SIZE];
std::vector<uint8_t> track_data(TOTAL_TRACK_SIZE);
std::vector<uint32_t> raw_track_data;
- io_generic_read(io, header, 0, HEADER_SIZE);
+ io.read_at(0, header, HEADER_SIZE, actual);
const int tracks = header[4];
const int heads = header[5];
@@ -104,7 +107,7 @@ bool sdf_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
raw_track_data.clear();
// Read track
- io_generic_read(io, &track_data[0], HEADER_SIZE + ( heads * track + head ) * TOTAL_TRACK_SIZE, TOTAL_TRACK_SIZE);
+ io.read_at(HEADER_SIZE + (heads * track + head) * TOTAL_TRACK_SIZE, &track_data[0], TOTAL_TRACK_SIZE, actual);
int sector_count = track_data[0];
@@ -181,7 +184,7 @@ bool sdf_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
}
-bool sdf_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool sdf_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
return false;
}
diff --git a/src/lib/formats/sdf_dsk.h b/src/lib/formats/sdf_dsk.h
index fe3f6eb7a98..b86692f618a 100644
--- a/src/lib/formats/sdf_dsk.h
+++ b/src/lib/formats/sdf_dsk.h
@@ -22,9 +22,9 @@ class sdf_format : public floppy_image_format_t
public:
sdf_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/st_dsk.cpp b/src/lib/formats/st_dsk.cpp
index cb363cbe3e3..d044bc5bdac 100644
--- a/src/lib/formats/st_dsk.cpp
+++ b/src/lib/formats/st_dsk.cpp
@@ -8,10 +8,11 @@
*********************************************************************/
-#include <cassert>
-
#include "formats/st_dsk.h"
+#include "ioprocs.h"
+
+
st_format::st_format()
{
}
@@ -36,18 +37,20 @@ bool st_format::supports_save() const
return true;
}
-void st_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
+void st_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
{
- uint64_t size = io_generic_size(io);
- for(track_count=80; track_count <= 82; track_count++)
- for(head_count=1; head_count <= 2; head_count++)
- for(sector_count=9; sector_count <= 11; sector_count++)
- if(size == (uint32_t)512*track_count*head_count*sector_count)
- return;
+ uint64_t size;
+ if(!io.length(size)) {
+ for(track_count=80; track_count <= 82; track_count++)
+ for(head_count=1; head_count <= 2; head_count++)
+ for(sector_count=9; sector_count <= 11; sector_count++)
+ if(size == (uint32_t)512*track_count*head_count*sector_count)
+ return;
+ }
track_count = head_count = sector_count = 0;
}
-int st_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int st_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint8_t track_count, head_count, sector_count;
find_size(io, track_count, head_count, sector_count);
@@ -57,7 +60,7 @@ int st_format::identify(io_generic *io, uint32_t form_factor, const std::vector<
return 0;
}
-bool st_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool st_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint8_t track_count, head_count, sector_count;
find_size(io, track_count, head_count, sector_count);
@@ -73,7 +76,8 @@ bool st_format::load(io_generic *io, uint32_t form_factor, const std::vector<uin
int track_size = sector_count*512;
for(int track=0; track < track_count; track++) {
for(int head=0; head < head_count; head++) {
- io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size);
+ size_t actual;
+ io.read_at((track*head_count + head)*track_size, sectdata, track_size, actual);
generate_track(atari_st_fcp_get_desc(track, head, head_count, sector_count),
track, head, sectors, sector_count, 100000, image);
}
@@ -84,7 +88,7 @@ bool st_format::load(io_generic *io, uint32_t form_factor, const std::vector<uin
return true;
}
-bool st_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool st_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int track_count, head_count, sector_count;
get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);
@@ -109,7 +113,8 @@ bool st_format::save(io_generic *io, const std::vector<uint32_t> &variants, flop
for(int track=0; track < track_count; track++) {
for(int head=0; head < head_count; head++) {
get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
- io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size);
+ size_t actual;
+ io.write_at((track*head_count + head)*track_size, sectdata, track_size, actual);
}
}
@@ -141,10 +146,11 @@ bool msa_format::supports_save() const
return true;
}
-void msa_format::read_header(io_generic *io, uint16_t &sign, uint16_t &sect, uint16_t &head, uint16_t &strack, uint16_t &etrack)
+void msa_format::read_header(util::random_read &io, uint16_t &sign, uint16_t &sect, uint16_t &head, uint16_t &strack, uint16_t &etrack)
{
uint8_t h[10];
- io_generic_read(io, h, 0, 10);
+ size_t actual;
+ io.read_at(0, h, 10, actual);
sign = (h[0] << 8) | h[1];
sect = (h[2] << 8) | h[3];
head = (h[4] << 8) | h[5];
@@ -206,7 +212,7 @@ bool msa_format::compress(const uint8_t *buffer, int usize, uint8_t *dest, int &
return dst < usize;
}
-int msa_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int msa_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
uint16_t sign, sect, head, strack, etrack;
read_header(io, sign, sect, head, strack, etrack);
@@ -220,7 +226,7 @@ int msa_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool msa_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool msa_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint16_t sign, sect, heads, strack, etrack;
read_header(io, sign, sect, heads, strack, etrack);
@@ -238,11 +244,12 @@ bool msa_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
for(int track=strack; track <= etrack; track++) {
for(int head=0; head <= heads; head++) {
+ size_t actual;
uint8_t th[2];
- io_generic_read(io, th, pos, 2);
+ io.read_at(pos, th, 2, actual);
pos += 2;
int tsize = (th[0] << 8) | th[1];
- io_generic_read(io, sectdata, pos, tsize);
+ io.read_at(pos, sectdata, tsize, actual);
pos += tsize;
if(tsize < track_size) {
if(!uncompress(sectdata, tsize, track_size))
@@ -258,7 +265,7 @@ bool msa_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
}
-bool msa_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool msa_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int track_count, head_count, sector_count;
get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);
@@ -289,9 +296,10 @@ bool msa_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
header[8] = 0;
header[9] = track_count-1;
- io_generic_write(io, header, 0, 10);
-
- int pos = 10;
+ if(io.seek(0, SEEK_SET))
+ return false;
+ size_t actual;
+ io.write(header, 10, actual);
uint8_t sectdata[11*512];
uint8_t compdata[11*512];
@@ -305,16 +313,14 @@ bool msa_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
uint8_t th[2];
th[0] = csize >> 8;
th[1] = csize;
- io_generic_write(io, th, pos, 2);
- io_generic_write(io, compdata, pos+2, csize);
- pos += 2+csize;
+ io.write(th, 2, actual);
+ io.write(compdata, csize, actual);
} else {
uint8_t th[2];
th[0] = track_size >> 8;
th[1] = track_size;
- io_generic_write(io, th, pos, 2);
- io_generic_write(io, sectdata, pos+2, track_size);
- pos += 2+track_size;
+ io.write(th, 2, actual);
+ io.write(sectdata, track_size, actual);
}
}
}
diff --git a/src/lib/formats/st_dsk.h b/src/lib/formats/st_dsk.h
index ce501a9f516..34f303bb1ae 100644
--- a/src/lib/formats/st_dsk.h
+++ b/src/lib/formats/st_dsk.h
@@ -19,9 +19,9 @@ class st_format : public floppy_image_format_t
public:
st_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -29,7 +29,7 @@ public:
virtual bool supports_save() const override;
private:
- void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
+ void find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
};
class msa_format : public floppy_image_format_t
@@ -37,9 +37,9 @@ class msa_format : public floppy_image_format_t
public:
msa_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
@@ -49,7 +49,7 @@ public:
private:
bool uncompress(uint8_t *buffer, int csize, int usize);
bool compress(const uint8_t *src, int usize, uint8_t *dest, int &csize);
- void read_header(io_generic *io, uint16_t &sign, uint16_t &sect, uint16_t &head, uint16_t &strack, uint16_t &etrack);
+ void read_header(util::random_read &io, uint16_t &sign, uint16_t &sect, uint16_t &head, uint16_t &strack, uint16_t &etrack);
};
extern const floppy_format_type FLOPPY_ST_FORMAT;
diff --git a/src/lib/formats/svi_dsk.cpp b/src/lib/formats/svi_dsk.cpp
index e3cfa294fcb..0a05bd15c80 100644
--- a/src/lib/formats/svi_dsk.cpp
+++ b/src/lib/formats/svi_dsk.cpp
@@ -10,6 +10,9 @@
#include "svi_dsk.h"
+#include "ioprocs.h"
+
+
svi_format::svi_format()
{
}
@@ -29,9 +32,11 @@ const char *svi_format::extensions() const
return "dsk";
}
-int svi_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int svi_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ return 0;
if (size == 172032 || size == 346112)
return 50;
@@ -39,11 +44,13 @@ int svi_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool svi_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool svi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint64_t size = io_generic_size(io);
- int head_count;
+ uint64_t size;
+ if (io.length(size))
+ return false;
+ int head_count;
switch (size)
{
case 172032: head_count = 1; break;
@@ -51,7 +58,8 @@ bool svi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
default: return false;
}
- int file_offset = 0;
+ if (io.seek(0, SEEK_SET))
+ return false;
for (int track = 0; track < 40; track++)
{
@@ -75,10 +83,10 @@ bool svi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
sectors[i].bad_crc = false;
sectors[i].data = &sector_data[sector_offset];
- io_generic_read(io, sectors[i].data, file_offset, sector_size);
+ size_t actual;
+ io.read(sectors[i].data, sector_size, actual);
sector_offset += sector_size;
- file_offset += sector_size;
}
if (track == 0 && head == 0)
@@ -91,9 +99,10 @@ bool svi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return true;
}
-bool svi_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool svi_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint64_t file_offset = 0;
+ if (io.seek(0, SEEK_SET))
+ return false;
int track_count, head_count;
image->get_actual_geometry(track_count, head_count);
@@ -104,8 +113,8 @@ bool svi_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
for (int i = 0; i < 18; i++)
{
- io_generic_write(io, sectors[i + 1].data(), file_offset, 128);
- file_offset += 128;
+ size_t actual;
+ io.write(sectors[i + 1].data(), 128, actual);
}
// rest are mfm tracks
@@ -121,8 +130,8 @@ bool svi_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
for (int i = 0; i < 17; i++)
{
- io_generic_write(io, sectors[i + 1].data(), file_offset, 256);
- file_offset += 256;
+ size_t actual;
+ io.write(sectors[i + 1].data(), 256, actual);
}
}
}
diff --git a/src/lib/formats/svi_dsk.h b/src/lib/formats/svi_dsk.h
index 57f4f89ccca..a631bdf498c 100644
--- a/src/lib/formats/svi_dsk.h
+++ b/src/lib/formats/svi_dsk.h
@@ -23,9 +23,9 @@ public:
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override;
};
diff --git a/src/lib/formats/td0_dsk.cpp b/src/lib/formats/td0_dsk.cpp
index edac0aae010..345a242c86b 100644
--- a/src/lib/formats/td0_dsk.cpp
+++ b/src/lib/formats/td0_dsk.cpp
@@ -16,9 +16,11 @@
#include "flopimg.h"
-#include <cassert>
+#include "ioprocs.h"
+
#include <cstring>
+
#define BUFSZ 512 // new input buffer
/* LZSS Parameters */
@@ -59,7 +61,16 @@ struct tdlzhuf {
struct td0dsk_t
{
- io_generic *floppy_file;
+public:
+ td0dsk_t(util::random_read &f) : floppy_file(f) { }
+
+ void set_floppy_file_offset(uint64_t o) { floppy_file_offset = o; }
+
+ void init_Decode();
+ int Decode(uint8_t *buf, int len);
+
+private:
+ util::random_read &floppy_file;
uint64_t floppy_file_offset;
struct tdlzhuf tdctl;
@@ -87,29 +98,10 @@ struct td0dsk_t
void update(int c);
int16_t DecodeChar();
int16_t DecodePosition();
- void init_Decode();
- int Decode(uint8_t *buf, int len);
};
//static td0dsk_t td0dsk;
-struct floppy_image_legacy
-{
- struct io_generic io;
-
- const struct FloppyFormat *floppy_option;
- struct FloppyCallbacks format;
-
- /* loaded track stuff */
- int loaded_track_head;
- int loaded_track_index;
- uint32_t loaded_track_size;
- void *loaded_track_data;
- uint8_t loaded_track_status;
- uint8_t flags;
-};
-
-
static struct td0dsk_tag *get_tag(floppy_image_legacy *floppy)
{
struct td0dsk_tag *tag;
@@ -332,11 +324,13 @@ static floperr_t td0_get_indexed_sector_info(floppy_image_legacy *floppy, int he
int td0dsk_t::data_read(uint8_t *buf, uint16_t size)
{
- uint64_t image_size = io_generic_size(floppy_file);
+ uint64_t image_size = 0;
+ floppy_file.length(image_size);
if (size > image_size - floppy_file_offset) {
size = image_size - floppy_file_offset;
}
- io_generic_read(floppy_file,buf,floppy_file_offset,size);
+ size_t actual;
+ floppy_file.read_at(floppy_file_offset, buf, size, actual);
floppy_file_offset += size;
return size;
}
@@ -675,7 +669,6 @@ int td0dsk_t::Decode(uint8_t *buf, int len) /* Decoding/Uncompressing */
FLOPPY_CONSTRUCT( td0_dsk_construct )
{
- td0dsk_t state;
struct FloppyCallbacks *callbacks;
struct td0dsk_tag *tag;
uint8_t *header;
@@ -706,9 +699,9 @@ FLOPPY_CONSTRUCT( td0_dsk_construct )
int rd;
int off = 12;
int size = 0;
- state.floppy_file = &(floppy->io);
+ td0dsk_t state(floppy_get_io(floppy));
state.init_Decode();
- state.floppy_file_offset = 12;
+ state.set_floppy_file_offset(12);
do
{
if((rd = state.Decode(obuf, BUFSZ)) > 0) size += rd;
@@ -720,7 +713,7 @@ FLOPPY_CONSTRUCT( td0_dsk_construct )
return FLOPPY_ERROR_OUTOFMEMORY;
}
memcpy(tag->data,obuf,12);
- state.floppy_file_offset = 12;
+ state.set_floppy_file_offset(12);
state.init_Decode();
do
{
@@ -815,20 +808,22 @@ const char *td0_format::extensions() const
return "td0";
}
-int td0_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int td0_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
+ size_t actual;
uint8_t h[7];
- io_generic_read(io, h, 0, 7);
+ io.read_at(0, h, 7, actual);
if(((h[0] == 'T') && (h[1] == 'D')) || ((h[0] == 't') && (h[1] == 'd')))
{
- return 100;
+ return 100;
}
return 0;
}
-bool td0_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool td0_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
int track_count = 0;
int head_count = 0;
int track_spt;
@@ -837,20 +832,24 @@ bool td0_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
std::vector<uint8_t> imagebuf(max_size);
uint8_t header[12];
- io_generic_read(io, header, 0, 12);
+ io.read_at(0, header, 12, actual);
head_count = header[9];
if(header[0] == 't')
{
- td0dsk_t disk_decode;
+ td0dsk_t disk_decode(io);
- disk_decode.floppy_file = io;
disk_decode.init_Decode();
- disk_decode.floppy_file_offset = 12;
+ disk_decode.set_floppy_file_offset(12);
disk_decode.Decode(&imagebuf[0], max_size);
}
else
- io_generic_read(io, &imagebuf[0], 12, io_generic_size(io));
+ {
+ uint64_t image_size;
+ if(io.length(image_size))
+ return false;
+ io.read_at(12, &imagebuf[0], image_size, actual);
+ }
if(header[7] & 0x80)
offset = 10 + imagebuf[2] + (imagebuf[3] << 8);
@@ -1024,7 +1023,7 @@ bool td0_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
}
-bool td0_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool td0_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
return false;
}
diff --git a/src/lib/formats/td0_dsk.h b/src/lib/formats/td0_dsk.h
index b4656305920..cf625374130 100644
--- a/src/lib/formats/td0_dsk.h
+++ b/src/lib/formats/td0_dsk.h
@@ -13,9 +13,9 @@ class td0_format : public floppy_image_format_t
public:
td0_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/ti99_dsk.cpp b/src/lib/formats/ti99_dsk.cpp
index 06ce98dfda0..507d7dc0ae0 100644
--- a/src/lib/formats/ti99_dsk.cpp
+++ b/src/lib/formats/ti99_dsk.cpp
@@ -43,6 +43,8 @@
#include "ti99_dsk.h"
#include "imageutl.h"
+#include "ioprocs.h"
+
#include "osdcore.h" // osd_printf_* (in osdcore.h)
#include <cstring>
@@ -80,13 +82,16 @@ int ti99_floppy_format::get_encoding(int cell_size)
/*
Load the image from disk and convert it into a sequence of flux levels.
*/
-bool ti99_floppy_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool ti99_floppy_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ uint64_t file_size;
+ if (io.length(file_size))
+ return false;
+
int cell_size = 0;
int sector_count = 0;
int heads = 0;
int log_track_count = 0;
- int file_size = io_generic_size(io);
bool img_high_tpi = false;
bool drive_high_tpi = false;
@@ -211,7 +216,7 @@ bool ti99_floppy_format::load(io_generic *io, uint32_t form_factor, const std::v
/*
Save all tracks to the image file.
*/
-bool ti99_floppy_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool ti99_floppy_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint8_t sectordata[9216]; // max size (36*256)
@@ -916,9 +921,12 @@ const char *ti99_sdf_format::extensions() const
return "dsk";
}
-int ti99_sdf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int ti99_sdf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t file_size = io_generic_size(io);
+ uint64_t file_size;
+ if (io.length(file_size))
+ return 0;
+
int vote = 0;
// Adding support for another sector image format which adds 768 bytes
@@ -947,7 +955,8 @@ int ti99_sdf_format::identify(io_generic *io, uint32_t form_factor, const std::v
{
// Read first sector (Volume Information Block)
ti99vib vib;
- io_generic_read(io, &vib, 0, sizeof(ti99vib));
+ size_t actual;
+ io.read_at(0, &vib, sizeof(ti99vib), actual);
// Check from contents
if ((vib.id[0]=='D')&&(vib.id[1]=='S')&&(vib.id[2]=='K'))
@@ -964,10 +973,14 @@ int ti99_sdf_format::identify(io_generic *io, uint32_t form_factor, const std::v
return vote;
}
-void ti99_sdf_format::determine_sizes(io_generic *io, int& cell_size, int& sector_count, int& heads, int& tracks)
+void ti99_sdf_format::determine_sizes(util::random_read &io, int& cell_size, int& sector_count, int& heads, int& tracks)
{
- uint64_t file_size = io_generic_size(io);
- ti99vib vib;
+ uint64_t file_size;
+ if (io.length(file_size))
+ {
+ cell_size = sector_count = heads = tracks = 0;
+ return;
+ }
cell_size = 0;
sector_count = 0;
@@ -980,7 +993,9 @@ void ti99_sdf_format::determine_sizes(io_generic *io, int& cell_size, int& secto
file_size -= 768;
// Read first sector
- io_generic_read(io, &vib, 0, sizeof(ti99vib));
+ ti99vib vib;
+ size_t actual;
+ io.read_at(0, &vib, sizeof(ti99vib), actual);
// Check from contents
if ((vib.id[0]=='D')&&(vib.id[1]=='S')&&(vib.id[2]=='K'))
@@ -1059,13 +1074,14 @@ int ti99_sdf_format::get_track_size(int sector_count)
return sector_count * SECTOR_SIZE;
}
-void ti99_sdf_format::load_track(io_generic *io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount)
+void ti99_sdf_format::load_track(util::random_read &io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount)
{
// Calculate the track offset from the beginning of the image file
int logicaltrack = (head==0)? track : (2*trackcount - track - 1);
int position = logicaltrack * get_track_size(sectorcount);
- io_generic_read(io, sectordata, position, sectorcount*SECTOR_SIZE);
+ size_t actual;
+ io.read_at(position, sectordata, sectorcount*SECTOR_SIZE, actual);
// Interleave and skew
int interleave = 7;
@@ -1133,19 +1149,18 @@ std::string ti99_floppy_format::dumpline(uint8_t* line, int address) const
Write the data to the disk. We have a list of sector positions, so we
just need to go through that list and save each sector in the sector data.
*/
-void ti99_sdf_format::write_track(io_generic *io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count)
+void ti99_sdf_format::write_track(util::random_read_write &io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count)
{
- uint8_t* buf;
-
int logicaltrack = head * track_count;
logicaltrack += ((head&1)==0)? track : (track_count - 1 - track);
int trackoffset = logicaltrack * sector_count * SECTOR_SIZE;
for (int i=0; i < sector_count; i++)
{
- buf = sectordata + i * SECTOR_SIZE;
+ uint8_t const *const buf = sectordata + i * SECTOR_SIZE;
LOGMASKED(LOG_DETAIL, "[ti99_dsk] Writing sector %d (offset %06x)\n", sector[i], sector[i] * SECTOR_SIZE);
- io_generic_write(io, buf, trackoffset + sector[i] * SECTOR_SIZE, SECTOR_SIZE);
+ size_t actual;
+ io.write_at(trackoffset + sector[i] * SECTOR_SIZE, buf, SECTOR_SIZE, actual);
}
}
@@ -1209,7 +1224,7 @@ const char *ti99_tdf_format::extensions() const
/*
Determine whether the image file can be interpreted as a track dump
*/
-int ti99_tdf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int ti99_tdf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int vote = 0;
uint8_t fulltrack[6872];
@@ -1232,7 +1247,8 @@ int ti99_tdf_format::identify(io_generic *io, uint32_t form_factor, const std::v
LOGMASKED(LOG_INFO, "[ti99_dsk] Image file length matches TDF\n");
// Fetch track 0
- io_generic_read(io, fulltrack, 0, get_track_size(sector_count));
+ size_t actual;
+ io.read_at(0, fulltrack, get_track_size(sector_count), actual);
if (sector_count == 9)
{
@@ -1279,9 +1295,14 @@ int ti99_tdf_format::identify(io_generic *io, uint32_t form_factor, const std::v
Find the proper format for a given image file. Tracks are counted per side.
Note that only two formats are actually compatible with the PC99 emulator.
*/
-void ti99_tdf_format::determine_sizes(io_generic *io, int& cell_size, int& sector_count, int& heads, int& tracks)
+void ti99_tdf_format::determine_sizes(util::random_read &io, int& cell_size, int& sector_count, int& heads, int& tracks)
{
- uint64_t file_size = io_generic_size(io);
+ uint64_t file_size;
+ if (io.length(file_size))
+ {
+ cell_size = sector_count = heads = tracks = 0;
+ return;
+ }
// LOGMASKED(LOG_INFO, "[ti99_dsk] Image size = %ld\n", file_size); // doesn't compile
switch (file_size)
@@ -1336,13 +1357,14 @@ void ti99_tdf_format::determine_sizes(io_generic *io, int& cell_size, int& secto
track from scratch. TDF is not as flexible as it suggests, it does not
allow different gap lengths and so on.
*/
-void ti99_tdf_format::load_track(io_generic *io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount)
+void ti99_tdf_format::load_track(util::random_read &io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount)
{
+ size_t actual;
uint8_t fulltrack[12544]; // space for a full TDF track
// Read beginning of track 0. We need this to get the first gap, according
// to the format
- io_generic_read(io, fulltrack, 0, 100);
+ io.read_at(0, fulltrack, 100, actual);
int offset = 0;
int tracksize = get_track_size(sectorcount);
@@ -1383,7 +1405,7 @@ void ti99_tdf_format::load_track(io_generic *io, uint8_t *sectordata, int *secto
int base = (head * trackcount + track) * tracksize;
int position = 0;
- io_generic_read(io, fulltrack, base, tracksize);
+ io.read_at(base, fulltrack, tracksize, actual);
for (int i=0; i < sectorcount; i++)
{
@@ -1431,7 +1453,7 @@ void ti99_tdf_format::load_track(io_generic *io, uint8_t *sectordata, int *secto
need the sector contents and the sector sequence, which are passed via
sectordata, sector, and sector_count.
*/
-void ti99_tdf_format::write_track(io_generic *io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count)
+void ti99_tdf_format::write_track(util::random_read_write &io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count)
{
uint8_t trackdata[12544];
int offset = ((track_count * head) + track) * get_track_size(sector_count);
@@ -1485,7 +1507,8 @@ void ti99_tdf_format::write_track(io_generic *io, uint8_t *sectordata, int *sect
for (int i=0; i < param[WGAP3]; i++) trackdata[pos++] = param[WGAPBYTE];
}
for (int i=0; i < param[WGAP4]; i++) trackdata[pos++] = param[WGAPBYTE];
- io_generic_write(io, trackdata, offset, get_track_size(sector_count));
+ size_t actual;
+ io.write_at(offset, trackdata, get_track_size(sector_count), actual);
}
int ti99_tdf_format::get_track_size(int sector_count)
diff --git a/src/lib/formats/ti99_dsk.h b/src/lib/formats/ti99_dsk.h
index 5b59b164344..6590d1e7dd2 100644
--- a/src/lib/formats/ti99_dsk.h
+++ b/src/lib/formats/ti99_dsk.h
@@ -23,8 +23,8 @@ class ti99_floppy_format : public floppy_image_format_t
{
public:
bool supports_save() const override { return true; }
- bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
protected:
uint8_t get_data_from_encoding(uint16_t raw);
@@ -32,10 +32,10 @@ protected:
virtual int min_heads() =0;
- virtual void determine_sizes(io_generic *io, int& cell_size, int& sector_count, int& heads, int& tracks) =0;
+ virtual void determine_sizes(util::random_read &io, int& cell_size, int& sector_count, int& heads, int& tracks) =0;
virtual int get_track_size(int sector_count) =0;
- virtual void load_track(io_generic *io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount) =0;
- virtual void write_track(io_generic *io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) =0;
+ virtual void load_track(util::random_read &io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount) =0;
+ virtual void write_track(util::random_read_write &io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) =0;
int get_encoding(int cell_size);
@@ -53,16 +53,16 @@ protected:
class ti99_sdf_format : public ti99_floppy_format
{
public:
- int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
const char *name() const override;
const char *description() const override;
const char *extensions() const override;
private:
- void determine_sizes(io_generic *io, int& cell_size, int& sector_count, int& heads, int& tracks) override;
+ void determine_sizes(util::random_read &io, int& cell_size, int& sector_count, int& heads, int& tracks) override;
int get_track_size(int sector_count) override;
- void write_track(io_generic *io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) override;
- void load_track(io_generic *io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sector_count, int track_count) override;
+ void write_track(util::random_read_write &io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) override;
+ void load_track(util::random_read &io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sector_count, int track_count) override;
// This format supports single-sided images
int min_heads() override { return 1; }
@@ -92,15 +92,15 @@ extern const floppy_format_type FLOPPY_TI99_SDF_FORMAT;
class ti99_tdf_format : public ti99_floppy_format
{
public:
- int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
const char *name() const override;
const char *description() const override;
const char *extensions() const override;
private:
- void determine_sizes(io_generic *io, int& cell_size, int& sector_count, int& heads, int& tracks) override;
- void load_track(io_generic *io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount) override;
- void write_track(io_generic *io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) override;
+ void determine_sizes(util::random_read &io, int& cell_size, int& sector_count, int& heads, int& tracks) override;
+ void load_track(util::random_read &io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount) override;
+ void write_track(util::random_read_write &io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) override;
int get_track_size(int sector_count) override;
// This format only supports double-sided images
diff --git a/src/lib/formats/trd_dsk.cpp b/src/lib/formats/trd_dsk.cpp
index 26b6ce5b6a5..4236259cca5 100644
--- a/src/lib/formats/trd_dsk.cpp
+++ b/src/lib/formats/trd_dsk.cpp
@@ -8,10 +8,11 @@
*********************************************************************/
-#include <cassert>
-
#include "formats/trd_dsk.h"
+#include "ioprocs.h"
+
+
trd_format::trd_format() : wd177x_format(formats)
{
}
@@ -31,10 +32,13 @@ const char *trd_format::extensions() const
return "trd";
}
-int trd_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int trd_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
+ uint64_t size;
+ if (io.length(size))
+ return -1;
+
int index = -1;
- uint64_t size = io_generic_size(io);
for (int i = 0; formats[i].form_factor; i++)
{
const format &f = formats[i];
@@ -47,12 +51,13 @@ int trd_format::find_size(io_generic *io, uint32_t form_factor, const std::vecto
{
index = i; // at least size match, save it for the case if there will be no exact matches
+ size_t actual;
uint8_t sectdata[0x100];
if (f.encoding == floppy_image::MFM)
- io_generic_read(io, sectdata, 0x800, 0x100);
+ io.read_at(0x800, sectdata, 0x100, actual);
else
{
- io_generic_read(io, sectdata, 0x100, 0x100);
+ io.read_at(0x100, sectdata, 0x100, actual);
for (int i = 0; i < 0x100; i++)
sectdata[i] ^= 0xff;
}
diff --git a/src/lib/formats/trd_dsk.h b/src/lib/formats/trd_dsk.h
index 6f19f9976a5..c5a411c60bb 100644
--- a/src/lib/formats/trd_dsk.h
+++ b/src/lib/formats/trd_dsk.h
@@ -24,7 +24,7 @@ public:
private:
static const format formats[];
- virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
};
extern const floppy_format_type FLOPPY_TRD_FORMAT;
diff --git a/src/lib/formats/trs80_dsk.cpp b/src/lib/formats/trs80_dsk.cpp
index f010a24e570..acd48368239 100644
--- a/src/lib/formats/trs80_dsk.cpp
+++ b/src/lib/formats/trs80_dsk.cpp
@@ -66,6 +66,9 @@ Description of JV3:
#include "trs80_dsk.h"
+#include "ioprocs.h"
+
+
jv1_format::jv1_format() : wd177x_format(formats)
{
}
@@ -132,15 +135,18 @@ const char *jv3_format::extensions() const
return "jv3,dsk";
}
-int jv3_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int jv3_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint32_t image_size = io_generic_size(io);
+ uint64_t image_size;
+ if (io.length(image_size))
+ return 0;
if (image_size < 0x2200)
return 0; // too small, silent return
std::vector<uint8_t> data(image_size);
- io_generic_read(io, data.data(), 0, image_size);
+ size_t actual;
+ io.read_at(0, data.data(), image_size, actual);
const uint32_t entries = 2901;
const uint32_t header_size = entries *3 +1;
@@ -181,20 +187,20 @@ int jv3_format::identify(io_generic *io, uint32_t form_factor, const std::vector
// validate so we don't overrun the array
if (track >= MAX_TRACKS)
{
- printf("jv3_format::identify - track %d exceeds maximum allowed (%d)\n",track,MAX_TRACKS-1);
+ osd_printf_info("jv3_format::identify - track %d exceeds maximum allowed (%d)\n",track,MAX_TRACKS-1);
return 0;
}
if (sector >= MAX_SECTORS)
{
- printf("jv3_format::identify - sector %d exceeds maximum allowed (%d)\n",sector,MAX_SECTORS-1);
+ osd_printf_info("jv3_format::identify - sector %d exceeds maximum allowed (%d)\n",sector,MAX_SECTORS-1);
return 0;
}
// check if sector already exists
if (sector_array[flag_side][track][sector])
{
- printf("jv3_format::identify - side %d track %d sector %d is duplicated\n",flag_side,track,sector);
+ osd_printf_info("jv3_format::identify - side %d track %d sector %d is duplicated\n",flag_side,track,sector);
return 0;
}
@@ -214,21 +220,25 @@ int jv3_format::identify(io_generic *io, uint32_t form_factor, const std::vector
// Is all data in the image? (unused tracks at the end are optional)
if (last_data > image_size)
{
- printf("jv3_format::identify - disk is missing some data. Expected 0x%X, Actual = 0x%X\n",last_data,image_size);
+ osd_printf_info("jv3_format::identify - disk is missing some data. Expected 0x%X, Actual = 0x%X\n",last_data,image_size);
return 0;
}
return 80;
}
-bool jv3_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool jv3_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
// disk has already been validated in every way except if it exceeds drive tracks, we do that below
- printf("Disk detected as JV3\n");fflush(stdout);
+ osd_printf_info("Disk detected as JV3\n");
int drive_tracks, drive_sides;
image->get_maximal_geometry(drive_tracks, drive_sides);
- std::vector<uint8_t> data(io_generic_size(io));
- io_generic_read(io, data.data(), 0, data.size());
+ uint64_t image_size;
+ if (io.length(image_size))
+ return false;
+ std::vector<uint8_t> data(image_size);
+ size_t actual;
+ io.read_at(0, data.data(), data.size(), actual);
const uint32_t entries = 2901;
const uint32_t header_size = entries *3 +1;
bool is_dd = false, is_ds = false;
@@ -313,7 +323,7 @@ bool jv3_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
data_ptr += sector_size;
}
- //printf("Side %d, Track %d, %s density\n",curr_side,curr_track,ddensity ? "Double" : "Single");
+ //osd_printf_verbose("Side %d, Track %d, %s density\n",curr_side,curr_track,ddensity ? "Double" : "Single");
if (ddensity)
{
is_dd = true;
@@ -344,7 +354,7 @@ bool jv3_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return true;
}
-bool jv3_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool jv3_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int track_count, head_count;
image->get_actual_geometry(track_count, head_count);
@@ -352,10 +362,15 @@ bool jv3_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
if (track_count)
{
// If the disk already exists, find out if it's writable
- std::vector<uint8_t> data(io_generic_size(io));
- io_generic_read(io, data.data(), 0, data.size());
- if ((data.size() >= 0x2200) && (data[0x21ff] == 0))
- return false; // disk is readonly
+ uint64_t image_size;
+ if (!io.length(image_size))
+ {
+ std::vector<uint8_t> data(image_size);
+ size_t actual;
+ io.read_at(0, data.data(), data.size(), actual);
+ if ((data.size() >= 0x2200) && (data[0x21ff] == 0))
+ return false; // disk is readonly
+ }
}
uint32_t data_ptr = 0x2200, sect_ptr = 0;
@@ -396,7 +411,8 @@ bool jv3_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
header[sect_ptr++] = track;
header[sect_ptr++] = i;
header[sect_ptr++] = head ? 0x10 : 0;
- io_generic_write(io, &dummy[0], data_ptr, 256);
+ size_t actual;
+ io.write_at(data_ptr, &dummy[0], 256, actual);
data_ptr += 256;
}
}
@@ -417,14 +433,16 @@ bool jv3_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
flags |= (sectors[i].size() >> 8) ^1;
flags |= head ? 0x10 : 0;
header[sect_ptr++] = flags;
- io_generic_write(io, sectors[i].data(), data_ptr, sectors[i].size());
+ size_t actual;
+ io.write_at(data_ptr, sectors[i].data(), sectors[i].size(), actual);
data_ptr += sectors[i].size();
}
}
}
}
// Save the header
- io_generic_write(io, header, 0, 0x2200);
+ size_t actual;
+ io.write_at(0, header, 0x2200, actual);
return true;
}
diff --git a/src/lib/formats/trs80_dsk.h b/src/lib/formats/trs80_dsk.h
index 60618a93693..31955fe4a5e 100644
--- a/src/lib/formats/trs80_dsk.h
+++ b/src/lib/formats/trs80_dsk.h
@@ -35,9 +35,9 @@ class jv3_format : public floppy_image_format_t
public:
jv3_format();
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual const char *name() const override;
virtual const char *description() const override;
diff --git a/src/lib/formats/uniflex_dsk.cpp b/src/lib/formats/uniflex_dsk.cpp
index fa5d9b50acc..f85da09b75e 100644
--- a/src/lib/formats/uniflex_dsk.cpp
+++ b/src/lib/formats/uniflex_dsk.cpp
@@ -10,7 +10,10 @@
*/
#include "uniflex_dsk.h"
-#include "formats/imageutl.h"
+#include "imageutl.h"
+
+#include "ioprocs.h"
+
uniflex_format::uniflex_format() : wd177x_format(formats)
{
@@ -31,22 +34,26 @@ const char *uniflex_format::extensions() const
return "dsk";
}
-int uniflex_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int uniflex_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- int type = find_size(io, form_factor, variants);
+ int const type = find_size(io, form_factor, variants);
if (type != -1)
return 75;
+
return 0;
}
-int uniflex_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int uniflex_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
- uint8_t sir[192];
+ uint64_t size;
+ if (io.length(size))
+ return -1;
// Look at the SIR sector, the second sector.
- io_generic_read(io, sir, 1 * 512, sizeof(sir));
+ uint8_t sir[192];
+ size_t actual;
+ io.read_at(1 * 512, sir, sizeof(sir), actual);
uint16_t fdn_block_count = pick_integer_be(sir, 0x10, 2);
uint32_t last_block_number = pick_integer_be(sir, 0x12, 3);
diff --git a/src/lib/formats/uniflex_dsk.h b/src/lib/formats/uniflex_dsk.h
index fad6741f533..af39a09678e 100644
--- a/src/lib/formats/uniflex_dsk.h
+++ b/src/lib/formats/uniflex_dsk.h
@@ -19,8 +19,8 @@ public:
virtual const char *name() const override;
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
void build_sector_description(const format &f, uint8_t *sectdata, desc_s *sectors, int track, int head) const override;
private:
diff --git a/src/lib/formats/upd765_dsk.cpp b/src/lib/formats/upd765_dsk.cpp
index e7118dde236..d0afab39352 100644
--- a/src/lib/formats/upd765_dsk.cpp
+++ b/src/lib/formats/upd765_dsk.cpp
@@ -10,14 +10,19 @@
#include "formats/upd765_dsk.h"
+#include "ioprocs.h"
+
upd765_format::upd765_format(const format *_formats) : file_header_skip_bytes(0), file_footer_skip_bytes(0), formats(_formats)
{
}
-int upd765_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) const
+int upd765_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return -1;
+
for(int i=0; formats[i].form_factor; i++) {
const format &f = formats[i];
if(form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
@@ -31,7 +36,7 @@ int upd765_format::find_size(io_generic *io, uint32_t form_factor, const std::ve
return -1;
}
-int upd765_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int upd765_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int type = find_size(io, form_factor, variants);
@@ -175,7 +180,7 @@ floppy_image_format_t::desc_e* upd765_format::get_desc_mfm(const format &f, int
return desc;
}
-bool upd765_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool upd765_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
int type = find_size(io, form_factor, variants);
if(type == -1)
@@ -222,7 +227,8 @@ bool upd765_format::load(io_generic *io, uint32_t form_factor, const std::vector
for(int track=0; track < f.track_count; track++)
for(int head=0; head < f.head_count; head++) {
build_sector_description(f, sectdata, sectors, track, head);
- io_generic_read(io, sectdata, file_header_skip_bytes + (track*f.head_count + head)*track_size, track_size);
+ size_t actual;
+ io.read_at(file_header_skip_bytes + (track*f.head_count + head)*track_size, sectdata, track_size, actual);
generate_track(desc, track, head, sectors, f.sector_count, total_size, image);
}
@@ -236,7 +242,7 @@ bool upd765_format::supports_save() const
return true;
}
-bool upd765_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool upd765_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
// Count the number of formats
int formats_count;
@@ -346,7 +352,8 @@ bool upd765_format::save(io_generic *io, const std::vector<uint32_t> &variants,
for(int head=0; head < f.head_count; head++) {
build_sector_description(f, sectdata, sectors, track, head);
extract_sectors(image, f, sectors, track, head);
- io_generic_write(io, sectdata, (track*f.head_count + head)*track_size, track_size);
+ size_t actual;
+ io.write_at((track*f.head_count + head)*track_size, sectdata, track_size, actual);
}
return true;
diff --git a/src/lib/formats/upd765_dsk.h b/src/lib/formats/upd765_dsk.h
index e93a0f24326..48acfc02a88 100644
--- a/src/lib/formats/upd765_dsk.h
+++ b/src/lib/formats/upd765_dsk.h
@@ -39,9 +39,9 @@ public:
// End the array with {}
upd765_format(const format *formats);
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override;
protected:
@@ -50,7 +50,7 @@ protected:
floppy_image_format_t::desc_e* get_desc_fm(const format &f, int &current_size, int &end_gap_index);
floppy_image_format_t::desc_e* get_desc_mfm(const format &f, int &current_size, int &end_gap_index);
- int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) const;
+ int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const;
int compute_track_size(const format &f) const;
virtual void build_sector_description(const format &d, uint8_t *sectdata, desc_s *sectors, int track, int head) const;
void check_compatibility(floppy_image *image, std::vector<int> &candidates);
diff --git a/src/lib/formats/vdk_dsk.cpp b/src/lib/formats/vdk_dsk.cpp
index 57c44f8bb29..759697f852f 100644
--- a/src/lib/formats/vdk_dsk.cpp
+++ b/src/lib/formats/vdk_dsk.cpp
@@ -12,6 +12,9 @@
#include "vdk_dsk.h"
+#include "ioprocs.h"
+
+
vdk_format::vdk_format()
{
}
@@ -31,10 +34,11 @@ const char *vdk_format::extensions() const
return "vdk";
}
-int vdk_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int vdk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
+ size_t actual;
uint8_t id[2];
- io_generic_read(io, id, 0, 2);
+ io.read_at(0, id, 2, actual);
if (id[0] == 'd' && id[1] == 'k')
return 50;
@@ -42,16 +46,21 @@ int vdk_format::identify(io_generic *io, uint32_t form_factor, const std::vector
return 0;
}
-bool vdk_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool vdk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
+ size_t actual;
+ if (io.seek(0, SEEK_SET))
+ return false;
+
uint8_t header[0x100];
- io_generic_read(io, header, 0, 0x100);
+ io.read(header, 0x100, actual);
- int header_size = header[3] * 0x100 + header[2];
- int track_count = header[8];
- int head_count = header[9];
+ int const header_size = header[3] * 0x100 + header[2];
+ int const track_count = header[8];
+ int const head_count = header[9];
- int file_offset = header_size;
+ if (io.seek(header_size, SEEK_SET))
+ return false;
for (int track = 0; track < track_count; track++)
{
@@ -72,10 +81,9 @@ bool vdk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
sectors[i].bad_crc = false;
sectors[i].data = &sector_data[sector_offset];
- io_generic_read(io, sectors[i].data, file_offset, SECTOR_SIZE);
+ io.read(sectors[i].data, SECTOR_SIZE, actual);
sector_offset += SECTOR_SIZE;
- file_offset += SECTOR_SIZE;
}
build_wd_track_mfm(track, head, image, 100000, SECTOR_COUNT, sectors, 22, 32, 24);
@@ -85,9 +93,11 @@ bool vdk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui
return true;
}
-bool vdk_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool vdk_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
- uint64_t file_offset = 0;
+ size_t actual;
+ if (io.seek(0, SEEK_SET))
+ return false;
int track_count, head_count;
image->get_actual_geometry(track_count, head_count);
@@ -108,8 +118,7 @@ bool vdk_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
header[10] = 0;
header[11] = 0;
- io_generic_write(io, header, file_offset, sizeof(header));
- file_offset += sizeof(header);
+ io.write(header, sizeof(header), actual);
// write disk data
for (int track = 0; track < track_count; track++)
@@ -120,10 +129,7 @@ bool vdk_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo
auto sectors = extract_sectors_from_bitstream_mfm_pc(bitstream);
for (int i = 0; i < SECTOR_COUNT; i++)
- {
- io_generic_write(io, sectors[FIRST_SECTOR_ID + i].data(), file_offset, SECTOR_SIZE);
- file_offset += SECTOR_SIZE;
- }
+ io.write(sectors[FIRST_SECTOR_ID + i].data(), SECTOR_SIZE, actual);
}
}
diff --git a/src/lib/formats/vdk_dsk.h b/src/lib/formats/vdk_dsk.h
index 94347b326f6..797d2644972 100644
--- a/src/lib/formats/vdk_dsk.h
+++ b/src/lib/formats/vdk_dsk.h
@@ -25,9 +25,9 @@ public:
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override;
private:
diff --git a/src/lib/formats/victor9k_dsk.cpp b/src/lib/formats/victor9k_dsk.cpp
index ace1ec50933..3a142629726 100644
--- a/src/lib/formats/victor9k_dsk.cpp
+++ b/src/lib/formats/victor9k_dsk.cpp
@@ -99,6 +99,8 @@
#include "formats/victor9k_dsk.h"
+#include "ioprocs.h"
+
victor9k_format::victor9k_format()
{
@@ -119,18 +121,22 @@ const char *victor9k_format::extensions() const
return "img";
}
-int victor9k_format::find_size(io_generic *io, uint32_t form_factor)
+int victor9k_format::find_size(util::random_read &io, uint32_t form_factor)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return -1;
+
for(int i=0; formats[i].sector_count; i++) {
const format &f = formats[i];
if(size == (uint32_t) f.sector_count*f.sector_base_size*f.head_count)
return i;
}
+
return -1;
}
-int victor9k_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int victor9k_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
int type = find_size(io, form_factor);
@@ -248,19 +254,24 @@ void victor9k_format::build_sector_description(const format &f, uint8_t *sectdat
}
}
-bool victor9k_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool victor9k_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- int type = find_size(io, form_factor);
+ int const type = find_size(io, form_factor);
if(type == -1)
return false;
const format &f = formats[type];
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return false;
+
std::vector<uint8_t> img;
- img.resize(size);
+ try { img.resize(size); }
+ catch (...) { return false; }
- io_generic_read(io, &img[0], 0, size);
+ size_t actual;
+ io.read_at(0, &img[0], size, actual);
log_boot_sector(&img[0]);
@@ -392,7 +403,7 @@ const int victor9k_format::rpm[9] =
252, 267, 283, 300, 321, 342, 368, 401, 417
};
-bool victor9k_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool victor9k_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
const format &f = formats[0];
@@ -406,7 +417,8 @@ bool victor9k_format::save(io_generic *io, const std::vector<uint32_t> &variants
build_sector_description(f, sectdata, 0, sectors, sector_count);
extract_sectors(image, f, sectors, track, head, sector_count);
- io_generic_write(io, sectdata, offset, track_size);
+ size_t actual;
+ io.write_at(offset, sectdata, track_size, actual);
}
}
diff --git a/src/lib/formats/victor9k_dsk.h b/src/lib/formats/victor9k_dsk.h
index 92d1c664a5f..aafd8fdcb14 100644
--- a/src/lib/formats/victor9k_dsk.h
+++ b/src/lib/formats/victor9k_dsk.h
@@ -34,9 +34,9 @@ public:
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override { return true; }
static int get_rpm(int head, int track);
@@ -49,7 +49,7 @@ protected:
static const int speed_zone[2][80];
static const int rpm[9];
- int find_size(io_generic *io, uint32_t form_factor);
+ int find_size(util::random_read &io, uint32_t form_factor);
void log_boot_sector(uint8_t *data);
floppy_image_format_t::desc_e* get_sector_desc(const format &f, int &current_size, int sector_count);
void build_sector_description(const format &f, uint8_t *sectdata, uint32_t sect_offs, desc_s *sectors, int sector_count) const;
diff --git a/src/lib/formats/vt_dsk.cpp b/src/lib/formats/vt_dsk.cpp
index d6cc3da4521..15c6955bfcc 100644
--- a/src/lib/formats/vt_dsk.cpp
+++ b/src/lib/formats/vt_dsk.cpp
@@ -10,6 +10,9 @@
#include "formats/vt_dsk.h"
+#include "ioprocs.h"
+
+
// Zero = | 9187 |
// One = | 2237 | 6950 |
// 0.5us ~= 143
@@ -213,9 +216,11 @@ const char *vtech_dsk_format::extensions() const
return "dsk";
}
-int vtech_bin_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int vtech_bin_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- int size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return 0;
if(size == 40*16*256)
return 50;
@@ -223,14 +228,18 @@ int vtech_bin_format::identify(io_generic *io, uint32_t form_factor, const std::
return 0;
}
-int vtech_dsk_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int vtech_dsk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- int size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return 0;
+
if(size < 256)
return 0;
std::vector<uint8_t> bdata(size);
- io_generic_read(io, bdata.data(), 0, size);
+ size_t actual;
+ io.read_at(0, bdata.data(), size, actual);
// Structurally validate the presence of sector headers and data
int count_sh = 0, count_sd = 0;
@@ -246,25 +255,29 @@ int vtech_dsk_format::identify(io_generic *io, uint32_t form_factor, const std::
return count_sh >= 30*16 && count_sd >= 30*16 ? 100 : 0;
}
-bool vtech_bin_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool vtech_bin_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- int size = io_generic_size(io);
- if(size != 40*16*256)
+ uint64_t size;
+ if(io.length(size) || (size != 40*16*256))
return false;
std::vector<uint8_t> bdata(size);
- io_generic_read(io, bdata.data(), 0, size);
+ size_t actual;
+ io.read_at(0, bdata.data(), size, actual);
image_to_flux(bdata, image);
image->set_form_variant(floppy_image::FF_525, floppy_image::SSSD);
return true;
}
-bool vtech_dsk_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool vtech_dsk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- int size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return false;
std::vector<uint8_t> bdata(size);
- io_generic_read(io, bdata.data(), 0, size);
+ size_t actual;
+ io.read_at(0, bdata.data(), size, actual);
std::vector<uint8_t> bdatax(128*16*40, 0);
@@ -327,7 +340,7 @@ bool vtech_dsk_format::load(io_generic *io, uint32_t form_factor, const std::vec
return true;
}
-bool vtech_bin_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool vtech_bin_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int tracks, heads;
image->get_maximal_geometry(tracks, heads);
@@ -335,11 +348,12 @@ bool vtech_bin_format::save(io_generic *io, const std::vector<uint32_t> &variant
return false;
auto bdata = flux_to_image(image);
- io_generic_write(io, bdata.data(), 0, bdata.size());
+ size_t actual;
+ io.write_at(0, bdata.data(), bdata.size(), actual);
return true;
}
-bool vtech_dsk_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool vtech_dsk_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
int tracks, heads;
image->get_maximal_geometry(tracks, heads);
@@ -387,7 +401,8 @@ bool vtech_dsk_format::save(io_generic *io, const std::vector<uint32_t> &variant
}
}
- io_generic_write(io, bdatax.data(), 0, bdatax.size());
+ size_t actual;
+ io.write_at(0, bdatax.data(), bdatax.size(), actual);
return true;
}
diff --git a/src/lib/formats/vt_dsk.h b/src/lib/formats/vt_dsk.h
index 739e5234a3f..4bc46871e7e 100644
--- a/src/lib/formats/vt_dsk.h
+++ b/src/lib/formats/vt_dsk.h
@@ -34,9 +34,9 @@ public:
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
};
class vtech_dsk_format : public vtech_common_format {
@@ -47,9 +47,9 @@ public:
virtual const char *description() const override;
virtual const char *extensions() const override;
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
};
extern const floppy_format_type FLOPPY_VTECH_BIN_FORMAT;
diff --git a/src/lib/formats/wd177x_dsk.cpp b/src/lib/formats/wd177x_dsk.cpp
index 22309f32a12..da900b03db5 100644
--- a/src/lib/formats/wd177x_dsk.cpp
+++ b/src/lib/formats/wd177x_dsk.cpp
@@ -10,6 +10,8 @@
#include "formats/wd177x_dsk.h"
+#include "ioprocs.h"
+
wd177x_format::wd177x_format(const format *_formats)
{
@@ -29,9 +31,12 @@ const wd177x_format::format &wd177x_format::get_track_format(const format &f, in
/*
Default implementation for find_size. May be overwritten by subclasses.
*/
-int wd177x_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int wd177x_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return -1;
+
for(int i=0; formats[i].form_factor; i++) {
const format &f = formats[i];
if(form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
@@ -49,15 +54,17 @@ int wd177x_format::find_size(io_generic *io, uint32_t form_factor, const std::ve
if(size == format_size)
return i;
}
+
return -1;
}
-int wd177x_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants)
+int wd177x_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
{
- int type = find_size(io, form_factor, variants);
+ int const type = find_size(io, form_factor, variants);
if(type != -1)
return 50;
+
return 0;
}
@@ -197,9 +204,9 @@ floppy_image_format_t::desc_e* wd177x_format::get_desc_mfm(const format &f, int
return desc;
}
-bool wd177x_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
+bool wd177x_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image)
{
- int type = find_size(io, form_factor, variants);
+ int const type = find_size(io, form_factor, variants);
if(type == -1)
return false;
@@ -251,7 +258,8 @@ bool wd177x_format::load(io_generic *io, uint32_t form_factor, const std::vector
build_sector_description(tf, sectdata, sectors, track, head);
int track_size = compute_track_size(tf);
- io_generic_read(io, sectdata, get_image_offset(f, head, track), track_size);
+ size_t actual;
+ io.read_at(get_image_offset(f, head, track), sectdata, track_size, actual);
generate_track(desc, track, head, sectors, tf.sector_count, total_size, image);
}
@@ -265,7 +273,7 @@ bool wd177x_format::supports_save() const
return true;
}
-bool wd177x_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
+bool wd177x_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
{
// Count the number of formats
int formats_count;
@@ -377,7 +385,8 @@ bool wd177x_format::save(io_generic *io, const std::vector<uint32_t> &variants,
build_sector_description(tf, sectdata, sectors, track, head);
extract_sectors(image, tf, sectors, track, head);
int track_size = compute_track_size(tf);
- io_generic_write(io, sectdata, get_image_offset(f, head, track), track_size);
+ size_t actual;
+ io.write_at(get_image_offset(f, head, track), sectdata, track_size, actual);
}
}
diff --git a/src/lib/formats/wd177x_dsk.h b/src/lib/formats/wd177x_dsk.h
index 4cae9ffa754..a7bd92994e6 100644
--- a/src/lib/formats/wd177x_dsk.h
+++ b/src/lib/formats/wd177x_dsk.h
@@ -38,9 +38,9 @@ public:
// End the array with {}
wd177x_format(const format *formats);
- virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
- virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
- virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
+ virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
+ virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override;
virtual bool supports_save() const override;
protected:
@@ -51,7 +51,7 @@ protected:
virtual const wd177x_format::format &get_track_format(const format &f, int head, int track);
virtual floppy_image_format_t::desc_e* get_desc_fm(const format &f, int &current_size, int &end_gap_index);
virtual floppy_image_format_t::desc_e* get_desc_mfm(const format &f, int &current_size, int &end_gap_index);
- virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants);
+ virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants);
virtual int get_image_offset(const format &f, int head, int track);
virtual int get_track_dam_fm(const format &f, int head, int track);
virtual int get_track_dam_mfm(const format &f, int head, int track);
diff --git a/src/lib/util/avhuff.cpp b/src/lib/util/avhuff.cpp
index ac5cea71526..0689fe25b80 100644
--- a/src/lib/util/avhuff.cpp
+++ b/src/lib/util/avhuff.cpp
@@ -896,9 +896,9 @@ avhuff_error avhuff_decoder::decode_audio(int channels, int samples, const uint8
{
// reset and decode
if (!m_flac_decoder.reset(48000, 1, samples, source, size))
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
if (!m_flac_decoder.decode_interleaved(reinterpret_cast<int16_t *>(curdest), samples, swap_endian))
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
// finish up
m_flac_decoder.finish();
diff --git a/src/lib/util/aviio.cpp b/src/lib/util/aviio.cpp
index 03014611873..3a3a1a412f6 100644
--- a/src/lib/util/aviio.cpp
+++ b/src/lib/util/aviio.cpp
@@ -1710,8 +1710,8 @@ avi_file::error avi_file_impl::read_uncompressed_video_frame(std::uint32_t frame
/* read in the data */
std::uint32_t bytes_read;
- osd_file::error const filerr = m_file->read(&m_tempbuffer[0], stream->chunk(framenum).offset, stream->chunk(framenum).length, bytes_read);
- if (filerr != osd_file::error::NONE || bytes_read != stream->chunk(framenum).length)
+ std::error_condition const filerr = m_file->read(&m_tempbuffer[0], stream->chunk(framenum).offset, stream->chunk(framenum).length, bytes_read);
+ if (filerr || bytes_read != stream->chunk(framenum).length)
return error::READ_ERROR;
/* validate this is good data */
@@ -1765,8 +1765,8 @@ avi_file::error avi_file_impl::read_video_frame(std::uint32_t framenum, bitmap_y
/* read in the data */
std::uint32_t bytes_read;
- osd_file::error const filerr = m_file->read(&m_tempbuffer[0], stream->chunk(framenum).offset, stream->chunk(framenum).length, bytes_read);
- if (filerr != osd_file::error::NONE || bytes_read != stream->chunk(framenum).length)
+ std::error_condition const filerr = m_file->read(&m_tempbuffer[0], stream->chunk(framenum).offset, stream->chunk(framenum).length, bytes_read);
+ if (filerr || bytes_read != stream->chunk(framenum).length)
return error::READ_ERROR;
/* validate this is good data */
@@ -1857,8 +1857,8 @@ avi_file::error avi_file_impl::read_sound_samples(int channel, std::uint32_t fir
return avierr;
/* read in the data */
- auto const filerr = m_file->read(&m_tempbuffer[0], stream->chunk(chunknum).offset, stream->chunk(chunknum).length, bytes_read);
- if (filerr != osd_file::error::NONE || bytes_read != stream->chunk(chunknum).length)
+ std::error_condition const filerr = m_file->read(&m_tempbuffer[0], stream->chunk(chunknum).offset, stream->chunk(chunknum).length, bytes_read);
+ if (filerr || bytes_read != stream->chunk(chunknum).length)
return error::READ_ERROR;
/* validate this is good data */
@@ -2085,14 +2085,15 @@ avi_file::error avi_file_impl::append_sound_samples(int channel, const std::int1
avi_file::error avi_file_impl::read_chunk_data(avi_chunk const &chunk, std::unique_ptr<std::uint8_t []> &buffer)
{
- /* allocate memory for the data */
- try { buffer.reset(new std::uint8_t[chunk.size]); }
- catch (...) { return error::NO_MEMORY; }
+ // allocate memory for the data
+ buffer.reset(new (std::nothrow) std::uint8_t[chunk.size]);
+ if (!buffer)
+ return error::NO_MEMORY;
- /* read from the file */
+ // read from the file
std::uint32_t bytes_read;
- osd_file::error const filerr = m_file->read(&buffer[0], chunk.offset + 8, chunk.size, bytes_read);
- if (filerr != osd_file::error::NONE || bytes_read != chunk.size)
+ std::error_condition const filerr = m_file->read(&buffer[0], chunk.offset + 8, chunk.size, bytes_read);
+ if (filerr || bytes_read != chunk.size)
{
buffer.reset();
return error::READ_ERROR;
@@ -2292,35 +2293,33 @@ avi_file::error avi_file_impl::find_next_list(std::uint32_t findme, const avi_ch
avi_file::error avi_file_impl::get_next_chunk_internal(const avi_chunk *parent, avi_chunk &newchunk, std::uint64_t offset)
{
- osd_file::error filerr;
- std::uint8_t buffer[12];
- std::uint32_t bytesread;
-
- /* nullptr parent implies the root */
- if (parent == nullptr)
+ // nullptr parent implies the root
+ if (!parent)
parent = &m_rootchunk;
- /* start at the current offset */
+ // start at the current offset
newchunk.offset = offset;
- /* if we're past the bounds of the parent, bail */
+ // if we're past the bounds of the parent, bail
if (newchunk.offset + 8 >= parent->offset + 8 + parent->size)
return error::END;
- /* read the header */
- filerr = m_file->read(buffer, newchunk.offset, 8, bytesread);
- if (filerr != osd_file::error::NONE || bytesread != 8)
+ // read the header
+ std::uint8_t buffer[12];
+ std::uint32_t bytesread;
+ std::error_condition filerr = m_file->read(buffer, newchunk.offset, 8, bytesread);
+ if (filerr || bytesread != 8)
return error::INVALID_DATA;
- /* fill in the new chunk */
+ // fill in the new chunk
newchunk.type = fetch_32bits(&buffer[0]);
newchunk.size = fetch_32bits(&buffer[4]);
- /* if we are a list, fetch the list type */
+ // if we are a list, fetch the list type
if (newchunk.type == CHUNKTYPE_LIST || newchunk.type == CHUNKTYPE_RIFF)
{
filerr = m_file->read(&buffer[8], newchunk.offset + 8, 4, bytesread);
- if (filerr != osd_file::error::NONE || bytesread != 4)
+ if (filerr || bytesread != 4)
return error::INVALID_DATA;
newchunk.listtype = fetch_32bits(&buffer[8]);
}
@@ -2643,16 +2642,15 @@ avi_file::error avi_file_impl::parse_indx_chunk(avi_stream &stream, avi_chunk co
/* loop over entries and create subchunks for each */
for (std::uint32_t entry = 0; entry < entries; entry++)
{
- const std::uint8_t *base = &chunkdata[24 + entry * 16];
- osd_file::error filerr;
+ std::uint8_t const *const base = &chunkdata[24 + entry * 16];
avi_chunk subchunk;
- std::uint32_t bytes_read;
- std::uint8_t buffer[8];
/* go read the subchunk */
subchunk.offset = fetch_64bits(&base[0]);
- filerr = m_file->read(buffer, subchunk.offset, sizeof(buffer), bytes_read);
- if (filerr != osd_file::error::NONE || bytes_read != sizeof(buffer))
+ std::uint32_t bytes_read;
+ std::uint8_t buffer[8];
+ std::error_condition const filerr = m_file->read(buffer, subchunk.offset, sizeof(buffer), bytes_read);
+ if (filerr || bytes_read != sizeof(buffer))
{
avierr = error::READ_ERROR;
break;
@@ -2788,8 +2786,8 @@ avi_file::error avi_file_impl::chunk_open(std::uint32_t type, std::uint32_t list
/* write the header */
std::uint32_t written;
- osd_file::error const filerr = m_file->write(buffer, m_writeoffs, sizeof(buffer), written);
- if (filerr != osd_file::error::NONE || written != sizeof(buffer))
+ std::error_condition const filerr = m_file->write(buffer, m_writeoffs, sizeof(buffer), written);
+ if (filerr || written != sizeof(buffer))
return error::WRITE_ERROR;
m_writeoffs += written;
}
@@ -2806,8 +2804,8 @@ avi_file::error avi_file_impl::chunk_open(std::uint32_t type, std::uint32_t list
/* write the header */
std::uint32_t written;
- osd_file::error const filerr = m_file->write(buffer, m_writeoffs, sizeof(buffer), written);
- if (filerr != osd_file::error::NONE || written != sizeof(buffer))
+ std::error_condition const filerr = m_file->write(buffer, m_writeoffs, sizeof(buffer), written);
+ if (filerr || written != sizeof(buffer))
return error::WRITE_ERROR;
m_writeoffs += written;
}
@@ -2846,8 +2844,8 @@ avi_file::error avi_file_impl::chunk_close()
put_32bits(&buffer[0], std::uint32_t(chunksize));
std::uint32_t written;
- osd_file::error const filerr = m_file->write(buffer, chunk.offset + 4, sizeof(buffer), written);
- if (filerr != osd_file::error::NONE || written != sizeof(buffer))
+ std::error_condition const filerr = m_file->write(buffer, chunk.offset + 4, sizeof(buffer), written);
+ if (filerr || written != sizeof(buffer))
return error::WRITE_ERROR;
}
@@ -2925,8 +2923,8 @@ avi_file::error avi_file_impl::chunk_write(std::uint32_t type, const void *data,
/* write the data */
std::uint32_t written;
- osd_file::error const filerr = m_file->write(data, m_writeoffs, length, written);
- if (filerr != osd_file::error::NONE || written != length)
+ std::error_condition const filerr = m_file->write(data, m_writeoffs, length, written);
+ if (filerr || written != length)
return error::WRITE_ERROR;
m_writeoffs += written;
@@ -3678,7 +3676,7 @@ avi_file::error avi_file::open(std::string const &filename, ptr &file)
/* open the file */
osd_file::ptr f;
std::uint64_t length;
- if (osd_file::open(filename, OPEN_FLAG_READ, f, length) != osd_file::error::NONE)
+ if (osd_file::open(filename, OPEN_FLAG_READ, f, length))
return error::CANT_OPEN_FILE;
/* allocate the file */
@@ -3731,8 +3729,8 @@ avi_file::error avi_file::create(std::string const &filename, movie_info const &
/* open the file */
osd_file::ptr f;
std::uint64_t length;
- osd_file::error const filerr = osd_file::open(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, f, length);
- if (filerr != osd_file::error::NONE)
+ std::error_condition const filerr = osd_file::open(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, f, length);
+ if (filerr)
return error::CANT_OPEN_FILE;
/* allocate the file */
diff --git a/src/lib/util/cdrom.cpp b/src/lib/util/cdrom.cpp
index 4ac1ab6e865..7510a1f9b47 100644
--- a/src/lib/util/cdrom.cpp
+++ b/src/lib/util/cdrom.cpp
@@ -19,6 +19,7 @@
#include "cdrom.h"
#include "chdcd.h"
+#include "corefile.h"
#include <cassert>
#include <cstdlib>
@@ -223,10 +224,10 @@ cdrom_file *cdrom_open(const char *inputfile)
return nullptr;
// set up the CD-ROM module and get the disc info
- chd_error err = chdcd_parse_toc(inputfile, file->cdtoc, file->track_info);
- if (err != CHDERR_NONE)
+ std::error_condition err = chdcd_parse_toc(inputfile, file->cdtoc, file->track_info);
+ if (err)
{
- fprintf(stderr, "Error reading input file: %s\n", chd_file::error_string(err));
+ fprintf(stderr, "Error reading input file: %s\n", err.message().c_str());
delete file;
return nullptr;
}
@@ -238,14 +239,15 @@ cdrom_file *cdrom_open(const char *inputfile)
for (i = 0; i < file->cdtoc.numtrks; i++)
{
- osd_file::error filerr = util::core_file::open(file->track_info.track[i].fname, OPEN_FLAG_READ, file->fhandle[i]);
- if (filerr != osd_file::error::NONE)
+ std::error_condition const filerr = util::core_file::open(file->track_info.track[i].fname, OPEN_FLAG_READ, file->fhandle[i]);
+ if (filerr)
{
fprintf(stderr, "Unable to open file: %s\n", file->track_info.track[i].fname.c_str());
cdrom_close(file);
return nullptr;
}
}
+
/* calculate the starting frame for each track, keeping in mind that CHDMAN
pads tracks out with extra frames to fit 4-frame size boundries
*/
@@ -336,8 +338,8 @@ cdrom_file *cdrom_open(chd_file *chd)
file->chd = chd;
/* read the CD-ROM metadata */
- chd_error err = cdrom_parse_metadata(chd, &file->cdtoc);
- if (err != CHDERR_NONE)
+ std::error_condition err = cdrom_parse_metadata(chd, &file->cdtoc);
+ if (err)
{
delete file;
return nullptr;
@@ -446,7 +448,7 @@ void cdrom_close(cdrom_file *file)
***************************************************************************/
/**
- * @fn chd_error read_partial_sector(cdrom_file *file, void *dest, uint32_t lbasector, uint32_t chdsector, uint32_t tracknum, uint32_t startoffs, uint32_t length)
+ * @fn std::error_condition read_partial_sector(cdrom_file *file, void *dest, uint32_t lbasector, uint32_t chdsector, uint32_t tracknum, uint32_t startoffs, uint32_t length)
*
* @brief Reads partial sector.
*
@@ -461,9 +463,9 @@ void cdrom_close(cdrom_file *file)
* @return The partial sector.
*/
-chd_error read_partial_sector(cdrom_file *file, void *dest, uint32_t lbasector, uint32_t chdsector, uint32_t tracknum, uint32_t startoffs, uint32_t length, bool phys=false)
+std::error_condition read_partial_sector(cdrom_file *file, void *dest, uint32_t lbasector, uint32_t chdsector, uint32_t tracknum, uint32_t startoffs, uint32_t length, bool phys=false)
{
- chd_error result = CHDERR_NONE;
+ std::error_condition result;
bool needswap = false;
// if this is pregap info that isn't actually in the file, just return blank data
@@ -570,14 +572,14 @@ uint32_t cdrom_read_data(cdrom_file *file, uint32_t lbasector, void *buffer, uin
if ((datatype == tracktype) || (datatype == CD_TRACK_RAW_DONTCARE))
{
- return (read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 0, file->cdtoc.tracks[tracknum].datasize, phys) == CHDERR_NONE);
+ return !read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 0, file->cdtoc.tracks[tracknum].datasize, phys);
}
else
{
// return 2048 bytes of mode 1 data from a 2352 byte mode 1 raw sector
if ((datatype == CD_TRACK_MODE1) && (tracktype == CD_TRACK_MODE1_RAW))
{
- return (read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 16, 2048, phys) == CHDERR_NONE);
+ return !read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 16, 2048, phys);
}
// return 2352 byte mode 1 raw sector from 2048 bytes of mode 1 data
@@ -593,25 +595,25 @@ uint32_t cdrom_read_data(cdrom_file *file, uint32_t lbasector, void *buffer, uin
bufptr[14] = msf&0xff;
bufptr[15] = 1; // mode 1
LOG(("CDROM: promotion of mode1/form1 sector to mode1 raw is not complete!\n"));
- return (read_partial_sector(file, bufptr+16, lbasector, chdsector, tracknum, 0, 2048, phys) == CHDERR_NONE);
+ return !read_partial_sector(file, bufptr+16, lbasector, chdsector, tracknum, 0, 2048, phys);
}
// return 2048 bytes of mode 1 data from a mode2 form1 or raw sector
if ((datatype == CD_TRACK_MODE1) && ((tracktype == CD_TRACK_MODE2_FORM1)||(tracktype == CD_TRACK_MODE2_RAW)))
{
- return (read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 24, 2048, phys) == CHDERR_NONE);
+ return !read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 24, 2048, phys);
}
// return 2048 bytes of mode 1 data from a mode2 form2 or XA sector
if ((datatype == CD_TRACK_MODE1) && (tracktype == CD_TRACK_MODE2_FORM_MIX))
{
- return (read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 8, 2048, phys) == CHDERR_NONE);
+ return !read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 8, 2048, phys);
}
// return mode 2 2336 byte data from a 2352 byte mode 1 or 2 raw sector (skip the header)
if ((datatype == CD_TRACK_MODE2) && ((tracktype == CD_TRACK_MODE1_RAW) || (tracktype == CD_TRACK_MODE2_RAW)))
{
- return (read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 16, 2336, phys) == CHDERR_NONE);
+ return !read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 16, 2336, phys);
}
LOG(("CDROM: Conversion from type %d to type %d not supported!\n", tracktype, datatype));
@@ -660,8 +662,8 @@ uint32_t cdrom_read_subcode(cdrom_file *file, uint32_t lbasector, void *buffer,
return 0;
// read the data
- chd_error err = read_partial_sector(file, buffer, lbasector, chdsector, tracknum, file->cdtoc.tracks[tracknum].datasize, file->cdtoc.tracks[tracknum].subsize);
- return (err == CHDERR_NONE);
+ std::error_condition err = read_partial_sector(file, buffer, lbasector, chdsector, tracknum, file->cdtoc.tracks[tracknum].datasize, file->cdtoc.tracks[tracknum].subsize);
+ return !err;
}
@@ -1139,21 +1141,20 @@ const char *cdrom_get_subtype_string(uint32_t subtype)
-------------------------------------------------*/
/**
- * @fn chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
+ * @fn std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
*
* @brief Cdrom parse metadata.
*
* @param [in,out] chd If non-null, the chd.
* @param [in,out] toc If non-null, the TOC.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
+std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
{
std::string metadata;
- chd_error err;
- int i;
+ std::error_condition err;
toc->flags = 0;
@@ -1168,49 +1169,49 @@ chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
/* fetch the metadata for this track */
err = chd->read_metadata(CDROM_TRACK_METADATA_TAG, toc->numtrks, metadata);
- if (err == CHDERR_NONE)
+ if (!err)
{
/* parse the metadata */
type[0] = subtype[0] = 0;
pgtype[0] = pgsub[0] = 0;
if (sscanf(metadata.c_str(), CDROM_TRACK_METADATA_FORMAT, &tracknum, type, subtype, &frames) != 4)
- return CHDERR_INVALID_DATA;
+ return chd_file::error::INVALID_DATA;
if (tracknum == 0 || tracknum > CD_MAX_TRACKS)
- return CHDERR_INVALID_DATA;
+ return chd_file::error::INVALID_DATA;
track = &toc->tracks[tracknum - 1];
}
else
{
err = chd->read_metadata(CDROM_TRACK_METADATA2_TAG, toc->numtrks, metadata);
- if (err == CHDERR_NONE)
+ if (!err)
{
/* parse the metadata */
type[0] = subtype[0] = 0;
pregap = postgap = 0;
if (sscanf(metadata.c_str(), CDROM_TRACK_METADATA2_FORMAT, &tracknum, type, subtype, &frames, &pregap, pgtype, pgsub, &postgap) != 8)
- return CHDERR_INVALID_DATA;
+ return chd_file::error::INVALID_DATA;
if (tracknum == 0 || tracknum > CD_MAX_TRACKS)
- return CHDERR_INVALID_DATA;
+ return chd_file::error::INVALID_DATA;
track = &toc->tracks[tracknum - 1];
}
else
{
err = chd->read_metadata(GDROM_OLD_METADATA_TAG, toc->numtrks, metadata);
- if (err == CHDERR_NONE)
+ if (!err)
/* legacy GDROM track was detected */
toc->flags |= CD_FLAG_GDROMLE;
else
err = chd->read_metadata(GDROM_TRACK_METADATA_TAG, toc->numtrks, metadata);
- if (err == CHDERR_NONE)
+ if (!err)
{
/* parse the metadata */
type[0] = subtype[0] = 0;
pregap = postgap = 0;
if (sscanf(metadata.c_str(), GDROM_TRACK_METADATA_FORMAT, &tracknum, type, subtype, &frames, &padframes, &pregap, pgtype, pgsub, &postgap) != 9)
- return CHDERR_INVALID_DATA;
+ return chd_file::error::INVALID_DATA;
if (tracknum == 0 || tracknum > CD_MAX_TRACKS)
- return CHDERR_INVALID_DATA;
+ return chd_file::error::INVALID_DATA;
track = &toc->tracks[tracknum - 1];
toc->flags |= CD_FLAG_GDROM;
}
@@ -1226,7 +1227,7 @@ chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
track->datasize = 0;
cdrom_convert_type_string_to_track_info(type, track);
if (track->datasize == 0)
- return CHDERR_INVALID_DATA;
+ return chd_file::error::INVALID_DATA;
/* extract the subtype and determine the subcode data size */
track->subtype = CD_SUB_NONE;
@@ -1261,21 +1262,21 @@ chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
/* if we got any tracks this way, we're done */
if (toc->numtrks > 0)
- return CHDERR_NONE;
+ return std::error_condition();
printf("toc->numtrks = %u?!\n", toc->numtrks);
/* look for old-style metadata */
std::vector<uint8_t> oldmetadata;
err = chd->read_metadata(CDROM_OLD_METADATA_TAG, 0, oldmetadata);
- if (err != CHDERR_NONE)
+ if (err)
return err;
/* reconstruct the TOC from it */
auto *mrp = reinterpret_cast<uint32_t *>(&oldmetadata[0]);
toc->numtrks = *mrp++;
- for (i = 0; i < CD_MAX_TRACKS; i++)
+ for (int i = 0; i < CD_MAX_TRACKS; i++)
{
toc->tracks[i].trktype = *mrp++;
toc->tracks[i].subtype = *mrp++;
@@ -1295,7 +1296,7 @@ chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
if (toc->numtrks > CD_MAX_TRACKS)
{
toc->numtrks = swapendian_int32(toc->numtrks);
- for (i = 0; i < CD_MAX_TRACKS; i++)
+ for (int i = 0; i < CD_MAX_TRACKS; i++)
{
toc->tracks[i].trktype = swapendian_int32(toc->tracks[i].trktype);
toc->tracks[i].subtype = swapendian_int32(toc->tracks[i].subtype);
@@ -1307,7 +1308,7 @@ chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
}
}
- return CHDERR_NONE;
+ return std::error_condition();
}
@@ -1316,19 +1317,19 @@ chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
-------------------------------------------------*/
/**
- * @fn chd_error cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc)
+ * @fn std::error_condition cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc)
*
* @brief Cdrom write metadata.
*
* @param [in,out] chd If non-null, the chd.
* @param toc The TOC.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc)
+std::error_condition cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc)
{
- chd_error err;
+ std::error_condition err;
/* write the metadata */
for (int i = 0; i < toc->numtrks; i++)
@@ -1363,10 +1364,10 @@ chd_error cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc)
err = chd->write_metadata(GDROM_TRACK_METADATA_TAG, i, metadata);
}
- if (err != CHDERR_NONE)
+ if (err)
return err;
}
- return CHDERR_NONE;
+ return std::error_condition();
}
/**
diff --git a/src/lib/util/cdrom.h b/src/lib/util/cdrom.h
index 27d41da845e..1847a1db83a 100644
--- a/src/lib/util/cdrom.h
+++ b/src/lib/util/cdrom.h
@@ -7,15 +7,15 @@
Generic MAME cd-rom implementation
***************************************************************************/
-
-#ifndef MAME_UTIL_CDROM_H
-#define MAME_UTIL_CDROM_H
+#ifndef MAME_LIB_UTIL_CDROM_H
+#define MAME_LIB_UTIL_CDROM_H
#pragma once
-#include "osdcore.h"
#include "chd.h"
+#include "osdcore.h"
+
/***************************************************************************
@@ -137,8 +137,8 @@ void cdrom_convert_subtype_string_to_track_info(const char *typestring, cdrom_tr
void cdrom_convert_subtype_string_to_pregap_info(const char *typestring, cdrom_track_info *info);
const char *cdrom_get_type_string(uint32_t trktype);
const char *cdrom_get_subtype_string(uint32_t subtype);
-chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc);
-chd_error cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc);
+std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc);
+std::error_condition cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc);
// ECC utilities
bool ecc_verify(const uint8_t *sector);
@@ -184,4 +184,4 @@ static inline uint32_t lba_to_msf_alt(int lba)
return ret;
}
-#endif // MAME_UTIL_CDROM_H
+#endif // MAME_LIB_UTIL_CDROM_H
diff --git a/src/lib/util/chd.cpp b/src/lib/util/chd.cpp
index 0de05849cdd..29792fc36df 100644
--- a/src/lib/util/chd.cpp
+++ b/src/lib/util/chd.cpp
@@ -8,20 +8,24 @@
***************************************************************************/
-#include <cassert>
-
#include "chd.h"
+
#include "avhuff.h"
-#include "hashing.h"
-#include "flac.h"
#include "cdrom.h"
+#include "corefile.h"
#include "coretmpl.h"
+#include "flac.h"
+#include "hashing.h"
+
+#include "eminline.h"
+
#include <zlib.h>
-#include <ctime>
+
+#include <cassert>
#include <cstddef>
#include <cstdlib>
+#include <ctime>
#include <new>
-#include "eminline.h"
//**************************************************************************
@@ -186,14 +190,17 @@ inline void chd_file::be_write_sha1(uint8_t *base, util::sha1_t value)
inline void chd_file::file_read(uint64_t offset, void *dest, uint32_t length)
{
// no file = failure
- if (m_file == nullptr)
- throw CHDERR_NOT_OPEN;
+ if (!m_file)
+ throw std::error_condition(error::NOT_OPEN);
// seek and read
m_file->seek(offset, SEEK_SET);
- uint32_t count = m_file->read(dest, length);
- if (count != length)
- throw CHDERR_READ_ERROR;
+ size_t count;
+ std::error_condition err = m_file->read(dest, length, count);
+ if (err)
+ throw err;
+ else if (count != length)
+ throw std::error_condition(std::errc::io_error); // TODO: revisit this error code (happens if file is cut off)
}
@@ -205,14 +212,17 @@ inline void chd_file::file_read(uint64_t offset, void *dest, uint32_t length)
inline void chd_file::file_write(uint64_t offset, const void *source, uint32_t length)
{
// no file = failure
- if (m_file == nullptr)
- throw CHDERR_NOT_OPEN;
+ if (!m_file)
+ throw std::error_condition(error::NOT_OPEN);
// seek and write
m_file->seek(offset, SEEK_SET);
- uint32_t count = m_file->write(source, length);
- if (count != length)
- throw CHDERR_WRITE_ERROR;
+ size_t count;
+ std::error_condition err = m_file->write(source, length, count);
+ if (err)
+ throw err;
+ else if (count != length)
+ throw std::error_condition(std::errc::interrupted); // can theoretically happen if write is inuterrupted by a signal
}
@@ -224,15 +234,22 @@ inline void chd_file::file_write(uint64_t offset, const void *source, uint32_t l
inline uint64_t chd_file::file_append(const void *source, uint32_t length, uint32_t alignment)
{
+ std::error_condition err;
+
// no file = failure
- if (m_file == nullptr)
- throw CHDERR_NOT_OPEN;
+ if (!m_file)
+ throw std::error_condition(error::NOT_OPEN);
// seek to the end and align if necessary
- m_file->seek(0, SEEK_END);
+ err = m_file->seek(0, SEEK_END);
+ if (err)
+ throw err;
if (alignment != 0)
{
- uint64_t offset = m_file->tell();
+ uint64_t offset;
+ err = m_file->tell(offset);
+ if (err)
+ throw err;
uint32_t delta = offset % alignment;
if (delta != 0)
{
@@ -242,20 +259,27 @@ inline uint64_t chd_file::file_append(const void *source, uint32_t length, uint3
delta = alignment - delta;
while (delta != 0)
{
- uint32_t bytes_to_write = (std::min<std::size_t>)(sizeof(buffer), delta);
- uint32_t count = m_file->write(buffer, bytes_to_write);
- if (count != bytes_to_write)
- throw CHDERR_WRITE_ERROR;
- delta -= bytes_to_write;
+ uint32_t bytes_to_write = std::min<std::size_t>(sizeof(buffer), delta);
+ size_t count;
+ err = m_file->write(buffer, bytes_to_write, count);
+ if (err)
+ throw err;
+ delta -= count;
}
}
}
// write the real data
- uint64_t offset = m_file->tell();
- uint32_t count = m_file->write(source, length);
- if (count != length)
- throw CHDERR_READ_ERROR;
+ uint64_t offset;
+ err = m_file->tell(offset);
+ if (err)
+ throw err;
+ size_t count;
+ err = m_file->write(source, length, count);
+ if (err)
+ throw err;
+ else if (count != length)
+ throw std::error_condition(std::errc::interrupted); // can theoretically happen if write is interrupted by a signal
return offset;
}
@@ -288,11 +312,8 @@ inline uint8_t chd_file::bits_for_value(uint64_t value)
*/
chd_file::chd_file()
- : m_file(nullptr),
- m_owns_file(false)
{
// reset state
- memset(m_decompressor, 0, sizeof(m_decompressor));
close();
}
@@ -311,6 +332,22 @@ chd_file::~chd_file()
}
/**
+ * @fn util::random_read chd_file::file()
+ *
+ * @brief -------------------------------------------------
+ * file - return our underlying file
+ * -------------------------------------------------.
+ *
+ * @return A random_read.
+ */
+
+util::random_read &chd_file::file()
+{
+ assert(m_file);
+ return *m_file;
+}
+
+/**
* @fn util::sha1_t chd_file::sha1()
*
* @brief -------------------------------------------------
@@ -329,7 +366,7 @@ util::sha1_t chd_file::sha1()
file_read(m_sha1_offset, rawbuf, sizeof(rawbuf));
return be_read_sha1(rawbuf);
}
- catch (chd_error &)
+ catch (std::error_condition const &)
{
// on failure, return nullptr
return util::sha1_t::null;
@@ -354,15 +391,15 @@ util::sha1_t chd_file::raw_sha1()
try
{
// determine offset within the file for data-only
- if (m_rawsha1_offset == 0)
- throw CHDERR_UNSUPPORTED_VERSION;
+ if (!m_rawsha1_offset)
+ throw std::error_condition(error::UNSUPPORTED_VERSION);
// read the big-endian version
uint8_t rawbuf[sizeof(util::sha1_t)];
file_read(m_rawsha1_offset, rawbuf, sizeof(rawbuf));
return be_read_sha1(rawbuf);
}
- catch (chd_error &)
+ catch (std::error_condition const &)
{
// on failure, return nullptr
return util::sha1_t::null;
@@ -387,15 +424,15 @@ util::sha1_t chd_file::parent_sha1()
try
{
// determine offset within the file
- if (m_parentsha1_offset == 0)
- throw CHDERR_UNSUPPORTED_VERSION;
+ if (!m_parentsha1_offset)
+ throw std::error_condition(error::UNSUPPORTED_VERSION);
// read the big-endian version
uint8_t rawbuf[sizeof(util::sha1_t)];
file_read(m_parentsha1_offset, rawbuf, sizeof(rawbuf));
return be_read_sha1(rawbuf);
}
- catch (chd_error &)
+ catch (std::error_condition const &)
{
// on failure, return nullptr
return util::sha1_t::null;
@@ -403,7 +440,7 @@ util::sha1_t chd_file::parent_sha1()
}
/**
- * @fn chd_error chd_file::hunk_info(uint32_t hunknum, chd_codec_type &compressor, uint32_t &compbytes)
+ * @fn std::error_condition chd_file::hunk_info(uint32_t hunknum, chd_codec_type &compressor, uint32_t &compbytes)
*
* @brief -------------------------------------------------
* hunk_info - return information about this hunk
@@ -413,14 +450,14 @@ util::sha1_t chd_file::parent_sha1()
* @param [in,out] compressor The compressor.
* @param [in,out] compbytes The compbytes.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::hunk_info(uint32_t hunknum, chd_codec_type &compressor, uint32_t &compbytes)
+std::error_condition chd_file::hunk_info(uint32_t hunknum, chd_codec_type &compressor, uint32_t &compbytes)
{
// error if invalid
if (hunknum >= m_hunkcount)
- return CHDERR_HUNK_OUT_OF_RANGE;
+ return std::error_condition(error::HUNK_OUT_OF_RANGE);
// get the map pointer
uint8_t *rawmap;
@@ -506,11 +543,11 @@ chd_error chd_file::hunk_info(uint32_t hunknum, chd_codec_type &compressor, uint
break;
default:
- return CHDERR_UNKNOWN_COMPRESSION;
+ return error::UNKNOWN_COMPRESSION;
}
break;
}
- return CHDERR_NONE;
+ return std::error_condition();
}
/**
@@ -554,8 +591,8 @@ void chd_file::set_raw_sha1(util::sha1_t rawdata)
void chd_file::set_parent_sha1(util::sha1_t parent)
{
// if no file, fail
- if (m_file == nullptr)
- throw CHDERR_INVALID_FILE;
+ if (!m_file)
+ throw std::error_condition(error::INVALID_FILE);
// create a big-endian version
uint8_t rawbuf[sizeof(util::sha1_t)];
@@ -567,7 +604,7 @@ void chd_file::set_parent_sha1(util::sha1_t parent)
}
/**
- * @fn chd_error chd_file::create(util::core_file &file, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t unitbytes, chd_codec_type compression[4])
+ * @fn std::error_condition chd_file::create(util::random_read_write::ptr &&file, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t unitbytes, chd_codec_type compression[4])
*
* @brief -------------------------------------------------
* create - create a new file with no parent using an existing opened file handle
@@ -579,14 +616,16 @@ void chd_file::set_parent_sha1(util::sha1_t parent)
* @param unitbytes The unitbytes.
* @param compression The compression.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::create(util::core_file &file, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t unitbytes, chd_codec_type compression[4])
+std::error_condition chd_file::create(util::random_read_write::ptr &&file, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t unitbytes, chd_codec_type compression[4])
{
// make sure we don't already have a file open
- if (m_file != nullptr)
- return CHDERR_ALREADY_OPEN;
+ if (m_file)
+ return error::ALREADY_OPEN;
+ else if (!file)
+ return std::errc::invalid_argument;
// set the header parameters
m_logicalbytes = logicalbytes;
@@ -596,13 +635,12 @@ chd_error chd_file::create(util::core_file &file, uint64_t logicalbytes, uint32_
m_parent = nullptr;
// take ownership of the file
- m_file = &file;
- m_owns_file = false;
+ m_file = std::move(file);
return create_common();
}
/**
- * @fn chd_error chd_file::create(util::core_file &file, uint64_t logicalbytes, uint32_t hunkbytes, chd_codec_type compression[4], chd_file &parent)
+ * @fn std::error_condition chd_file::create(util::random_read_write::ptr &&file, uint64_t logicalbytes, uint32_t hunkbytes, chd_codec_type compression[4], chd_file &parent)
*
* @brief -------------------------------------------------
* create - create a new file with a parent using an existing opened file handle
@@ -614,14 +652,16 @@ chd_error chd_file::create(util::core_file &file, uint64_t logicalbytes, uint32_
* @param compression The compression.
* @param [in,out] parent The parent.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::create(util::core_file &file, uint64_t logicalbytes, uint32_t hunkbytes, chd_codec_type compression[4], chd_file &parent)
+std::error_condition chd_file::create(util::random_read_write::ptr &&file, uint64_t logicalbytes, uint32_t hunkbytes, chd_codec_type compression[4], chd_file &parent)
{
// make sure we don't already have a file open
- if (m_file != nullptr)
- return CHDERR_ALREADY_OPEN;
+ if (m_file)
+ return error::ALREADY_OPEN;
+ else if (!file)
+ return std::errc::invalid_argument;
// set the header parameters
m_logicalbytes = logicalbytes;
@@ -631,13 +671,12 @@ chd_error chd_file::create(util::core_file &file, uint64_t logicalbytes, uint32_
m_parent = &parent;
// take ownership of the file
- m_file = &file;
- m_owns_file = false;
+ m_file = std::move(file);
return create_common();
}
/**
- * @fn chd_error chd_file::create(const char *filename, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t unitbytes, chd_codec_type compression[4])
+ * @fn std::error_condition chd_file::create(std::string_view filename, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t unitbytes, chd_codec_type compression[4])
*
* @brief -------------------------------------------------
* create - create a new file with no parent using a filename
@@ -649,40 +688,38 @@ chd_error chd_file::create(util::core_file &file, uint64_t logicalbytes, uint32_
* @param unitbytes The unitbytes.
* @param compression The compression.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::create(const char *filename, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t unitbytes, chd_codec_type compression[4])
+std::error_condition chd_file::create(std::string_view filename, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t unitbytes, chd_codec_type compression[4])
{
// make sure we don't already have a file open
- if (m_file != nullptr)
- return CHDERR_ALREADY_OPEN;
+ if (m_file)
+ return error::ALREADY_OPEN;
// create the new file
util::core_file::ptr file;
- const osd_file::error filerr = util::core_file::open(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
- if (filerr != osd_file::error::NONE)
- return CHDERR_FILE_NOT_FOUND;
+ std::error_condition filerr = util::core_file::open(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
+ if (filerr)
+ return filerr;
+ util::random_read_write::ptr io = util::core_file_read_write(std::move(file));
+ if (!io)
+ return std::errc::not_enough_memory;
// create the file normally, then claim the file
- const chd_error chderr = create(*file, logicalbytes, hunkbytes, unitbytes, compression);
- m_owns_file = true;
+ std::error_condition chderr = create(std::move(io), logicalbytes, hunkbytes, unitbytes, compression);
// if an error happened, close and delete the file
- if (chderr != CHDERR_NONE)
+ if (chderr)
{
- file.reset();
- osd_file::remove(filename);
- }
- else
- {
- file.release();
+ io.reset();
+ osd_file::remove(std::string(filename)); // FIXME: allow osd_file to use std::string_view
}
return chderr;
}
/**
- * @fn chd_error chd_file::create(const char *filename, uint64_t logicalbytes, uint32_t hunkbytes, chd_codec_type compression[4], chd_file &parent)
+ * @fn std::error_condition chd_file::create(std::string_view filename, uint64_t logicalbytes, uint32_t hunkbytes, chd_codec_type compression[4], chd_file &parent)
*
* @brief -------------------------------------------------
* create - create a new file with a parent using a filename
@@ -694,40 +731,38 @@ chd_error chd_file::create(const char *filename, uint64_t logicalbytes, uint32_t
* @param compression The compression.
* @param [in,out] parent The parent.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::create(const char *filename, uint64_t logicalbytes, uint32_t hunkbytes, chd_codec_type compression[4], chd_file &parent)
+std::error_condition chd_file::create(std::string_view filename, uint64_t logicalbytes, uint32_t hunkbytes, chd_codec_type compression[4], chd_file &parent)
{
// make sure we don't already have a file open
- if (m_file != nullptr)
- return CHDERR_ALREADY_OPEN;
+ if (m_file)
+ return error::ALREADY_OPEN;
// create the new file
util::core_file::ptr file;
- const osd_file::error filerr = util::core_file::open(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
- if (filerr != osd_file::error::NONE)
- return CHDERR_FILE_NOT_FOUND;
+ std::error_condition filerr = util::core_file::open(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
+ if (filerr)
+ return filerr;
+ util::random_read_write::ptr io = util::core_file_read_write(std::move(file));
+ if (!io)
+ return std::errc::not_enough_memory;
// create the file normally, then claim the file
- const chd_error chderr = create(*file, logicalbytes, hunkbytes, compression, parent);
- m_owns_file = true;
+ std::error_condition chderr = create(std::move(io), logicalbytes, hunkbytes, compression, parent);
// if an error happened, close and delete the file
- if (chderr != CHDERR_NONE)
- {
- file.reset();
- osd_file::remove(filename);
- }
- else
+ if (chderr)
{
- file.release();
+ io.reset();
+ osd_file::remove(std::string(filename)); // FIXME: allow osd_file to use std::string_view
}
return chderr;
}
/**
- * @fn chd_error chd_file::open(const char *filename, bool writeable, chd_file *parent)
+ * @fn std::error_condition chd_file::open(std::string_view filename, bool writeable, chd_file *parent)
*
* @brief -------------------------------------------------
* open - open an existing file for read or read/write
@@ -737,35 +772,36 @@ chd_error chd_file::create(const char *filename, uint64_t logicalbytes, uint32_t
* @param writeable true if writeable.
* @param [in,out] parent If non-null, the parent.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::open(const char *filename, bool writeable, chd_file *parent)
+std::error_condition chd_file::open(std::string_view filename, bool writeable, chd_file *parent)
{
// make sure we don't already have a file open
- if (m_file != nullptr)
- return CHDERR_ALREADY_OPEN;
+ if (m_file)
+ return error::ALREADY_OPEN;
// open the file
const uint32_t openflags = writeable ? (OPEN_FLAG_READ | OPEN_FLAG_WRITE) : OPEN_FLAG_READ;
util::core_file::ptr file;
- const osd_file::error filerr = util::core_file::open(filename, openflags, file);
- if (filerr != osd_file::error::NONE)
- return CHDERR_FILE_NOT_FOUND;
+ std::error_condition filerr = util::core_file::open(filename, openflags, file);
+ if (filerr)
+ return filerr;
+ util::random_read_write::ptr io = util::core_file_read_write(std::move(file));
+ if (!io)
+ return std::errc::not_enough_memory;
// now open the CHD
- chd_error err = open(*file, writeable, parent);
- if (err != CHDERR_NONE)
+ std::error_condition err = open(std::move(io), writeable, parent);
+ if (err)
return err;
// we now own this file
- file.release();
- m_owns_file = true;
return err;
}
/**
- * @fn chd_error chd_file::open(util::core_file &file, bool writeable, chd_file *parent)
+ * @fn std::error_condition chd_file::open(util::random_read_write::ptr &&file, bool writeable, chd_file *parent)
*
* @brief -------------------------------------------------
* open - open an existing file for read or read/write
@@ -775,18 +811,19 @@ chd_error chd_file::open(const char *filename, bool writeable, chd_file *parent)
* @param writeable true if writeable.
* @param [in,out] parent If non-null, the parent.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::open(util::core_file &file, bool writeable, chd_file *parent)
+std::error_condition chd_file::open(util::random_read_write::ptr &&file, bool writeable, chd_file *parent)
{
// make sure we don't already have a file open
- if (m_file != nullptr)
- return CHDERR_ALREADY_OPEN;
+ if (m_file)
+ return error::ALREADY_OPEN;
+ else if (!file)
+ return std::errc::invalid_argument;
// open the file
- m_file = &file;
- m_owns_file = false;
+ m_file = std::move(file);
m_parent = parent;
m_cachehunk = ~0;
return open_common(writeable);
@@ -803,10 +840,7 @@ chd_error chd_file::open(util::core_file &file, bool writeable, chd_file *parent
void chd_file::close()
{
// reset file characteristics
- if (m_owns_file && m_file)
- delete m_file;
- m_file = nullptr;
- m_owns_file = false;
+ m_file.reset();
m_allow_reads = false;
m_allow_writes = false;
@@ -836,10 +870,7 @@ void chd_file::close()
// reset compression management
for (auto & elem : m_decompressor)
- {
- delete elem;
- elem = nullptr;
- }
+ elem.reset();
m_compressed.clear();
// reset caching
@@ -848,7 +879,7 @@ void chd_file::close()
}
/**
- * @fn chd_error chd_file::read_hunk(uint32_t hunknum, void *buffer)
+ * @fn std::error_condition chd_file::read_hunk(uint32_t hunknum, void *buffer)
*
* @brief -------------------------------------------------
* read - read a single hunk from the CHD file
@@ -870,18 +901,18 @@ void chd_file::close()
* @return The hunk.
*/
-chd_error chd_file::read_hunk(uint32_t hunknum, void *buffer)
+std::error_condition chd_file::read_hunk(uint32_t hunknum, void *buffer)
{
// wrap this for clean reporting
try
{
// punt if no file
- if (m_file == nullptr)
- throw CHDERR_NOT_OPEN;
+ if (!m_file)
+ throw std::error_condition(error::NOT_OPEN);
// return an error if out of range
if (hunknum >= m_hunkcount)
- throw CHDERR_HUNK_OUT_OF_RANGE;
+ throw std::error_condition(error::HUNK_OUT_OF_RANGE);
// get a pointer to the map entry
uint64_t blockoffs;
@@ -904,29 +935,29 @@ chd_error chd_file::read_hunk(uint32_t hunknum, void *buffer)
file_read(blockoffs, &m_compressed[0], blocklen);
m_decompressor[0]->decompress(&m_compressed[0], blocklen, dest, m_hunkbytes);
if (!(rawmap[15] & V34_MAP_ENTRY_FLAG_NO_CRC) && dest != nullptr && util::crc32_creator::simple(dest, m_hunkbytes) != blockcrc)
- throw CHDERR_DECOMPRESSION_ERROR;
- return CHDERR_NONE;
+ throw std::error_condition(error::DECOMPRESSION_ERROR);
+ return std::error_condition();
case V34_MAP_ENTRY_TYPE_UNCOMPRESSED:
file_read(blockoffs, dest, m_hunkbytes);
if (!(rawmap[15] & V34_MAP_ENTRY_FLAG_NO_CRC) && util::crc32_creator::simple(dest, m_hunkbytes) != blockcrc)
- throw CHDERR_DECOMPRESSION_ERROR;
- return CHDERR_NONE;
+ throw std::error_condition(error::DECOMPRESSION_ERROR);
+ return std::error_condition();
case V34_MAP_ENTRY_TYPE_MINI:
be_write(dest, blockoffs, 8);
for (uint32_t bytes = 8; bytes < m_hunkbytes; bytes++)
dest[bytes] = dest[bytes - 8];
if (!(rawmap[15] & V34_MAP_ENTRY_FLAG_NO_CRC) && util::crc32_creator::simple(dest, m_hunkbytes) != blockcrc)
- throw CHDERR_DECOMPRESSION_ERROR;
- return CHDERR_NONE;
+ throw std::error_condition(error::DECOMPRESSION_ERROR);
+ return std::error_condition();
case V34_MAP_ENTRY_TYPE_SELF_HUNK:
return read_hunk(blockoffs, dest);
case V34_MAP_ENTRY_TYPE_PARENT_HUNK:
if (m_parent_missing)
- throw CHDERR_REQUIRES_PARENT;
+ throw std::error_condition(error::REQUIRES_PARENT);
return m_parent->read_hunk(blockoffs, dest);
}
break;
@@ -942,12 +973,12 @@ chd_error chd_file::read_hunk(uint32_t hunknum, void *buffer)
if (blockoffs != 0)
file_read(blockoffs, dest, m_hunkbytes);
else if (m_parent_missing)
- throw CHDERR_REQUIRES_PARENT;
+ throw std::error_condition(error::REQUIRES_PARENT);
else if (m_parent != nullptr)
m_parent->read_hunk(hunknum, dest);
else
memset(dest, 0, m_hunkbytes);
- return CHDERR_NONE;
+ return std::error_condition();
}
// compressed case
@@ -963,41 +994,40 @@ chd_error chd_file::read_hunk(uint32_t hunknum, void *buffer)
file_read(blockoffs, &m_compressed[0], blocklen);
m_decompressor[rawmap[0]]->decompress(&m_compressed[0], blocklen, dest, m_hunkbytes);
if (!m_decompressor[rawmap[0]]->lossy() && dest != nullptr && util::crc16_creator::simple(dest, m_hunkbytes) != blockcrc)
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(error::DECOMPRESSION_ERROR);
if (m_decompressor[rawmap[0]]->lossy() && util::crc16_creator::simple(&m_compressed[0], blocklen) != blockcrc)
- throw CHDERR_DECOMPRESSION_ERROR;
- return CHDERR_NONE;
+ throw std::error_condition(error::DECOMPRESSION_ERROR);
+ return std::error_condition();
case COMPRESSION_NONE:
file_read(blockoffs, dest, m_hunkbytes);
if (util::crc16_creator::simple(dest, m_hunkbytes) != blockcrc)
- throw CHDERR_DECOMPRESSION_ERROR;
- return CHDERR_NONE;
+ throw std::error_condition(error::DECOMPRESSION_ERROR);
+ return std::error_condition();
case COMPRESSION_SELF:
return read_hunk(blockoffs, dest);
case COMPRESSION_PARENT:
if (m_parent_missing)
- throw CHDERR_REQUIRES_PARENT;
+ throw std::error_condition(error::REQUIRES_PARENT);
return m_parent->read_bytes(uint64_t(blockoffs) * uint64_t(m_parent->unit_bytes()), dest, m_hunkbytes);
}
break;
}
// if we get here, something was wrong
- throw CHDERR_READ_ERROR;
+ throw std::error_condition(std::errc::io_error);
}
-
- // just return errors
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
+ // just return errors
return err;
}
}
/**
- * @fn chd_error chd_file::write_hunk(uint32_t hunknum, const void *buffer)
+ * @fn std::error_condition chd_file::write_hunk(uint32_t hunknum, const void *buffer)
*
* @brief -------------------------------------------------
* write - write a single hunk to the CHD file
@@ -1012,29 +1042,29 @@ chd_error chd_file::read_hunk(uint32_t hunknum, void *buffer)
* @param hunknum The hunknum.
* @param buffer The buffer.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::write_hunk(uint32_t hunknum, const void *buffer)
+std::error_condition chd_file::write_hunk(uint32_t hunknum, const void *buffer)
{
// wrap this for clean reporting
try
{
// punt if no file
- if (m_file == nullptr)
- throw CHDERR_NOT_OPEN;
+ if (!m_file)
+ throw std::error_condition(error::NOT_OPEN);
// return an error if out of range
if (hunknum >= m_hunkcount)
- throw CHDERR_HUNK_OUT_OF_RANGE;
+ throw std::error_condition(error::HUNK_OUT_OF_RANGE);
// if not writeable, fail
if (!m_allow_writes)
- throw CHDERR_FILE_NOT_WRITEABLE;
+ throw std::error_condition(error::FILE_NOT_WRITEABLE);
// uncompressed writes only via this interface
if (compressed())
- throw CHDERR_FILE_NOT_WRITEABLE;
+ throw std::error_condition(error::FILE_NOT_WRITEABLE);
// see if we have allocated the space on disk for this hunk
uint8_t *rawmap = &m_rawmap[hunknum * 4];
@@ -1055,7 +1085,7 @@ chd_error chd_file::write_hunk(uint32_t hunknum, const void *buffer)
// if it's all zeros, do nothing more
if (all_zeros)
- return CHDERR_NONE;
+ return std::error_condition();
// append new data to the end of the file, aligning the first chunk
rawentry = file_append(buffer, m_hunkbytes, m_hunkbytes) / m_hunkbytes;
@@ -1068,22 +1098,22 @@ chd_error chd_file::write_hunk(uint32_t hunknum, const void *buffer)
if (hunknum == m_cachehunk && buffer != &m_cache[0])
memcpy(&m_cache[0], buffer, m_hunkbytes);
}
-
- // otherwise, just overwrite
else
+ {
+ // otherwise, just overwrite
file_write(uint64_t(rawentry) * uint64_t(m_hunkbytes), buffer, m_hunkbytes);
- return CHDERR_NONE;
+ }
+ return std::error_condition();
}
-
- // just return errors
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
+ // just return errors
return err;
}
}
/**
- * @fn chd_error chd_file::read_units(uint64_t unitnum, void *buffer, uint32_t count)
+ * @fn std::error_condition chd_file::read_units(uint64_t unitnum, void *buffer, uint32_t count)
*
* @brief -------------------------------------------------
* read_units - read the given number of units from the CHD
@@ -1096,13 +1126,13 @@ chd_error chd_file::write_hunk(uint32_t hunknum, const void *buffer)
* @return The units.
*/
-chd_error chd_file::read_units(uint64_t unitnum, void *buffer, uint32_t count)
+std::error_condition chd_file::read_units(uint64_t unitnum, void *buffer, uint32_t count)
{
return read_bytes(unitnum * uint64_t(m_unitbytes), buffer, count * m_unitbytes);
}
/**
- * @fn chd_error chd_file::write_units(uint64_t unitnum, const void *buffer, uint32_t count)
+ * @fn std::error_condition chd_file::write_units(uint64_t unitnum, const void *buffer, uint32_t count)
*
* @brief -------------------------------------------------
* write_units - write the given number of units to the CHD
@@ -1112,16 +1142,16 @@ chd_error chd_file::read_units(uint64_t unitnum, void *buffer, uint32_t count)
* @param buffer The buffer.
* @param count Number of.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::write_units(uint64_t unitnum, const void *buffer, uint32_t count)
+std::error_condition chd_file::write_units(uint64_t unitnum, const void *buffer, uint32_t count)
{
return write_bytes(unitnum * uint64_t(m_unitbytes), buffer, count * m_unitbytes);
}
/**
- * @fn chd_error chd_file::read_bytes(uint64_t offset, void *buffer, uint32_t bytes)
+ * @fn std::error_condition chd_file::read_bytes(uint64_t offset, void *buffer, uint32_t bytes)
*
* @brief -------------------------------------------------
* read_bytes - read from the CHD at a byte level, using the cache to handle partial
@@ -1135,7 +1165,7 @@ chd_error chd_file::write_units(uint64_t unitnum, const void *buffer, uint32_t c
* @return The bytes.
*/
-chd_error chd_file::read_bytes(uint64_t offset, void *buffer, uint32_t bytes)
+std::error_condition chd_file::read_bytes(uint64_t offset, void *buffer, uint32_t bytes)
{
// iterate over hunks
uint32_t first_hunk = offset / m_hunkbytes;
@@ -1148,7 +1178,7 @@ chd_error chd_file::read_bytes(uint64_t offset, void *buffer, uint32_t bytes)
uint32_t endoffs = (curhunk == last_hunk) ? ((offset + bytes - 1) % m_hunkbytes) : (m_hunkbytes - 1);
// if it's a full block, just read directly from disk unless it's the cached hunk
- chd_error err = CHDERR_NONE;
+ std::error_condition err;
if (startoffs == 0 && endoffs == m_hunkbytes - 1 && curhunk != m_cachehunk)
err = read_hunk(curhunk, dest);
@@ -1158,7 +1188,7 @@ chd_error chd_file::read_bytes(uint64_t offset, void *buffer, uint32_t bytes)
if (curhunk != m_cachehunk)
{
err = read_hunk(curhunk, &m_cache[0]);
- if (err != CHDERR_NONE)
+ if (err)
return err;
m_cachehunk = curhunk;
}
@@ -1166,15 +1196,15 @@ chd_error chd_file::read_bytes(uint64_t offset, void *buffer, uint32_t bytes)
}
// handle errors and advance
- if (err != CHDERR_NONE)
+ if (err)
return err;
dest += endoffs + 1 - startoffs;
}
- return CHDERR_NONE;
+ return std::error_condition();
}
/**
- * @fn chd_error chd_file::write_bytes(uint64_t offset, const void *buffer, uint32_t bytes)
+ * @fn std::error_condition chd_file::write_bytes(uint64_t offset, const void *buffer, uint32_t bytes)
*
* @brief -------------------------------------------------
* write_bytes - write to the CHD at a byte level, using the cache to handle partial
@@ -1185,10 +1215,10 @@ chd_error chd_file::read_bytes(uint64_t offset, void *buffer, uint32_t bytes)
* @param buffer The buffer.
* @param bytes The bytes.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::write_bytes(uint64_t offset, const void *buffer, uint32_t bytes)
+std::error_condition chd_file::write_bytes(uint64_t offset, const void *buffer, uint32_t bytes)
{
// iterate over hunks
uint32_t first_hunk = offset / m_hunkbytes;
@@ -1201,7 +1231,7 @@ chd_error chd_file::write_bytes(uint64_t offset, const void *buffer, uint32_t by
uint32_t endoffs = (curhunk == last_hunk) ? ((offset + bytes - 1) % m_hunkbytes) : (m_hunkbytes - 1);
// if it's a full block, just write directly to disk unless it's the cached hunk
- chd_error err = CHDERR_NONE;
+ std::error_condition err;
if (startoffs == 0 && endoffs == m_hunkbytes - 1 && curhunk != m_cachehunk)
err = write_hunk(curhunk, source);
@@ -1211,7 +1241,7 @@ chd_error chd_file::write_bytes(uint64_t offset, const void *buffer, uint32_t by
if (curhunk != m_cachehunk)
{
err = read_hunk(curhunk, &m_cache[0]);
- if (err != CHDERR_NONE)
+ if (err)
return err;
m_cachehunk = curhunk;
}
@@ -1220,15 +1250,15 @@ chd_error chd_file::write_bytes(uint64_t offset, const void *buffer, uint32_t by
}
// handle errors and advance
- if (err != CHDERR_NONE)
+ if (err)
return err;
source += endoffs + 1 - startoffs;
}
- return CHDERR_NONE;
+ return std::error_condition();
}
/**
- * @fn chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::string &output)
+ * @fn std::error_condition chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::string &output)
*
* @brief -------------------------------------------------
* read_metadata - read the indexed metadata of the given type
@@ -1244,7 +1274,7 @@ chd_error chd_file::write_bytes(uint64_t offset, const void *buffer, uint32_t by
* @return The metadata.
*/
-chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::string &output)
+std::error_condition chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::string &output)
{
// wrap this for clean reporting
try
@@ -1252,23 +1282,22 @@ chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchind
// if we didn't find it, just return
metadata_entry metaentry;
if (!metadata_find(searchtag, searchindex, metaentry))
- throw CHDERR_METADATA_NOT_FOUND;
+ throw std::error_condition(error::METADATA_NOT_FOUND);
// read the metadata
output.assign(metaentry.length, '\0');
file_read(metaentry.offset + METADATA_HEADER_SIZE, &output[0], metaentry.length);
- return CHDERR_NONE;
+ return std::error_condition();
}
-
- // just return errors
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
+ // just return errors
return err;
}
}
/**
- * @fn chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::vector<uint8_t> &output)
+ * @fn std::error_condition chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::vector<uint8_t> &output)
*
* @brief Reads a metadata.
*
@@ -1282,7 +1311,7 @@ chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchind
* @return The metadata.
*/
-chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::vector<uint8_t> &output)
+std::error_condition chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::vector<uint8_t> &output)
{
// wrap this for clean reporting
try
@@ -1290,23 +1319,22 @@ chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchind
// if we didn't find it, just return
metadata_entry metaentry;
if (!metadata_find(searchtag, searchindex, metaentry))
- throw CHDERR_METADATA_NOT_FOUND;
+ throw std::error_condition(error::METADATA_NOT_FOUND);
// read the metadata
output.resize(metaentry.length);
file_read(metaentry.offset + METADATA_HEADER_SIZE, &output[0], metaentry.length);
- return CHDERR_NONE;
+ return std::error_condition();
}
-
- // just return errors
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
+ // just return errors
return err;
}
}
/**
- * @fn chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, void *output, uint32_t outputlen, uint32_t &resultlen)
+ * @fn std::error_condition chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, void *output, uint32_t outputlen, uint32_t &resultlen)
*
* @brief Reads a metadata.
*
@@ -1322,7 +1350,7 @@ chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchind
* @return The metadata.
*/
-chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, void *output, uint32_t outputlen, uint32_t &resultlen)
+std::error_condition chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, void *output, uint32_t outputlen, uint32_t &resultlen)
{
// wrap this for clean reporting
try
@@ -1330,23 +1358,22 @@ chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchind
// if we didn't find it, just return
metadata_entry metaentry;
if (!metadata_find(searchtag, searchindex, metaentry))
- throw CHDERR_METADATA_NOT_FOUND;
+ throw std::error_condition(error::METADATA_NOT_FOUND);
// read the metadata
resultlen = metaentry.length;
file_read(metaentry.offset + METADATA_HEADER_SIZE, output, std::min(outputlen, resultlen));
- return CHDERR_NONE;
+ return std::error_condition();
}
-
- // just return errors
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
+ // just return errors
return err;
}
}
/**
- * @fn chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::vector<uint8_t> &output, chd_metadata_tag &resulttag, uint8_t &resultflags)
+ * @fn std::error_condition chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::vector<uint8_t> &output, chd_metadata_tag &resulttag, uint8_t &resultflags)
*
* @brief Reads a metadata.
*
@@ -1362,7 +1389,7 @@ chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchind
* @return The metadata.
*/
-chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::vector<uint8_t> &output, chd_metadata_tag &resulttag, uint8_t &resultflags)
+std::error_condition chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::vector<uint8_t> &output, chd_metadata_tag &resulttag, uint8_t &resultflags)
{
// wrap this for clean reporting
try
@@ -1370,25 +1397,24 @@ chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchind
// if we didn't find it, just return
metadata_entry metaentry;
if (!metadata_find(searchtag, searchindex, metaentry))
- throw CHDERR_METADATA_NOT_FOUND;
+ throw std::error_condition(error::METADATA_NOT_FOUND);
// read the metadata
output.resize(metaentry.length);
file_read(metaentry.offset + METADATA_HEADER_SIZE, &output[0], metaentry.length);
resulttag = metaentry.metatag;
resultflags = metaentry.flags;
- return CHDERR_NONE;
+ return std::error_condition();
}
-
- // just return errors
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
+ // just return errors
return err;
}
}
/**
- * @fn chd_error chd_file::write_metadata(chd_metadata_tag metatag, uint32_t metaindex, const void *inputbuf, uint32_t inputlen, uint8_t flags)
+ * @fn std::error_condition chd_file::write_metadata(chd_metadata_tag metatag, uint32_t metaindex, const void *inputbuf, uint32_t inputlen, uint8_t flags)
*
* @brief -------------------------------------------------
* write_metadata - write the indexed metadata of the given type
@@ -1400,17 +1426,17 @@ chd_error chd_file::read_metadata(chd_metadata_tag searchtag, uint32_t searchind
* @param inputlen The inputlen.
* @param flags The flags.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::write_metadata(chd_metadata_tag metatag, uint32_t metaindex, const void *inputbuf, uint32_t inputlen, uint8_t flags)
+std::error_condition chd_file::write_metadata(chd_metadata_tag metatag, uint32_t metaindex, const void *inputbuf, uint32_t inputlen, uint8_t flags)
{
// wrap this for clean reporting
try
{
// must write at least 1 byte and no more than 16MB
if (inputlen < 1 || inputlen >= 16 * 1024 * 1024)
- return CHDERR_INVALID_PARAMETER;
+ return std::error_condition(std::errc::invalid_argument);
// find the entry if it already exists
metadata_entry metaentry;
@@ -1459,18 +1485,17 @@ chd_error chd_file::write_metadata(chd_metadata_tag metatag, uint32_t metaindex,
// update the hash
metadata_update_hash();
- return CHDERR_NONE;
+ return std::error_condition();
}
-
- // return any errors
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
+ // return any errors
return err;
}
}
/**
- * @fn chd_error chd_file::delete_metadata(chd_metadata_tag metatag, uint32_t metaindex)
+ * @fn std::error_condition chd_file::delete_metadata(chd_metadata_tag metatag, uint32_t metaindex)
*
* @brief -------------------------------------------------
* delete_metadata - remove the given metadata from the list
@@ -1482,10 +1507,10 @@ chd_error chd_file::write_metadata(chd_metadata_tag metatag, uint32_t metaindex,
* @param metatag The metatag.
* @param metaindex The metaindex.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::delete_metadata(chd_metadata_tag metatag, uint32_t metaindex)
+std::error_condition chd_file::delete_metadata(chd_metadata_tag metatag, uint32_t metaindex)
{
// wrap this for clean reporting
try
@@ -1493,22 +1518,21 @@ chd_error chd_file::delete_metadata(chd_metadata_tag metatag, uint32_t metaindex
// find the entry
metadata_entry metaentry;
if (!metadata_find(metatag, metaindex, metaentry))
- throw CHDERR_METADATA_NOT_FOUND;
+ throw std::error_condition(error::METADATA_NOT_FOUND);
// point the previous to the next, unlinking us
metadata_set_previous_next(metaentry.prev, metaentry.next);
- return CHDERR_NONE;
+ return std::error_condition();
}
-
- // return any errors
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
+ // return any errors
return err;
}
}
/**
- * @fn chd_error chd_file::clone_all_metadata(chd_file &source)
+ * @fn std::error_condition chd_file::clone_all_metadata(chd_file &source)
*
* @brief -------------------------------------------------
* clone_all_metadata - clone the metadata from one CHD to a second
@@ -1518,10 +1542,10 @@ chd_error chd_file::delete_metadata(chd_metadata_tag metatag, uint32_t metaindex
*
* @param [in,out] source Another instance to copy.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::clone_all_metadata(chd_file &source)
+std::error_condition chd_file::clone_all_metadata(chd_file &source)
{
// wrap this for clean reporting
try
@@ -1540,16 +1564,15 @@ chd_error chd_file::clone_all_metadata(chd_file &source)
source.file_read(metaentry.offset + METADATA_HEADER_SIZE, &filedata[0], metaentry.length);
// write it to the destination
- chd_error err = write_metadata(metaentry.metatag, (uint32_t)-1, &filedata[0], metaentry.length, metaentry.flags);
- if (err != CHDERR_NONE)
+ std::error_condition err = write_metadata(metaentry.metatag, (uint32_t)-1, &filedata[0], metaentry.length, metaentry.flags);
+ if (err)
throw err;
}
- return CHDERR_NONE;
+ return std::error_condition();
}
-
- // return any errors
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
+ // return any errors
return err;
}
}
@@ -1607,7 +1630,7 @@ util::sha1_t chd_file::compute_overall_sha1(util::sha1_t rawsha1)
}
/**
- * @fn chd_error chd_file::codec_configure(chd_codec_type codec, int param, void *config)
+ * @fn std::error_condition chd_file::codec_configure(chd_codec_type codec, int param, void *config)
*
* @brief -------------------------------------------------
* codec_config - set internal codec parameters
@@ -1617,10 +1640,10 @@ util::sha1_t chd_file::compute_overall_sha1(util::sha1_t rawsha1)
* @param param The parameter.
* @param [in,out] config If non-null, the configuration.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::codec_configure(chd_codec_type codec, int param, void *config)
+std::error_condition chd_file::codec_configure(chd_codec_type codec, int param, void *config)
{
// wrap this for clean reporting
try
@@ -1630,14 +1653,13 @@ chd_error chd_file::codec_configure(chd_codec_type codec, int param, void *confi
if (m_compression[codecnum] == codec)
{
m_decompressor[codecnum]->configure(param, config);
- return CHDERR_NONE;
+ return std::error_condition();
}
- return CHDERR_INVALID_PARAMETER;
+ return std::errc::invalid_argument;
}
-
- // return any errors
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
+ // return any errors
return err;
}
}
@@ -1654,44 +1676,49 @@ chd_error chd_file::codec_configure(chd_codec_type codec, int param, void *confi
* @return null if it fails, else a char*.
*/
-const char *chd_file::error_string(chd_error err)
+std::error_category const &chd_category() noexcept
{
- switch (err)
+ class chd_category_impl : public std::error_category
{
- case CHDERR_NONE: return "no error";
- case CHDERR_NO_INTERFACE: return "no drive interface";
- case CHDERR_OUT_OF_MEMORY: return "out of memory";
- case CHDERR_NOT_OPEN: return "file not open";
- case CHDERR_ALREADY_OPEN: return "file already open";
- case CHDERR_INVALID_FILE: return "invalid file";
- case CHDERR_INVALID_PARAMETER: return "invalid parameter";
- case CHDERR_INVALID_DATA: return "invalid data";
- case CHDERR_FILE_NOT_FOUND: return "file not found";
- case CHDERR_REQUIRES_PARENT: return "requires parent";
- case CHDERR_FILE_NOT_WRITEABLE: return "file not writeable";
- case CHDERR_READ_ERROR: return "read error";
- case CHDERR_WRITE_ERROR: return "write error";
- case CHDERR_CODEC_ERROR: return "codec error";
- case CHDERR_INVALID_PARENT: return "invalid parent";
- case CHDERR_HUNK_OUT_OF_RANGE: return "hunk out of range";
- case CHDERR_DECOMPRESSION_ERROR: return "decompression error";
- case CHDERR_COMPRESSION_ERROR: return "compression error";
- case CHDERR_CANT_CREATE_FILE: return "can't create file";
- case CHDERR_CANT_VERIFY: return "can't verify file";
- case CHDERR_NOT_SUPPORTED: return "operation not supported";
- case CHDERR_METADATA_NOT_FOUND: return "can't find metadata";
- case CHDERR_INVALID_METADATA_SIZE: return "invalid metadata size";
- case CHDERR_UNSUPPORTED_VERSION: return "mismatched DIFF and CHD or unsupported CHD version";
- case CHDERR_VERIFY_INCOMPLETE: return "incomplete verify";
- case CHDERR_INVALID_METADATA: return "invalid metadata";
- case CHDERR_INVALID_STATE: return "invalid state";
- case CHDERR_OPERATION_PENDING: return "operation pending";
- case CHDERR_UNSUPPORTED_FORMAT: return "unsupported format";
- case CHDERR_UNKNOWN_COMPRESSION: return "unknown compression type";
- case CHDERR_WALKING_PARENT: return "currently examining parent";
- case CHDERR_COMPRESSING: return "currently compressing";
- default: return "undocumented error";
- }
+ virtual char const *name() const noexcept override { return "chd"; }
+
+ virtual std::string message(int condition) const override
+ {
+ using namespace std::literals;
+ static std::string_view const s_messages[] = {
+ "No error"sv,
+ "No drive interface"sv,
+ "File not open"sv,
+ "File already open"sv,
+ "Invalid file"sv,
+ "Invalid data"sv,
+ "Requires parent"sv,
+ "File not writeable"sv,
+ "Codec error"sv,
+ "Invalid parent"sv,
+ "Hunk out of range"sv,
+ "Decompression error"sv,
+ "Compression error"sv,
+ "Can't verify file"sv,
+ "Can't find metadata"sv,
+ "Invalid metadata size"sv,
+ "Mismatched DIFF and CHD or unsupported CHD version"sv,
+ "Incomplete verify"sv,
+ "Invalid metadata"sv,
+ "Invalid state"sv,
+ "Operation pending"sv,
+ "Unsupported format"sv,
+ "Unknown compression type"sv,
+ "Currently examining parent"sv,
+ "Currently compressing"sv };
+ if ((0 <= condition) && (std::size(s_messages) > condition))
+ return std::string(s_messages[condition]);
+ else
+ return "Unknown error"s;
+ }
+ };
+ static chd_category_impl const s_chd_category_instance;
+ return s_chd_category_instance;
}
@@ -1716,15 +1743,15 @@ uint32_t chd_file::guess_unitbytes()
// look for hard disk metadata; if found, then the unit size == sector size
std::string metadata;
int i0, i1, i2, i3;
- if (read_metadata(HARD_DISK_METADATA_TAG, 0, metadata) == CHDERR_NONE && sscanf(metadata.c_str(), HARD_DISK_METADATA_FORMAT, &i0, &i1, &i2, &i3) == 4)
+ if (!read_metadata(HARD_DISK_METADATA_TAG, 0, metadata) && sscanf(metadata.c_str(), HARD_DISK_METADATA_FORMAT, &i0, &i1, &i2, &i3) == 4)
return i3;
// look for CD-ROM metadata; if found, then the unit size == CD frame size
- if (read_metadata(CDROM_OLD_METADATA_TAG, 0, metadata) == CHDERR_NONE ||
- read_metadata(CDROM_TRACK_METADATA_TAG, 0, metadata) == CHDERR_NONE ||
- read_metadata(CDROM_TRACK_METADATA2_TAG, 0, metadata) == CHDERR_NONE ||
- read_metadata(GDROM_OLD_METADATA_TAG, 0, metadata) == CHDERR_NONE ||
- read_metadata(GDROM_TRACK_METADATA_TAG, 0, metadata) == CHDERR_NONE)
+ if (!read_metadata(CDROM_OLD_METADATA_TAG, 0, metadata) ||
+ !read_metadata(CDROM_TRACK_METADATA_TAG, 0, metadata) ||
+ !read_metadata(CDROM_TRACK_METADATA2_TAG, 0, metadata) ||
+ !read_metadata(GDROM_OLD_METADATA_TAG, 0, metadata) ||
+ !read_metadata(GDROM_TRACK_METADATA_TAG, 0, metadata))
return CD_FRAME_SIZE;
// otherwise, just map 1:1 with the hunk size
@@ -1751,7 +1778,7 @@ void chd_file::parse_v3_header(uint8_t *rawheader, util::sha1_t &parentsha1)
{
// verify header length
if (be_read(&rawheader[8], 4) != V3_HEADER_SIZE)
- throw CHDERR_INVALID_FILE;
+ throw std::error_condition(error::INVALID_FILE);
// extract core info
m_logicalbytes = be_read(&rawheader[28], 8);
@@ -1771,7 +1798,7 @@ void chd_file::parse_v3_header(uint8_t *rawheader, util::sha1_t &parentsha1)
case 1: m_compression[0] = CHD_CODEC_ZLIB; break;
case 2: m_compression[0] = CHD_CODEC_ZLIB; break;
case 3: m_compression[0] = CHD_CODEC_AVHUFF; break;
- default: throw CHDERR_UNKNOWN_COMPRESSION;
+ default: throw std::error_condition(error::UNKNOWN_COMPRESSION);
}
m_compression[1] = m_compression[2] = m_compression[3] = CHD_CODEC_NONE;
@@ -1814,7 +1841,7 @@ void chd_file::parse_v4_header(uint8_t *rawheader, util::sha1_t &parentsha1)
{
// verify header length
if (be_read(&rawheader[8], 4) != V4_HEADER_SIZE)
- throw CHDERR_INVALID_FILE;
+ throw std::error_condition(error::INVALID_FILE);
// extract core info
m_logicalbytes = be_read(&rawheader[28], 8);
@@ -1834,7 +1861,7 @@ void chd_file::parse_v4_header(uint8_t *rawheader, util::sha1_t &parentsha1)
case 1: m_compression[0] = CHD_CODEC_ZLIB; break;
case 2: m_compression[0] = CHD_CODEC_ZLIB; break;
case 3: m_compression[0] = CHD_CODEC_AVHUFF; break;
- default: throw CHDERR_UNKNOWN_COMPRESSION;
+ default: throw std::error_condition(error::UNKNOWN_COMPRESSION);
}
m_compression[1] = m_compression[2] = m_compression[3] = CHD_CODEC_NONE;
@@ -1874,7 +1901,7 @@ void chd_file::parse_v5_header(uint8_t *rawheader, util::sha1_t &parentsha1)
{
// verify header length
if (be_read(&rawheader[8], 4) != V5_HEADER_SIZE)
- throw CHDERR_INVALID_FILE;
+ throw std::error_condition(error::INVALID_FILE);
// extract core info
m_logicalbytes = be_read(&rawheader[32], 8);
@@ -1908,7 +1935,7 @@ void chd_file::parse_v5_header(uint8_t *rawheader, util::sha1_t &parentsha1)
}
/**
- * @fn chd_error chd_file::compress_v5_map()
+ * @fn std::error_condition chd_file::compress_v5_map()
*
* @brief -------------------------------------------------
* compress_v5_map - compress the v5 map and write it to the end of the file
@@ -1917,10 +1944,10 @@ void chd_file::parse_v5_header(uint8_t *rawheader, util::sha1_t &parentsha1)
* @exception CHDERR_COMPRESSION_ERROR Thrown when a chderr compression error error
* condition occurs.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::compress_v5_map()
+std::error_condition chd_file::compress_v5_map()
{
try
{
@@ -2015,10 +2042,10 @@ chd_error chd_file::compress_v5_map()
bitstream_out bitbuf(&compressed[16], compressed.size() - 16);
huffman_error err = encoder.compute_tree_from_histo();
if (err != HUFFERR_NONE)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(error::COMPRESSION_ERROR);
err = encoder.export_tree_rle(bitbuf);
if (err != HUFFERR_NONE)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(error::COMPRESSION_ERROR);
// encode the data
for (uint8_t *src = &compression_rle[0]; src < dest; src++)
@@ -2113,9 +2140,9 @@ chd_error chd_file::compress_v5_map()
uint8_t rawbuf[sizeof(uint64_t)];
be_write(rawbuf, m_mapoffset, 8);
file_write(m_mapoffset_offset, rawbuf, sizeof(rawbuf));
- return CHDERR_NONE;
+ return std::error_condition();
}
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
return err;
}
@@ -2160,7 +2187,7 @@ void chd_file::decompress_v5_map()
huffman_decoder<16, 8> decoder;
huffman_error err = decoder.import_tree_rle(bitbuf);
if (err != HUFFERR_NONE)
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(error::DECOMPRESSION_ERROR);
uint8_t lastcomp = 0;
int repcount = 0;
for (int hunknum = 0; hunknum < m_hunkcount; hunknum++)
@@ -2244,11 +2271,11 @@ void chd_file::decompress_v5_map()
// verify the final CRC
if (util::crc16_creator::simple(&m_rawmap[0], m_hunkcount * 12) != mapcrc)
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(error::DECOMPRESSION_ERROR);
}
/**
- * @fn chd_error chd_file::create_common()
+ * @fn std::error_condition chd_file::create_common()
*
* @brief -------------------------------------------------
* create_common - command path when creating a new CHD file
@@ -2264,7 +2291,7 @@ void chd_file::decompress_v5_map()
* @return The new common.
*/
-chd_error chd_file::create_common()
+std::error_condition chd_file::create_common()
{
// wrap in try for proper error handling
try
@@ -2273,14 +2300,14 @@ chd_error chd_file::create_common()
m_metaoffset = 0;
// if we have a parent, it must be V3 or later
- if (m_parent != nullptr && m_parent->version() < 3)
- throw CHDERR_UNSUPPORTED_VERSION;
+ if (m_parent && m_parent->version() < 3)
+ throw std::error_condition(error::UNSUPPORTED_VERSION);
// must be an even number of units per hunk
if (m_hunkbytes % m_unitbytes != 0)
- throw CHDERR_INVALID_PARAMETER;
- if (m_parent != nullptr && m_unitbytes != m_parent->unit_bytes())
- throw CHDERR_INVALID_PARAMETER;
+ throw std::error_condition(std::errc::invalid_argument);
+ if (m_parent && m_unitbytes != m_parent->unit_bytes())
+ throw std::error_condition(std::errc::invalid_argument);
// verify the compression types
bool found_zero = false;
@@ -2290,9 +2317,9 @@ chd_error chd_file::create_common()
if (elem == CHD_CODEC_NONE)
found_zero = true;
else if (found_zero)
- throw CHDERR_INVALID_PARAMETER;
+ throw std::error_condition(std::errc::invalid_argument);
else if (!chd_codec_list::codec_exists(elem))
- throw CHDERR_UNKNOWN_COMPRESSION;
+ throw std::error_condition(error::UNKNOWN_COMPRESSION);
}
// create our V5 header
@@ -2342,10 +2369,9 @@ chd_error chd_file::create_common()
// finish opening the file
create_open_common();
}
-
- // handle errors by closing ourself
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
+ // handle errors by closing ourself
close();
return err;
}
@@ -2354,11 +2380,11 @@ chd_error chd_file::create_common()
close();
throw;
}
- return CHDERR_NONE;
+ return std::error_condition();
}
/**
- * @fn chd_error chd_file::open_common(bool writeable)
+ * @fn std::error_condition chd_file::open_common(bool writeable)
*
* @brief -------------------------------------------------
* open_common - common path when opening an existing CHD file for input
@@ -2377,10 +2403,10 @@ chd_error chd_file::create_common()
*
* @param writeable true if writeable.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file::open_common(bool writeable)
+std::error_condition chd_file::open_common(bool writeable)
{
// wrap in try for proper error handling
try
@@ -2394,7 +2420,7 @@ chd_error chd_file::open_common(bool writeable)
// verify the signature
if (memcmp(rawheader, "MComprHD", 8) != 0)
- throw CHDERR_INVALID_FILE;
+ throw std::error_condition(error::INVALID_FILE);
m_version = be_read(&rawheader[12], 4);
@@ -2405,7 +2431,7 @@ chd_error chd_file::open_common(bool writeable)
case 3: parse_v3_header(rawheader, parentsha1); break;
case 4: parse_v4_header(rawheader, parentsha1); break;
case 5: parse_v5_header(rawheader, parentsha1); break;
- default: throw CHDERR_UNSUPPORTED_VERSION;
+ default: throw std::error_condition(error::UNSUPPORTED_VERSION);
}
// only allow writes to the most recent version
@@ -2413,27 +2439,26 @@ chd_error chd_file::open_common(bool writeable)
m_allow_writes = false;
if (writeable && !m_allow_writes)
- throw CHDERR_FILE_NOT_WRITEABLE;
+ throw std::error_condition(error::FILE_NOT_WRITEABLE);
// make sure we have a parent if we need one (and don't if we don't)
if (parentsha1 != util::sha1_t::null)
{
- if (m_parent == nullptr)
+ if (!m_parent)
m_parent_missing = true;
else if (m_parent->sha1() != parentsha1)
- throw CHDERR_INVALID_PARENT;
+ throw std::error_condition(error::INVALID_PARENT);
}
- else if (m_parent != nullptr)
- throw CHDERR_INVALID_PARAMETER;
+ else if (m_parent)
+ throw std::error_condition(std::errc::invalid_argument);
// finish opening the file
create_open_common();
- return CHDERR_NONE;
+ return std::error_condition();
}
-
- // handle errors by closing ourself
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
+ // handle errors by closing ourself
close();
return err;
}
@@ -2457,7 +2482,7 @@ void chd_file::create_open_common()
{
m_decompressor[decompnum] = chd_codec_list::new_decompressor(m_compression[decompnum], *this);
if (m_decompressor[decompnum] == nullptr && m_compression[decompnum] != 0)
- throw CHDERR_UNKNOWN_COMPRESSION;
+ throw std::error_condition(error::UNKNOWN_COMPRESSION);
}
// read the map; v5+ compressed drives need to read and decompress their map
@@ -2494,30 +2519,30 @@ void chd_file::create_open_common()
void chd_file::verify_proper_compression_append(uint32_t hunknum)
{
// punt if no file
- if (m_file == nullptr)
- throw CHDERR_NOT_OPEN;
+ if (!m_file)
+ throw std::error_condition(error::NOT_OPEN);
// return an error if out of range
if (hunknum >= m_hunkcount)
- throw CHDERR_HUNK_OUT_OF_RANGE;
+ throw std::error_condition(error::HUNK_OUT_OF_RANGE);
// if not writeable, fail
if (!m_allow_writes)
- throw CHDERR_FILE_NOT_WRITEABLE;
+ throw std::error_condition(error::FILE_NOT_WRITEABLE);
// compressed writes only via this interface
if (!compressed())
- throw CHDERR_FILE_NOT_WRITEABLE;
+ throw std::error_condition(error::FILE_NOT_WRITEABLE);
// only permitted to write new blocks
uint8_t *rawmap = &m_rawmap[hunknum * 12];
if (rawmap[0] != 0xff)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(error::COMPRESSION_ERROR);
// if this isn't the first block, only permitted to write immediately
// after the previous one
if (hunknum != 0 && rawmap[-12] == 0xff)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(error::COMPRESSION_ERROR);
}
/**
@@ -2572,7 +2597,7 @@ void chd_file::hunk_copy_from_self(uint32_t hunknum, uint32_t otherhunk)
// only permitted to reference prior hunks
if (otherhunk >= hunknum)
- throw CHDERR_INVALID_PARAMETER;
+ throw std::error_condition(std::errc::invalid_argument);
// update the map entry
uint8_t *rawmap = &m_rawmap[hunknum * 12];
@@ -2841,7 +2866,7 @@ void chd_file_compressor::compress_begin()
}
/**
- * @fn chd_error chd_file_compressor::compress_continue(double &progress, double &ratio)
+ * @fn std::error_condition chd_file_compressor::compress_continue(double &progress, double &ratio)
*
* @brief -------------------------------------------------
* compress_continue - continue compression
@@ -2850,14 +2875,14 @@ void chd_file_compressor::compress_begin()
* @param [in,out] progress The progress.
* @param [in,out] ratio The ratio.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chd_file_compressor::compress_continue(double &progress, double &ratio)
+std::error_condition chd_file_compressor::compress_continue(double &progress, double &ratio)
{
// if we got an error, return an error
if (m_read_error)
- return CHDERR_READ_ERROR;
+ return std::errc::io_error;
// if done reading, queue some more
while (m_read_queue_offset < m_logicalbytes && osd_work_queue_items(m_read_queue) < 2)
@@ -2911,8 +2936,8 @@ chd_error chd_file_compressor::compress_continue(double &progress, double &ratio
// if we're uncompressed, use regular writes
else if (!compressed())
{
- chd_error err = write_hunk(item.m_hunknum, item.m_data);
- if (err != CHDERR_NONE)
+ std::error_condition err = write_hunk(item.m_hunknum, item.m_data);
+ if (err)
return err;
// writes of all-0 data don't actually take space, so see if we count this
@@ -2973,7 +2998,7 @@ chd_error chd_file_compressor::compress_continue(double &progress, double &ratio
{
osd_work_queue_wait(m_read_queue, 30 * osd_ticks_per_second());
if (!compressed())
- return CHDERR_NONE;
+ return std::error_condition();
set_raw_sha1(m_compsha1.finish());
return compress_v5_map();
}
@@ -2994,7 +3019,7 @@ chd_error chd_file_compressor::compress_continue(double &progress, double &ratio
m_work_item[m_write_hunk % WORK_BUFFER_HUNKS].m_osd != nullptr)
osd_work_item_wait(m_work_item[m_write_hunk % WORK_BUFFER_HUNKS].m_osd, osd_ticks_per_second());
- return m_walking_parent ? CHDERR_WALKING_PARENT : CHDERR_COMPRESSING;
+ return m_walking_parent ? error::WALKING_PARENT : error::COMPRESSING;
}
/**
@@ -3171,12 +3196,12 @@ void chd_file_compressor::async_read()
// advance the read pointer
m_read_done_offset += numbytes;
}
- catch (chd_error& err)
+ catch (std::error_condition const &err)
{
- fprintf(stderr, "CHD error occurred: %s\n", chd_file::error_string(err));
+ fprintf(stderr, "CHD error occurred: %s\n", err.message().c_str());
m_read_error = true;
}
- catch (std::exception& ex)
+ catch (std::exception const &ex)
{
fprintf(stderr, "exception occurred: %s\n", ex.what());
m_read_error = true;
diff --git a/src/lib/util/chd.h b/src/lib/util/chd.h
index 705967d3dda..8d3e639438b 100644
--- a/src/lib/util/chd.h
+++ b/src/lib/util/chd.h
@@ -7,18 +7,22 @@
MAME Compressed Hunks of Data file format
***************************************************************************/
-
-#ifndef MAME_UTIL_CHD_H
-#define MAME_UTIL_CHD_H
+#ifndef MAME_LIB_UTIL_CHD_H
+#define MAME_LIB_UTIL_CHD_H
#pragma once
-#include "osdcore.h"
-#include <string>
-#include "corefile.h"
-#include "hashing.h"
#include "chdcodec.h"
+#include "hashing.h"
+#include "ioprocs.h"
+
+#include "osdcore.h"
+
#include <atomic>
+#include <string>
+#include <string_view>
+#include <system_error>
+
/***************************************************************************
@@ -190,86 +194,49 @@
//**************************************************************************
// pseudo-codecs returned by hunk_info
-const chd_codec_type CHD_CODEC_SELF = 1; // copy of another hunk
-const chd_codec_type CHD_CODEC_PARENT = 2; // copy of a parent's hunk
-const chd_codec_type CHD_CODEC_MINI = 3; // legacy "mini" 8-byte repeat
+constexpr chd_codec_type CHD_CODEC_SELF = 1; // copy of another hunk
+constexpr chd_codec_type CHD_CODEC_PARENT = 2; // copy of a parent's hunk
+constexpr chd_codec_type CHD_CODEC_MINI = 3; // legacy "mini" 8-byte repeat
// core types
typedef uint32_t chd_metadata_tag;
// metadata parameters
-const chd_metadata_tag CHDMETATAG_WILDCARD = 0;
-const uint32_t CHDMETAINDEX_APPEND = ~0;
+constexpr chd_metadata_tag CHDMETATAG_WILDCARD = 0;
+constexpr uint32_t CHDMETAINDEX_APPEND = ~0;
// metadata flags
-const uint8_t CHD_MDFLAGS_CHECKSUM = 0x01; // indicates data is checksummed
+constexpr uint8_t CHD_MDFLAGS_CHECKSUM = 0x01; // indicates data is checksummed
// standard hard disk metadata
-const chd_metadata_tag HARD_DISK_METADATA_TAG = CHD_MAKE_TAG('G','D','D','D');
+constexpr chd_metadata_tag HARD_DISK_METADATA_TAG = CHD_MAKE_TAG('G','D','D','D');
extern const char *HARD_DISK_METADATA_FORMAT;
// hard disk identify information
-const chd_metadata_tag HARD_DISK_IDENT_METADATA_TAG = CHD_MAKE_TAG('I','D','N','T');
+constexpr chd_metadata_tag HARD_DISK_IDENT_METADATA_TAG = CHD_MAKE_TAG('I','D','N','T');
// hard disk key information
-const chd_metadata_tag HARD_DISK_KEY_METADATA_TAG = CHD_MAKE_TAG('K','E','Y',' ');
+constexpr chd_metadata_tag HARD_DISK_KEY_METADATA_TAG = CHD_MAKE_TAG('K','E','Y',' ');
// pcmcia CIS information
-const chd_metadata_tag PCMCIA_CIS_METADATA_TAG = CHD_MAKE_TAG('C','I','S',' ');
+constexpr chd_metadata_tag PCMCIA_CIS_METADATA_TAG = CHD_MAKE_TAG('C','I','S',' ');
// standard CD-ROM metadata
-const chd_metadata_tag CDROM_OLD_METADATA_TAG = CHD_MAKE_TAG('C','H','C','D');
-const chd_metadata_tag CDROM_TRACK_METADATA_TAG = CHD_MAKE_TAG('C','H','T','R');
+constexpr chd_metadata_tag CDROM_OLD_METADATA_TAG = CHD_MAKE_TAG('C','H','C','D');
+constexpr chd_metadata_tag CDROM_TRACK_METADATA_TAG = CHD_MAKE_TAG('C','H','T','R');
extern const char *CDROM_TRACK_METADATA_FORMAT;
-const chd_metadata_tag CDROM_TRACK_METADATA2_TAG = CHD_MAKE_TAG('C','H','T','2');
+constexpr chd_metadata_tag CDROM_TRACK_METADATA2_TAG = CHD_MAKE_TAG('C','H','T','2');
extern const char *CDROM_TRACK_METADATA2_FORMAT;
-const chd_metadata_tag GDROM_OLD_METADATA_TAG = CHD_MAKE_TAG('C','H','G','T');
-const chd_metadata_tag GDROM_TRACK_METADATA_TAG = CHD_MAKE_TAG('C', 'H', 'G', 'D');
+constexpr chd_metadata_tag GDROM_OLD_METADATA_TAG = CHD_MAKE_TAG('C','H','G','T');
+constexpr chd_metadata_tag GDROM_TRACK_METADATA_TAG = CHD_MAKE_TAG('C', 'H', 'G', 'D');
extern const char *GDROM_TRACK_METADATA_FORMAT;
// standard A/V metadata
-const chd_metadata_tag AV_METADATA_TAG = CHD_MAKE_TAG('A','V','A','V');
+constexpr chd_metadata_tag AV_METADATA_TAG = CHD_MAKE_TAG('A','V','A','V');
extern const char *AV_METADATA_FORMAT;
// A/V laserdisc frame metadata
-const chd_metadata_tag AV_LD_METADATA_TAG = CHD_MAKE_TAG('A','V','L','D');
-
-// error types
-enum chd_error
-{
- CHDERR_NONE,
- CHDERR_NO_INTERFACE,
- CHDERR_OUT_OF_MEMORY,
- CHDERR_NOT_OPEN,
- CHDERR_ALREADY_OPEN,
- CHDERR_INVALID_FILE,
- CHDERR_INVALID_PARAMETER,
- CHDERR_INVALID_DATA,
- CHDERR_FILE_NOT_FOUND,
- CHDERR_REQUIRES_PARENT,
- CHDERR_FILE_NOT_WRITEABLE,
- CHDERR_READ_ERROR,
- CHDERR_WRITE_ERROR,
- CHDERR_CODEC_ERROR,
- CHDERR_INVALID_PARENT,
- CHDERR_HUNK_OUT_OF_RANGE,
- CHDERR_DECOMPRESSION_ERROR,
- CHDERR_COMPRESSION_ERROR,
- CHDERR_CANT_CREATE_FILE,
- CHDERR_CANT_VERIFY,
- CHDERR_NOT_SUPPORTED,
- CHDERR_METADATA_NOT_FOUND,
- CHDERR_INVALID_METADATA_SIZE,
- CHDERR_UNSUPPORTED_VERSION,
- CHDERR_VERIFY_INCOMPLETE,
- CHDERR_INVALID_METADATA,
- CHDERR_INVALID_STATE,
- CHDERR_OPERATION_PENDING,
- CHDERR_UNSUPPORTED_FORMAT,
- CHDERR_UNKNOWN_COMPRESSION,
- CHDERR_WALKING_PARENT,
- CHDERR_COMPRESSING
-};
+constexpr chd_metadata_tag AV_LD_METADATA_TAG = CHD_MAKE_TAG('A','V','L','D');
@@ -277,9 +244,6 @@ enum chd_error
// TYPE DEFINITIONS
//**************************************************************************
-class chd_codec;
-
-
// ======================> chd_file
// core file class
@@ -289,22 +253,49 @@ class chd_file
friend class chd_verifier;
// constants
- static const uint32_t HEADER_VERSION = 5;
- static const uint32_t V3_HEADER_SIZE = 120;
- static const uint32_t V4_HEADER_SIZE = 108;
- static const uint32_t V5_HEADER_SIZE = 124;
- static const uint32_t MAX_HEADER_SIZE = V5_HEADER_SIZE;
+ static constexpr uint32_t HEADER_VERSION = 5;
+ static constexpr uint32_t V3_HEADER_SIZE = 120;
+ static constexpr uint32_t V4_HEADER_SIZE = 108;
+ static constexpr uint32_t V5_HEADER_SIZE = 124;
+ static constexpr uint32_t MAX_HEADER_SIZE = V5_HEADER_SIZE;
public:
+ // error types
+ enum class error
+ {
+ NO_INTERFACE = 1,
+ NOT_OPEN,
+ ALREADY_OPEN,
+ INVALID_FILE,
+ INVALID_DATA,
+ REQUIRES_PARENT,
+ FILE_NOT_WRITEABLE,
+ CODEC_ERROR,
+ INVALID_PARENT,
+ HUNK_OUT_OF_RANGE,
+ DECOMPRESSION_ERROR,
+ COMPRESSION_ERROR,
+ CANT_VERIFY,
+ METADATA_NOT_FOUND,
+ INVALID_METADATA_SIZE,
+ UNSUPPORTED_VERSION,
+ VERIFY_INCOMPLETE,
+ INVALID_METADATA,
+ INVALID_STATE,
+ OPERATION_PENDING,
+ UNSUPPORTED_FORMAT,
+ UNKNOWN_COMPRESSION,
+ WALKING_PARENT,
+ COMPRESSING
+ };
+
// construction/destruction
chd_file();
virtual ~chd_file();
- // operators
- operator util::core_file &() { return *m_file; }
-
// getters
- bool opened() const { return (m_file != nullptr); }
+ util::random_read &file();
+ bool opened() const { return bool(m_file); }
uint32_t version() const { return m_version; }
uint64_t logical_bytes() const { return m_logicalbytes; }
uint32_t hunk_bytes() const { return m_hunkbytes; }
@@ -317,52 +308,49 @@ public:
util::sha1_t sha1();
util::sha1_t raw_sha1();
util::sha1_t parent_sha1();
- chd_error hunk_info(uint32_t hunknum, chd_codec_type &compressor, uint32_t &compbytes);
+ std::error_condition hunk_info(uint32_t hunknum, chd_codec_type &compressor, uint32_t &compbytes);
// setters
void set_raw_sha1(util::sha1_t rawdata);
void set_parent_sha1(util::sha1_t parent);
// file create
- chd_error create(const char *filename, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t unitbytes, chd_codec_type compression[4]);
- chd_error create(util::core_file &file, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t unitbytes, chd_codec_type compression[4]);
- chd_error create(const char *filename, uint64_t logicalbytes, uint32_t hunkbytes, chd_codec_type compression[4], chd_file &parent);
- chd_error create(util::core_file &file, uint64_t logicalbytes, uint32_t hunkbytes, chd_codec_type compression[4], chd_file &parent);
+ std::error_condition create(std::string_view filename, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t unitbytes, chd_codec_type compression[4]);
+ std::error_condition create(util::random_read_write::ptr &&file, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t unitbytes, chd_codec_type compression[4]);
+ std::error_condition create(std::string_view filename, uint64_t logicalbytes, uint32_t hunkbytes, chd_codec_type compression[4], chd_file &parent);
+ std::error_condition create(util::random_read_write::ptr &&file, uint64_t logicalbytes, uint32_t 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(util::core_file &file, bool writeable = false, chd_file *parent = nullptr);
+ std::error_condition open(std::string_view filename, bool writeable = false, chd_file *parent = nullptr);
+ std::error_condition open(util::random_read_write::ptr &&file, bool writeable = false, chd_file *parent = nullptr);
// file close
void close();
// read/write
- chd_error read_hunk(uint32_t hunknum, void *buffer);
- chd_error write_hunk(uint32_t hunknum, const void *buffer);
- chd_error read_units(uint64_t unitnum, void *buffer, uint32_t count = 1);
- chd_error write_units(uint64_t unitnum, const void *buffer, uint32_t count = 1);
- chd_error read_bytes(uint64_t offset, void *buffer, uint32_t bytes);
- chd_error write_bytes(uint64_t offset, const void *buffer, uint32_t bytes);
+ std::error_condition read_hunk(uint32_t hunknum, void *buffer);
+ std::error_condition write_hunk(uint32_t hunknum, const void *buffer);
+ std::error_condition read_units(uint64_t unitnum, void *buffer, uint32_t count = 1);
+ std::error_condition write_units(uint64_t unitnum, const void *buffer, uint32_t count = 1);
+ std::error_condition read_bytes(uint64_t offset, void *buffer, uint32_t bytes);
+ std::error_condition write_bytes(uint64_t offset, const void *buffer, uint32_t bytes);
// metadata management
- chd_error read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::string &output);
- chd_error read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::vector<uint8_t> &output);
- chd_error read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, void *output, uint32_t outputlen, uint32_t &resultlen);
- chd_error read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::vector<uint8_t> &output, chd_metadata_tag &resulttag, uint8_t &resultflags);
- chd_error write_metadata(chd_metadata_tag metatag, uint32_t metaindex, const void *inputbuf, uint32_t inputlen, uint8_t flags = CHD_MDFLAGS_CHECKSUM);
- chd_error write_metadata(chd_metadata_tag metatag, uint32_t metaindex, const std::string &input, uint8_t flags = CHD_MDFLAGS_CHECKSUM) { return write_metadata(metatag, metaindex, input.c_str(), input.length() + 1, flags); }
- chd_error write_metadata(chd_metadata_tag metatag, uint32_t metaindex, const std::vector<uint8_t> &input, uint8_t flags = CHD_MDFLAGS_CHECKSUM) { return write_metadata(metatag, metaindex, &input[0], input.size(), flags); }
- chd_error delete_metadata(chd_metadata_tag metatag, uint32_t metaindex);
- chd_error clone_all_metadata(chd_file &source);
+ std::error_condition read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::string &output);
+ std::error_condition read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::vector<uint8_t> &output);
+ std::error_condition read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, void *output, uint32_t outputlen, uint32_t &resultlen);
+ std::error_condition read_metadata(chd_metadata_tag searchtag, uint32_t searchindex, std::vector<uint8_t> &output, chd_metadata_tag &resulttag, uint8_t &resultflags);
+ std::error_condition write_metadata(chd_metadata_tag metatag, uint32_t metaindex, const void *inputbuf, uint32_t inputlen, uint8_t flags = CHD_MDFLAGS_CHECKSUM);
+ std::error_condition write_metadata(chd_metadata_tag metatag, uint32_t metaindex, const std::string &input, uint8_t flags = CHD_MDFLAGS_CHECKSUM) { return write_metadata(metatag, metaindex, input.c_str(), input.length() + 1, flags); }
+ std::error_condition write_metadata(chd_metadata_tag metatag, uint32_t metaindex, const std::vector<uint8_t> &input, uint8_t flags = CHD_MDFLAGS_CHECKSUM) { return write_metadata(metatag, metaindex, &input[0], input.size(), flags); }
+ std::error_condition delete_metadata(chd_metadata_tag metatag, uint32_t metaindex);
+ std::error_condition clone_all_metadata(chd_file &source);
// hashing helper
util::sha1_t compute_overall_sha1(util::sha1_t rawsha1);
// codec interfaces
- chd_error codec_configure(chd_codec_type codec, int param, void *config);
-
- // static helpers
- static const char *error_string(chd_error err);
+ std::error_condition codec_configure(chd_codec_type codec, int param, void *config);
private:
struct metadata_entry;
@@ -383,10 +371,10 @@ private:
void parse_v3_header(uint8_t *rawheader, util::sha1_t &parentsha1);
void parse_v4_header(uint8_t *rawheader, util::sha1_t &parentsha1);
void parse_v5_header(uint8_t *rawheader, util::sha1_t &parentsha1);
- chd_error compress_v5_map();
+ std::error_condition compress_v5_map();
void decompress_v5_map();
- chd_error create_common();
- chd_error open_common(bool writeable);
+ std::error_condition create_common();
+ std::error_condition open_common(bool writeable);
void create_open_common();
void verify_proper_compression_append(uint32_t hunknum);
void hunk_write_compressed(uint32_t hunknum, int8_t compression, const uint8_t *compressed, uint32_t complength, util::crc16_t crc16);
@@ -398,42 +386,41 @@ private:
static int CLIB_DECL metadata_hash_compare(const void *elem1, const void *elem2);
// file characteristics
- 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()
+ util::random_read_write::ptr m_file; // handle to the open core file
bool m_allow_reads; // permit reads from this CHD?
bool m_allow_writes; // permit writes to this CHD?
// core parameters from the header
- uint32_t m_version; // version of the header
- uint64_t m_logicalbytes; // logical size of the raw CHD data in bytes
- uint64_t m_mapoffset; // offset of map
- uint64_t m_metaoffset; // offset to first metadata bit
- uint32_t m_hunkbytes; // size of each raw hunk in bytes
- uint32_t m_hunkcount; // number of hunks represented
- uint32_t m_unitbytes; // size of each unit in bytes
- uint64_t m_unitcount; // number of units represented
+ uint32_t m_version; // version of the header
+ uint64_t m_logicalbytes; // logical size of the raw CHD data in bytes
+ uint64_t m_mapoffset; // offset of map
+ uint64_t m_metaoffset; // offset to first metadata bit
+ uint32_t m_hunkbytes; // size of each raw hunk in bytes
+ uint32_t m_hunkcount; // number of hunks represented
+ uint32_t m_unitbytes; // size of each unit in bytes
+ uint64_t m_unitcount; // number of units represented
chd_codec_type m_compression[4]; // array of compression types used
chd_file * m_parent; // pointer to parent file, or nullptr if none
bool m_parent_missing; // are we missing our parent?
// key offsets within the header
- uint64_t m_mapoffset_offset; // offset of map offset field
- uint64_t m_metaoffset_offset;// offset of metaoffset field
- uint64_t m_sha1_offset; // offset of SHA1 field
- uint64_t m_rawsha1_offset; // offset of raw SHA1 field
- uint64_t m_parentsha1_offset;// offset of paren SHA1 field
+ uint64_t m_mapoffset_offset; // offset of map offset field
+ uint64_t m_metaoffset_offset;// offset of metaoffset field
+ uint64_t m_sha1_offset; // offset of SHA1 field
+ uint64_t m_rawsha1_offset; // offset of raw SHA1 field
+ uint64_t m_parentsha1_offset;// offset of paren SHA1 field
// map information
- uint32_t m_mapentrybytes; // length of each entry in a map
- std::vector<uint8_t> m_rawmap; // raw map data
+ uint32_t m_mapentrybytes; // length of each entry in a map
+ std::vector<uint8_t> m_rawmap; // raw map data
// compression management
- chd_decompressor * m_decompressor[4]; // array of decompression codecs
- std::vector<uint8_t> m_compressed; // temporary buffer for compressed data
+ chd_decompressor::ptr m_decompressor[4]; // array of decompression codecs
+ std::vector<uint8_t> m_compressed; // temporary buffer for compressed data
// caching
- std::vector<uint8_t> m_cache; // single-hunk cache for partial reads/writes
- uint32_t m_cachehunk; // which hunk is in the cache?
+ std::vector<uint8_t> m_cache; // single-hunk cache for partial reads/writes
+ uint32_t m_cachehunk; // which hunk is in the cache?
};
@@ -449,7 +436,7 @@ public:
// compression management
void compress_begin();
- chd_error compress_continue(double &progress, double &ratio);
+ std::error_condition compress_continue(double &progress, double &ratio);
protected:
// required override: read more data
@@ -470,24 +457,24 @@ private:
void add(uint64_t itemnum, util::crc16_t crc16, util::sha1_t sha1);
// constants
- static const uint64_t NOT_FOUND = ~uint64_t(0);
+ static constexpr uint64_t NOT_FOUND = ~uint64_t(0);
+
private:
// internal entry
struct entry_t
{
entry_t * m_next; // next entry in list
- uint64_t m_itemnum; // item number
+ uint64_t m_itemnum; // item number
util::sha1_t m_sha1; // SHA-1 of the block
};
// block of entries
struct entry_block
{
- entry_block(entry_block *prev)
- : m_next(prev), m_nextalloc(0) { }
+ entry_block(entry_block *prev) : m_next(prev), m_nextalloc(0) { }
entry_block * m_next; // next block in list
- uint32_t m_nextalloc; // next to be allocated
+ uint32_t m_nextalloc; // next to be allocated
entry_t m_array[16384]; // array of entries
};
@@ -551,8 +538,8 @@ private:
// current compression status
bool m_walking_parent; // are we building the parent map?
- uint64_t m_total_in; // total bytes in
- uint64_t m_total_out; // total bytes out
+ uint64_t m_total_in; // total bytes in
+ uint64_t m_total_out; // total bytes out
util::sha1_creator m_compsha1; // running SHA-1 on raw data
// hash lookup maps
@@ -561,20 +548,31 @@ private:
// read I/O thread
osd_work_queue * m_read_queue; // work queue for reading
- uint64_t m_read_queue_offset;// next offset to enqueue
- uint64_t m_read_done_offset; // next offset that will complete
+ uint64_t m_read_queue_offset;// next offset to enqueue
+ uint64_t m_read_done_offset; // next offset that will complete
bool m_read_error; // error during reading?
// work item thread
- static const int WORK_BUFFER_HUNKS = 256;
+ static constexpr int WORK_BUFFER_HUNKS = 256;
osd_work_queue * m_work_queue; // queue for doing work on other threads
- std::vector<uint8_t> m_work_buffer; // buffer containing hunk data to work on
- std::vector<uint8_t> m_compressed_buffer;// buffer containing compressed data
+ std::vector<uint8_t> m_work_buffer; // buffer containing hunk data to work on
+ std::vector<uint8_t> m_compressed_buffer;// buffer containing compressed data
work_item m_work_item[WORK_BUFFER_HUNKS]; // status of each hunk
chd_compressor_group * m_codecs[WORK_MAX_THREADS]; // codecs to use
// output state
- uint32_t m_write_hunk; // next hunk to write
+ uint32_t m_write_hunk; // next hunk to write
};
-#endif // MAME_UTIL_CHD_H
+
+// error category for CHD errors
+std::error_category const &chd_category() noexcept;
+inline std::error_condition make_error_condition(chd_file::error err) noexcept { return std::error_condition(int(err), chd_category()); }
+
+namespace std {
+
+template <> struct is_error_condition_enum<chd_file::error> : public std::true_type { };
+
+} // namespace std
+
+#endif // MAME_LIB_UTIL_CHD_H
diff --git a/src/lib/util/chdcd.cpp b/src/lib/util/chdcd.cpp
index ef013b41f48..63b633536bf 100644
--- a/src/lib/util/chdcd.cpp
+++ b/src/lib/util/chdcd.cpp
@@ -7,15 +7,19 @@
***************************************************************************/
-#include <cctype>
-#include <cstdlib>
-#include <cassert>
-#include "osdcore.h"
-#include "chd.h"
#include "chdcd.h"
+
+#include "chd.h"
#include "corefile.h"
#include "corestr.h"
+#include "osdcore.h"
+
+#include <cassert>
+#include <cctype>
+#include <cerrno>
+#include <cstdlib>
+
/***************************************************************************
@@ -230,8 +234,8 @@ static uint32_t parse_wav_sample(const char *filename, uint32_t *dataoffs)
uint64_t fsize = 0;
std::uint32_t actual;
- osd_file::error filerr = osd_file::open(filename, OPEN_FLAG_READ, file, fsize);
- if (filerr != osd_file::error::NONE)
+ std::error_condition const filerr = osd_file::open(filename, OPEN_FLAG_READ, file, fsize);
+ if (filerr)
{
printf("ERROR: could not open (%s)\n", filename);
return 0;
@@ -449,7 +453,7 @@ uint64_t read_uint64(FILE *infile)
-------------------------------------------------*/
/**
- * @fn chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
+ * @fn std::error_condition chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
*
* @brief Chdcd parse nero.
*
@@ -457,26 +461,25 @@ uint64_t read_uint64(FILE *infile)
* @param [in,out] outtoc The outtoc.
* @param [in,out] outinfo The outinfo.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
+std::error_condition chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
{
- FILE *infile;
unsigned char buffer[12];
uint32_t chain_offs, chunk_size;
int done = 0;
std::string path = std::string(tocfname);
- infile = fopen(tocfname, "rb");
- path = get_file_path(path);
-
- if (infile == (FILE *)nullptr)
+ FILE *infile = fopen(tocfname, "rb");
+ if (!infile)
{
- return CHDERR_FILE_NOT_FOUND;
+ return std::error_condition(errno, std::generic_category());
}
+ path = get_file_path(path);
+
/* clear structures */
memset(&outtoc, 0, sizeof(outtoc));
outinfo.reset();
@@ -489,7 +492,7 @@ chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_
{
printf("ERROR: Not a Nero 5.5 or later image!\n");
fclose(infile);
- return CHDERR_UNSUPPORTED_VERSION;
+ return chd_file::error::UNSUPPORTED_FORMAT;
}
chain_offs = buffer[11] | (buffer[10]<<8) | (buffer[9]<<16) | (buffer[8]<<24);
@@ -498,7 +501,7 @@ chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_
{
printf("ERROR: File size is > 4GB, this version of CHDMAN cannot handle it.");
fclose(infile);
- return CHDERR_UNSUPPORTED_FORMAT;
+ return chd_file::error::UNSUPPORTED_FORMAT;
}
// printf("NER5 detected, chain offset: %x\n", chain_offs);
@@ -559,12 +562,12 @@ chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_
case 0x0300: // Mode 2 Form 1
printf("ERROR: Mode 2 Form 1 tracks not supported\n");
fclose(infile);
- return CHDERR_UNSUPPORTED_FORMAT;
+ return chd_file::error::UNSUPPORTED_FORMAT;
case 0x0500: // raw data
printf("ERROR: Raw data tracks not supported\n");
fclose(infile);
- return CHDERR_UNSUPPORTED_FORMAT;
+ return chd_file::error::UNSUPPORTED_FORMAT;
case 0x0600: // 2352 byte mode 2 raw
outtoc.tracks[track-1].trktype = CD_TRACK_MODE2_RAW;
@@ -579,22 +582,22 @@ chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_
case 0x0f00: // raw data with sub-channel
printf("ERROR: Raw data tracks with sub-channel not supported\n");
fclose(infile);
- return CHDERR_UNSUPPORTED_FORMAT;
+ return chd_file::error::UNSUPPORTED_FORMAT;
case 0x1000: // audio with sub-channel
printf("ERROR: Audio tracks with sub-channel not supported\n");
fclose(infile);
- return CHDERR_UNSUPPORTED_FORMAT;
+ return chd_file::error::UNSUPPORTED_FORMAT;
case 0x1100: // raw Mode 2 Form 1 with sub-channel
printf("ERROR: Raw Mode 2 Form 1 tracks with sub-channel not supported\n");
fclose(infile);
- return CHDERR_UNSUPPORTED_FORMAT;
+ return chd_file::error::UNSUPPORTED_FORMAT;
default:
printf("ERROR: Unknown track type %x, contact MAMEDEV!\n", mode);
fclose(infile);
- return CHDERR_UNSUPPORTED_FORMAT;
+ return chd_file::error::UNSUPPORTED_FORMAT;
}
outtoc.tracks[track-1].datasize = size;
@@ -627,7 +630,7 @@ chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_
fclose(infile);
- return CHDERR_NONE;
+ return std::error_condition();
}
/*-------------------------------------------------
@@ -635,7 +638,7 @@ chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_
-------------------------------------------------*/
/**
- * @fn chd_error chdcd_parse_iso(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
+ * @fn std::error_condition chdcd_parse_iso(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
*
* @brief Chdcd parse ISO.
*
@@ -643,22 +646,21 @@ chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_
* @param [in,out] outtoc The outtoc.
* @param [in,out] outinfo The outinfo.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chdcd_parse_iso(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
+std::error_condition chdcd_parse_iso(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
{
- FILE *infile;
std::string path = std::string(tocfname);
- infile = fopen(tocfname, "rb");
- path = get_file_path(path);
-
- if (infile == (FILE *)nullptr)
+ FILE *infile = fopen(tocfname, "rb");
+ if (!infile)
{
- return CHDERR_FILE_NOT_FOUND;
+ return std::error_condition(errno, std::generic_category());
}
+ path = get_file_path(path);
+
/* clear structures */
memset(&outtoc, 0, sizeof(outtoc));
outinfo.reset();
@@ -693,7 +695,7 @@ chd_error chdcd_parse_iso(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
outinfo.track[0].swap = false;
} else {
printf("ERROR: Unrecognized track type\n");
- return CHDERR_UNSUPPORTED_FORMAT;
+ return chd_file::error::UNSUPPORTED_FORMAT;
}
outtoc.tracks[0].subtype = CD_SUB_NONE;
@@ -709,7 +711,7 @@ chd_error chdcd_parse_iso(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
outtoc.tracks[0].padframes = 0;
- return CHDERR_NONE;
+ return std::error_condition();
}
/*-------------------------------------------------
@@ -717,7 +719,7 @@ chd_error chdcd_parse_iso(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
-------------------------------------------------*/
/**
- * @fn static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
+ * @fn static std::error_condition chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
*
* @brief Chdcd parse GDI.
*
@@ -725,24 +727,23 @@ chd_error chdcd_parse_iso(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
* @param [in,out] outtoc The outtoc.
* @param [in,out] outinfo The outinfo.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
+static std::error_condition chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
{
- FILE *infile;
int i, numtracks;
std::string path = std::string(tocfname);
- infile = fopen(tocfname, "rt");
- path = get_file_path(path);
-
- if (infile == (FILE *)nullptr)
+ FILE *infile = fopen(tocfname, "rt");
+ if (!infile)
{
- return CHDERR_FILE_NOT_FOUND;
+ return std::error_condition(errno, std::generic_category());
}
+ path = get_file_path(path);
+
/* clear structures */
memset(&outtoc, 0, sizeof(outtoc));
outinfo.reset();
@@ -841,7 +842,7 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_
/* store the number of tracks found */
outtoc.numtrks = numtracks;
- return CHDERR_NONE;
+ return std::error_condition();
}
/*-------------------------------------------------
@@ -849,7 +850,7 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_
-------------------------------------------------*/
/**
- * @fn chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
+ * @fn std::error_condition chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
*
* @brief Chdcd parse cue.
*
@@ -857,25 +858,25 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_
* @param [in,out] outtoc The outtoc.
* @param [in,out] outinfo The outinfo.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
+std::error_condition chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
{
- FILE *infile;
int i, trknum;
static char token[512];
std::string lastfname;
uint32_t wavlen, wavoffs;
std::string path = std::string(tocfname);
- infile = fopen(tocfname, "rt");
- path = get_file_path(path);
- if (infile == (FILE *)nullptr)
+ FILE *infile = fopen(tocfname, "rt");
+ if (!infile)
{
- return CHDERR_FILE_NOT_FOUND;
+ return std::error_condition(errno, std::generic_category());
}
+ path = get_file_path(path);
+
/* clear structures */
memset(&outtoc, 0, sizeof(outtoc));
outinfo.reset();
@@ -921,14 +922,14 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
{
fclose(infile);
printf("ERROR: couldn't read [%s] or not a valid .WAV\n", lastfname.c_str());
- return CHDERR_INVALID_DATA;
+ return chd_file::error::INVALID_DATA;
}
}
else
{
fclose(infile);
printf("ERROR: Unhandled track type %s\n", token);
- return CHDERR_UNSUPPORTED_FORMAT;
+ return chd_file::error::UNSUPPORTED_FORMAT;
}
}
else if (!strcmp(token, "TRACK"))
@@ -970,7 +971,7 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
{
fclose(infile);
printf("ERROR: Unknown track type [%s]. Contact MAMEDEV.\n", token);
- return CHDERR_UNSUPPORTED_FORMAT;
+ return chd_file::error::UNSUPPORTED_FORMAT;
}
/* next (optional) token on the line is the subcode type */
@@ -1083,7 +1084,7 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
if (tlen == 0)
{
printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum-1].fname.c_str());
- return CHDERR_FILE_NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
}
outinfo.track[trknum].offset = outinfo.track[trknum-1].offset + outtoc.tracks[trknum-1].frames * (outtoc.tracks[trknum-1].datasize + outtoc.tracks[trknum-1].subsize);
outtoc.tracks[trknum].frames = (tlen - outinfo.track[trknum].offset) / (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
@@ -1094,7 +1095,7 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
if (tlen == 0)
{
printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum-1].fname.c_str());
- return CHDERR_FILE_NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
}
tlen /= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
outtoc.tracks[trknum].frames = tlen;
@@ -1120,7 +1121,7 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
if (!outtoc.tracks[trknum].frames)
{
printf("ERROR: unable to determine size of track %d, missing INDEX 01 markers?\n", trknum+1);
- return CHDERR_INVALID_DATA;
+ return chd_file::error::INVALID_DATA;
}
}
else /* data files are different */
@@ -1129,7 +1130,7 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
if (tlen == 0)
{
printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum].fname.c_str());
- return CHDERR_FILE_NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
}
tlen /= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
outtoc.tracks[trknum].frames = tlen;
@@ -1140,7 +1141,7 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
//printf("trk %d: %d frames @ offset %d\n", trknum+1, outtoc.tracks[trknum].frames, outinfo.track[trknum].offset);
}
- return CHDERR_NONE;
+ return std::error_condition();
}
/*---------------------------------------------------------------------------------------
@@ -1161,18 +1162,18 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
bool chdcd_is_gdicue(const char *tocfname)
{
- FILE *infile;
bool has_rem_singledensity = false;
bool has_rem_highdensity = false;
std::string path = std::string(tocfname);
- infile = fopen(tocfname, "rt");
- path = get_file_path(path);
- if (infile == (FILE *)nullptr)
+ FILE *infile = fopen(tocfname, "rt");
+ if (!infile)
{
return false;
}
+ path = get_file_path(path);
+
while (!feof(infile))
{
fgets(linebuffer, 511, infile);
@@ -1195,7 +1196,7 @@ bool chdcd_is_gdicue(const char *tocfname)
------------------------------------------------------------------*/
/**
- * @fn chd_error chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
+ * @fn std::error_condition chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
*
* @brief Chdcd parse cue.
*
@@ -1203,7 +1204,7 @@ bool chdcd_is_gdicue(const char *tocfname)
* @param [in,out] outtoc The outtoc.
* @param [in,out] outinfo The outinfo.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*
* Dreamcast discs have two images on a single disc. The first image is SINGLE-DENSITY and the second image
* is HIGH-DENSITY. The SINGLE-DENSITY area starts 0 LBA and HIGH-DENSITY area starts 45000 LBA.
@@ -1218,9 +1219,8 @@ bool chdcd_is_gdicue(const char *tocfname)
* layout from a TOSEC .gdi.
*/
-chd_error chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
+std::error_condition chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
{
- FILE *infile;
int i, trknum;
static char token[512];
std::string lastfname;
@@ -1229,13 +1229,14 @@ chd_error chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_trac
enum gdi_area current_area = SINGLE_DENSITY;
enum gdi_pattern disc_pattern = TYPE_UNKNOWN;
- infile = fopen(tocfname, "rt");
- path = get_file_path(path);
- if (infile == (FILE *)nullptr)
+ FILE *infile = fopen(tocfname, "rt");
+ if (!infile)
{
- return CHDERR_FILE_NOT_FOUND;
+ return std::error_condition(errno, std::generic_category());
}
+ path = get_file_path(path);
+
/* clear structures */
memset(&outtoc, 0, sizeof(outtoc));
outinfo.reset();
@@ -1297,14 +1298,14 @@ chd_error chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_trac
{
fclose(infile);
printf("ERROR: couldn't read [%s] or not a valid .WAV\n", lastfname.c_str());
- return CHDERR_INVALID_DATA;
+ return chd_file::error::INVALID_DATA;
}
}
else
{
fclose(infile);
printf("ERROR: Unhandled track type %s\n", token);
- return CHDERR_UNSUPPORTED_FORMAT;
+ return chd_file::error::UNSUPPORTED_FORMAT;
}
}
else if (!strcmp(token, "TRACK"))
@@ -1349,7 +1350,7 @@ chd_error chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_trac
{
fclose(infile);
printf("ERROR: Unknown track type [%s]. Contact MAMEDEV.\n", token);
- return CHDERR_UNSUPPORTED_FORMAT;
+ return chd_file::error::UNSUPPORTED_FORMAT;
}
/* next (optional) token on the line is the subcode type */
@@ -1462,7 +1463,7 @@ chd_error chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_trac
if (tlen == 0)
{
printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum-1].fname.c_str());
- return CHDERR_FILE_NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
}
outinfo.track[trknum].offset = outinfo.track[trknum-1].offset + outtoc.tracks[trknum-1].frames * (outtoc.tracks[trknum-1].datasize + outtoc.tracks[trknum-1].subsize);
outtoc.tracks[trknum].frames = (tlen - outinfo.track[trknum].offset) / (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
@@ -1473,7 +1474,7 @@ chd_error chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_trac
if (tlen == 0)
{
printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum-1].fname.c_str());
- return CHDERR_FILE_NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
}
tlen /= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
outtoc.tracks[trknum].frames = tlen;
@@ -1499,7 +1500,7 @@ chd_error chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_trac
if (!outtoc.tracks[trknum].frames)
{
printf("ERROR: unable to determine size of track %d, missing INDEX 01 markers?\n", trknum+1);
- return CHDERR_INVALID_DATA;
+ return chd_file::error::INVALID_DATA;
}
}
else /* data files are different */
@@ -1508,7 +1509,7 @@ chd_error chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_trac
if (tlen == 0)
{
printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum].fname.c_str());
- return CHDERR_FILE_NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
}
tlen /= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
outtoc.tracks[trknum].frames = tlen;
@@ -1638,7 +1639,7 @@ chd_error chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_trac
}
#endif
- return CHDERR_NONE;
+ return std::error_condition();
}
/*-------------------------------------------------
@@ -1646,7 +1647,7 @@ chd_error chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_trac
-------------------------------------------------*/
/**
- * @fn chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
+ * @fn std::error_condition chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
*
* @brief Chdcd parse TOC.
*
@@ -1654,12 +1655,11 @@ chd_error chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_trac
* @param [in,out] outtoc The outtoc.
* @param [in,out] outinfo The outinfo.
*
- * @return A chd_error.
+ * @return A std::error_condition.
*/
-chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
+std::error_condition chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
{
- FILE *infile;
int i, trknum;
static char token[512];
char tocftemp[512];
@@ -1695,14 +1695,14 @@ chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
std::string path = std::string(tocfname);
- infile = fopen(tocfname, "rt");
- path = get_file_path(path);
-
- if (infile == (FILE *)nullptr)
+ FILE *infile = fopen(tocfname, "rt");
+ if (!infile)
{
- return CHDERR_FILE_NOT_FOUND;
+ return std::error_condition(errno, std::generic_category());
}
+ path = get_file_path(path);
+
/* clear structures */
memset(&outtoc, 0, sizeof(outtoc));
outinfo.reset();
@@ -1817,7 +1817,7 @@ chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
{
fclose(infile);
printf("ERROR: Unknown track type [%s]. Contact MAMEDEV.\n", token);
- return CHDERR_UNSUPPORTED_FORMAT;
+ return chd_file::error::UNSUPPORTED_FORMAT;
}
/* next (optional) token on the line is the subcode type */
@@ -1844,5 +1844,5 @@ chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i
/* store the number of tracks found */
outtoc.numtrks = trknum + 1;
- return CHDERR_NONE;
+ return std::error_condition();
}
diff --git a/src/lib/util/chdcd.h b/src/lib/util/chdcd.h
index 65e4b943964..95f214e5831 100644
--- a/src/lib/util/chdcd.h
+++ b/src/lib/util/chdcd.h
@@ -5,14 +5,16 @@
CDRDAO TOC parser for CHD compression frontend
***************************************************************************/
-
-#ifndef MAME_UTIL_CHDCD_H
-#define MAME_UTIL_CHDCD_H
+#ifndef MAME_LIB_UTIL_CHDCD_H
+#define MAME_LIB_UTIL_CHDCD_H
#pragma once
#include "cdrom.h"
+#include <system_error>
+
+
struct chdcd_track_input_entry
{
chdcd_track_input_entry() { reset(); }
@@ -33,6 +35,6 @@ struct chdcd_track_input_info
};
-chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo);
+std::error_condition chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo);
-#endif // MAME_UTIL_CHDCD_H
+#endif // MAME_LIB_UTIL_CHDCD_H
diff --git a/src/lib/util/chdcodec.cpp b/src/lib/util/chdcodec.cpp
index 4f5c23b3104..eca9403b56c 100644
--- a/src/lib/util/chdcodec.cpp
+++ b/src/lib/util/chdcodec.cpp
@@ -8,24 +8,29 @@
***************************************************************************/
-#include <cassert>
+#include "chdcodec.h"
-#include "chd.h"
-#include "hashing.h"
#include "avhuff.h"
-#include "flac.h"
#include "cdrom.h"
-#include <zlib.h>
-#include "lzma/C/LzmaEnc.h"
+#include "chd.h"
+#include "flac.h"
+#include "hashing.h"
+
#include "lzma/C/LzmaDec.h"
+#include "lzma/C/LzmaEnc.h"
+
+#include <zlib.h>
+
#include <new>
+namespace {
+
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
-static const uint8_t s_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 };
+constexpr uint8_t f_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 };
@@ -35,7 +40,7 @@ static const uint8_t s_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff
// ======================> chd_zlib_allocator
-// allocation helper clas for zlib
+// allocation helper class for zlib
class chd_zlib_allocator
{
public:
@@ -51,7 +56,8 @@ private:
static voidpf fast_alloc(voidpf opaque, uInt items, uInt size);
static void fast_free(voidpf opaque, voidpf address);
- static const int MAX_ZLIB_ALLOCS = 64;
+ static constexpr int MAX_ZLIB_ALLOCS = 64;
+
uint32_t * m_allocptr[MAX_ZLIB_ALLOCS];
};
@@ -111,7 +117,7 @@ private:
static void *fast_alloc(void *p, size_t size);
static void fast_free(void *p, void *address);
- static const int MAX_LZMA_ALLOCS = 64;
+ static constexpr int MAX_LZMA_ALLOCS = 64;
uint32_t * m_allocptr[MAX_LZMA_ALLOCS];
};
@@ -287,7 +293,7 @@ private:
// ======================> chd_cd_compressor
-template<class _BaseCompressor, class _SubcodeCompressor>
+template<class BaseCompressor, class SubcodeCompressor>
class chd_cd_compressor : public chd_compressor
{
public:
@@ -300,7 +306,7 @@ public:
{
// make sure the CHD's hunk size is an even multiple of the frame size
if (hunkbytes % CD_FRAME_SIZE != 0)
- throw CHDERR_CODEC_ERROR;
+ throw std::error_condition(chd_file::error::CODEC_ERROR);
}
// core functionality
@@ -323,10 +329,10 @@ public:
// clear out ECC data if we can
uint8_t *sector = &m_buffer[framenum * CD_MAX_SECTOR_DATA];
- if (memcmp(sector, s_cd_sync_header, sizeof(s_cd_sync_header)) == 0 && ecc_verify(sector))
+ if (memcmp(sector, f_cd_sync_header, sizeof(f_cd_sync_header)) == 0 && ecc_verify(sector))
{
dest[framenum / 8] |= 1 << (framenum % 8);
- memset(sector, 0, sizeof(s_cd_sync_header));
+ memset(sector, 0, sizeof(f_cd_sync_header));
ecc_clear(sector);
}
}
@@ -334,7 +340,7 @@ public:
// encode the base portion
uint32_t complen = m_base_compressor.compress(&m_buffer[0], frames * CD_MAX_SECTOR_DATA, &dest[header_bytes]);
if (complen >= srclen)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
// write compressed length
dest[ecc_bytes + 0] = complen >> ((complen_bytes - 1) * 8);
@@ -348,15 +354,15 @@ public:
private:
// internal state
- _BaseCompressor m_base_compressor;
- _SubcodeCompressor m_subcode_compressor;
+ BaseCompressor m_base_compressor;
+ SubcodeCompressor m_subcode_compressor;
std::vector<uint8_t> m_buffer;
};
// ======================> chd_cd_decompressor
-template<class _BaseDecompressor, class _SubcodeDecompressor>
+template<class BaseDecompressor, class SubcodeDecompressor>
class chd_cd_decompressor : public chd_decompressor
{
public:
@@ -369,7 +375,7 @@ public:
{
// make sure the CHD's hunk size is an even multiple of the frame size
if (hunkbytes % CD_FRAME_SIZE != 0)
- throw CHDERR_CODEC_ERROR;
+ throw std::error_condition(chd_file::error::CODEC_ERROR);
}
// core functionality
@@ -400,7 +406,7 @@ public:
uint8_t *sector = &dest[framenum * CD_FRAME_SIZE];
if ((src[framenum / 8] & (1 << (framenum % 8))) != 0)
{
- memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header));
+ memcpy(sector, f_cd_sync_header, sizeof(f_cd_sync_header));
ecc_generate(sector);
}
}
@@ -408,8 +414,8 @@ public:
private:
// internal state
- _BaseDecompressor m_base_decompressor;
- _SubcodeDecompressor m_subcode_decompressor;
+ BaseDecompressor m_base_decompressor;
+ SubcodeDecompressor m_subcode_decompressor;
std::vector<uint8_t> m_buffer;
};
@@ -460,25 +466,65 @@ private:
// CODEC LIST
//**************************************************************************
+// an entry in the list
+struct codec_entry
+{
+ chd_codec_type m_type;
+ bool m_lossy;
+ const char * m_name;
+ chd_compressor::ptr (*m_construct_compressor)(chd_file &, uint32_t, bool);
+ chd_decompressor::ptr (*m_construct_decompressor)(chd_file &, uint32_t, bool);
+
+ template <class CompressorClass>
+ static chd_compressor::ptr construct_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
+ {
+ return std::make_unique<CompressorClass>(chd, hunkbytes, lossy);
+ }
+
+ template <class DecompressorClass>
+ static chd_decompressor::ptr construct_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
+ {
+ return std::make_unique<DecompressorClass>(chd, hunkbytes, lossy);
+ }
+};
+
+
// static list of available known codecs
-const chd_codec_list::codec_entry chd_codec_list::s_codec_list[] =
+const codec_entry f_codec_list[] =
{
// general codecs
- { CHD_CODEC_ZLIB, false, "Deflate", &chd_codec_list::construct_compressor<chd_zlib_compressor>, &chd_codec_list::construct_decompressor<chd_zlib_decompressor> },
- { CHD_CODEC_LZMA, false, "LZMA", &chd_codec_list::construct_compressor<chd_lzma_compressor>, &chd_codec_list::construct_decompressor<chd_lzma_decompressor> },
- { CHD_CODEC_HUFFMAN, false, "Huffman", &chd_codec_list::construct_compressor<chd_huffman_compressor>, &chd_codec_list::construct_decompressor<chd_huffman_decompressor> },
- { CHD_CODEC_FLAC, false, "FLAC", &chd_codec_list::construct_compressor<chd_flac_compressor>, &chd_codec_list::construct_decompressor<chd_flac_decompressor> },
+ { CHD_CODEC_ZLIB, false, "Deflate", &codec_entry::construct_compressor<chd_zlib_compressor>, &codec_entry::construct_decompressor<chd_zlib_decompressor> },
+ { CHD_CODEC_LZMA, false, "LZMA", &codec_entry::construct_compressor<chd_lzma_compressor>, &codec_entry::construct_decompressor<chd_lzma_decompressor> },
+ { CHD_CODEC_HUFFMAN, false, "Huffman", &codec_entry::construct_compressor<chd_huffman_compressor>, &codec_entry::construct_decompressor<chd_huffman_decompressor> },
+ { CHD_CODEC_FLAC, false, "FLAC", &codec_entry::construct_compressor<chd_flac_compressor>, &codec_entry::construct_decompressor<chd_flac_decompressor> },
// general codecs with CD frontend
- { CHD_CODEC_CD_ZLIB, false, "CD Deflate", &chd_codec_list::construct_compressor<chd_cd_compressor<chd_zlib_compressor, chd_zlib_compressor> >, &chd_codec_list::construct_decompressor<chd_cd_decompressor<chd_zlib_decompressor, chd_zlib_decompressor> > },
- { CHD_CODEC_CD_LZMA, false, "CD LZMA", &chd_codec_list::construct_compressor<chd_cd_compressor<chd_lzma_compressor, chd_zlib_compressor> >, &chd_codec_list::construct_decompressor<chd_cd_decompressor<chd_lzma_decompressor, chd_zlib_decompressor> > },
- { CHD_CODEC_CD_FLAC, false, "CD FLAC", &chd_codec_list::construct_compressor<chd_cd_flac_compressor>, &chd_codec_list::construct_decompressor<chd_cd_flac_decompressor> },
+ { CHD_CODEC_CD_ZLIB, false, "CD Deflate", &codec_entry::construct_compressor<chd_cd_compressor<chd_zlib_compressor, chd_zlib_compressor> >, &codec_entry::construct_decompressor<chd_cd_decompressor<chd_zlib_decompressor, chd_zlib_decompressor> > },
+ { CHD_CODEC_CD_LZMA, false, "CD LZMA", &codec_entry::construct_compressor<chd_cd_compressor<chd_lzma_compressor, chd_zlib_compressor> >, &codec_entry::construct_decompressor<chd_cd_decompressor<chd_lzma_decompressor, chd_zlib_decompressor> > },
+ { CHD_CODEC_CD_FLAC, false, "CD FLAC", &codec_entry::construct_compressor<chd_cd_flac_compressor>, &codec_entry::construct_decompressor<chd_cd_flac_decompressor> },
// A/V codecs
- { CHD_CODEC_AVHUFF, false, "A/V Huffman", &chd_codec_list::construct_compressor<chd_avhuff_compressor>, &chd_codec_list::construct_decompressor<chd_avhuff_decompressor> },
+ { CHD_CODEC_AVHUFF, false, "A/V Huffman", &codec_entry::construct_compressor<chd_avhuff_compressor>, &codec_entry::construct_decompressor<chd_avhuff_decompressor> },
};
+//-------------------------------------------------
+// find_in_list - create a new compressor
+// instance of the given type
+//-------------------------------------------------
+
+const codec_entry *find_in_list(chd_codec_type type)
+{
+ // find in the list and construct the class
+ for (auto & elem : f_codec_list)
+ if (elem.m_type == type)
+ return &elem;
+ return nullptr;
+}
+
+} // anonymous namespace
+
+
//**************************************************************************
// CHD CODEC
@@ -512,7 +558,7 @@ chd_codec::~chd_codec()
void chd_codec::configure(int param, void *config)
{
// if not overridden, it is always a failure
- throw CHDERR_INVALID_PARAMETER;
+ throw std::error_condition(std::errc::invalid_argument);
}
@@ -556,11 +602,11 @@ chd_decompressor::chd_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy
// instance of the given type
//-------------------------------------------------
-chd_compressor *chd_codec_list::new_compressor(chd_codec_type type, chd_file &chd)
+chd_compressor::ptr chd_codec_list::new_compressor(chd_codec_type type, chd_file &chd)
{
// find in the list and construct the class
- const codec_entry *entry = find_in_list(type);
- return (entry == nullptr) ? nullptr : (*entry->m_construct_compressor)(chd, chd.hunk_bytes(), entry->m_lossy);
+ codec_entry const *const entry = find_in_list(type);
+ return entry ? (*entry->m_construct_compressor)(chd, chd.hunk_bytes(), entry->m_lossy) : nullptr;
}
@@ -569,39 +615,36 @@ chd_compressor *chd_codec_list::new_compressor(chd_codec_type type, chd_file &ch
// instance of the given type
//-------------------------------------------------
-chd_decompressor *chd_codec_list::new_decompressor(chd_codec_type type, chd_file &chd)
+chd_decompressor::ptr chd_codec_list::new_decompressor(chd_codec_type type, chd_file &chd)
{
// find in the list and construct the class
const codec_entry *entry = find_in_list(type);
- return (entry == nullptr) ? nullptr : (*entry->m_construct_decompressor)(chd, chd.hunk_bytes(), entry->m_lossy);
+ return entry ? (*entry->m_construct_decompressor)(chd, chd.hunk_bytes(), entry->m_lossy) : nullptr;
}
//-------------------------------------------------
-// codec_name - return the name of the given
-// codec
+// codec_exists - determine whether a codec type
+// corresponds to a supported codec
//-------------------------------------------------
-const char *chd_codec_list::codec_name(chd_codec_type type)
+bool chd_codec_list::codec_exists(chd_codec_type type)
{
// find in the list and construct the class
- const codec_entry *entry = find_in_list(type);
- return (entry == nullptr) ? nullptr : entry->m_name;
+ return bool(find_in_list(type));
}
//-------------------------------------------------
-// find_in_list - create a new compressor
-// instance of the given type
+// codec_name - return the name of the given
+// codec
//-------------------------------------------------
-const chd_codec_list::codec_entry *chd_codec_list::find_in_list(chd_codec_type type)
+const char *chd_codec_list::codec_name(chd_codec_type type)
{
// find in the list and construct the class
- for (auto & elem : s_codec_list)
- if (elem.m_type == type)
- return &elem;
- return nullptr;
+ const codec_entry *entry = find_in_list(type);
+ return entry ? entry->m_name : nullptr;
}
@@ -615,25 +658,24 @@ const chd_codec_list::codec_entry *chd_codec_list::find_in_list(chd_codec_type t
//-------------------------------------------------
chd_compressor_group::chd_compressor_group(chd_file &chd, uint32_t compressor_list[4])
- : m_hunkbytes(chd.hunk_bytes()),
- m_compress_test(m_hunkbytes)
+ : m_hunkbytes(chd.hunk_bytes())
+ , m_compress_test(m_hunkbytes)
#if CHDCODEC_VERIFY_COMPRESSION
- ,m_decompressed(m_hunkbytes)
+ , m_decompressed(m_hunkbytes)
#endif
{
// verify the compression types and initialize the codecs
for (int codecnum = 0; codecnum < std::size(m_compressor); codecnum++)
{
- m_compressor[codecnum] = nullptr;
if (compressor_list[codecnum] != CHD_CODEC_NONE)
{
m_compressor[codecnum] = chd_codec_list::new_compressor(compressor_list[codecnum], chd);
- if (m_compressor[codecnum] == nullptr)
- throw CHDERR_UNKNOWN_COMPRESSION;
+ if (!m_compressor[codecnum])
+ throw std::error_condition(chd_file::error::UNKNOWN_COMPRESSION);
#if CHDCODEC_VERIFY_COMPRESSION
m_decompressor[codecnum] = chd_codec_list::new_decompressor(compressor_list[codecnum], chd);
- if (m_decompressor[codecnum] == nullptr)
- throw CHDERR_UNKNOWN_COMPRESSION;
+ if (!m_decompressor[codecnum])
+ throw std::error_condition(chd_file::error::UNKNOWN_COMPRESSION);
#endif
}
}
@@ -646,9 +688,7 @@ chd_compressor_group::chd_compressor_group(chd_file &chd, uint32_t compressor_li
chd_compressor_group::~chd_compressor_group()
{
- // delete the codecs and the test buffer
- for (auto & elem : m_compressor)
- delete elem;
+ // codecs and test buffer deleted automatically
}
@@ -664,7 +704,7 @@ int8_t chd_compressor_group::find_best_compressor(const uint8_t *src, uint8_t *c
complen = m_hunkbytes;
int8_t compression = -1;
for (int codecnum = 0; codecnum < std::size(m_compressor); codecnum++)
- if (m_compressor[codecnum] != nullptr)
+ if (m_compressor[codecnum])
{
// attempt to compress, swallowing errors
try
@@ -702,7 +742,9 @@ printf(" codec%d=%d bytes \n", codecnum, compbytes);
memcpy(compressed, &m_compress_test[0], compbytes);
}
}
- catch (...) { }
+ catch (...)
+ {
+ }
}
// if the best is none, copy it over
@@ -835,7 +877,7 @@ chd_zlib_compressor::chd_zlib_compressor(chd_file &chd, uint32_t hunkbytes, bool
if (zerr == Z_MEM_ERROR)
throw std::bad_alloc();
else if (zerr != Z_OK)
- throw CHDERR_CODEC_ERROR;
+ throw std::error_condition(chd_file::error::CODEC_ERROR);
}
@@ -864,14 +906,14 @@ uint32_t chd_zlib_compressor::compress(const uint8_t *src, uint32_t srclen, uint
m_deflater.total_out = 0;
int zerr = deflateReset(&m_deflater);
if (zerr != Z_OK)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
// do it
zerr = deflate(&m_deflater, Z_FINISH);
// if we ended up with more data than we started with, return an error
if (zerr != Z_STREAM_END || m_deflater.total_out >= srclen)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
// otherwise, return the length
return m_deflater.total_out;
@@ -900,7 +942,7 @@ chd_zlib_decompressor::chd_zlib_decompressor(chd_file &chd, uint32_t hunkbytes,
if (zerr == Z_MEM_ERROR)
throw std::bad_alloc();
else if (zerr != Z_OK)
- throw CHDERR_CODEC_ERROR;
+ throw std::error_condition(chd_file::error::CODEC_ERROR);
}
@@ -930,14 +972,14 @@ void chd_zlib_decompressor::decompress(const uint8_t *src, uint32_t complen, uin
m_inflater.total_out = 0;
int zerr = inflateReset(&m_inflater);
if (zerr != Z_OK)
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
// do it
zerr = inflate(&m_inflater, Z_FINISH);
if (zerr != Z_STREAM_END)
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
if (m_inflater.total_out != destlen)
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
}
@@ -1071,20 +1113,20 @@ uint32_t chd_lzma_compressor::compress(const uint8_t *src, uint32_t srclen, uint
// allocate the encoder
CLzmaEncHandle encoder = LzmaEnc_Create(&m_allocator);
if (encoder == nullptr)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
try
{
// configure the encoder
SRes res = LzmaEnc_SetProps(encoder, &m_props);
if (res != SZ_OK)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
// run it
SizeT complen = srclen;
res = LzmaEnc_MemEncode(encoder, dest, &complen, src, srclen, 0, nullptr, &m_allocator, &m_allocator);
if (res != SZ_OK)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
// clean up
LzmaEnc_Destroy(encoder, &m_allocator, &m_allocator);
@@ -1140,24 +1182,24 @@ chd_lzma_decompressor::chd_lzma_decompressor(chd_file &chd, uint32_t hunkbytes,
// convert to decoder properties
CLzmaEncHandle enc = LzmaEnc_Create(&m_allocator);
if (!enc)
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
if (LzmaEnc_SetProps(enc, &encoder_props) != SZ_OK)
{
LzmaEnc_Destroy(enc, &m_allocator, &m_allocator);
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
}
Byte decoder_props[LZMA_PROPS_SIZE];
SizeT props_size = sizeof(decoder_props);
if (LzmaEnc_WriteProperties(enc, decoder_props, &props_size) != SZ_OK)
{
LzmaEnc_Destroy(enc, &m_allocator, &m_allocator);
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
}
LzmaEnc_Destroy(enc, &m_allocator, &m_allocator);
// do memory allocations
if (LzmaDec_Allocate(&m_decoder, decoder_props, LZMA_PROPS_SIZE, &m_allocator) != SZ_OK)
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
}
@@ -1188,7 +1230,7 @@ void chd_lzma_decompressor::decompress(const uint8_t *src, uint32_t complen, uin
ELzmaStatus status;
SRes res = LzmaDec_DecodeToBuf(&m_decoder, dest, &decodedlen, src, &consumedlen, LZMA_FINISH_END, &status);
if ((res != SZ_OK && res != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) || consumedlen != complen || decodedlen != destlen)
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
}
@@ -1216,7 +1258,7 @@ uint32_t chd_huffman_compressor::compress(const uint8_t *src, uint32_t srclen, u
{
uint32_t complen;
if (m_encoder.encode(src, srclen, dest, srclen, complen) != HUFFERR_NONE)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
return complen;
}
@@ -1244,7 +1286,7 @@ chd_huffman_decompressor::chd_huffman_decompressor(chd_file &chd, uint32_t hunkb
void chd_huffman_decompressor::decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
{
if (m_decoder.decode(src, complen, dest, destlen) != HUFFERR_NONE)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
}
@@ -1282,19 +1324,19 @@ uint32_t chd_flac_compressor::compress(const uint8_t *src, uint32_t srclen, uint
// reset and encode big-endian
m_encoder.reset(dest + 1, hunkbytes() - 1);
if (!m_encoder.encode_interleaved(reinterpret_cast<const int16_t *>(src), srclen / 4, !m_big_endian))
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
uint32_t complen_be = m_encoder.finish();
// reset and encode little-endian
m_encoder.reset(dest + 1, hunkbytes() - 1);
if (!m_encoder.encode_interleaved(reinterpret_cast<const int16_t *>(src), srclen / 4, m_big_endian))
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
uint32_t complen_le = m_encoder.finish();
// pick the best one and add a byte
uint32_t complen = std::min(complen_le, complen_be);
if (complen + 1 >= hunkbytes())
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
// if big-endian was better, re-do it
dest[0] = 'L';
@@ -1303,7 +1345,7 @@ uint32_t chd_flac_compressor::compress(const uint8_t *src, uint32_t srclen, uint
dest[0] = 'B';
m_encoder.reset(dest + 1, hunkbytes() - 1);
if (!m_encoder.encode_interleaved(reinterpret_cast<const int16_t *>(src), srclen / 4, !m_big_endian))
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
m_encoder.finish();
}
return complen + 1;
@@ -1358,13 +1400,13 @@ void chd_flac_decompressor::decompress(const uint8_t *src, uint32_t complen, uin
else if (src[0] == 'B')
swap_endian = !m_big_endian;
else
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
// reset and decode
if (!m_decoder.reset(44100, 2, chd_flac_compressor::blocksize(destlen), src + 1, complen - 1))
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
if (!m_decoder.decode_interleaved(reinterpret_cast<int16_t *>(dest), destlen / 4, swap_endian))
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
// finish up
m_decoder.finish();
@@ -1386,7 +1428,7 @@ chd_cd_flac_compressor::chd_cd_flac_compressor(chd_file &chd, uint32_t hunkbytes
{
// make sure the CHD's hunk size is an even multiple of the frame size
if (hunkbytes % CD_FRAME_SIZE != 0)
- throw CHDERR_CODEC_ERROR;
+ throw std::error_condition(chd_file::error::CODEC_ERROR);
// determine whether we want native or swapped samples
uint16_t native_endian = 0;
@@ -1409,7 +1451,7 @@ chd_cd_flac_compressor::chd_cd_flac_compressor(chd_file &chd, uint32_t hunkbytes
if (zerr == Z_MEM_ERROR)
throw std::bad_alloc();
else if (zerr != Z_OK)
- throw CHDERR_CODEC_ERROR;
+ throw std::error_condition(chd_file::error::CODEC_ERROR);
}
@@ -1442,7 +1484,7 @@ uint32_t chd_cd_flac_compressor::compress(const uint8_t *src, uint32_t srclen, u
m_encoder.reset(dest, hunkbytes());
uint8_t *buffer = &m_buffer[0];
if (!m_encoder.encode_interleaved(reinterpret_cast<int16_t *>(buffer), frames * CD_MAX_SECTOR_DATA/4, m_swap_endian))
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
// finish up
uint32_t complen = m_encoder.finish();
@@ -1456,7 +1498,7 @@ uint32_t chd_cd_flac_compressor::compress(const uint8_t *src, uint32_t srclen, u
m_deflater.total_out = 0;
int zerr = deflateReset(&m_deflater);
if (zerr != Z_OK)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
// do it
zerr = deflate(&m_deflater, Z_FINISH);
@@ -1464,7 +1506,7 @@ uint32_t chd_cd_flac_compressor::compress(const uint8_t *src, uint32_t srclen, u
// if we ended up with more data than we started with, return an error
complen += m_deflater.total_out;
if (zerr != Z_STREAM_END || complen >= srclen)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
return complen;
}
@@ -1515,7 +1557,7 @@ chd_cd_flac_decompressor::chd_cd_flac_decompressor(chd_file &chd, uint32_t hunkb
{
// make sure the CHD's hunk size is an even multiple of the frame size
if (hunkbytes % CD_FRAME_SIZE != 0)
- throw CHDERR_CODEC_ERROR;
+ throw std::error_condition(chd_file::error::CODEC_ERROR);
// determine whether we want native or swapped samples
uint16_t native_endian = 0;
@@ -1532,7 +1574,7 @@ chd_cd_flac_decompressor::chd_cd_flac_decompressor(chd_file &chd, uint32_t hunkb
if (zerr == Z_MEM_ERROR)
throw std::bad_alloc();
else if (zerr != Z_OK)
- throw CHDERR_CODEC_ERROR;
+ throw std::error_condition(chd_file::error::CODEC_ERROR);
}
/**
@@ -1569,10 +1611,10 @@ void chd_cd_flac_decompressor::decompress(const uint8_t *src, uint32_t complen,
// reset and decode
uint32_t frames = destlen / CD_FRAME_SIZE;
if (!m_decoder.reset(44100, 2, chd_cd_flac_compressor::blocksize(frames * CD_MAX_SECTOR_DATA), src, complen))
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
uint8_t *buffer = &m_buffer[0];
if (!m_decoder.decode_interleaved(reinterpret_cast<int16_t *>(buffer), frames * CD_MAX_SECTOR_DATA/4, m_swap_endian))
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
// inflate the subcode data
uint32_t offset = m_decoder.finish();
@@ -1584,14 +1626,14 @@ void chd_cd_flac_decompressor::decompress(const uint8_t *src, uint32_t complen,
m_inflater.total_out = 0;
int zerr = inflateReset(&m_inflater);
if (zerr != Z_OK)
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
// do it
zerr = inflate(&m_inflater, Z_FINISH);
if (zerr != Z_STREAM_END)
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
if (m_inflater.total_out != frames * CD_MAX_SUBCODE_DATA)
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
// reassemble the data
for (uint32_t framenum = 0; framenum < frames; framenum++)
@@ -1620,15 +1662,15 @@ void chd_cd_flac_decompressor::decompress(const uint8_t *src, uint32_t complen,
*/
chd_avhuff_compressor::chd_avhuff_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
- : chd_compressor(chd, hunkbytes, lossy),
- m_postinit(false)
+ : chd_compressor(chd, hunkbytes, lossy)
+ , m_postinit(false)
{
try
{
// attempt to do a post-init now
postinit();
}
- catch (chd_error &)
+ catch (std::error_condition const &)
{
// if we're creating a new CHD, it won't work but that's ok
}
@@ -1665,14 +1707,14 @@ uint32_t chd_avhuff_compressor::compress(const uint8_t *src, uint32_t srclen, ui
int size = avhuff_encoder::raw_data_size(src);
while (size < srclen)
if (src[size++] != 0)
- throw CHDERR_INVALID_DATA;
+ throw std::error_condition(chd_file::error::INVALID_DATA);
}
// encode the audio and video
uint32_t complen;
avhuff_error averr = m_encoder.encode_data(src, dest, complen);
if (averr != AVHERR_NONE || complen > srclen)
- throw CHDERR_COMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
return complen;
}
@@ -1693,21 +1735,21 @@ void chd_avhuff_compressor::postinit()
{
// get the metadata
std::string metadata;
- chd_error err = chd().read_metadata(AV_METADATA_TAG, 0, metadata);
- if (err != CHDERR_NONE)
+ std::error_condition err = chd().read_metadata(AV_METADATA_TAG, 0, metadata);
+ if (err)
throw err;
// extract the info
int fps, fpsfrac, width, height, interlaced, channels, rate;
if (sscanf(metadata.c_str(), AV_METADATA_FORMAT, &fps, &fpsfrac, &width, &height, &interlaced, &channels, &rate) != 7)
- throw CHDERR_INVALID_METADATA;
+ throw std::error_condition(chd_file::error::INVALID_METADATA);
// compute the bytes per frame
uint32_t fps_times_1million = fps * 1000000 + fpsfrac;
uint32_t max_samples_per_frame = (uint64_t(rate) * 1000000 + fps_times_1million - 1) / fps_times_1million;
uint32_t bytes_per_frame = 12 + channels * max_samples_per_frame * 2 + width * height * 2;
if (bytes_per_frame > hunkbytes())
- throw CHDERR_INVALID_METADATA;
+ throw std::error_condition(chd_file::error::INVALID_METADATA);
// done with post-init
m_postinit = true;
@@ -1757,7 +1799,7 @@ void chd_avhuff_decompressor::decompress(const uint8_t *src, uint32_t complen, u
// decode the audio and video
avhuff_error averr = m_decoder.decode_data(src, complen, dest);
if (averr != AVHERR_NONE)
- throw CHDERR_DECOMPRESSION_ERROR;
+ throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
// pad short frames with 0
if (dest != nullptr)
@@ -1790,5 +1832,5 @@ void chd_avhuff_decompressor::configure(int param, void *config)
// anything else is invalid
else
- throw CHDERR_INVALID_PARAMETER;
+ throw std::error_condition(std::errc::invalid_argument);
}
diff --git a/src/lib/util/chdcodec.h b/src/lib/util/chdcodec.h
index dc9c074fd37..700ae8f8979 100644
--- a/src/lib/util/chdcodec.h
+++ b/src/lib/util/chdcodec.h
@@ -7,13 +7,15 @@
Codecs used by the CHD format
***************************************************************************/
-
-#ifndef MAME_UTIL_CHDCODEC_H
-#define MAME_UTIL_CHDCODEC_H
+#ifndef MAME_LIB_UTIL_CHDCODEC_H
+#define MAME_LIB_UTIL_CHDCODEC_H
#pragma once
+#include "utilfwd.h"
+
#include <cstdint>
+#include <memory>
#include <vector>
@@ -21,20 +23,9 @@
//**************************************************************************
-// MACROS
-//**************************************************************************
-
-#define CHD_MAKE_TAG(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
-
-
-
-//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
-// forward references
-class chd_file;
-
// base types
typedef uint32_t chd_codec_type;
@@ -63,7 +54,7 @@ public:
private:
// internal state
chd_file & m_chd;
- uint32_t m_hunkbytes;
+ uint32_t m_hunkbytes;
bool m_lossy;
};
@@ -78,6 +69,8 @@ protected:
chd_compressor(chd_file &file, uint32_t hunkbytes, bool lossy);
public:
+ using ptr = std::unique_ptr<chd_compressor>;
+
// implementation
virtual uint32_t compress(const uint8_t *src, uint32_t srclen, uint8_t *dest) = 0;
};
@@ -93,6 +86,8 @@ protected:
chd_decompressor(chd_file &file, uint32_t hunkbytes, bool lossy);
public:
+ using ptr = std::unique_ptr<chd_decompressor>;
+
// implementation
virtual void decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) = 0;
};
@@ -105,35 +100,12 @@ class chd_codec_list
{
public:
// create compressors or decompressors
- static chd_compressor *new_compressor(chd_codec_type type, chd_file &file);
- static chd_decompressor *new_decompressor(chd_codec_type type, chd_file &file);
+ static chd_compressor::ptr new_compressor(chd_codec_type type, chd_file &file);
+ static chd_decompressor::ptr new_decompressor(chd_codec_type type, chd_file &file);
// utilities
- static bool codec_exists(chd_codec_type type) { return (find_in_list(type) != nullptr); }
+ static bool codec_exists(chd_codec_type type);
static const char *codec_name(chd_codec_type type);
-
-private:
- // an entry in the list
- struct codec_entry
- {
- chd_codec_type m_type;
- bool m_lossy;
- const char * m_name;
- chd_compressor * (*m_construct_compressor)(chd_file &, uint32_t, bool);
- chd_decompressor * (*m_construct_decompressor)(chd_file &, uint32_t, bool);
- };
-
- // internal helper functions
- static const codec_entry *find_in_list(chd_codec_type type);
-
- template<class _CompressorClass>
- static chd_compressor *construct_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy) { return new _CompressorClass(chd, hunkbytes, lossy); }
-
- template<class _DecompressorClass>
- static chd_decompressor *construct_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy) { return new _DecompressorClass(chd, hunkbytes, lossy); }
-
- // the static list
- static const codec_entry s_codec_list[];
};
@@ -152,37 +124,48 @@ public:
private:
// internal state
- uint32_t m_hunkbytes; // number of bytes in a hunk
- chd_compressor * m_compressor[4]; // array of active codecs
- std::vector<uint8_t> m_compress_test; // test buffer for compression
+ uint32_t m_hunkbytes; // number of bytes in a hunk
+ chd_compressor::ptr m_compressor[4]; // array of active codecs
+ std::vector<uint8_t> m_compress_test; // test buffer for compression
#if CHDCODEC_VERIFY_COMPRESSION
- chd_decompressor * m_decompressor[4]; // array of active codecs
- std::vector<uint8_t> m_decompressed; // verification buffer
+ chd_decompressor::ptr m_decompressor[4]; // array of active codecs
+ std::vector<uint8_t> m_decompressed; // verification buffer
#endif
};
//**************************************************************************
+// MACROS
+//**************************************************************************
+
+constexpr chd_codec_type CHD_MAKE_TAG(char a, char b, char c, char d)
+{
+ return (uint32_t(uint8_t(a)) << 24) | uint32_t(uint8_t((b)) << 16) | uint32_t(uint8_t((c)) << 8) | uint32_t(uint8_t(d));
+}
+
+
+
+//**************************************************************************
// CONSTANTS
//**************************************************************************
// currently-defined codecs
-const chd_codec_type CHD_CODEC_NONE = 0;
+constexpr chd_codec_type CHD_CODEC_NONE = 0;
// general codecs
-const chd_codec_type CHD_CODEC_ZLIB = CHD_MAKE_TAG('z','l','i','b');
-const chd_codec_type CHD_CODEC_LZMA = CHD_MAKE_TAG('l','z','m','a');
-const chd_codec_type CHD_CODEC_HUFFMAN = CHD_MAKE_TAG('h','u','f','f');
-const chd_codec_type CHD_CODEC_FLAC = CHD_MAKE_TAG('f','l','a','c');
+constexpr chd_codec_type CHD_CODEC_ZLIB = CHD_MAKE_TAG('z','l','i','b');
+constexpr chd_codec_type CHD_CODEC_LZMA = CHD_MAKE_TAG('l','z','m','a');
+constexpr chd_codec_type CHD_CODEC_HUFFMAN = CHD_MAKE_TAG('h','u','f','f');
+constexpr chd_codec_type CHD_CODEC_FLAC = CHD_MAKE_TAG('f','l','a','c');
// general codecs with CD frontend
-const chd_codec_type CHD_CODEC_CD_ZLIB = CHD_MAKE_TAG('c','d','z','l');
-const chd_codec_type CHD_CODEC_CD_LZMA = CHD_MAKE_TAG('c','d','l','z');
-const chd_codec_type CHD_CODEC_CD_FLAC = CHD_MAKE_TAG('c','d','f','l');
+constexpr chd_codec_type CHD_CODEC_CD_ZLIB = CHD_MAKE_TAG('c','d','z','l');
+constexpr chd_codec_type CHD_CODEC_CD_LZMA = CHD_MAKE_TAG('c','d','l','z');
+constexpr chd_codec_type CHD_CODEC_CD_FLAC = CHD_MAKE_TAG('c','d','f','l');
// A/V codecs
-const chd_codec_type CHD_CODEC_AVHUFF = CHD_MAKE_TAG('a','v','h','u');
+constexpr chd_codec_type CHD_CODEC_AVHUFF = CHD_MAKE_TAG('a','v','h','u');
// A/V codec configuration parameters
enum
@@ -190,4 +173,4 @@ enum
AVHUFF_CODEC_DECOMPRESS_CONFIG = 1
};
-#endif // MAME_UTIL_CHDCODEC_H
+#endif // MAME_LIB_UTIL_CHDCODEC_H
diff --git a/src/lib/util/corefile.cpp b/src/lib/util/corefile.cpp
index e681c0f1fac..0c72e1337be 100644
--- a/src/lib/util/corefile.cpp
+++ b/src/lib/util/corefile.cpp
@@ -12,18 +12,16 @@
#include "coretmpl.h"
#include "osdcore.h"
+#include "path.h"
#include "unicode.h"
#include "vecstream.h"
-#include <zlib.h>
-
#include <algorithm>
#include <cassert>
+#include <cctype>
#include <cstring>
#include <iterator>
-#include <cctype>
-
namespace util {
@@ -43,110 +41,11 @@ namespace {
TYPE DEFINITIONS
***************************************************************************/
-class zlib_data
-{
-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;
- }
-
- ~zlib_data()
- {
- if (m_compress) deflateEnd(&m_stream);
- else if (m_decompress) inflateEnd(&m_stream);
- }
-
- std::size_t buffer_size() const { return sizeof(m_buffer); }
- void const *buffer_data() const { return m_buffer; }
- void *buffer_data() { return m_buffer; }
-
- // 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;
- }
-
- // 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);
- }
-
- // 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)
- {
- m_stream.next_in = const_cast<Bytef *>(reinterpret_cast<Bytef const *>(data));
- m_stream.avail_in = size;
- }
-
- // 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;
- }
-
- 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); }
-
- std::uint64_t realoffset() const { return m_realoffset; }
- void add_realoffset(std::uint32_t increment) { m_realoffset += increment; }
-
- bool is_nextoffset(std::uint64_t value) const { return m_nextoffset == value; }
- void add_nextoffset(std::uint32_t increment) { m_nextoffset += increment; }
-
-private:
- zlib_data(std::uint64_t offset)
- : m_compress(false)
- , m_decompress(false)
- , m_realoffset(offset)
- , m_nextoffset(offset)
- {
- m_stream.zalloc = Z_NULL;
- m_stream.zfree = Z_NULL;
- m_stream.opaque = Z_NULL;
- m_stream.avail_in = m_stream.avail_out = 0;
- }
-
- 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;
-};
-
-
class core_proxy_file : public core_file
{
public:
- core_proxy_file(core_file &file) : m_file(file) { }
+ core_proxy_file(core_file &file) noexcept : m_file(file) { }
virtual ~core_proxy_file() override { }
- virtual osd_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(); }
@@ -162,9 +61,9 @@ public:
virtual std::uint32_t write(const void *buffer, std::uint32_t length) override { return m_file.write(buffer, length); }
virtual int puts(std::string_view s) override { return m_file.puts(s); }
virtual int vprintf(util::format_argument_pack<std::ostream> const &args) override { return m_file.vprintf(args); }
- virtual osd_file::error truncate(std::uint64_t offset) override { return m_file.truncate(offset); }
+ virtual std::error_condition truncate(std::uint64_t offset) override { return m_file.truncate(offset); }
- virtual osd_file::error flush() override { return m_file.flush(); }
+ virtual std::error_condition flush() override { return m_file.flush(); }
private:
core_file &m_file;
@@ -230,12 +129,12 @@ public:
if (copy)
{
void *const buf = allocate();
- if (buf) std::memcpy(buf, data, length);
+ if (buf)
+ std::memcpy(buf, data, length);
}
}
~core_in_memory_file() override { purge(); }
- virtual osd_file::error compress(int level) override { return osd_file::error::INVALID_ACCESS; }
virtual int seek(std::int64_t offset, int whence) override;
virtual std::uint64_t tell() const override { return m_offset; }
@@ -246,8 +145,8 @@ public:
virtual void const *buffer() override { return m_data; }
virtual std::uint32_t write(void const *buffer, std::uint32_t length) override { return 0; }
- virtual osd_file::error truncate(std::uint64_t offset) override;
- virtual osd_file::error flush() override { clear_putback(); return osd_file::error::NONE; }
+ virtual std::error_condition truncate(std::uint64_t offset) override;
+ virtual std::error_condition flush() override { clear_putback(); return std::error_condition(); }
protected:
core_in_memory_file(std::uint32_t openflags, std::uint64_t length)
@@ -262,7 +161,8 @@ protected:
bool is_loaded() const { return nullptr != m_data; }
void *allocate()
{
- if (m_data) return nullptr;
+ if (m_data)
+ return nullptr;
void *data = malloc(m_length);
if (data)
{
@@ -273,7 +173,8 @@ protected:
}
void purge()
{
- if (m_data && m_data_allocated) free(const_cast<void *>(m_data));
+ if (m_data && m_data_allocated)
+ free(const_cast<void *>(m_data));
m_data_allocated = false;
m_data = nullptr;
}
@@ -301,23 +202,18 @@ public:
core_osd_file(std::uint32_t openmode, osd_file::ptr &&file, std::uint64_t length)
: core_in_memory_file(openmode, length)
, m_file(std::move(file))
- , m_zdata()
, m_bufferbase(0)
, m_bufferbytes(0)
{
}
~core_osd_file() override;
- virtual osd_file::error compress(int level) override;
-
- 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;
virtual std::uint32_t write(void const *buffer, std::uint32_t length) override;
- virtual osd_file::error truncate(std::uint64_t offset) override;
- virtual osd_file::error flush() override;
+ virtual std::error_condition truncate(std::uint64_t offset) override;
+ virtual std::error_condition flush() override;
protected:
@@ -326,11 +222,7 @@ protected:
private:
static constexpr std::size_t FILE_BUFFER_SIZE = 512;
- osd_file::error osd_or_zlib_read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual);
- osd_file::error osd_or_zlib_write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual);
-
osd_file::ptr 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
@@ -673,14 +565,14 @@ std::uint32_t core_in_memory_file::read(void *buffer, std::uint32_t length)
truncate - truncate a file
-------------------------------------------------*/
-osd_file::error core_in_memory_file::truncate(std::uint64_t offset)
+std::error_condition core_in_memory_file::truncate(std::uint64_t offset)
{
if (m_length < offset)
- return osd_file::error::FAILURE;
+ return std::errc::io_error; // TODO: revisit this error code
// adjust to new length and offset
set_length(offset);
- return osd_file::error::NONE;
+ return std::error_condition();
}
@@ -719,91 +611,6 @@ std::size_t core_in_memory_file::safe_buffer_copy(
core_osd_file::~core_osd_file()
{
// close files and free memory
- if (m_zdata)
- core_osd_file::compress(FCOMPRESS_NONE);
-}
-
-
-/*-------------------------------------------------
- compress - enable/disable streaming file
- compression via zlib; level is 0 to disable
- compression, or up to 9 for max compression
--------------------------------------------------*/
-
-osd_file::error core_osd_file::compress(int level)
-{
- osd_file::error result = osd_file::error::NONE;
-
- // can only do this for read-only and write-only cases
- if (read_access() && write_access())
- return osd_file::error::INVALID_ACCESS;
-
- // if we have been compressing, flush and free the data
- if (m_zdata && (level == FCOMPRESS_NONE))
- {
- int zerr = Z_OK;
-
- // flush any remaining data if we are writing
- while (write_access() && (zerr != Z_STREAM_END))
- {
- // deflate some more
- zerr = m_zdata->finalise();
- if ((zerr != Z_STREAM_END) && (zerr != Z_OK))
- {
- result = osd_file::error::INVALID_DATA;
- break;
- }
-
- // write the data
- if (m_zdata->has_output())
- {
- std::uint32_t actualdata;
- auto const filerr = m_file->write(m_zdata->buffer_data(), m_zdata->realoffset(), m_zdata->output_size(), actualdata);
- if (filerr != osd_file::error::NONE)
- break;
- m_zdata->add_realoffset(actualdata);
- m_zdata->reset_output();
- }
- }
-
- // free memory
- m_zdata.reset();
- }
-
- // if we are just starting to compress, allocate a new buffer
- if (!m_zdata && (level > FCOMPRESS_NONE))
- {
- int zerr;
-
- // 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 osd_file::error::OUT_OF_MEMORY;
-
- // flush buffers
- m_bufferbytes = 0;
- }
-
- return result;
-}
-
-
-/*-------------------------------------------------
- seek - seek within a file
--------------------------------------------------*/
-
-int core_osd_file::seek(std::int64_t offset, int whence)
-{
- // error if compressing
- if (m_zdata)
- return 1;
- else
- return core_in_memory_file::seek(offset, whence);
}
@@ -833,7 +640,7 @@ std::uint32_t core_osd_file::read(void *buffer, std::uint32_t length)
// 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);
+ m_file->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);
@@ -842,7 +649,7 @@ std::uint32_t core_osd_file::read(void *buffer, std::uint32_t length)
{
// 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);
+ m_file->read(reinterpret_cast<std::uint8_t *>(buffer) + bytes_read, offset() + bytes_read, length - bytes_read, new_bytes_read);
bytes_read += new_bytes_read;
}
}
@@ -866,18 +673,16 @@ void const *core_osd_file::buffer()
{
// allocate some memory
void *buf = allocate();
- if (!buf) return nullptr;
+ 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 != osd_file::error::NONE) || (read_length != length()))
+ auto const filerr = m_file->read(buf, 0, length(), read_length);
+ if (filerr || (read_length != length()))
purge();
else
- {
- // close the file because we don't need it anymore
- m_file.reset();
- }
+ m_file.reset(); // close the file because we don't need it anymore
}
return core_in_memory_file::buffer();
}
@@ -901,7 +706,7 @@ std::uint32_t core_osd_file::write(void const *buffer, std::uint32_t length)
// do the write
std::uint32_t bytes_written = 0;
- osd_or_zlib_write(buffer, offset(), length, bytes_written);
+ m_file->write(buffer, offset(), length, bytes_written);
// return the number of bytes written
add_offset(bytes_written);
@@ -913,19 +718,19 @@ std::uint32_t core_osd_file::write(void const *buffer, std::uint32_t length)
truncate - truncate a file
-------------------------------------------------*/
-osd_file::error core_osd_file::truncate(std::uint64_t offset)
+std::error_condition core_osd_file::truncate(std::uint64_t offset)
{
if (is_loaded())
return core_in_memory_file::truncate(offset);
// truncate file
auto const err = m_file->truncate(offset);
- if (err != osd_file::error::NONE)
+ if (err)
return err;
// and adjust to new length and offset
set_length(offset);
- return osd_file::error::NONE;
+ return std::error_condition();
}
@@ -933,7 +738,7 @@ osd_file::error core_osd_file::truncate(std::uint64_t offset)
flush - flush file buffers
-------------------------------------------------*/
-osd_file::error core_osd_file::flush()
+std::error_condition core_osd_file::flush()
{
if (is_loaded())
return core_in_memory_file::flush();
@@ -947,116 +752,6 @@ osd_file::error core_osd_file::flush()
return m_file->flush();
}
-
-/*-------------------------------------------------
- osd_or_zlib_read - wrapper for osd_read that
- handles zlib-compressed data
--------------------------------------------------*/
-
-osd_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 (!m_zdata)
- return m_file->read(buffer, offset, length, actual);
-
- // if the offset doesn't match the next offset, fail
- if (!m_zdata->is_nextoffset(offset))
- return osd_file::error::INVALID_ACCESS;
-
- // set up the destination
- osd_file::error filerr = osd_file::error::NONE;
- m_zdata->set_output(buffer, length);
- while (!m_zdata->output_full())
- {
- // if we didn't make progress, report an error or the end
- if (m_zdata->has_input())
- {
- auto const zerr = m_zdata->decompress();
- if (Z_OK != zerr)
- {
- if (Z_STREAM_END != zerr) filerr = osd_file::error::INVALID_DATA;
- break;
- }
- }
-
- // fetch more data if needed
- if (!m_zdata->has_input())
- {
- std::uint32_t actualdata = 0;
- filerr = m_file->read(m_zdata->buffer_data(), m_zdata->realoffset(), m_zdata->buffer_size(), actualdata);
- if (filerr != osd_file::error::NONE) break;
- m_zdata->add_realoffset(actualdata);
- m_zdata->reset_input(actualdata);
- if (!m_zdata->has_input()) break;
- }
- }
-
- // adjust everything
- actual = length - m_zdata->output_space();
- m_zdata->add_nextoffset(actual);
- return filerr;
-}
-
-
-/*-------------------------------------------------
- osd_or_zlib_write - wrapper for osd_write that
- handles zlib-compressed data
--------------------------------------------------*/
-
-/**
- * @fn osd_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 buffer The buffer.
- * @param offset The offset.
- * @param length The length.
- * @param [in,out] actual The actual.
- *
- * @return A osd_file::error.
- */
-
-osd_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 (!m_zdata)
- return m_file->write(buffer, offset, length, actual);
-
- // if the offset doesn't match the next offset, fail
- if (!m_zdata->is_nextoffset(offset))
- return osd_file::error::INVALID_ACCESS;
-
- // set up the source
- m_zdata->set_input(buffer, length);
- while (m_zdata->has_input())
- {
- // if we didn't make progress, report an error or the end
- auto const zerr = m_zdata->compress();
- if (zerr != Z_OK)
- {
- actual = length - m_zdata->input_size();
- m_zdata->add_nextoffset(actual);
- return osd_file::error::INVALID_DATA;
- }
-
- // write more data if we are full up
- if (m_zdata->output_full())
- {
- std::uint32_t actualdata = 0;
- auto const filerr = m_file->write(m_zdata->buffer_data(), m_zdata->realoffset(), m_zdata->output_size(), actualdata);
- if (filerr != osd_file::error::NONE)
- return filerr;
- m_zdata->add_realoffset(actualdata);
- m_zdata->reset_output();
- }
- }
-
- // we wrote everything
- actual = length;
- m_zdata->add_nextoffset(actual);
- return osd_file::error::NONE;
-}
-
} // anonymous namespace
@@ -1070,23 +765,23 @@ osd_file::error core_osd_file::osd_or_zlib_write(void const *buffer, std::uint64
return an error code
-------------------------------------------------*/
-osd_file::error core_file::open(std::string const &filename, std::uint32_t openflags, ptr &file)
+std::error_condition core_file::open(std::string_view filename, std::uint32_t openflags, ptr &file)
{
try
{
// attempt to open the file
osd_file::ptr f;
std::uint64_t length = 0;
- auto const filerr = osd_file::open(filename, openflags, f, length);
- if (filerr != osd_file::error::NONE)
+ auto const filerr = osd_file::open(std::string(filename), openflags, f, length); // FIXME: allow osd_file to accept std::string_view
+ if (filerr)
return filerr;
file = std::make_unique<core_osd_file>(openflags, std::move(f), length);
- return osd_file::error::NONE;
+ return std::error_condition();
}
catch (...)
{
- return osd_file::error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
}
@@ -1096,20 +791,20 @@ osd_file::error core_file::open(std::string const &filename, std::uint32_t openf
like access and return an error code
-------------------------------------------------*/
-osd_file::error core_file::open_ram(void const *data, std::size_t length, std::uint32_t openflags, ptr &file)
+std::error_condition 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 osd_file::error::INVALID_ACCESS;
+ return std::errc::invalid_argument;
try
{
file.reset(new core_in_memory_file(openflags, data, length, false));
- return osd_file::error::NONE;
+ return std::error_condition();
}
catch (...)
{
- return osd_file::error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
}
@@ -1120,24 +815,24 @@ osd_file::error core_file::open_ram(void const *data, std::size_t length, std::u
error code
-------------------------------------------------*/
-osd_file::error core_file::open_ram_copy(void const *data, std::size_t length, std::uint32_t openflags, ptr &file)
+std::error_condition 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 osd_file::error::INVALID_ACCESS;
+ return std::errc::invalid_argument;
try
{
ptr result(new core_in_memory_file(openflags, data, length, true));
if (!result->buffer())
- return osd_file::error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
file = std::move(result);
- return osd_file::error::NONE;
+ return std::error_condition();
}
catch (...)
{
- return osd_file::error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
}
@@ -1147,17 +842,14 @@ osd_file::error core_file::open_ram_copy(void const *data, std::size_t length, s
object and return an error code
-------------------------------------------------*/
-osd_file::error core_file::open_proxy(core_file &file, ptr &proxy)
+std::error_condition core_file::open_proxy(core_file &file, ptr &proxy)
{
- try
- {
- proxy = std::make_unique<core_proxy_file>(file);
- return osd_file::error::NONE;
- }
- catch (...)
- {
- return osd_file::error::OUT_OF_MEMORY;
- }
+ ptr result(new (std::nothrow) core_proxy_file(file));
+ if (!result)
+ return std::errc::not_enough_memory;
+
+ proxy = std::move(result);
+ return std::error_condition();
}
@@ -1176,61 +868,64 @@ core_file::~core_file()
pointer
-------------------------------------------------*/
-osd_file::error core_file::load(std::string const &filename, void **data, std::uint32_t &length)
+std::error_condition core_file::load(std::string_view 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 != osd_file::error::NONE)
+ if (err)
return err;
// get the size
auto const size = file->size();
if (std::uint32_t(size) != size)
- return osd_file::error::OUT_OF_MEMORY;
+ return std::errc::file_too_large;
// allocate memory
*data = malloc(size);
+ if (!*data)
+ return std::errc::not_enough_memory;
length = std::uint32_t(size);
// read the data
if (file->read(*data, size) != size)
{
free(*data);
- return osd_file::error::FAILURE;
+ return std::errc::io_error; // TODO: revisit this error code
}
// close the file and return data
- return osd_file::error::NONE;
+ return std::error_condition();
}
-osd_file::error core_file::load(std::string const &filename, std::vector<uint8_t> &data)
+std::error_condition core_file::load(std::string_view filename, std::vector<uint8_t> &data)
{
ptr file;
// attempt to open the file
auto const err = open(filename, OPEN_FLAG_READ, file);
- if (err != osd_file::error::NONE)
+ if (err)
return err;
// get the size
auto const size = file->size();
if (std::uint32_t(size) != size)
- return osd_file::error::OUT_OF_MEMORY;
+ return std::errc::file_too_large;
// allocate memory
- data.resize(size);
+ try { data.resize(size); }
+ catch (...) { return std::errc::not_enough_memory; }
// read the data
if (file->read(&data[0], size) != size)
{
data.clear();
- return osd_file::error::FAILURE;
+ return std::errc::io_error; // TODO: revisit this error code
}
// close the file and return data
- return osd_file::error::NONE;
+ return std::error_condition();
}
@@ -1256,7 +951,7 @@ core_file::core_file()
// assumptions about path separators
// -------------------------------------------------
-std::string_view core_filename_extract_base(std::string_view name, bool strip_extension)
+std::string_view core_filename_extract_base(std::string_view name, bool strip_extension) noexcept
{
// find the start of the basename
auto const start = std::find_if(name.rbegin(), name.rend(), &util::is_directory_separator);
@@ -1279,7 +974,7 @@ std::string_view core_filename_extract_base(std::string_view name, bool strip_ex
// core_filename_extract_extension
// -------------------------------------------------
-std::string_view core_filename_extract_extension(std::string_view filename, bool strip_period)
+std::string_view core_filename_extract_extension(std::string_view filename, bool strip_period) noexcept
{
auto loc = filename.find_last_of('.');
if (loc != std::string_view::npos)
@@ -1294,7 +989,7 @@ std::string_view core_filename_extract_extension(std::string_view filename, bool
// filename end with the specified extension?
// -------------------------------------------------
-bool core_filename_ends_with(std::string_view filename, std::string_view extension)
+bool core_filename_ends_with(std::string_view filename, std::string_view extension) noexcept
{
auto namelen = filename.length();
auto extlen = extension.length();
diff --git a/src/lib/util/corefile.h b/src/lib/util/corefile.h
index 6aaa8f609e1..19febbb46f1 100644
--- a/src/lib/util/corefile.h
+++ b/src/lib/util/corefile.h
@@ -12,14 +12,13 @@
#pragma once
-
#include "osdfile.h"
#include "strformat.h"
#include <cstdint>
#include <memory>
-#include <string>
#include <string_view>
+#include <system_error>
namespace util {
@@ -30,11 +29,6 @@ namespace util {
#define OPEN_FLAG_NO_BOM 0x0100 /* don't output BOM */
-#define FCOMPRESS_NONE 0 /* no compression */
-#define FCOMPRESS_MIN 1 /* minimal compression */
-#define FCOMPRESS_MEDIUM 6 /* standard compression */
-#define FCOMPRESS_MAX 9 /* maximum compression */
-
/***************************************************************************
TYPE DEFINITIONS
@@ -49,23 +43,20 @@ public:
// ----- file open/close -----
// open a file with the specified filename
- static osd_file::error open(std::string const &filename, std::uint32_t openflags, ptr &file);
+ static std::error_condition open(std::string_view filename, std::uint32_t openflags, ptr &file);
// open a RAM-based "file" using the given data and length (read-only)
- static osd_file::error open_ram(const void *data, std::size_t length, std::uint32_t openflags, ptr &file);
+ static std::error_condition 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), copying the data
- static osd_file::error open_ram_copy(const void *data, std::size_t length, std::uint32_t openflags, ptr &file);
+ static std::error_condition open_ram_copy(const void *data, std::size_t length, std::uint32_t openflags, ptr &file);
// open a proxy "file" that forwards requests to another file object
- static osd_file::error open_proxy(core_file &file, ptr &proxy);
+ static std::error_condition open_proxy(core_file &file, ptr &proxy);
// 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
- virtual osd_file::error compress(int level) = 0;
-
// ----- file positioning -----
@@ -101,8 +92,8 @@ public:
virtual const void *buffer() = 0;
// open a file with the specified filename, read it into memory, and return a pointer
- static osd_file::error load(std::string const &filename, void **data, std::uint32_t &length);
- static osd_file::error load(std::string const &filename, std::vector<uint8_t> &data);
+ static std::error_condition load(std::string_view filename, void **data, std::uint32_t &length);
+ static std::error_condition load(std::string_view filename, std::vector<uint8_t> &data);
// ----- file write -----
@@ -121,32 +112,16 @@ public:
}
// file truncation
- virtual osd_file::error truncate(std::uint64_t offset) = 0;
+ virtual std::error_condition truncate(std::uint64_t offset) = 0;
// flush file buffers
- virtual osd_file::error flush() = 0;
+ virtual std::error_condition flush() = 0;
protected:
core_file();
};
-
-/***************************************************************************
- INLINE FUNCTIONS
-***************************************************************************/
-
-// is a given character a directory separator?
-
-constexpr bool is_directory_separator(char c)
-{
-#if defined(WIN32)
- return ('\\' == c) || ('/' == c) || (':' == c);
-#else
- return '/' == c;
-#endif
-}
-
} // namespace util
@@ -157,13 +132,13 @@ constexpr bool is_directory_separator(char c)
/* ----- filename utilities ----- */
// extract the base part of a filename (remove extensions and paths)
-std::string_view core_filename_extract_base(std::string_view name, bool strip_extension = false);
+std::string_view core_filename_extract_base(std::string_view name, bool strip_extension = false) noexcept;
// extracts the file extension from a filename
-std::string_view core_filename_extract_extension(std::string_view filename, bool strip_period = false);
+std::string_view core_filename_extract_extension(std::string_view filename, bool strip_period = false) noexcept;
// true if the given filename ends with a particular extension
-bool core_filename_ends_with(std::string_view filename, std::string_view extension);
+bool core_filename_ends_with(std::string_view filename, std::string_view extension) noexcept;
#endif // MAME_LIB_UTIL_COREFILE_H
diff --git a/src/lib/util/harddisk.cpp b/src/lib/util/harddisk.cpp
index e91759c44f2..2e8d14f9a8a 100644
--- a/src/lib/util/harddisk.cpp
+++ b/src/lib/util/harddisk.cpp
@@ -8,11 +8,13 @@
***************************************************************************/
-#include <cassert>
#include "harddisk.h"
-#include "osdcore.h"
+
+#include "corefile.h"
+
#include <cstdlib>
+
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
@@ -40,7 +42,7 @@ hard_disk_file *hard_disk_open(chd_file *chd)
int cylinders, heads, sectors, sectorbytes;
hard_disk_file *file;
std::string metadata;
- chd_error err;
+ std::error_condition err;
/* punt if no CHD */
if (chd == nullptr)
@@ -48,7 +50,7 @@ hard_disk_file *hard_disk_open(chd_file *chd)
/* read the hard disk metadata */
err = chd->read_metadata(HARD_DISK_METADATA_TAG, 0, metadata);
- if (err != CHDERR_NONE)
+ if (err)
return nullptr;
/* parse the metadata */
@@ -177,8 +179,8 @@ uint32_t hard_disk_read(hard_disk_file *file, uint32_t lbasector, void *buffer)
{
if (file->chd)
{
- chd_error err = file->chd->read_units(lbasector, buffer);
- return (err == CHDERR_NONE);
+ std::error_condition err = file->chd->read_units(lbasector, buffer);
+ return !err;
}
else
{
@@ -211,8 +213,8 @@ uint32_t hard_disk_write(hard_disk_file *file, uint32_t lbasector, const void *b
{
if (file->chd)
{
- chd_error err = file->chd->write_units(lbasector, buffer);
- return (err == CHDERR_NONE);
+ std::error_condition err = file->chd->write_units(lbasector, buffer);
+ return !err;
}
else
{
diff --git a/src/lib/util/harddisk.h b/src/lib/util/harddisk.h
index 2a4b727e7e7..e6fae165f19 100644
--- a/src/lib/util/harddisk.h
+++ b/src/lib/util/harddisk.h
@@ -8,13 +8,15 @@
***************************************************************************/
-#ifndef MAME_UTIL_HARDDISK_H
-#define MAME_UTIL_HARDDISK_H
+#ifndef MAME_LIB_UTIL_HARDDISK_H
+#define MAME_LIB_UTIL_HARDDISK_H
#pragma once
-#include "osdcore.h"
#include "chd.h"
+#include "utilfwd.h"
+
+#include "osdcore.h"
/***************************************************************************
@@ -49,4 +51,4 @@ hard_disk_info *hard_disk_get_info(hard_disk_file *file);
uint32_t hard_disk_read(hard_disk_file *file, uint32_t lbasector, void *buffer);
uint32_t hard_disk_write(hard_disk_file *file, uint32_t lbasector, const void *buffer);
-#endif // MAME_UTIL_HARDDISK_H
+#endif // MAME_LIB_UTIL_HARDDISK_H
diff --git a/src/lib/util/ioprocs.cpp b/src/lib/util/ioprocs.cpp
new file mode 100644
index 00000000000..1f52a3daf97
--- /dev/null
+++ b/src/lib/util/ioprocs.cpp
@@ -0,0 +1,1248 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/***************************************************************************
+
+ ioprocs.h
+
+ I/O interfaces
+
+***************************************************************************/
+
+#include "ioprocs.h"
+
+#include "corefile.h"
+#include "ioprocsfill.h"
+
+#include "osdfile.h"
+
+#include <algorithm>
+#include <cassert>
+#include <cerrno>
+#include <cstring>
+#include <iterator>
+#include <limits>
+#include <type_traits>
+
+
+namespace util {
+
+namespace {
+
+// helper for holding a block of memory and deallocating it (or not) as necessary
+
+template <typename T, bool Owned>
+class ram_adapter_base : public virtual random_access
+{
+public:
+ virtual ~ram_adapter_base()
+ {
+ if constexpr (Owned)
+ std::free(m_data);
+ }
+
+ virtual std::error_condition seek(std::int64_t offset, int whence) noexcept override
+ {
+ switch (whence)
+ {
+ case SEEK_SET:
+ if (0 > offset)
+ return std::errc::invalid_argument;
+ m_pointer = std::uint64_t(offset);
+ return std::error_condition();
+
+ case SEEK_CUR:
+ if (0 > offset)
+ {
+ if (std::uint64_t(-offset) > m_pointer)
+ return std::errc::invalid_argument;
+ }
+ else if ((std::numeric_limits<std::uint64_t>::max() - offset) < m_pointer)
+ {
+ return std::errc::invalid_argument;
+ }
+ m_pointer += offset;
+ return std::error_condition();
+
+ case SEEK_END:
+ if (0 > offset)
+ {
+ if (std::uint64_t(-offset) > m_size)
+ return std::errc::invalid_argument;
+ }
+ else if ((std::numeric_limits<std::uint64_t>::max() - offset) < m_size)
+ {
+ return std::errc::invalid_argument;
+ }
+ m_pointer = std::uint64_t(m_size) + offset;
+ return std::error_condition();
+
+ default:
+ return std::errc::invalid_argument;
+ }
+ }
+
+ virtual std::error_condition tell(std::uint64_t &result) noexcept override
+ {
+ result = m_pointer;
+ return std::error_condition();
+ }
+
+ virtual std::error_condition length(std::uint64_t &result) noexcept override
+ {
+ if (std::numeric_limits<uint64_t>::max() < m_size)
+ return std::errc::file_too_large;
+
+ result = m_size;
+ return std::error_condition();
+ }
+
+protected:
+ template <typename U>
+ ram_adapter_base(U *data, std::size_t size) noexcept : m_data(reinterpret_cast<T>(data)), m_size(size)
+ {
+ static_assert(sizeof(*m_data) == 1U, "Element type must be byte-sized");
+ assert(m_data || !m_size);
+ }
+
+ T m_data;
+ std::uint64_t m_pointer = 0U;
+ std::size_t m_size;
+};
+
+
+// RAM read implementation
+
+template <typename T, bool Owned>
+class ram_read_adapter : public ram_adapter_base<T, Owned>, public virtual random_read
+{
+public:
+ template <typename U>
+ ram_read_adapter(U *data, std::size_t size) noexcept : ram_adapter_base<T, Owned>(data, size)
+ {
+ }
+
+ virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ do_read(this->m_pointer, buffer, length, actual);
+ this->m_pointer += actual;
+ return std::error_condition();
+ }
+
+ virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ do_read(offset, buffer, length, actual);
+ return std::error_condition();
+ }
+
+private:
+ void do_read(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) const noexcept
+ {
+ if ((offset < this->m_size) && length)
+ {
+ actual = std::min(std::size_t(this->m_size - offset), length);
+ if constexpr (Owned)
+ std::memcpy(buffer, this->m_data + offset, actual);
+ else
+ std::memmove(buffer, this->m_data + offset, actual);
+ }
+ else
+ {
+ actual = 0U;
+ }
+ }
+};
+
+
+// helper for holding a stdio FILE and closing it (or not) as necessary
+
+class stdio_adapter_base : public virtual random_access
+{
+public:
+ virtual ~stdio_adapter_base()
+ {
+ if (m_close)
+ std::fclose(m_file);
+ }
+
+ virtual std::error_condition seek(std::int64_t offset, int whence) noexcept override
+ {
+ if ((std::numeric_limits<long>::max() < offset) || (std::numeric_limits<long>::min() > offset))
+ return std::errc::invalid_argument;
+ else if (!std::fseek(m_file, long(offset), whence))
+ return std::error_condition();
+ else
+ return std::error_condition(errno, std::generic_category());
+ }
+
+ virtual std::error_condition tell(std::uint64_t &result) noexcept override
+ {
+ long const pos = std::ftell(m_file);
+ if (0 > pos)
+ return std::error_condition(errno, std::generic_category());
+ result = static_cast<unsigned long>(pos);
+ return std::error_condition();
+ }
+
+ virtual std::error_condition length(std::uint64_t &result) noexcept override
+ {
+ std::fpos_t oldpos;
+ if (std::fgetpos(m_file, &oldpos))
+ return std::error_condition(errno, std::generic_category());
+
+ long endpos = -1;
+ if (!std::fseek(m_file, 0, SEEK_END))
+ {
+ m_dangling_read = m_dangling_write = false;
+ endpos = std::ftell(m_file);
+ }
+ std::error_condition err;
+ if (0 > endpos)
+ err.assign(errno, std::generic_category());
+ else if (std::numeric_limits<std::uint64_t>::max() < static_cast<unsigned long>(endpos))
+ err = std::errc::file_too_large;
+ else
+ result = static_cast<unsigned long>(endpos);
+
+ if (!std::fsetpos(m_file, &oldpos))
+ m_dangling_read = m_dangling_write = false;
+ else if (!err)
+ err.assign(errno, std::generic_category());
+
+ return err;
+ }
+
+protected:
+ stdio_adapter_base(FILE *file, bool close) noexcept : m_file(file), m_close(close)
+ {
+ assert(m_file);
+ }
+
+ FILE *file() noexcept
+ {
+ return m_file;
+ }
+
+private:
+ FILE *const m_file;
+ bool const m_close;
+
+protected:
+ bool m_dangling_read = true, m_dangling_write = true;
+};
+
+
+// stdio read implementation
+
+class stdio_read_adapter : public stdio_adapter_base, public virtual random_read
+{
+public:
+ stdio_read_adapter(FILE *file, bool close) noexcept : stdio_adapter_base(file, close)
+ {
+ }
+
+ virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ if (m_dangling_write)
+ {
+ if (std::fflush(file()))
+ {
+ std::clearerr(file());
+ actual = 0U;
+ return std::error_condition(errno, std::generic_category());
+ }
+ m_dangling_write = false;
+ }
+
+ actual = std::fread(buffer, sizeof(std::uint8_t), length, file());
+ m_dangling_read = true;
+ if (length != actual)
+ {
+ if (std::ferror(file()))
+ {
+ std::clearerr(file());
+ return std::error_condition(errno, std::generic_category());
+ }
+ else if (std::feof(file()))
+ {
+ m_dangling_read = false;
+ }
+ }
+
+ return std::error_condition();
+ }
+
+ virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ actual = 0U;
+
+ if (static_cast<unsigned long>(std::numeric_limits<long>::max()) < offset)
+ return std::errc::invalid_argument;
+
+ std::fpos_t oldpos;
+ if (std::fgetpos(file(), &oldpos))
+ return std::error_condition(errno, std::generic_category());
+
+ std::error_condition err;
+ if (std::fseek(file(), long(static_cast<unsigned long>(offset)), SEEK_SET))
+ {
+ err.assign(errno, std::generic_category());
+ }
+ else
+ {
+ m_dangling_write = false;
+ actual = std::fread(buffer, sizeof(std::uint8_t), length, file());
+ m_dangling_read = true;
+ if (length != actual)
+ {
+ if (std::ferror(file()))
+ {
+ err.assign(errno, std::generic_category());
+ std::clearerr(file());
+ }
+ else if (std::feof(file()))
+ {
+ m_dangling_read = false;
+ }
+ }
+ }
+
+ if (!std::fsetpos(file(), &oldpos))
+ m_dangling_read = m_dangling_write = false;
+ else if (!err)
+ err.assign(errno, std::generic_category());
+
+ return err;
+ }
+};
+
+
+// stdio read/write implementation
+
+class stdio_read_write_adapter : public stdio_read_adapter, public random_read_write
+{
+public:
+ using stdio_read_adapter::stdio_read_adapter;
+
+ virtual std::error_condition finalize() noexcept override
+ {
+ return std::error_condition();
+ }
+
+ virtual std::error_condition flush() noexcept override
+ {
+ if (std::fflush(file()))
+ {
+ std::clearerr(file());
+ return std::error_condition(errno, std::generic_category());
+ }
+ m_dangling_write = false;
+ return std::error_condition();
+ }
+
+ virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ if (m_dangling_read)
+ {
+ if (std::fseek(file(), 0, SEEK_CUR))
+ {
+ actual = 0U;
+ return std::error_condition(errno, std::generic_category());
+ }
+ m_dangling_read = false;
+ }
+
+ actual = std::fwrite(buffer, sizeof(std::uint8_t), length, file());
+ m_dangling_write = true;
+ if (length != actual)
+ {
+ std::clearerr(file());
+ return std::error_condition(errno, std::generic_category());
+ }
+
+ return std::error_condition();
+ }
+
+ virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ actual = 0U;
+
+ if (static_cast<unsigned long>(std::numeric_limits<long>::max()) < offset)
+ return std::errc::invalid_argument;
+
+ std::fpos_t oldpos;
+ if (std::fgetpos(file(), &oldpos))
+ return std::error_condition(errno, std::generic_category());
+
+ std::error_condition err;
+ if (std::fseek(file(), long(static_cast<unsigned long>(offset)), SEEK_SET))
+ {
+ err.assign(errno, std::generic_category());
+ }
+ else
+ {
+ m_dangling_read = false;
+ actual = std::fwrite(buffer, sizeof(std::uint8_t), length, file());
+ m_dangling_write = true;
+ if (length != actual)
+ {
+ err.assign(errno, std::generic_category());
+ std::clearerr(file());
+ }
+ }
+
+ if (!std::fsetpos(file(), &oldpos))
+ m_dangling_read = m_dangling_write = false;
+ else if (!err)
+ err.assign(errno, std::generic_category());
+
+ return err;
+ }
+};
+
+
+// stdio helper that fills space when writing past the end-of-file
+
+class stdio_read_write_filler : public random_read_fill_wrapper<stdio_read_write_adapter>
+{
+public:
+ stdio_read_write_filler(FILE *file, bool close, std::uint8_t fill) noexcept : random_read_fill_wrapper<stdio_read_write_adapter>(file, close)
+ {
+ set_filler(fill);
+ }
+
+ virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ actual = 0U;
+
+ long const offset = std::ftell(file());
+ if (0 > offset)
+ return std::error_condition(errno, std::generic_category());
+
+ if (std::fseek(file(), 0, SEEK_END))
+ {
+ std::error_condition err(errno, std::generic_category());
+ if (!std::fseek(file(), offset, SEEK_SET))
+ m_dangling_read = m_dangling_write = false;
+ return err;
+ }
+ m_dangling_read = m_dangling_write = false;
+ long endpos = std::ftell(file());
+ if (0 > endpos)
+ {
+ std::error_condition err(errno, std::generic_category());
+ std::fseek(file(), offset, SEEK_SET);
+ return err;
+ }
+
+ if (offset > endpos)
+ {
+ std::uint8_t block[1024];
+ std::fill_n(
+ block,
+ std::min<std::common_type_t<std::size_t, std::uint64_t, long> >(std::size(block), offset - endpos),
+ get_filler());
+ do
+ {
+ std::size_t const chunk = std::min<std::common_type_t<std::size_t, std::uint64_t, long> >(std::size(block), offset - endpos);
+ std::size_t const filled = std::fwrite(block, sizeof(block[0]), chunk, file());
+ endpos += filled;
+ m_dangling_write = true;
+ if (chunk != filled)
+ {
+ std::error_condition err(errno, std::generic_category());
+ std::clearerr(file());
+ if (!std::fseek(file(), offset, SEEK_SET))
+ m_dangling_write = false;
+ return err;
+ }
+ }
+ while (static_cast<unsigned long>(endpos) < offset);
+ }
+ else if ((offset < endpos) && std::fseek(file(), offset, SEEK_SET))
+ {
+ return std::error_condition(errno, std::generic_category());
+ }
+
+ actual = std::fwrite(buffer, sizeof(std::uint8_t), length, file());
+ m_dangling_write = true;
+ if (length != actual)
+ {
+ std::clearerr(file());
+ return std::error_condition(errno, std::generic_category());
+ }
+
+ return std::error_condition();
+ }
+
+ virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ actual = 0U;
+
+ if (static_cast<unsigned long>(std::numeric_limits<long>::max()) < offset)
+ return std::errc::invalid_argument;
+
+ std::fpos_t oldpos;
+ if (std::fgetpos(file(), &oldpos))
+ return std::error_condition(errno, std::generic_category());
+
+ std::error_condition err;
+ if (std::fseek(file(), 0, SEEK_END))
+ {
+ err.assign(errno, std::generic_category());
+ }
+ else
+ {
+ m_dangling_read = m_dangling_write = false;
+ long endpos = std::ftell(file());
+ if (0 > endpos)
+ {
+ err.assign(errno, std::generic_category());
+ }
+ else if (static_cast<unsigned long>(endpos) > offset)
+ {
+ if (std::fseek(file(), long(static_cast<unsigned long>(offset)), SEEK_SET))
+ err.assign(errno, std::generic_category());
+ }
+ else if (static_cast<unsigned long>(endpos) < offset)
+ {
+ std::uint8_t block[1024];
+ std::fill_n(
+ block,
+ std::min<std::common_type_t<std::size_t, std::uint64_t, long> >(std::size(block), offset - endpos),
+ get_filler());
+ do
+ {
+ std::size_t const chunk = std::min<std::common_type_t<std::size_t, std::uint64_t, long> >(std::size(block), offset - endpos);
+ std::size_t const filled = std::fwrite(block, sizeof(block[0]), chunk, file());
+ endpos += filled;
+ m_dangling_write = true;
+ if (chunk != filled)
+ {
+ err.assign(errno, std::generic_category());
+ std::clearerr(file());
+ }
+ }
+ while (!err && (static_cast<unsigned long>(endpos) < offset));
+ }
+ }
+
+ if (!err)
+ {
+ actual = std::fwrite(buffer, sizeof(std::uint8_t), length, file());
+ m_dangling_write = true;
+ if (length != actual)
+ {
+ err.assign(errno, std::generic_category());
+ std::clearerr(file());
+ }
+ }
+
+ if (!std::fsetpos(file(), &oldpos))
+ m_dangling_read = m_dangling_write = false;
+ else if (!err)
+ err.assign(errno, std::generic_category());
+
+ return err;
+ }
+};
+
+
+// helper class for holding an osd_file and closing it (or not) as necessary
+
+class osd_file_adapter_base : public virtual random_access
+{
+public:
+ virtual ~osd_file_adapter_base()
+ {
+ if (m_close)
+ delete m_file;
+ }
+
+ virtual std::error_condition seek(std::int64_t offset, int whence) noexcept override
+ {
+ switch (whence)
+ {
+ case SEEK_SET:
+ if (0 > offset)
+ return std::errc::invalid_argument;
+ m_pointer = std::uint64_t(offset);
+ return std::error_condition();
+
+ case SEEK_CUR:
+ if (0 > offset)
+ {
+ if (std::uint64_t(-offset) > m_pointer)
+ return std::errc::invalid_argument;
+ }
+ else if ((std::numeric_limits<std::uint64_t>::max() - offset) < m_pointer)
+ {
+ return std::errc::invalid_argument;
+ }
+ m_pointer += offset;
+ return std::error_condition();
+
+ // TODO: add SEEK_END when osd_file can support it - should it return a different error?
+ default:
+ return std::errc::invalid_argument;
+ }
+ }
+
+ virtual std::error_condition tell(std::uint64_t &result) noexcept override
+ {
+ result = m_pointer;
+ return std::error_condition();
+ }
+
+ virtual std::error_condition length(std::uint64_t &result) noexcept override
+ {
+ // not supported by osd_file
+ return std::errc::not_supported; // TODO: revisit this error code
+ }
+
+protected:
+ osd_file_adapter_base(osd_file::ptr &&file) noexcept : m_file(file.release()), m_close(true)
+ {
+ assert(m_file);
+ }
+
+ osd_file_adapter_base(osd_file &file) noexcept : m_file(&file), m_close(false)
+ {
+ }
+
+ osd_file &file() noexcept
+ {
+ return *m_file;
+ }
+
+ std::uint64_t m_pointer = 0U;
+
+private:
+ osd_file *const m_file;
+ bool const m_close;
+};
+
+
+// osd_file read implementation
+
+class osd_file_read_adapter : public osd_file_adapter_base, public virtual random_read
+{
+public:
+ osd_file_read_adapter(osd_file::ptr &&file) noexcept : osd_file_adapter_base(std::move(file))
+ {
+ }
+
+ osd_file_read_adapter(osd_file &file) noexcept : osd_file_adapter_base(file)
+ {
+ }
+
+ virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ // TODO: should the client have to deal with reading less than expected even if EOF isn't hit?
+ if (std::numeric_limits<std::uint32_t>::max() < length)
+ {
+ actual = 0U;
+ return std::errc::invalid_argument;
+ }
+
+ // actual length not valid on error
+ std::uint32_t count;
+ std::error_condition err = file().read(buffer, m_pointer, std::uint32_t(length), count);
+ if (!err)
+ {
+ m_pointer += count;
+ actual = std::size_t(count);
+ }
+ else
+ {
+ actual = 0U;
+ }
+ return err;
+ }
+
+ virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ // TODO: should the client have to deal with reading less than expected even if EOF isn't hit?
+ if (std::numeric_limits<std::uint32_t>::max() < length)
+ {
+ actual = 0U;
+ return std::errc::invalid_argument;
+ }
+
+ // actual length not valid on error
+ std::uint32_t count;
+ std::error_condition err = file().read(buffer, offset, std::uint32_t(length), count);
+ if (!err)
+ actual = std::size_t(count);
+ else
+ actual = 0U;
+ return err;
+ }
+};
+
+
+// osd_file read/write implementation
+
+class osd_file_read_write_adapter : public osd_file_read_adapter, public random_read_write
+{
+public:
+ using osd_file_read_adapter::osd_file_read_adapter;
+
+ virtual std::error_condition finalize() noexcept override
+ {
+ return std::error_condition();
+ }
+
+ virtual std::error_condition flush() noexcept override
+ {
+ return file().flush();
+ }
+
+ virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ actual = 0U;
+ while (length)
+ {
+ // actual length not valid on error
+ std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length);
+ std::uint32_t written;
+ std::error_condition err = file().write(buffer, m_pointer, chunk, written);
+ if (err)
+ return err;
+ m_pointer += written;
+ buffer = reinterpret_cast<std::uint8_t const *>(buffer) + written;
+ length -= written;
+ actual += written;
+ }
+ return std::error_condition();
+ }
+
+ virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ actual = 0U;
+ while (length)
+ {
+ // actual length not valid on error
+ std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length);
+ std::uint32_t written;
+ std::error_condition err = file().write(buffer, offset, chunk, written);
+ if (err)
+ return err;
+ offset += written;
+ buffer = reinterpret_cast<std::uint8_t const *>(buffer) + written;
+ length -= written;
+ actual += written;
+ }
+ return std::error_condition();
+ }
+};
+
+
+// helper class for holding a core_file and closing it (or not) as necessary
+
+class core_file_adapter_base : public virtual random_access
+{
+public:
+ virtual ~core_file_adapter_base()
+ {
+ if (m_close)
+ delete m_file;
+ }
+
+ virtual std::error_condition seek(std::int64_t offset, int whence) noexcept override
+ {
+ if (!m_file->seek(offset, whence))
+ return std::error_condition();
+ else
+ return std::errc::invalid_argument; // TODO: better error reporting for core_file
+ }
+
+ virtual std::error_condition tell(std::uint64_t &result) noexcept override
+ {
+ // no error reporting
+ result = m_file->tell();
+ return std::error_condition();
+ }
+
+ virtual std::error_condition length(std::uint64_t &result) noexcept override
+ {
+ // no error reporting
+ result = m_file->size();
+ return std::error_condition();
+ }
+
+protected:
+ core_file_adapter_base(core_file::ptr &&file) noexcept : m_file(file.release()), m_close(true)
+ {
+ assert(m_file);
+ }
+
+ core_file_adapter_base(core_file &file) noexcept : m_file(&file), m_close(false)
+ {
+ }
+
+ core_file &file() noexcept
+ {
+ return *m_file;
+ }
+
+private:
+ core_file *const m_file;
+ bool const m_close;
+};
+
+
+// core_file read implementation
+
+class core_file_read_adapter : public core_file_adapter_base, public virtual random_read
+{
+public:
+ core_file_read_adapter(core_file::ptr &&file) noexcept : core_file_adapter_base(std::move(file))
+ {
+ }
+
+ core_file_read_adapter(core_file &file) noexcept : core_file_adapter_base(file)
+ {
+ }
+
+ virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ // TODO: should the client have to deal with reading less than expected even if EOF isn't hit?
+ if (std::numeric_limits<std::uint32_t>::max() < length)
+ {
+ actual = 0U;
+ return std::errc::invalid_argument;
+ }
+
+ // no way to distinguish between EOF and error
+ actual = file().read(buffer, std::uint32_t(length));
+ return std::error_condition();
+ }
+
+ virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ actual = 0U;
+
+ // TODO: should the client have to deal with reading less than expected even if EOF isn't hit?
+ if (std::numeric_limits<std::uint32_t>::max() < length)
+ return std::errc::invalid_argument;
+
+ // no error reporting for tell
+ std::uint64_t const oldpos = file().tell();
+ if (file().seek(offset, SEEK_SET))
+ {
+ file().seek(oldpos, SEEK_SET);
+ return std::errc::invalid_argument; // TODO: better error reporting for core_file
+ }
+
+ // no way to distinguish between EOF and error
+ actual = file().read(buffer, std::uint32_t(length));
+
+ if (!file().seek(oldpos, SEEK_SET))
+ return std::error_condition();
+ else
+ return std::errc::invalid_argument; // TODO: better error reporting for core_file
+ }
+};
+
+
+// core_file read/write implementation
+
+class core_file_read_write_adapter : public core_file_read_adapter, public random_read_write
+{
+public:
+ using core_file_read_adapter::core_file_read_adapter;
+
+ virtual std::error_condition finalize() noexcept override
+ {
+ return std::error_condition();
+ }
+
+ virtual std::error_condition flush() noexcept override
+ {
+ return file().flush();
+ }
+
+ virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ actual = 0U;
+ while (length)
+ {
+ std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length);
+ std::uint32_t const written = file().write(buffer, chunk);
+ actual += written;
+ if (written < chunk)
+ return std::errc::io_error; // TODO: better error reporting for core_file
+ buffer = reinterpret_cast<std::uint8_t const *>(buffer) + written;
+ length -= written;
+ }
+ return std::error_condition();
+ }
+
+ virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ actual = 0U;
+
+ // no error reporting for tell
+ std::uint64_t const oldpos = file().tell();
+ if (file().seek(offset, SEEK_SET))
+ {
+ file().seek(oldpos, SEEK_SET);
+ return std::errc::invalid_argument; // TODO: better error reporting for core_file
+ }
+
+ std::error_condition err;
+ while (!err && length)
+ {
+ std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length);
+ std::uint32_t const written = file().write(buffer, chunk);
+ actual += written;
+ if (written < chunk)
+ {
+ err = std::errc::io_error; // TODO: better error reporting for core_file
+ }
+ else
+ {
+ buffer = reinterpret_cast<std::uint8_t const *>(buffer) + written;
+ length -= written;
+ }
+ }
+
+ if (!file().seek(oldpos, SEEK_SET) || err)
+ return err;
+ else
+ return std::errc::invalid_argument; // TODO: better error reporting for core_file
+ }
+};
+
+
+// core_file helper that fills space when writing past the end-of-file
+
+class core_file_read_write_filler : public random_read_fill_wrapper<core_file_read_write_adapter>
+{
+public:
+ core_file_read_write_filler(core_file::ptr &&file, std::uint8_t fill) noexcept : random_read_fill_wrapper<core_file_read_write_adapter>(std::move(file))
+ {
+ set_filler(fill);
+ }
+
+ core_file_read_write_filler(core_file &file, std::uint8_t fill) noexcept : random_read_fill_wrapper<core_file_read_write_adapter>(file)
+ {
+ set_filler(fill);
+ }
+
+ virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ // no error reporting for tell or size
+ std::uint64_t const offset = file().tell();
+ std::uint64_t endpos = file().size();
+ if (endpos < offset)
+ {
+ if (file().seek(endpos, SEEK_SET))
+ {
+ file().seek(offset, SEEK_SET);
+ actual = 0U;
+ return std::errc::invalid_argument; // TODO: better error reporting for core_file
+ }
+ std::uint8_t block[1024];
+ std::fill_n(
+ block,
+ std::min<std::common_type_t<std::size_t, std::uint64_t> >(std::size(block), offset - endpos),
+ get_filler());
+ do
+ {
+ std::uint32_t const chunk = std::min<std::common_type_t<std::size_t, std::uint64_t> >(sizeof(block), offset - endpos);
+ std::uint32_t const filled = file().write(block, chunk);
+ endpos += filled;
+ if (chunk != filled)
+ {
+ file().seek(offset, SEEK_SET);
+ actual = 0U;
+ return std::errc::io_error; // TODO: better error reporting for core_file
+ }
+ }
+ while (endpos < offset);
+ }
+
+ return core_file_read_write_adapter::write(buffer, length, actual);
+ }
+
+ virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ actual = 0U;
+
+ // no error reporting for tell
+ std::uint64_t const oldpos = file().tell();
+ if (file().seek(0, SEEK_END))
+ {
+ file().seek(oldpos, SEEK_SET);
+ return std::errc::invalid_argument; // TODO: better error reporting for core_file
+ }
+ std::uint64_t endpos = file().tell();
+
+ std::error_condition err;
+ if (endpos > offset)
+ {
+ if (file().seek(offset, SEEK_SET))
+ err = std::errc::invalid_argument; // TODO: better error reporting for core_file
+ }
+ else if (endpos < offset)
+ {
+ std::uint8_t block[1024];
+ std::fill_n(
+ block,
+ std::min<std::common_type_t<std::size_t, std::uint64_t> >(std::size(block), offset - endpos),
+ get_filler());
+ do
+ {
+ std::uint32_t const chunk = std::min<std::common_type_t<std::size_t, std::uint64_t> >(sizeof(block), offset - endpos);
+ std::uint32_t const filled = file().write(block, chunk);
+ endpos += filled;
+ if (chunk != filled)
+ err = std::errc::io_error; // TODO: better error reporting for core_file
+ }
+ while (!err && (endpos < offset));
+ }
+
+ while (!err && length)
+ {
+ std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length);
+ std::uint32_t const written = file().write(buffer, chunk);
+ actual += written;
+ if (written < chunk)
+ {
+ err = std::errc::io_error; // TODO: better error reporting for core_file
+ }
+ else
+ {
+ buffer = reinterpret_cast<std::uint8_t const *>(buffer) + written;
+ length -= written;
+ }
+ }
+
+ if (!file().seek(oldpos, SEEK_SET) || err)
+ return err;
+ else
+ return std::errc::invalid_argument; // TODO: better error reporting for core_file
+ }
+};
+
+} // anonymous namespace
+
+
+// creating RAM read adapters
+
+random_read::ptr ram_read(void const *data, std::size_t size) noexcept
+{
+ random_read::ptr result;
+ if (data || !size)
+ result.reset(new (std::nothrow) ram_read_adapter<std::uint8_t const *const, false>(data, size));
+ return result;
+}
+
+random_read::ptr ram_read(void const *data, std::size_t size, std::uint8_t filler) noexcept
+{
+ std::unique_ptr<random_read_fill_wrapper<ram_read_adapter<std::uint8_t const *const, false> > > result;
+ if (data || !size)
+ result.reset(new (std::nothrow) decltype(result)::element_type(data, size));
+ if (result)
+ result->set_filler(filler);
+ return result;
+}
+
+random_read::ptr ram_read_copy(void const *data, std::size_t size) noexcept
+{
+ random_read::ptr result;
+ void *const copy = size ? std::malloc(size) : nullptr;
+ if (copy)
+ std::memcpy(copy, data, size);
+ if (copy || !size)
+ result.reset(new (std::nothrow) ram_read_adapter<std::uint8_t *const, true>(copy, size));
+ if (!result)
+ std::free(copy);
+ return result;
+}
+
+random_read::ptr ram_read_copy(void const *data, std::size_t size, std::uint8_t filler) noexcept
+{
+ std::unique_ptr<random_read_fill_wrapper<ram_read_adapter<std::uint8_t *const, true> > > result;
+ void *const copy = size ? std::malloc(size) : nullptr;
+ if (copy)
+ std::memcpy(copy, data, size);
+ if (copy || !size)
+ result.reset(new (std::nothrow) decltype(result)::element_type(copy, size));
+ if (!result)
+ std::free(copy);
+ return result;
+}
+
+
+// creating stdio read adapters
+
+random_read::ptr stdio_read(FILE *file) noexcept
+{
+ random_read::ptr result;
+ if (file)
+ result.reset(new (std::nothrow) stdio_read_adapter(file, true));
+ return result;
+}
+
+random_read::ptr stdio_read(FILE *file, std::uint8_t filler) noexcept
+{
+ std::unique_ptr<random_read_fill_wrapper<stdio_read_adapter> > result;
+ if (file)
+ result.reset(new (std::nothrow) decltype(result)::element_type(file, true));
+ if (result)
+ result->set_filler(filler);
+ return result;
+}
+
+random_read::ptr stdio_read_noclose(FILE *file) noexcept
+{
+ random_read::ptr result;
+ if (file)
+ result.reset(new (std::nothrow) stdio_read_adapter(file, false));
+ return result;
+}
+
+random_read::ptr stdio_read_noclose(FILE *file, std::uint8_t filler) noexcept
+{
+ std::unique_ptr<random_read_fill_wrapper<stdio_read_adapter> > result;
+ if (file)
+ result.reset(new (std::nothrow) decltype(result)::element_type(file, false));
+ if (result)
+ result->set_filler(filler);
+ return result;
+}
+
+
+// creating stdio read/write adapters
+
+random_read_write::ptr stdio_read_write(FILE *file) noexcept
+{
+ random_read_write::ptr result;
+ if (file)
+ result.reset(new (std::nothrow) stdio_read_write_adapter(file, true));
+ return result;
+}
+
+random_read_write::ptr stdio_read_write(FILE *file, std::uint8_t filler) noexcept
+{
+ random_read_write::ptr result;
+ if (file)
+ result.reset(new (std::nothrow) stdio_read_write_filler(file, true, filler));
+ return result;
+}
+
+random_read_write::ptr stdio_read_write_noclose(FILE *file) noexcept
+{
+ random_read_write::ptr result;
+ if (file)
+ result.reset(new (std::nothrow) stdio_read_write_adapter(file, false));
+ return result;
+}
+
+random_read_write::ptr stdio_read_write_noclose(FILE *file, std::uint8_t filler) noexcept
+{
+ random_read_write::ptr result;
+ if (file)
+ result.reset(new (std::nothrow) stdio_read_write_filler(file, false, filler));
+ return result;
+}
+
+
+// creating osd_file read adapters
+
+random_read::ptr osd_file_read(osd_file::ptr &&file) noexcept
+{
+ random_read::ptr result;
+ if (file)
+ result.reset(new (std::nothrow) osd_file_read_adapter(std::move(file)));
+ return result;
+}
+
+random_read::ptr osd_file_read(osd_file &file) noexcept
+{
+ return random_read::ptr(new (std::nothrow) osd_file_read_adapter(file));
+}
+
+
+// creating osd_file read/write adapters
+
+random_read_write::ptr osd_file_read_write(osd_file::ptr &&file) noexcept
+{
+ random_read_write::ptr result;
+ if (file)
+ result.reset(new (std::nothrow) osd_file_read_write_adapter(std::move(file)));
+ return result;
+}
+
+random_read_write::ptr osd_file_read_write(osd_file &file) noexcept
+{
+ return random_read_write::ptr(new (std::nothrow) osd_file_read_write_adapter(file));
+}
+
+
+// creating core_file read adapters
+
+random_read::ptr core_file_read(core_file::ptr &&file) noexcept
+{
+ random_read::ptr result;
+ if (file)
+ result.reset(new (std::nothrow) core_file_read_adapter(std::move(file)));
+ return result;
+}
+
+random_read::ptr core_file_read(core_file::ptr &&file, std::uint8_t filler) noexcept
+{
+ std::unique_ptr<random_read_fill_wrapper<core_file_read_adapter> > result;
+ if (file)
+ result.reset(new (std::nothrow) decltype(result)::element_type(std::move(file)));
+ if (result)
+ result->set_filler(filler);
+ return result;
+}
+
+random_read::ptr core_file_read(core_file &file) noexcept
+{
+ return random_read::ptr(new (std::nothrow) core_file_read_adapter(file));
+}
+
+random_read::ptr core_file_read(core_file &file, std::uint8_t filler) noexcept
+{
+ std::unique_ptr<random_read_fill_wrapper<core_file_read_adapter> > result;
+ result.reset(new (std::nothrow) decltype(result)::element_type(file));
+ if (result)
+ result->set_filler(filler);
+ return result;
+}
+
+
+// creating core_file read/write adapters
+
+random_read_write::ptr core_file_read_write(core_file::ptr &&file) noexcept
+{
+ random_read_write::ptr result;
+ if (file)
+ result.reset(new (std::nothrow) core_file_read_write_adapter(std::move(file)));
+ return result;
+}
+
+random_read_write::ptr core_file_read_write(core_file::ptr &&file, std::uint8_t filler) noexcept
+{
+ random_read_write::ptr result;
+ if (file)
+ result.reset(new (std::nothrow) core_file_read_write_filler(std::move(file), filler));
+ return result;
+}
+
+random_read_write::ptr core_file_read_write(core_file &file) noexcept
+{
+ return random_read_write::ptr(new (std::nothrow) core_file_read_write_adapter(file));
+}
+
+random_read_write::ptr core_file_read_write(core_file &file, std::uint8_t filler) noexcept
+{
+ return random_read_write::ptr(new (std::nothrow) core_file_read_write_filler(file, filler));
+}
+
+} // namespace util
diff --git a/src/lib/util/ioprocs.h b/src/lib/util/ioprocs.h
new file mode 100644
index 00000000000..78c06e71318
--- /dev/null
+++ b/src/lib/util/ioprocs.h
@@ -0,0 +1,130 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/***************************************************************************
+
+ ioprocs.h
+
+ I/O interfaces
+
+***************************************************************************/
+#ifndef MAME_LIB_UTIL_IOPROCS_H
+#define MAME_LIB_UTIL_IOPROCS_H
+
+#pragma once
+
+#include "utilfwd.h"
+
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <memory>
+#include <system_error>
+
+
+// FIXME: make a proper place for OSD forward declarations
+class osd_file;
+
+
+namespace util {
+
+class read_stream
+{
+public:
+ using ptr = std::unique_ptr<read_stream>;
+
+ virtual ~read_stream() = default;
+
+ virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept = 0;
+};
+
+
+class write_stream
+{
+public:
+ using ptr = std::unique_ptr<write_stream>;
+
+ virtual ~write_stream() = default;
+
+ virtual std::error_condition finalize() noexcept = 0;
+ virtual std::error_condition flush() noexcept = 0;
+ virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept = 0;
+};
+
+
+class read_write_stream : public virtual read_stream, public virtual write_stream
+{
+public:
+ using ptr = std::unique_ptr<read_write_stream>;
+};
+
+
+class random_access
+{
+public:
+ virtual ~random_access() = default;
+
+ virtual std::error_condition seek(std::int64_t offset, int whence) noexcept = 0;
+ virtual std::error_condition tell(std::uint64_t &result) noexcept = 0;
+ virtual std::error_condition length(std::uint64_t &result) noexcept = 0;
+};
+
+
+class random_read : public virtual read_stream, public virtual random_access
+{
+public:
+ using ptr = std::unique_ptr<random_read>;
+
+ virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept = 0;
+};
+
+
+class random_write : public virtual write_stream, public virtual random_access
+{
+public:
+ using ptr = std::unique_ptr<random_write>;
+
+ virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept = 0;
+};
+
+
+class random_read_write : public read_write_stream, public virtual random_read, public virtual random_write
+{
+public:
+ using ptr = std::unique_ptr<random_read_write>;
+};
+
+
+random_read::ptr ram_read(void const *data, std::size_t size) noexcept;
+random_read::ptr ram_read(void const *data, std::size_t size, std::uint8_t filler) noexcept;
+random_read::ptr ram_read_copy(void const *data, std::size_t size) noexcept;
+random_read::ptr ram_read_copy(void const *data, std::size_t size, std::uint8_t filler) noexcept;
+
+random_read::ptr stdio_read(FILE *file) noexcept;
+random_read::ptr stdio_read(FILE *file, std::uint8_t filler) noexcept;
+random_read::ptr stdio_read_noclose(FILE *file) noexcept;
+random_read::ptr stdio_read_noclose(FILE *file, std::uint8_t filler) noexcept;
+
+random_read_write::ptr stdio_read_write(FILE *file) noexcept;
+random_read_write::ptr stdio_read_write(FILE *file, std::uint8_t filler) noexcept;
+random_read_write::ptr stdio_read_write_noclose(FILE *file) noexcept;
+random_read_write::ptr stdio_read_write_noclose(FILE *file, std::uint8_t filler) noexcept;
+
+random_read::ptr osd_file_read(std::unique_ptr<osd_file> &&file) noexcept;
+random_read::ptr osd_file_read(osd_file &file) noexcept;
+
+random_read_write::ptr osd_file_read_write(std::unique_ptr<osd_file> &&file) noexcept;
+random_read_write::ptr osd_file_read_write(osd_file &file) noexcept;
+
+random_read::ptr core_file_read(std::unique_ptr<core_file> &&file) noexcept;
+random_read::ptr core_file_read(std::unique_ptr<core_file> &&file, std::uint8_t filler) noexcept;
+random_read::ptr core_file_read(core_file &file) noexcept;
+random_read::ptr core_file_read(core_file &file, std::uint8_t filler) noexcept;
+
+random_read_write::ptr core_file_read_write(std::unique_ptr<core_file> &&file) noexcept;
+random_read_write::ptr core_file_read_write(std::unique_ptr<core_file> &&file, std::uint8_t filler) noexcept;
+random_read_write::ptr core_file_read_write(core_file &file) noexcept;
+random_read_write::ptr core_file_read_write(core_file &file, std::uint8_t filler) noexcept;
+
+} // namespace util
+
+#endif // MAME_LIB_UTIL_IOPROCS_H
diff --git a/src/lib/util/ioprocsfill.h b/src/lib/util/ioprocsfill.h
new file mode 100644
index 00000000000..e49b10687f0
--- /dev/null
+++ b/src/lib/util/ioprocsfill.h
@@ -0,0 +1,163 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/***************************************************************************
+
+ ioprocsfill.h
+
+ Wrappers that automatically fill extra space
+
+***************************************************************************/
+#ifndef MAME_LIB_UTIL_IOPROCSFILL_H
+#define MAME_LIB_UTIL_IOPROCSFILL_H
+
+#pragma once
+
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <system_error>
+
+
+namespace util {
+
+template <std::uint8_t DefaultFiller>
+class fill_wrapper_base
+{
+public:
+ std::uint8_t get_filler() const noexcept
+ {
+ return m_filler;
+ }
+
+ void set_filler(std::uint8_t filler) noexcept
+ {
+ m_filler = filler;
+ }
+
+private:
+ std::uint8_t m_filler = DefaultFiller;
+};
+
+
+template <typename Base, std::uint8_t DefaultFiller = 0U>
+class read_stream_fill_wrapper : public Base, public virtual fill_wrapper_base<DefaultFiller>
+{
+public:
+ using Base::Base;
+
+ virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ std::error_condition err = Base::read(buffer, length, actual);
+ assert(length >= actual);
+ std::fill(
+ reinterpret_cast<std::uint8_t *>(buffer) + actual,
+ reinterpret_cast<std::uint8_t *>(buffer) + length,
+ fill_wrapper_base<DefaultFiller>::get_filler());
+ return err;
+ }
+};
+
+
+template <typename Base, std::uint8_t DefaultFiller = 0U>
+class random_read_fill_wrapper : public read_stream_fill_wrapper<Base, DefaultFiller>
+{
+public:
+ using read_stream_fill_wrapper<Base, DefaultFiller>::read_stream_fill_wrapper;
+
+ virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ std::error_condition err = Base::read_at(offset, buffer, length, actual);
+ assert(length >= actual);
+ std::fill(
+ reinterpret_cast<std::uint8_t *>(buffer) + actual,
+ reinterpret_cast<std::uint8_t *>(buffer) + length,
+ fill_wrapper_base<DefaultFiller>::get_filler());
+ return err;
+ }
+};
+
+
+template <typename Base, std::uint8_t DefaultFiller = 0U, std::size_t FillBlock = 1024U>
+class random_write_fill_wrapper : public Base, public virtual fill_wrapper_base<DefaultFiller>
+{
+public:
+ using Base::Base;
+
+ virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ std::error_condition err;
+ actual = 0U;
+
+ std::uint64_t offset;
+ std::uint64_t current;
+ err = Base::tell(offset);
+ if (err)
+ return err;
+ err = Base::length(current);
+ if (err)
+ return err;
+
+ if (current < offset)
+ {
+ std::uint64_t unfilled = offset - current;
+ std::uint8_t fill_buffer[FillBlock];
+ std::fill(
+ fill_buffer,
+ fill_buffer + std::min<std::common_type_t<std::size_t, std::uint64_t> >(FillBlock, unfilled),
+ fill_wrapper_base<DefaultFiller>::get_filler());
+ do
+ {
+ std::size_t const chunk = std::min<std::common_type_t<std::size_t, std::uint64_t> >(FillBlock, unfilled);
+ err = Base::write_at(current, fill_buffer, chunk, actual);
+ if (err)
+ {
+ actual = 0U;
+ return err;
+ }
+ current += chunk;
+ unfilled -= chunk;
+ }
+ while (unfilled);
+ }
+
+ return Base::write(buffer, length, actual);
+ }
+
+ virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ std::error_condition err;
+ std::uint64_t current;
+ err = Base::length(current);
+ if (!err && (current < offset))
+ {
+ std::uint64_t unfilled = offset - current;
+ std::uint8_t fill_buffer[FillBlock];
+ std::fill(
+ fill_buffer,
+ fill_buffer + std::min<std::common_type_t<std::size_t, std::uint64_t> >(FillBlock, unfilled),
+ fill_wrapper_base<DefaultFiller>::get_filler());
+ do
+ {
+ std::size_t const chunk = std::min<std::common_type_t<std::size_t, std::uint64_t> >(FillBlock, unfilled);
+ err = Base::write_at(current, fill_buffer, chunk, actual);
+ current += chunk;
+ unfilled -= chunk;
+ }
+ while (unfilled && !err);
+ }
+ if (err)
+ {
+ actual = 0U;
+ return err;
+ }
+ return Base::write_at(offset, buffer, length, actual);
+ }
+};
+
+
+template <typename Base, std::uint8_t DefaultFiller = 0U, std::size_t FillBlock = 1024U>
+using random_read_write_fill_wrapper = random_write_fill_wrapper<random_read_fill_wrapper<Base, DefaultFiller>, DefaultFiller, FillBlock>;
+
+} // namespace util
+
+#endif // MAME_LIB_UTIL_IOPROCSFILL_H
diff --git a/src/lib/util/ioprocsfilter.cpp b/src/lib/util/ioprocsfilter.cpp
new file mode 100644
index 00000000000..da67b8c41f2
--- /dev/null
+++ b/src/lib/util/ioprocsfilter.cpp
@@ -0,0 +1,598 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/***************************************************************************
+
+ ioprocs.h
+
+ I/O filters
+
+***************************************************************************/
+
+#include "ioprocsfilter.h"
+
+#include "ioprocs.h"
+
+#include <zlib.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cerrno>
+#include <cstdint>
+#include <limits>
+#include <system_error>
+#include <type_traits>
+#include <utility>
+
+
+namespace util {
+
+namespace {
+
+// helper class for holding zlib data
+
+class zlib_data
+{
+protected:
+ zlib_data(std::size_t buffer_size) noexcept :
+ m_buffer_size(std::min<std::common_type_t<uInt, std::size_t> >(std::numeric_limits<uInt>::max(), buffer_size))
+ {
+ assert(buffer_size);
+ }
+
+ z_stream &get_z_stream() noexcept { return m_z_stream; }
+ z_stream const &get_z_stream() const noexcept { return m_z_stream; }
+ Bytef *get_buffer() noexcept { return m_buffer.get(); }
+ Bytef const *get_buffer() const noexcept { return m_buffer.get(); }
+ std::size_t get_buffer_size() const noexcept { return m_buffer_size; }
+
+ bool input_empty() const noexcept { return !m_z_stream.avail_in; }
+ bool output_available() const noexcept { return bool(m_z_stream.avail_out); }
+
+ void initialize_z_stream() noexcept
+ {
+ m_z_stream.zalloc = Z_NULL;
+ m_z_stream.zfree = Z_NULL;
+ m_z_stream.opaque = Z_NULL;
+ }
+
+ std::error_condition allocate_buffer() noexcept
+ {
+ if (!m_buffer)
+ m_buffer.reset(new (std::nothrow) Bytef [m_buffer_size]);
+ return m_buffer ? std::error_condition() : std::errc::not_enough_memory;
+ }
+
+ void release_buffer() noexcept
+ {
+ m_buffer.reset();
+ }
+
+ static std::error_condition convert_z_error(int err) noexcept
+ {
+ switch (err)
+ {
+ case Z_OK:
+ case Z_STREAM_END:
+ return std::error_condition();
+ case Z_NEED_DICT:
+ return std::errc::invalid_argument;
+ case Z_ERRNO:
+ return std::error_condition(errno, std::generic_category());
+ case Z_STREAM_ERROR:
+ return std::errc::invalid_argument;
+ case Z_DATA_ERROR:
+ return std::errc::invalid_argument; // TODO: revisit this error code
+ case Z_MEM_ERROR:
+ return std::errc::not_enough_memory;
+ case Z_BUF_ERROR:
+ return std::errc::operation_would_block; // TODO: revisit this error code (should be handled internally)
+ case Z_VERSION_ERROR:
+ return std::errc::invalid_argument; // TODO: revisit this error code (library ABI mismatch)
+ default:
+ return std::errc::io_error; // TODO: better default error code
+ }
+ }
+
+private:
+ z_stream m_z_stream;
+ std::unique_ptr<Bytef []> m_buffer;
+ std::size_t const m_buffer_size;
+};
+
+
+// helper class for decompressing deflated data
+
+class inflate_data : private zlib_data
+{
+protected:
+ using zlib_data::zlib_data;
+
+ ~inflate_data()
+ {
+ if (m_inflate_initialized)
+ inflateEnd(&get_z_stream());
+ }
+
+ using zlib_data::input_empty;
+
+ bool stream_initialized() const noexcept
+ {
+ return m_inflate_initialized;
+ }
+
+ std::error_condition initialize_z_stream() noexcept
+ {
+ if (m_inflate_initialized)
+ return std::errc::invalid_argument;
+ std::error_condition err = allocate_buffer();
+ if (err)
+ return err;
+ zlib_data::initialize_z_stream();
+ int const zerr = inflateInit(&get_z_stream());
+ if (Z_OK == zerr)
+ m_inflate_initialized = true;
+ return convert_z_error(zerr);
+ }
+
+ std::error_condition close_z_stream() noexcept
+ {
+ if (!m_inflate_initialized)
+ return std::errc::invalid_argument;
+ int const zerr = inflateEnd(&get_z_stream());
+ m_inflate_initialized = false;
+ return convert_z_error(zerr);
+ }
+
+ std::error_condition decompress_some(bool &stream_end) noexcept
+ {
+ assert(m_inflate_initialized);
+ int const zerr = inflate(&get_z_stream(), Z_SYNC_FLUSH);
+ if (!get_z_stream().avail_in)
+ reset_input();
+ stream_end = Z_STREAM_END == zerr;
+ return convert_z_error(zerr);
+ }
+
+ std::size_t input_available() const noexcept
+ {
+ return std::size_t(get_z_stream().avail_in);
+ }
+
+ void reset_input() noexcept
+ {
+ get_z_stream().next_in = get_buffer();
+ get_z_stream().avail_in = 0U;
+ }
+
+ std::pair<void *, std::size_t> get_unfilled_input() noexcept
+ {
+ assert(get_buffer());
+ Bytef *const base = get_z_stream().next_in + get_z_stream().avail_in;
+ return std::make_pair(base, get_buffer() + get_buffer_size() - base);
+ }
+
+ void add_input(std::size_t length) noexcept
+ {
+ assert(get_buffer());
+ get_z_stream().avail_in += length;
+ assert((get_buffer() + get_buffer_size()) >= (get_z_stream().next_in + get_z_stream().avail_in));
+ }
+
+ std::size_t output_produced() const noexcept
+ {
+ return m_output_max - get_z_stream().avail_out;
+ }
+
+ void set_output(void *buffer, std::size_t length) noexcept
+ {
+ m_output_max = std::min<std::common_type_t<uInt, std::size_t> >(std::numeric_limits<uInt>::max(), length);
+ get_z_stream().next_out = reinterpret_cast<Bytef *>(buffer);
+ get_z_stream().avail_out = uInt(m_output_max);
+ }
+
+private:
+ std::error_condition allocate_buffer() noexcept
+ {
+ std::error_condition err;
+ if (!get_buffer())
+ {
+ err = zlib_data::allocate_buffer();
+ reset_input();
+ }
+ return err;
+ }
+
+ bool m_inflate_initialized = false;
+ std::size_t m_output_max = 0U;
+};
+
+
+// helper class for deflating data
+
+class deflate_data : private zlib_data
+{
+protected:
+ deflate_data(int level, std::size_t buffer_size) noexcept : zlib_data(buffer_size), m_level(level)
+ {
+ }
+
+ ~deflate_data()
+ {
+ if (m_deflate_initialized)
+ deflateEnd(&get_z_stream());
+ }
+
+ using zlib_data::input_empty;
+ using zlib_data::output_available;
+
+ bool stream_initialized() const noexcept
+ {
+ return m_deflate_initialized;
+ }
+
+ bool compression_finished() const noexcept
+ {
+ return m_compression_finished;
+ }
+
+ std::error_condition initialize_z_stream() noexcept
+ {
+ if (m_deflate_initialized)
+ return std::errc::invalid_argument;
+ std::error_condition err = allocate_buffer();
+ if (err)
+ return err;
+ zlib_data::initialize_z_stream();
+ int const zerr = deflateInit(&get_z_stream(), m_level);
+ reset_output();
+ if (Z_OK == zerr)
+ m_deflate_initialized = true;
+ return convert_z_error(zerr);
+ }
+
+ std::error_condition close_z_stream() noexcept
+ {
+ if (!m_deflate_initialized)
+ return std::errc::invalid_argument;
+ m_deflate_initialized = m_compression_finished = false;
+ return convert_z_error(deflateEnd(&get_z_stream()));
+ }
+
+ std::error_condition reset_z_stream() noexcept
+ {
+ if (!m_deflate_initialized)
+ return std::errc::invalid_argument;
+ assert(get_buffer());
+ reset_output();
+ m_compression_finished = false;
+ return convert_z_error(deflateReset(&get_z_stream()));
+ }
+
+ std::error_condition compress_some() noexcept
+ {
+ assert(m_deflate_initialized);
+ return convert_z_error(deflate(&get_z_stream(), Z_NO_FLUSH));
+ }
+
+ std::error_condition finish_compression() noexcept
+ {
+ assert(m_deflate_initialized);
+ int const zerr = deflate(&get_z_stream(), Z_FINISH);
+ if (Z_STREAM_END == zerr)
+ m_compression_finished = true;
+ return convert_z_error(zerr);
+ }
+
+ std::size_t input_used() const noexcept
+ {
+ return m_input_max - get_z_stream().avail_in;
+ }
+
+ void set_input(void const *data, std::size_t length) noexcept
+ {
+ m_input_max = std::min<std::common_type_t<uInt, std::size_t> >(std::numeric_limits<uInt>::max(), length);
+ get_z_stream().next_in = const_cast<Bytef z_const *>(reinterpret_cast<Bytef const *>(data));
+ get_z_stream().avail_in = uInt(m_input_max);
+ }
+
+ std::pair<void const *, std::size_t> get_output() const noexcept
+ {
+ assert(get_buffer());
+ return std::make_pair(
+ &get_buffer()[m_output_used],
+ get_buffer_size() - get_z_stream().avail_out - m_output_used);
+ }
+
+ void consume_output(std::size_t length) noexcept
+ {
+ m_output_used += length;
+ assert(m_output_used <= (get_buffer_size() - get_z_stream().avail_out));
+ if (m_output_used == (get_buffer_size() - get_z_stream().avail_out))
+ reset_output();
+ }
+
+private:
+ void reset_output() noexcept
+ {
+ assert(get_buffer());
+ m_output_used = 0U;
+ get_z_stream().next_out = get_buffer();
+ get_z_stream().avail_out = uInt(get_buffer_size());
+ }
+
+ int const m_level;
+ bool m_deflate_initialized = false;
+ bool m_compression_finished = false;
+ std::size_t m_output_used = 0U;
+ std::size_t m_input_max = 0U;
+};
+
+
+// helper for holding an object and deleting it (or not) as necessary
+
+template <typename T>
+class filter_base
+{
+protected:
+ filter_base(std::unique_ptr<T> &&object) noexcept : m_object(object.release()), m_owned(true)
+ {
+ assert(m_object);
+ }
+
+ filter_base(T &object) noexcept : m_object(&object), m_owned(false)
+ {
+ }
+
+ ~filter_base()
+ {
+ if (m_owned)
+ delete m_object;
+ }
+
+ T &object() noexcept
+ {
+ return *m_object;
+ }
+
+private:
+ T *const m_object;
+ bool const m_owned;
+};
+
+
+// filter for decompressing deflated data
+
+template <typename Stream>
+class zlib_read_filter : public read_stream, protected filter_base<Stream>, protected inflate_data
+{
+public:
+ zlib_read_filter(std::unique_ptr<Stream> &&stream, std::size_t read_chunk) noexcept :
+ filter_base<Stream>(std::move(stream)),
+ inflate_data(read_chunk)
+ {
+ }
+
+ zlib_read_filter(Stream &stream, std::size_t read_chunk) noexcept :
+ filter_base<Stream>(stream),
+ inflate_data(read_chunk)
+ {
+ }
+
+ virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ std::error_condition err;
+ actual = 0U;
+
+ if (!stream_initialized())
+ err = initialize_z_stream();
+
+ if (!err && (length > actual))
+ {
+ bool short_input = false;
+ do
+ {
+ if (input_empty())
+ {
+ auto const space = get_unfilled_input();
+ std::size_t filled;
+ err = this->object().read(space.first, space.second, filled);
+ add_input(filled);
+ short_input = space.second > filled;
+ }
+
+ if (!err && !input_empty())
+ {
+ set_output(reinterpret_cast<std::uint8_t *>(buffer) + actual, length - actual);
+ bool stream_end;
+ err = decompress_some(stream_end);
+ actual += output_produced();
+
+ if (stream_end)
+ {
+ assert(!err);
+ if constexpr (std::is_base_of_v<random_read, Stream>)
+ {
+ if (!input_empty())
+ {
+ std::int64_t const overshoot = std::uint64_t(input_available());
+ reset_input();
+ return this->object().seek(-overshoot, SEEK_CUR);
+ }
+ }
+ else
+ {
+ return std::error_condition();
+ }
+ }
+ }
+ }
+ while (!err && (length > actual) && !short_input);
+ }
+
+ return err;
+ }
+};
+
+
+// filter for deflating data
+
+class zlib_write_filter : public write_stream, protected filter_base<write_stream>, protected deflate_data
+{
+public:
+ zlib_write_filter(write_stream::ptr &&stream, int level, std::size_t buffer_size) noexcept :
+ filter_base<write_stream>(std::move(stream)),
+ deflate_data(level, buffer_size)
+ {
+ }
+
+ zlib_write_filter(write_stream &stream, int level, std::size_t buffer_size) noexcept :
+ filter_base<write_stream>(stream),
+ deflate_data(level, buffer_size)
+ {
+ }
+
+ ~zlib_write_filter()
+ {
+ finalize();
+ }
+
+ virtual std::error_condition finalize() noexcept override
+ {
+ if (!stream_initialized())
+ return std::error_condition();
+
+ do
+ {
+ if (!compression_finished() && output_available())
+ {
+ std::error_condition err = finish_compression();
+ if (err)
+ return err;
+ }
+
+ while ((compression_finished() && get_output().second) || !output_available())
+ {
+ std::error_condition err = write_some();
+ if (err)
+ return err;
+ }
+ }
+ while (!compression_finished());
+
+ return close_z_stream();
+ }
+
+ virtual std::error_condition flush() noexcept override
+ {
+ if (stream_initialized())
+ {
+ auto const output = get_output();
+ if (output.second)
+ {
+ std::size_t written;
+ std::error_condition err = object().write(output.first, output.second, written);
+ consume_output(written);
+ if (err)
+ {
+ object().flush();
+ return err;
+ }
+ }
+ }
+ return object().flush();
+ }
+
+ virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ std::error_condition err;
+ actual = 0U;
+
+ if (!stream_initialized())
+ {
+ err = initialize_z_stream();
+ }
+ else if (compression_finished())
+ {
+ while (!err && get_output().second)
+ err = write_some();
+ if (!err)
+ err = reset_z_stream();
+ }
+
+ while (!err && (length > actual))
+ {
+ set_input(reinterpret_cast<std::uint8_t const *>(buffer) + actual, length - actual);
+ do
+ {
+ if (output_available())
+ err = compress_some();
+
+ while (!err && !output_available())
+ err = write_some();
+ }
+ while (!err && !input_empty());
+ actual += input_used();
+ }
+
+ return err;
+ }
+
+private:
+ std::error_condition write_some() noexcept
+ {
+ auto const output = get_output();
+ std::size_t written;
+ std::error_condition err = object().write(output.first, output.second, written);
+ consume_output(written);
+ return err;
+ }
+};
+
+} // anonymous namespace
+
+
+// creating decompressing filters
+
+read_stream::ptr zlib_read(read_stream::ptr &&stream, std::size_t read_chunk) noexcept
+{
+ read_stream::ptr result;
+ if (stream)
+ result.reset(new (std::nothrow) zlib_read_filter<read_stream>(std::move(stream), read_chunk));
+ return result;
+}
+
+read_stream::ptr zlib_read(random_read::ptr &&stream, std::size_t read_chunk) noexcept
+{
+ read_stream::ptr result;
+ if (stream)
+ result.reset(new (std::nothrow) zlib_read_filter<random_read>(std::move(stream), read_chunk));
+ return result;
+}
+
+read_stream::ptr zlib_read(read_stream &stream, std::size_t read_chunk) noexcept
+{
+ return read_stream::ptr(new (std::nothrow) zlib_read_filter<read_stream>(stream, read_chunk));
+}
+
+read_stream::ptr zlib_read(random_read &stream, std::size_t read_chunk) noexcept
+{
+ return read_stream::ptr(new (std::nothrow) zlib_read_filter<random_read>(stream, read_chunk));
+}
+
+
+// creating compressing filters
+
+write_stream::ptr zlib_write(write_stream::ptr &&stream, int level, std::size_t buffer_size) noexcept
+{
+ write_stream::ptr result;
+ if (stream)
+ result.reset(new (std::nothrow) zlib_write_filter(std::move(stream), level, buffer_size));
+ return result;
+}
+
+write_stream::ptr zlib_write(write_stream &stream, int level, std::size_t buffer_size) noexcept
+{
+ return write_stream::ptr(new (std::nothrow) zlib_write_filter(stream, level, buffer_size));
+}
+
+} // namespace util
diff --git a/src/lib/util/ioprocsfilter.h b/src/lib/util/ioprocsfilter.h
new file mode 100644
index 00000000000..a146dd737ce
--- /dev/null
+++ b/src/lib/util/ioprocsfilter.h
@@ -0,0 +1,31 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/***************************************************************************
+
+ ioprocs.h
+
+ I/O filters
+
+***************************************************************************/
+#ifndef MAME_LIB_UTIL_IOPROCSFILTER_H
+#define MAME_LIB_UTIL_IOPROCSFILTER_H
+
+#include "utilfwd.h"
+
+#include <cstdlib>
+#include <memory>
+
+
+namespace util {
+
+std::unique_ptr<read_stream> zlib_read(std::unique_ptr<read_stream> &&stream, std::size_t read_chunk) noexcept;
+std::unique_ptr<read_stream> zlib_read(std::unique_ptr<random_read> &&stream, std::size_t read_chunk) noexcept;
+std::unique_ptr<read_stream> zlib_read(read_stream &stream, std::size_t read_chunk) noexcept;
+std::unique_ptr<read_stream> zlib_read(random_read &stream, std::size_t read_chunk) noexcept;
+
+std::unique_ptr<write_stream> zlib_write(std::unique_ptr<write_stream> &&stream, int level, std::size_t buffer_size) noexcept;
+std::unique_ptr<write_stream> zlib_write(write_stream &stream, int level, std::size_t buffer_size) noexcept;
+
+} // namespace util
+
+#endif // MAME_LIB_UTIL_IOPROCSFILTER_H
diff --git a/src/lib/util/ioprocsvec.h b/src/lib/util/ioprocsvec.h
new file mode 100644
index 00000000000..27dda095ad3
--- /dev/null
+++ b/src/lib/util/ioprocsvec.h
@@ -0,0 +1,211 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/***************************************************************************
+
+ ioprocsvec.h
+
+ Helper for using a vector as an in-memory file
+
+***************************************************************************/
+#ifndef MAME_LIB_UTIL_IOPROCSVEC_H
+#define MAME_LIB_UTIL_IOPROCSVEC_H
+
+#include "ioprocs.h"
+
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <limits>
+#include <system_error>
+#include <type_traits>
+#include <vector>
+
+
+namespace util {
+
+template <typename T = std::uint8_t>
+class vector_read_write_adapter : public random_read_write
+{
+public:
+ vector_read_write_adapter(std::vector<T> &storage) noexcept : m_storage(storage)
+ {
+ check_resized();
+ }
+
+ virtual std::error_condition seek(std::int64_t offset, int whence) noexcept override
+ {
+ switch (whence)
+ {
+ case SEEK_SET:
+ if (0 > offset)
+ return std::errc::invalid_argument;
+ m_pointer = std::uint64_t(offset);
+ return std::error_condition();
+
+ case SEEK_CUR:
+ if (0 > offset)
+ {
+ if (std::uint64_t(-offset) > m_pointer)
+ return std::errc::invalid_argument;
+ }
+ else if ((std::numeric_limits<std::uint64_t>::max() - offset) < m_pointer)
+ {
+ return std::errc::invalid_argument;
+ }
+ m_pointer += offset;
+ return std::error_condition();
+
+ case SEEK_END:
+ check_resized();
+ if (0 > offset)
+ {
+ if (std::uint64_t(-offset) > m_size)
+ return std::errc::invalid_argument;
+ }
+ else if ((std::numeric_limits<std::uint64_t>::max() - offset) < m_size)
+ {
+ return std::errc::invalid_argument;
+ }
+ m_pointer = std::uint64_t(m_size) + offset;
+ return std::error_condition();
+
+ default:
+ return std::errc::invalid_argument;
+ }
+ }
+
+ virtual std::error_condition tell(std::uint64_t &result) noexcept override
+ {
+ result = m_pointer;
+ return std::error_condition();
+ }
+
+ virtual std::error_condition length(std::uint64_t &result) noexcept override
+ {
+ check_resized();
+ if (std::numeric_limits<uint64_t>::max() < m_size)
+ return std::errc::file_too_large;
+
+ result = m_size;
+ return std::error_condition();
+ }
+
+ virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ do_read(m_pointer, buffer, length, actual);
+ m_pointer += actual;
+ return std::error_condition();
+ }
+
+ virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ do_read(offset, buffer, length, actual);
+ return std::error_condition();
+ }
+
+ virtual std::error_condition finalize() noexcept override
+ {
+ return std::error_condition();
+ }
+
+ virtual std::error_condition flush() noexcept override
+ {
+ return std::error_condition();
+ }
+
+ virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ std::error_condition result = do_write(m_pointer, buffer, length, actual);
+ m_pointer += actual;
+ return result;
+ }
+
+ virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ return do_write(offset, buffer, length, actual);
+ }
+
+private:
+ using elements_type = typename std::vector<T>::size_type;
+ using common_size_type = std::common_type_t<std::uint64_t, std::size_t>;
+
+ void check_resized() noexcept
+ {
+ if (m_storage.size() != m_elements)
+ {
+ m_elements = m_storage.size();
+ m_size = m_elements * sizeof(T);
+ }
+ }
+
+ void do_read(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept
+ {
+ check_resized();
+ if ((offset < m_size) && length)
+ {
+ actual = std::min(std::size_t(m_size - offset), length);
+ std::memmove(buffer, reinterpret_cast<std::uint8_t *>(m_storage.data()) + offset, actual);
+ }
+ else
+ {
+ actual = 0U;
+ }
+ }
+
+ std::error_condition do_write(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept
+ {
+ check_resized();
+ std::size_t allocated = m_elements * sizeof(T);
+ std::uint64_t const target = ((std::numeric_limits<std::uint64_t>::max() - offset) >= length)
+ ? (offset + length)
+ : std::numeric_limits<std::uint64_t>::max();
+
+ std::error_condition result;
+ if (target > allocated)
+ {
+ elements_type const required = std::min<std::common_type_t<elements_type, std::uint64_t> >(
+ std::numeric_limits<elements_type>::max(),
+ (target + sizeof(T) - 1) / sizeof(T)); // technically can overflow but unlikely
+ try { m_storage.resize(required); } // unpredictable if constructing/assigning T can throw
+ catch (...) { result = std::errc::not_enough_memory; }
+ m_elements = m_storage.size();
+ allocated = m_elements * sizeof(T);
+ assert(allocated >= m_size);
+
+ if (offset > m_size)
+ {
+ std::size_t const new_size = std::size_t(std::min<common_size_type>(allocated, offset));
+ std::memset(
+ reinterpret_cast<std::uint8_t *>(m_storage.data()) + m_size,
+ 0x00, // POSIX says unwritten areas of files should read as zero
+ new_size - m_size);
+ m_size = new_size;
+ }
+ }
+
+ std::size_t const limit = std::min<common_size_type>(target, allocated);
+ if (limit > offset)
+ {
+ actual = std::size_t(limit - offset);
+ std::memmove(reinterpret_cast<std::uint8_t *>(m_storage.data()) + offset, buffer, actual);
+ m_size = limit;
+ }
+ else
+ {
+ actual = 0U;
+ }
+ if (!result && (actual < length))
+ result = std::errc::no_space_on_device;
+
+ return result;
+ }
+
+ std::vector<T> &m_storage;
+ std::uint64_t m_pointer = 0U;
+ elements_type m_elements = 0U;
+ std::size_t m_size = 0U;
+};
+
+} // namespace util
+
+#endif // MAME_LIB_UTIL_IOPROCSVEC_H
diff --git a/src/lib/util/path.cpp b/src/lib/util/path.cpp
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/lib/util/path.cpp
diff --git a/src/lib/util/path.h b/src/lib/util/path.h
new file mode 100644
index 00000000000..1291d7b17d3
--- /dev/null
+++ b/src/lib/util/path.h
@@ -0,0 +1,65 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/***************************************************************************
+
+ path.h
+
+ Filesystem path utilties
+
+***************************************************************************/
+#ifndef MAME_LIB_UTIL_PATH_H
+#define MAME_LIB_UTIL_PATH_H
+
+#include "osdfile.h" // for PATH_SEPARATOR
+
+#include <string>
+#include <utility>
+
+
+namespace util {
+
+/***************************************************************************
+ INLINE FUNCTIONS
+***************************************************************************/
+
+// is a given character a directory separator?
+
+constexpr bool is_directory_separator(char c)
+{
+#if defined(WIN32)
+ return ('\\' == c) || ('/' == c) || (':' == c);
+#else
+ return '/' == c;
+#endif
+}
+
+
+// append to a path
+
+template <typename T, typename... U>
+inline std::string &path_append(std::string &path, T &&next, U &&... more)
+{
+ if (!path.empty() && !is_directory_separator(path.back()))
+ path.append(PATH_SEPARATOR);
+ path.append(std::forward<T>(next));
+ if constexpr (sizeof...(U))
+ return path_append(std::forward<U>(more)...);
+ else
+ return path;
+}
+
+
+// concatenate paths
+
+template <typename T, typename... U>
+inline std::string path_concat(T &&first, U &&... more)
+{
+ std::string result(std::forward<T>(first));
+ if constexpr (sizeof...(U))
+ path_append(result, std::forward<U>(more)...);
+ return result;
+}
+
+} // namespace util
+
+#endif // MAME_LIB_UTIL_PATH_H
diff --git a/src/lib/util/strformat.h b/src/lib/util/strformat.h
index b8c9b4f1a99..a3ba1d11261 100644
--- a/src/lib/util/strformat.h
+++ b/src/lib/util/strformat.h
@@ -578,16 +578,16 @@ template <typename Stream, typename T>
class format_output
{
private:
- template <typename U> struct string_semantics
- { static constexpr bool value = false; };
- template <typename CharT, typename Traits, typename Allocator> struct string_semantics<std::basic_string<CharT, Traits, Allocator> >
- { static constexpr bool value = true; };
- template <typename CharT, typename Traits> struct string_semantics<std::basic_string_view<CharT, Traits> >
- { static constexpr bool value = true; };
- template <typename U> struct signed_integer_semantics
- { static constexpr bool value = std::is_integral_v<U>&& std::is_signed_v<U>; };
- template <typename U> struct unsigned_integer_semantics
- { static constexpr bool value = std::is_integral_v<U>&& !std::is_signed_v<U>; };
+ template <typename U>
+ struct string_semantics : public std::false_type { };
+ template <typename CharT, typename Traits, typename Allocator>
+ struct string_semantics<std::basic_string<CharT, Traits, Allocator> > : public std::true_type { };
+ template <typename CharT, typename Traits>
+ struct string_semantics<std::basic_string_view<CharT, Traits> > : public std::true_type { };
+ template <typename U>
+ using signed_integer_semantics = std::bool_constant<std::is_integral_v<U> && std::is_signed_v<U> >;
+ template <typename U>
+ using unsigned_integer_semantics = std::bool_constant<std::is_integral_v<U> && !std::is_signed_v<U> >;
static void apply_signed(Stream &str, char16_t const &value)
{
@@ -865,8 +865,8 @@ template <typename Stream, typename T>
class format_output<Stream, T *>
{
protected:
- template <typename U> struct string_semantics
- { static constexpr bool value = std::is_same<std::remove_const_t<U>, typename Stream::char_type>::value; };
+ template <typename U>
+ using string_semantics = std::bool_constant<std::is_same_v<std::remove_const_t<U>, typename Stream::char_type> >;
public:
template <typename U>
@@ -940,10 +940,10 @@ template <typename T>
class format_make_integer
{
private:
- template <typename U> struct use_unsigned_cast
- { static constexpr bool value = std::is_convertible<U const, unsigned>::value && std::is_unsigned<U>::value; };
- template <typename U> struct use_signed_cast
- { static constexpr bool value = !use_unsigned_cast<U>::value && std::is_convertible<U const, int>::value; };
+ template <typename U>
+ using use_unsigned_cast = std::bool_constant<std::is_convertible_v<U const, unsigned> && std::is_unsigned_v<U> >;
+ template <typename U>
+ using use_signed_cast = std::bool_constant<!use_unsigned_cast<U>::value && std::is_convertible_v<U const, int> >;
public:
template <typename U> static bool apply(U const &value, int &result)
@@ -974,14 +974,14 @@ template <typename T>
class format_store_integer
{
private:
- template <typename U> struct is_non_const_ptr
- { static constexpr bool value = std::is_pointer<U>::value && !std::is_const<std::remove_pointer_t<U> >::value; };
- template <typename U> struct is_unsigned_ptr
- { static constexpr bool value = std::is_pointer<U>::value && std::is_unsigned<std::remove_pointer_t<U> >::value; };
- template <typename U> struct use_unsigned_cast
- { static constexpr bool value = is_non_const_ptr<U>::value && is_unsigned_ptr<U>::value && std::is_convertible<std::make_unsigned_t<std::streamoff>, std::remove_pointer_t<U> >::value; };
- template <typename U> struct use_signed_cast
- { static constexpr bool value = is_non_const_ptr<U>::value && !use_unsigned_cast<U>::value && std::is_convertible<std::streamoff, std::remove_pointer_t<U> >::value; };
+ template <typename U>
+ using is_non_const_ptr = std::bool_constant<std::is_pointer_v<U> && !std::is_const_v<std::remove_pointer_t<U> > >;
+ template <typename U>
+ using is_unsigned_ptr = std::bool_constant<std::is_pointer_v<U> && std::is_unsigned_v<std::remove_pointer_t<U> > >;
+ template <typename U>
+ using use_unsigned_cast = std::bool_constant<is_non_const_ptr<U>::value && is_unsigned_ptr<U>::value && std::is_convertible_v<std::make_unsigned_t<std::streamoff>, std::remove_pointer_t<U> > >;
+ template <typename U>
+ using use_signed_cast = std::bool_constant<is_non_const_ptr<U>::value && !use_unsigned_cast<U>::value && std::is_convertible_v<std::streamoff, std::remove_pointer_t<U> > >;
public:
template <typename U> static bool apply(U const &value, std::streamoff data)
@@ -1091,11 +1091,11 @@ public:
protected:
template <typename T>
- struct handle_char_ptr { static constexpr bool value = std::is_pointer<T>::value && std::is_same<std::remove_cv_t<std::remove_pointer_t<T> >, char_type>::value; };
+ using handle_char_ptr = std::bool_constant<std::is_pointer_v<T> && std::is_same_v<std::remove_cv_t<std::remove_pointer_t<T> >, char_type> >;
template <typename T>
- struct handle_char_array { static constexpr bool value = std::is_array<T>::value && std::is_same<std::remove_cv_t<std::remove_extent_t<T> >, char_type>::value; };
+ using handle_char_array = std::bool_constant<std::is_array_v<T> && std::is_same_v<std::remove_cv_t<std::remove_extent_t<T> >, char_type> >;
template <typename T>
- struct handle_container { static constexpr bool value = !handle_char_ptr<T>::value && !handle_char_array<T>::value; };
+ using handle_container = std::bool_constant<!handle_char_ptr<T>::value && !handle_char_array<T>::value>;
template <typename Format>
format_argument_pack(
diff --git a/src/lib/util/timeconv.cpp b/src/lib/util/timeconv.cpp
index 99953712003..469b6b592a2 100644
--- a/src/lib/util/timeconv.cpp
+++ b/src/lib/util/timeconv.cpp
@@ -14,42 +14,10 @@
namespace util {
-/***************************************************************************
- PROTOTYPES
-***************************************************************************/
-
-static std::chrono::system_clock::duration calculate_system_clock_adjustment();
-
-
-/***************************************************************************
- GLOBAL VARIABLES
-***************************************************************************/
-
-std::chrono::system_clock::duration system_clock_adjustment(calculate_system_clock_adjustment());
-
-
-/***************************************************************************
- IMPLEMENTATION
-***************************************************************************/
-
-arbitrary_datetime arbitrary_datetime::now()
-{
- time_t sec;
- time(&sec);
- auto t = *localtime(&sec);
-
- arbitrary_datetime dt;
- dt.year = t.tm_year + 1900;
- dt.month = t.tm_mon + 1;
- dt.day_of_month = t.tm_mday;
- dt.hour = t.tm_hour;
- dt.minute = t.tm_min;
- dt.second = t.tm_sec;
- return dt;
-}
+namespace {
-static std::chrono::system_clock::duration calculate_system_clock_adjustment()
+std::chrono::system_clock::duration calculate_system_clock_adjustment()
{
constexpr auto days_in_year(365);
constexpr auto days_in_four_years((days_in_year * 4) + 1);
@@ -84,6 +52,39 @@ static std::chrono::system_clock::duration calculate_system_clock_adjustment()
return result - std::chrono::system_clock::from_time_t(0).time_since_epoch();
}
+} // anonymous namespace
+
+
+
+/***************************************************************************
+ GLOBAL VARIABLES
+***************************************************************************/
+
+std::chrono::system_clock::duration system_clock_adjustment(calculate_system_clock_adjustment());
+
+
+
+/***************************************************************************
+ IMPLEMENTATION
+***************************************************************************/
+
+arbitrary_datetime arbitrary_datetime::now()
+{
+ time_t sec;
+ time(&sec);
+ auto t = *localtime(&sec);
+
+ arbitrary_datetime dt;
+ dt.year = t.tm_year + 1900;
+ dt.month = t.tm_mon + 1;
+ dt.day_of_month = t.tm_mday;
+ dt.hour = t.tm_hour;
+ dt.minute = t.tm_min;
+ dt.second = t.tm_sec;
+
+ return dt;
+}
+
// -------------------------------------------------
diff --git a/src/lib/util/timeconv.h b/src/lib/util/timeconv.h
index f9d1b070012..91327dbac16 100644
--- a/src/lib/util/timeconv.h
+++ b/src/lib/util/timeconv.h
@@ -22,6 +22,7 @@
namespace util {
+
/***************************************************************************
GLOBAL VARIABLES
***************************************************************************/
@@ -58,7 +59,7 @@ struct arbitrary_datetime
// date of the epoch's begining
//---------------------------------------------------------
-template<typename Rep, int Y, int M, int D, int H, int N, int S, typename Ratio>
+template <typename Rep, int Y, int M, int D, int H, int N, int S, typename Ratio>
class arbitrary_clock
{
public:
@@ -89,7 +90,7 @@ public:
// with a different scale to this arbitrary_clock's scale
//---------------------------------------------------------
- template<typename Rep2, int YY, int MM, int DD, int HH, int NN, int SS, typename Ratio2>
+ template <typename Rep2, int YY, int MM, int DD, int HH, int NN, int SS, typename Ratio2>
static time_point from_arbitrary_time_point(const std::chrono::time_point<arbitrary_clock<Rep2, YY, MM, DD, HH, NN, SS, Ratio2> > &tp)
{
arbitrary_datetime dt;
@@ -111,7 +112,7 @@ public:
// of this scale to one of different scale
//---------------------------------------------------------
- template<typename Rep2, int YY, int MM, int DD, int HH, int NN, int SS, typename Ratio2>
+ template <typename Rep2, int YY, int MM, int DD, int HH, int NN, int SS, typename Ratio2>
static std::chrono::time_point<arbitrary_clock<Rep2, YY, MM, DD, HH, NN, SS, Ratio2> > to_arbitrary_time_point(const time_point &tp)
{
return arbitrary_clock<Rep2, YY, MM, DD, HH, NN, SS, Ratio2>::from_arbitrary_time_point(tp);
@@ -125,14 +126,14 @@ public:
static struct tm to_tm(const time_point &tp)
{
std::chrono::time_point<tm_conversion_clock> normalized_tp = to_arbitrary_time_point<
- std::int64_t,
- tm_conversion_clock::base_year,
- tm_conversion_clock::base_month,
- tm_conversion_clock::base_day,
- tm_conversion_clock::base_hour,
- tm_conversion_clock::base_minute,
- tm_conversion_clock::base_second,
- tm_conversion_clock::period>(tp);
+ std::int64_t,
+ tm_conversion_clock::base_year,
+ tm_conversion_clock::base_month,
+ tm_conversion_clock::base_day,
+ tm_conversion_clock::base_hour,
+ tm_conversion_clock::base_minute,
+ tm_conversion_clock::base_second,
+ tm_conversion_clock::period>(tp);
return internal_to_tm(normalized_tp.time_since_epoch());
}
@@ -144,14 +145,14 @@ public:
static std::chrono::time_point<std::chrono::system_clock> to_system_clock(const time_point &tp)
{
auto normalized_tp = to_arbitrary_time_point<
- std::int64_t,
- system_conversion_clock::base_year,
- system_conversion_clock::base_month,
- system_conversion_clock::base_day,
- system_conversion_clock::base_hour,
- system_conversion_clock::base_minute,
- system_conversion_clock::base_second,
- system_conversion_clock::period>(tp);
+ std::int64_t,
+ system_conversion_clock::base_year,
+ system_conversion_clock::base_month,
+ system_conversion_clock::base_day,
+ system_conversion_clock::base_hour,
+ system_conversion_clock::base_minute,
+ system_conversion_clock::base_second,
+ system_conversion_clock::period>(tp);
return std::chrono::time_point<std::chrono::system_clock>(normalized_tp.time_since_epoch() + system_clock_adjustment);
}
diff --git a/src/lib/util/un7z.cpp b/src/lib/util/un7z.cpp
index 879da294c69..b35af479d5d 100644
--- a/src/lib/util/un7z.cpp
+++ b/src/lib/util/un7z.cpp
@@ -13,11 +13,13 @@
#include "unzip.h"
#include "corestr.h"
-#include "osdcore.h"
-#include "osdfile.h"
+#include "ioprocs.h"
#include "unicode.h"
#include "timeconv.h"
+#include "osdcore.h"
+#include "osdfile.h"
+
#include "lzma/C/7z.h"
#include "lzma/C/7zAlloc.h"
#include "lzma/C/7zCrc.h"
@@ -38,47 +40,71 @@
namespace util {
+
namespace {
+
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
-struct CSzFile
+struct CFileInStream : public ISeekInStream
{
- CSzFile() : currfpos(0), length(0), osdfile() {}
+ CFileInStream() noexcept
+ {
+ Read = [] (void *pp, void *buf, size_t *size) { return reinterpret_cast<CFileInStream *>(pp)->read(buf, *size); };
+ Seek = [] (void *pp, Int64 *pos, ESzSeek origin) { return reinterpret_cast<CFileInStream *>(pp)->seek(*pos, origin); };
+ }
- std::uint64_t currfpos;
- std::uint64_t length;
- osd_file::ptr osdfile;
+ random_read::ptr file;
+ std::uint64_t currfpos = 0;
+ std::uint64_t length = 0;
- SRes read(void *data, std::size_t &size)
+private:
+ SRes read(void *data, std::size_t &size) noexcept
{
- if (!osdfile)
+ if (!file)
{
- osd_printf_error("un7z: called CSzFile::read without file\n");
+ osd_printf_error("un7z: called CFileInStream::read without file\n");
return SZ_ERROR_READ;
}
if (!size)
return SZ_OK;
- // TODO: this casts a size_t to a uint32_t, so it will fail if >=4GB is requested at once (need a loop)
- std::uint32_t read_length(0);
- auto const err = osdfile->read(data, currfpos, size, read_length);
+ std::size_t read_length(0);
+ std::error_condition const err = file->read_at(currfpos, data, size, read_length);
size = read_length;
currfpos += read_length;
- return (osd_file::error::NONE == err) ? SZ_OK : SZ_ERROR_READ;
+ return !err ? SZ_OK : SZ_ERROR_READ;
}
- SRes seek(Int64 &pos, ESzSeek origin)
+ SRes seek(Int64 &pos, ESzSeek origin) noexcept
{
+ // need to synthesise this because the OSD file wrapper doesn't implement SEEK_END
switch (origin)
{
- case SZ_SEEK_CUR: currfpos += pos; break;
- case SZ_SEEK_SET: currfpos = pos; break;
- case SZ_SEEK_END: currfpos = length + pos; break;
- default: return SZ_ERROR_READ;
+ case SZ_SEEK_CUR:
+ if ((0 > pos) && (-pos > currfpos))
+ {
+ osd_printf_error("un7z: attemped to seek back %d bytes when current offset is %u\n", -pos, currfpos);
+ return SZ_ERROR_READ;
+ }
+ currfpos += pos;
+ break;
+ case SZ_SEEK_SET:
+ currfpos = pos;
+ break;
+ case SZ_SEEK_END:
+ if ((0 > pos) && (-pos > length))
+ {
+ osd_printf_error("un7z: attemped to seek %d bytes before end of file %u\n", -pos, currfpos);
+ return SZ_ERROR_READ;
+ }
+ currfpos = length + pos;
+ break;
+ default:
+ return SZ_ERROR_READ;
}
pos = currfpos;
return SZ_OK;
@@ -86,18 +112,18 @@ struct CSzFile
};
-struct CFileInStream : public ISeekInStream, public CSzFile
-{
- CFileInStream();
-};
-
-
-class m7z_file_impl
+class m7z_file_impl
{
public:
typedef std::unique_ptr<m7z_file_impl> ptr;
- m7z_file_impl(const std::string &filename);
+ m7z_file_impl(std::string &&filename) noexcept;
+
+ m7z_file_impl(random_read::ptr &&file) noexcept
+ : m7z_file_impl(std::string())
+ {
+ m_archive_stream.file = std::move(file);
+ }
virtual ~m7z_file_impl()
{
@@ -107,7 +133,7 @@ public:
SzArEx_Free(&m_db, &m_alloc_imp);
}
- static ptr find_cached(const std::string &filename)
+ static ptr find_cached(std::string_view filename) noexcept
{
std::lock_guard<std::mutex> guard(s_cache_mutex);
for (std::size_t cachenum = 0; cachenum < s_cache.size(); cachenum++)
@@ -115,47 +141,60 @@ public:
// if we have a valid entry and it matches our filename, use it and remove from the cache
if (s_cache[cachenum] && (filename == s_cache[cachenum]->m_filename))
{
+ using std::swap;
ptr result;
- std::swap(s_cache[cachenum], result);
+ swap(s_cache[cachenum], result);
osd_printf_verbose("un7z: found %s in cache\n", filename);
return result;
}
}
return ptr();
}
- static void close(ptr &&archive);
- static void cache_clear()
+
+ static void close(ptr &&archive) noexcept;
+
+ static void cache_clear() noexcept
{
// clear call cache entries
std::lock_guard<std::mutex> guard(s_cache_mutex);
- for (std::size_t cachenum = 0; cachenum < s_cache.size(); s_cache[cachenum++].reset()) { }
+ for (auto &cached : s_cache)
+ cached.reset();
}
- archive_file::error initialize();
+ std::error_condition initialize() noexcept;
- int first_file() { return search(0, 0, std::string(), false, false, false); }
- int next_file() { return (m_curr_file_idx < 0) ? -1 : search(m_curr_file_idx + 1, 0, std::string(), false, false, false); }
+ int first_file() noexcept
+ {
+ return search(0, 0, std::string_view(), false, false, false);
+ }
- int search(std::uint32_t crc)
+ int next_file() noexcept
{
- return search(0, crc, std::string(), true, false, false);
+ return (m_curr_file_idx < 0) ? -1 : search(m_curr_file_idx + 1, 0, std::string_view(), false, false, false);
}
- int search(const std::string &filename, bool partialpath)
+
+ int search(std::uint32_t crc) noexcept
+ {
+ return search(0, crc, std::string_view(), true, false, false);
+ }
+
+ int search(std::string_view filename, bool partialpath) noexcept
{
return search(0, 0, filename, false, true, partialpath);
}
- int search(std::uint32_t crc, const std::string &filename, bool partialpath)
+
+ int search(std::uint32_t crc, std::string_view filename, bool partialpath) noexcept
{
return search(0, crc, filename, true, true, partialpath);
}
- bool current_is_directory() const { return m_curr_is_dir; }
- const std::string &current_name() const { return m_curr_name; }
- std::uint64_t current_uncompressed_length() const { return m_curr_length; }
- virtual std::chrono::system_clock::time_point current_last_modified() const { return m_curr_modified; }
- std::uint32_t current_crc() const { return m_curr_crc; }
+ bool current_is_directory() const noexcept { return m_curr_is_dir; }
+ const std::string &current_name() const noexcept { return m_curr_name; }
+ std::uint64_t current_uncompressed_length() const noexcept { return m_curr_length; }
+ virtual std::chrono::system_clock::time_point current_last_modified() const noexcept { return m_curr_modified; }
+ std::uint32_t current_crc() const noexcept { return m_curr_crc; }
- archive_file::error decompress(void *buffer, std::uint32_t length);
+ std::error_condition decompress(void *buffer, std::size_t length) noexcept;
private:
m7z_file_impl(const m7z_file_impl &) = delete;
@@ -166,12 +205,12 @@ private:
int search(
int i,
std::uint32_t search_crc,
- const std::string &search_filename,
+ std::string_view search_filename,
bool matchcrc,
bool matchname,
- bool partialpath);
+ bool partialpath) noexcept;
void make_utf8_name(int index);
- void set_curr_modified();
+ void set_curr_modified() noexcept;
static constexpr std::size_t CACHE_SIZE = 8;
static std::array<ptr, CACHE_SIZE> s_cache;
@@ -187,7 +226,7 @@ private:
std::uint32_t m_curr_crc; // current file crc
std::vector<UInt16> m_utf16_buf;
- std::vector<char32_t> m_uchar_buf;
+ std::vector<char32_t> m_uchar_buf;
std::vector<char> m_utf8_buf;
CFileInStream m_archive_stream;
@@ -201,39 +240,38 @@ private:
UInt32 m_block_index;
Byte * m_out_buffer;
std::size_t m_out_buffer_size;
-
};
class m7z_file_wrapper : public archive_file
{
public:
- m7z_file_wrapper(m7z_file_impl::ptr &&impl) : m_impl(std::move(impl)) { assert(m_impl); }
+ m7z_file_wrapper(m7z_file_impl::ptr &&impl) noexcept : m_impl(std::move(impl)) { assert(m_impl); }
virtual ~m7z_file_wrapper() override { m7z_file_impl::close(std::move(m_impl)); }
- virtual int first_file() override { return m_impl->first_file(); }
- virtual int next_file() override { return m_impl->next_file(); }
+ virtual int first_file() noexcept override { return m_impl->first_file(); }
+ virtual int next_file() noexcept override { return m_impl->next_file(); }
- virtual int search(std::uint32_t crc) override
+ virtual int search(std::uint32_t crc) noexcept override
{
return m_impl->search(crc);
}
- virtual int search(const std::string &filename, bool partialpath) override
+ virtual int search(std::string_view filename, bool partialpath) noexcept override
{
return m_impl->search(filename, partialpath);
}
- virtual int search(std::uint32_t crc, const std::string &filename, bool partialpath) override
+ virtual int search(std::uint32_t crc, std::string_view filename, bool partialpath) noexcept override
{
return m_impl->search(crc, filename, partialpath);
}
- virtual bool current_is_directory() const override { return m_impl->current_is_directory(); }
- virtual const std::string &current_name() const override { return m_impl->current_name(); }
- virtual std::uint64_t current_uncompressed_length() const override { return m_impl->current_uncompressed_length(); }
- virtual std::chrono::system_clock::time_point current_last_modified() const override { return m_impl->current_last_modified(); }
- virtual std::uint32_t current_crc() const override { return m_impl->current_crc(); }
+ virtual bool current_is_directory() const noexcept override { return m_impl->current_is_directory(); }
+ virtual const std::string &current_name() const noexcept override { return m_impl->current_name(); }
+ virtual std::uint64_t current_uncompressed_length() const noexcept override { return m_impl->current_uncompressed_length(); }
+ virtual std::chrono::system_clock::time_point current_last_modified() const noexcept override { return m_impl->current_last_modified(); }
+ virtual std::uint32_t current_crc() const noexcept override { return m_impl->current_crc(); }
- virtual error decompress(void *buffer, std::uint32_t length) override { return m_impl->decompress(buffer, length); }
+ virtual std::error_condition decompress(void *buffer, std::size_t length) noexcept override { return m_impl->decompress(buffer, length); }
private:
m7z_file_impl::ptr m_impl;
@@ -251,48 +289,20 @@ std::mutex m7z_file_impl::s_cache_mutex;
/***************************************************************************
- 7Zip Memory / File handling (adapted from 7zfile.c/.h and 7zalloc.c/.h)
-***************************************************************************/
-
-/* ---------- FileInStream ---------- */
-
-extern "C" {
-static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
-{
- return (reinterpret_cast<CFileInStream *>(pp)->read(buf, *size) == 0) ? SZ_OK : SZ_ERROR_READ;
-}
-
-static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
-{
- return reinterpret_cast<CFileInStream *>(pp)->seek(*pos, origin);
-}
-
-} // extern "C"
-
-
-CFileInStream::CFileInStream()
-{
- Read = &FileInStream_Read;
- Seek = &FileInStream_Seek;
-}
-
-
-
-/***************************************************************************
CACHE MANAGEMENT
***************************************************************************/
-m7z_file_impl::m7z_file_impl(const std::string &filename)
- : m_filename(filename)
+m7z_file_impl::m7z_file_impl(std::string &&filename) noexcept
+ : m_filename(std::move(filename))
, m_curr_file_idx(-1)
, m_curr_is_dir(false)
, m_curr_name()
, m_curr_length(0)
, m_curr_modified()
, m_curr_crc(0)
- , m_utf16_buf(128)
- , m_uchar_buf(128)
- , m_utf8_buf(512)
+ , m_utf16_buf()
+ , m_uchar_buf()
+ , m_utf8_buf()
, m_inited(false)
, m_block_index(0)
, m_out_buffer(nullptr)
@@ -310,15 +320,45 @@ m7z_file_impl::m7z_file_impl(const std::string &filename)
}
-archive_file::error m7z_file_impl::initialize()
+std::error_condition m7z_file_impl::initialize() noexcept
{
- osd_file::error const err = osd_file::open(m_filename, OPEN_FLAG_READ, m_archive_stream.osdfile, m_archive_stream.length);
- if (err != osd_file::error::NONE)
- return archive_file::error::FILE_ERROR;
+ try
+ {
+ if (m_utf16_buf.size() < 128)
+ m_utf16_buf.resize(128);
+ if (m_uchar_buf.size() < 128)
+ m_uchar_buf.resize(128);
+ m_utf8_buf.reserve(512);
+ }
+ catch (...)
+ {
+ return std::errc::not_enough_memory;
+ }
- osd_printf_verbose("un7z: opened archive file %s\n", m_filename);
+ if (!m_archive_stream.file)
+ {
+ osd_file::ptr file;
+ std::error_condition const err = osd_file::open(m_filename, OPEN_FLAG_READ, file, m_archive_stream.length);
+ if (err)
+ return err;
+ m_archive_stream.file = osd_file_read(std::move(file));
+ osd_printf_verbose("un7z: opened archive file %s\n", m_filename);
+ }
+ else if (!m_archive_stream.length)
+ {
+ std::error_condition const err = m_archive_stream.file->length(m_archive_stream.length);
+ if (err)
+ {
+ osd_printf_verbose(
+ "un7z: error getting length of archive file %s (%s:%d %s)\n",
+ m_filename, err.category().name(), err.value(), err.message());
+ return err;
+ }
+ }
- CrcGenerateTable(); // FIXME: doesn't belong here - it should be called once statically
+ // TODO: coordinate this with other LZMA users in the codebase?
+ struct crc_table_generator { crc_table_generator() { CrcGenerateTable(); } };
+ static crc_table_generator crc_table;
SzArEx_Init(&m_db);
m_inited = true;
@@ -329,13 +369,13 @@ archive_file::error m7z_file_impl::initialize()
switch (res)
{
case SZ_ERROR_UNSUPPORTED: return archive_file::error::UNSUPPORTED;
- case SZ_ERROR_MEM: return archive_file::error::OUT_OF_MEMORY;
+ case SZ_ERROR_MEM: return std::errc::not_enough_memory;
case SZ_ERROR_INPUT_EOF: return archive_file::error::FILE_TRUNCATED;
- default: return archive_file::error::FILE_ERROR;
+ default: return std::errc::io_error; // TODO: better default error?
}
}
- return archive_file::error::NONE;
+ return std::error_condition();
}
@@ -344,33 +384,38 @@ archive_file::error m7z_file_impl::initialize()
to the cache
-------------------------------------------------*/
-void m7z_file_impl::close(ptr &&archive)
+void m7z_file_impl::close(ptr &&archive) noexcept
{
- if (!archive) return;
+ // if the filename isn't empty, the implementation can be cached
+ if (archive && !archive->m_filename.empty())
+ {
+ // close the open files
+ osd_printf_verbose("un7z: closing archive file %s and sending to cache\n", archive->m_filename);
+ archive->m_archive_stream.file.reset();
- // close the open files
- osd_printf_verbose("un7z: closing archive file %s and sending to cache\n", archive->m_filename);
- archive->m_archive_stream.osdfile.reset();
+ // find the first nullptr entry in the cache
+ std::lock_guard<std::mutex> guard(s_cache_mutex);
+ std::size_t cachenum;
+ for (cachenum = 0; cachenum < s_cache.size(); cachenum++)
+ if (!s_cache[cachenum])
+ break;
- // find the first nullptr entry in the cache
- std::lock_guard<std::mutex> guard(s_cache_mutex);
- std::size_t cachenum;
- for (cachenum = 0; cachenum < s_cache.size(); cachenum++)
- if (!s_cache[cachenum])
- break;
+ // if no room left in the cache, free the bottommost entry
+ if (cachenum == s_cache.size())
+ {
+ cachenum--;
+ osd_printf_verbose("un7z: removing %s from cache to make space\n", s_cache[cachenum]->m_filename);
+ s_cache[cachenum].reset();
+ }
- // if no room left in the cache, free the bottommost entry
- if (cachenum == s_cache.size())
- {
- cachenum--;
- osd_printf_verbose("un7z: removing %s from cache to make space\n", s_cache[cachenum]->m_filename);
- s_cache[cachenum].reset();
+ // move everyone else down and place us at the top
+ for ( ; cachenum > 0; cachenum--)
+ s_cache[cachenum] = std::move(s_cache[cachenum - 1]);
+ s_cache[0] = std::move(archive);
}
- // move everyone else down and place us at the top
- for ( ; cachenum > 0; cachenum--)
- s_cache[cachenum] = std::move(s_cache[cachenum - 1]);
- s_cache[0] = std::move(archive);
+ // make sure it's cleaned up
+ archive.reset();
}
@@ -384,7 +429,7 @@ void m7z_file_impl::close(ptr &&archive)
from a _7Z into the target buffer
-------------------------------------------------*/
-archive_file::error m7z_file_impl::decompress(void *buffer, std::uint32_t length)
+std::error_condition m7z_file_impl::decompress(void *buffer, std::size_t length) noexcept
{
// if we don't have enough buffer, error
if (length < m_curr_length)
@@ -394,15 +439,19 @@ archive_file::error m7z_file_impl::decompress(void *buffer, std::uint32_t length
}
// make sure the file is open..
- if (!m_archive_stream.osdfile)
+ if (!m_archive_stream.file)
{
- m_archive_stream.currfpos = 0;
- osd_file::error const err = osd_file::open(m_filename, OPEN_FLAG_READ, m_archive_stream.osdfile, m_archive_stream.length);
- if (err != osd_file::error::NONE)
+ m_archive_stream.currfpos = 0; // FIXME: should it really be changing the file pointer out from under LZMA?
+ osd_file::ptr file;
+ std::error_condition const err = osd_file::open(m_filename, OPEN_FLAG_READ, file, m_archive_stream.length);
+ if (err)
{
- osd_printf_error("un7z: error reopening archive file %s (%d)\n", m_filename, int(err));
- return archive_file::error::FILE_ERROR;
+ osd_printf_error(
+ "un7z: error reopening archive file %s (%s:%d %s)\n",
+ m_filename, err.category().name(), err.value(), err.message());
+ return err;
}
+ m_archive_stream.file = osd_file_read(std::move(file));
osd_printf_verbose("un7z: reopened archive file %s\n", m_filename);
}
@@ -419,7 +468,7 @@ archive_file::error m7z_file_impl::decompress(void *buffer, std::uint32_t length
switch (res)
{
case SZ_ERROR_UNSUPPORTED: return archive_file::error::UNSUPPORTED;
- case SZ_ERROR_MEM: return archive_file::error::OUT_OF_MEMORY;
+ case SZ_ERROR_MEM: return std::errc::not_enough_memory;
case SZ_ERROR_INPUT_EOF: return archive_file::error::FILE_TRUNCATED;
default: return archive_file::error::DECOMPRESS_ERROR;
}
@@ -427,45 +476,64 @@ archive_file::error m7z_file_impl::decompress(void *buffer, std::uint32_t length
// copy to destination buffer
std::memcpy(buffer, m_out_buffer + offset, (std::min<std::size_t>)(length, out_size_processed));
- return archive_file::error::NONE;
+ return std::error_condition();
}
int m7z_file_impl::search(
int i,
std::uint32_t search_crc,
- const std::string &search_filename,
+ std::string_view search_filename,
bool matchcrc,
bool matchname,
- bool partialpath)
+ bool partialpath) noexcept
{
- for ( ; i < m_db.NumFiles; i++)
- {
- make_utf8_name(i);
- bool const is_dir(SzArEx_IsDir(&m_db, i));
- const std::uint64_t size(SzArEx_GetFileSize(&m_db, i));
- const std::uint32_t crc(m_db.CRCs.Vals[i]);
- const bool crcmatch(SzBitArray_Check(m_db.CRCs.Defs, i) && (crc == search_crc));
- auto const partialoffset(m_utf8_buf.size() - 1 - search_filename.length());
- bool const partialpossible((m_utf8_buf.size() > (search_filename.length() + 1)) && (m_utf8_buf[partialoffset - 1] == '/'));
- const bool namematch(
- !core_stricmp(search_filename.c_str(), &m_utf8_buf[0]) ||
- (partialpath && partialpossible && !core_stricmp(search_filename.c_str(), &m_utf8_buf[partialoffset])));
-
- const bool found = ((!matchcrc && !matchname) || !is_dir) && (!matchcrc || crcmatch) && (!matchname || namematch);
- if (found)
+ try
+ {
+ for ( ; i < m_db.NumFiles; i++)
{
- m_curr_file_idx = i;
- m_curr_is_dir = is_dir;
- m_curr_name = &m_utf8_buf[0];
- m_curr_length = size;
- set_curr_modified();
- m_curr_crc = crc;
-
- return i;
+ make_utf8_name(i);
+ bool const is_dir(SzArEx_IsDir(&m_db, i));
+ const std::uint64_t size(SzArEx_GetFileSize(&m_db, i));
+ const std::uint32_t crc(m_db.CRCs.Vals[i]);
+
+ const bool crcmatch(SzBitArray_Check(m_db.CRCs.Defs, i) && (crc == search_crc));
+ bool found;
+ if (!matchname)
+ {
+ found = !matchcrc || (crcmatch && !is_dir);
+ }
+ else
+ {
+ auto const partialoffset = m_utf8_buf.size() - search_filename.length();
+ const bool namematch =
+ (search_filename.length() == m_utf8_buf.size()) &&
+ (search_filename.empty() || !core_strnicmp(&search_filename[0], &m_utf8_buf[0], search_filename.length()));
+ bool const partialmatch =
+ partialpath &&
+ ((m_utf8_buf.size() > search_filename.length()) && (m_utf8_buf[partialoffset - 1] == '/')) &&
+ (search_filename.empty() || !core_strnicmp(&search_filename[0], &m_utf8_buf[partialoffset], search_filename.length()));
+ found = (!matchcrc || crcmatch) && (namematch || partialmatch);
+ }
+
+ if (found)
+ {
+ // set the name first - resizing it can throw an exception, and we want the state to be consistent
+ m_curr_name.assign(m_utf8_buf.begin(), m_utf8_buf.end());
+ m_curr_file_idx = i;
+ m_curr_is_dir = is_dir;
+ m_curr_length = size;
+ set_curr_modified();
+ m_curr_crc = crc;
+
+ return i;
+ }
}
}
-
+ catch (...)
+ {
+ // allocation error handling name
+ }
return -1;
}
@@ -475,14 +543,14 @@ void m7z_file_impl::make_utf8_name(int index)
std::size_t len, out_pos;
len = SzArEx_GetFileNameUtf16(&m_db, index, nullptr);
- m_utf16_buf.resize((std::max<std::size_t>)(m_utf16_buf.size(), len));
+ m_utf16_buf.resize(std::max<std::size_t>(m_utf16_buf.size(), len));
SzArEx_GetFileNameUtf16(&m_db, index, &m_utf16_buf[0]);
- m_uchar_buf.resize((std::max<std::size_t>)(m_uchar_buf.size(), len));
+ m_uchar_buf.resize(std::max<std::size_t>(m_uchar_buf.size(), len));
out_pos = 0;
for (std::size_t in_pos = 0; in_pos < (len - 1); )
{
- const int used = uchar_from_utf16(&m_uchar_buf[out_pos], (char16_t *)&m_utf16_buf[in_pos], len - in_pos);
+ const int used = uchar_from_utf16(&m_uchar_buf[out_pos], reinterpret_cast<char16_t const *>(&m_utf16_buf[in_pos]), len - in_pos);
if (used < 0)
{
in_pos++;
@@ -497,7 +565,7 @@ void m7z_file_impl::make_utf8_name(int index)
}
len = out_pos;
- m_utf8_buf.resize((std::max<std::size_t>)(m_utf8_buf.size(), 4 * len + 1));
+ m_utf8_buf.resize((std::max<std::size_t>)(m_utf8_buf.size(), 4 * len));
out_pos = 0;
for (std::size_t in_pos = 0; in_pos < len; in_pos++)
{
@@ -508,30 +576,35 @@ void m7z_file_impl::make_utf8_name(int index)
out_pos += produced;
assert(out_pos < m_utf8_buf.size());
}
- m_utf8_buf[out_pos++] = '\0';
m_utf8_buf.resize(out_pos);
}
-void m7z_file_impl::set_curr_modified()
+void m7z_file_impl::set_curr_modified() noexcept
{
if (SzBitWithVals_Check(&m_db.MTime, m_curr_file_idx))
{
CNtfsFileTime const &file_time(m_db.MTime.Vals[m_curr_file_idx]);
- auto ticks = ntfs_duration_from_filetime(file_time.High, file_time.Low);
- m_curr_modified = system_clock_time_point_from_ntfs_duration(ticks);
- }
- else
- {
- // FIXME: what do we do about a lack of time?
+ try
+ {
+ auto ticks = ntfs_duration_from_filetime(file_time.High, file_time.Low);
+ m_curr_modified = system_clock_time_point_from_ntfs_duration(ticks);
+ return;
+ }
+ catch (...)
+ {
+ }
}
+
+ // no modification time available, or out-of-range exception
+ m_curr_modified = std::chrono::system_clock::from_time_t(std::time_t(0));
}
} // anonymous namespace
-archive_file::error archive_file::open_7z(const std::string &filename, ptr &result)
+std::error_condition archive_file::open_7z(std::string_view filename, ptr &result) noexcept
{
// ensure we start with a nullptr result
result.reset();
@@ -542,21 +615,49 @@ archive_file::error archive_file::open_7z(const std::string &filename, ptr &resu
if (!newimpl)
{
// allocate memory for the 7z file structure
- try { newimpl = std::make_unique<m7z_file_impl>(filename); }
- catch (...) { return error::OUT_OF_MEMORY; }
- error const err = newimpl->initialize();
- if (err != error::NONE) return err;
+ try { newimpl = std::make_unique<m7z_file_impl>(std::string(filename)); }
+ catch (...) { return std::errc::not_enough_memory; }
+ auto const err = newimpl->initialize();
+ if (err)
+ return err;
}
- try
+ // allocate the archive API wrapper
+ result.reset(new (std::nothrow) m7z_file_wrapper(std::move(newimpl)));
+ if (result)
{
- result = std::make_unique<m7z_file_wrapper>(std::move(newimpl));
- return error::NONE;
+ return std::error_condition();
}
- catch (...)
+ else
+ {
+ m7z_file_impl::close(std::move(newimpl));
+ return std::errc::not_enough_memory;
+ }
+}
+
+std::error_condition archive_file::open_7z(random_read::ptr &&file, ptr &result) noexcept
+{
+ // ensure we start with a nullptr result
+ result.reset();
+
+ // allocate memory for the zip_file structure
+ m7z_file_impl::ptr newimpl(new (std::nothrow) m7z_file_impl(std::move(file)));
+ if (!newimpl)
+ return std::errc::not_enough_memory;
+ auto const err = newimpl->initialize();
+ if (err)
+ return err;
+
+ // allocate the archive API wrapper
+ result.reset(new (std::nothrow) m7z_file_wrapper(std::move(newimpl)));
+ if (result)
+ {
+ return std::error_condition();
+ }
+ else
{
m7z_file_impl::close(std::move(newimpl));
- return error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
}
@@ -566,7 +667,7 @@ archive_file::error archive_file::open_7z(const std::string &filename, ptr &resu
cache and free all memory
-------------------------------------------------*/
-void m7z_file_cache_clear()
+void m7z_file_cache_clear() noexcept
{
// This is a trampoline called from unzip.cpp to avoid the need to have the zip and 7zip code in one file
m7z_file_impl::cache_clear();
diff --git a/src/lib/util/unzip.cpp b/src/lib/util/unzip.cpp
index a275cc7df06..d7df8fa5ce9 100644
--- a/src/lib/util/unzip.cpp
+++ b/src/lib/util/unzip.cpp
@@ -12,9 +12,11 @@
#include "corestr.h"
#include "hashing.h"
+#include "ioprocs.h"
+#include "timeconv.h"
+
#include "osdcore.h"
#include "osdfile.h"
-#include "timeconv.h"
#include "lzma/C/LzmaDec.h"
@@ -23,6 +25,7 @@
#include <algorithm>
#include <array>
#include <cassert>
+#include <cerrno>
#include <chrono>
#include <cstring>
#include <cstdlib>
@@ -34,31 +37,55 @@
namespace util {
+
namespace {
+
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
+class archive_category_impl : public std::error_category
+{
+public:
+ virtual char const *name() const noexcept override { return "archive"; }
+
+ virtual std::string message(int condition) const override
+ {
+ using namespace std::literals;
+ static std::string_view const s_messages[] = {
+ "No error"sv,
+ "Bad archive signature"sv,
+ "Decompression error"sv,
+ "Archive file truncated"sv,
+ "Archive file corrupt"sv,
+ "Archive file uses unsupported features"sv,
+ "Buffer too small for data"sv };
+ if ((0 <= condition) && (std::size(s_messages) > condition))
+ return std::string(s_messages[condition]);
+ else
+ return "Unknown error"s;
+ }
+};
+
+
class zip_file_impl
{
public:
- typedef std::unique_ptr<zip_file_impl> ptr;
-
- zip_file_impl(const std::string &filename)
- : m_filename(filename)
- , m_file()
- , m_length(0)
- , m_ecd()
- , m_cd()
- , m_cd_pos(0)
- , m_header()
- , m_curr_is_dir(false)
- , m_buffer()
+ using ptr = std::unique_ptr<zip_file_impl>;
+
+ zip_file_impl(std::string &&filename) noexcept
+ : m_filename(std::move(filename))
{
std::fill(m_buffer.begin(), m_buffer.end(), 0);
}
- static ptr find_cached(const std::string &filename)
+ zip_file_impl(random_read::ptr &&file) noexcept
+ : zip_file_impl(std::string())
+ {
+ m_file = std::move(file);
+ }
+
+ static ptr find_cached(std::string_view filename) noexcept
{
std::lock_guard<std::mutex> guard(s_cache_mutex);
for (std::size_t cachenum = 0; cachenum < s_cache.size(); cachenum++)
@@ -66,27 +93,31 @@ public:
// if we have a valid entry and it matches our filename, use it and remove from the cache
if (s_cache[cachenum] && (filename == s_cache[cachenum]->m_filename))
{
+ using std::swap;
ptr result;
- std::swap(s_cache[cachenum], result);
+ swap(s_cache[cachenum], result);
osd_printf_verbose("unzip: found %s in cache\n", filename);
return result;
}
}
return ptr();
}
- static void close(ptr &&zip);
- static void cache_clear()
+
+ static void close(ptr &&zip) noexcept;
+
+ static void cache_clear() noexcept
{
// clear call cache entries
std::lock_guard<std::mutex> guard(s_cache_mutex);
- for (std::size_t cachenum = 0; cachenum < s_cache.size(); s_cache[cachenum++].reset()) { }
+ for (auto &cached : s_cache)
+ cached.reset();
}
- archive_file::error initialize()
+ std::error_condition initialize() noexcept
{
// read ecd data
auto const ziperr = read_ecd();
- if (ziperr != archive_file::error::NONE)
+ if (ziperr)
return ziperr;
// verify that we can work with this zipfile (no disk spanning allowed)
@@ -111,7 +142,7 @@ public:
catch (...)
{
osd_printf_error("unzip: %s failed to allocate memory for central directory\n", m_filename);
- return archive_file::error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
// read the central directory
@@ -119,13 +150,15 @@ public:
std::size_t cd_offs(0);
while (cd_remaining)
{
- std::uint32_t const chunk(std::uint32_t((std::min<std::uint64_t>)(std::numeric_limits<std::uint32_t>::max(), cd_remaining)));
- std::uint32_t read_length(0);
- auto const filerr = m_file->read(&m_cd[cd_offs], m_ecd.cd_start_disk_offset + cd_offs, chunk, read_length);
- if (filerr != osd_file::error::NONE)
+ std::size_t const chunk(std::size_t(std::min<std::uint64_t>(std::numeric_limits<std::size_t>::max(), cd_remaining)));
+ std::size_t read_length(0);
+ std::error_condition const filerr = m_file->read_at(m_ecd.cd_start_disk_offset + cd_offs, &m_cd[cd_offs], chunk, read_length);
+ if (filerr)
{
- osd_printf_error("unzip: %s error reading central directory (%d)\n", m_filename, int(filerr));
- return archive_file::error::FILE_ERROR;
+ osd_printf_error(
+ "unzip: %s error reading central directory (%s:%d %s)\n",
+ m_filename, filerr.category().name(), filerr.value(), filerr.message());
+ return filerr;
}
if (!read_length)
{
@@ -137,39 +170,45 @@ public:
}
osd_printf_verbose("unzip: read %s central directory\n", m_filename);
- return archive_file::error::NONE;
+ return std::error_condition();
}
- int first_file()
+ int first_file() noexcept
{
m_cd_pos = 0;
- return search(0, std::string(), false, false, false);
+ return search(0, std::string_view(), false, false, false);
}
- int next_file()
+
+ int next_file() noexcept
{
- return search(0, std::string(), false, false, false);
+ return search(0, std::string_view(), false, false, false);
}
- int search(std::uint32_t crc)
+ int search(std::uint32_t crc) noexcept
{
m_cd_pos = 0;
- return search(crc, std::string(), true, false, false);
+ return search(crc, std::string_view(), true, false, false);
}
- int search(const std::string &filename, bool partialpath)
+
+ int search(std::string_view filename, bool partialpath) noexcept
{
m_cd_pos = 0;
return search(0, filename, false, true, partialpath);
}
- int search(std::uint32_t crc, const std::string &filename, bool partialpath)
+
+ int search(std::uint32_t crc, std::string_view filename, bool partialpath) noexcept
{
m_cd_pos = 0;
return search(crc, filename, true, true, partialpath);
}
- bool current_is_directory() const { return m_curr_is_dir; }
- const std::string &current_name() const { return m_header.file_name; }
- std::uint64_t current_uncompressed_length() const { return m_header.uncompressed_length; }
- std::chrono::system_clock::time_point current_last_modified() const
+ bool current_is_directory() const noexcept { return m_curr_is_dir; }
+
+ const std::string &current_name() const noexcept { return m_header.file_name; }
+
+ std::uint64_t current_uncompressed_length() const noexcept { return m_header.uncompressed_length; }
+
+ std::chrono::system_clock::time_point current_last_modified() const noexcept
{
if (!m_header.modified_cached)
{
@@ -178,9 +217,10 @@ public:
}
return m_header.modified;
}
- std::uint32_t current_crc() const { return m_header.crc; }
- archive_file::error decompress(void *buffer, std::uint32_t length);
+ std::uint32_t current_crc() const noexcept { return m_header.crc; }
+
+ std::error_condition decompress(void *buffer, std::size_t length) noexcept;
private:
zip_file_impl(const zip_file_impl &) = delete;
@@ -188,28 +228,43 @@ private:
zip_file_impl &operator=(const zip_file_impl &) = delete;
zip_file_impl &operator=(zip_file_impl &&) = delete;
- int search(std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname, bool partialpath);
+ int search(std::uint32_t search_crc, std::string_view search_filename, bool matchcrc, bool matchname, bool partialpath) noexcept;
- archive_file::error reopen()
+ std::error_condition reopen() noexcept
{
if (!m_file)
{
- auto const filerr = osd_file::open(m_filename, OPEN_FLAG_READ, m_file, m_length);
- if (filerr != osd_file::error::NONE)
+ osd_file::ptr file;
+ auto const filerr = osd_file::open(m_filename, OPEN_FLAG_READ, file, m_length);
+ if (filerr)
{
// this would spam every time it looks for a non-existent archive, which is a lot
- //osd_printf_error("unzip: error reopening archive file %s (%d)\n", m_filename, int(filerr));
- return archive_file::error::FILE_ERROR;
+ //osd_printf_error("unzip: error reopening archive file %s (%s:%d %s)\n", m_filename, filerr.category().name(), filerr.value(), filerr.message());
+ return filerr;
}
- else
+ m_file = osd_file_read(std::move(file));
+ if (!m_file)
{
- osd_printf_verbose("unzip: opened archive file %s\n", m_filename);
+ osd_printf_error("unzip: not enough memory to open archive file %s\n", m_filename);
+ return std::errc::not_enough_memory;
}
+ osd_printf_verbose("unzip: opened archive file %s\n", m_filename);
}
- return archive_file::error::NONE;
+ else if (!m_length)
+ {
+ auto const filerr = m_file->length(m_length);
+ if (filerr)
+ {
+ osd_printf_verbose(
+ "unzip: error getting length of archive file %s (%s:%d %s)\n",
+ m_filename, filerr.category().name(), filerr.value(), filerr.message());
+ return filerr;
+ }
+ }
+ return std::error_condition();
}
- static std::chrono::system_clock::time_point decode_dos_time(std::uint16_t date, std::uint16_t time)
+ static std::chrono::system_clock::time_point decode_dos_time(std::uint16_t date, std::uint16_t time) noexcept
{
// FIXME: work out why this doesn't always work
// negative tm_isdst should automatically determine whether DST is in effect for the date,
@@ -228,16 +283,22 @@ private:
}
// ZIP file parsing
- archive_file::error read_ecd();
- archive_file::error get_compressed_data_offset(std::uint64_t &offset);
+ std::error_condition read_ecd() noexcept;
+ std::error_condition get_compressed_data_offset(std::uint64_t &offset) noexcept;
// decompression interfaces
- archive_file::error decompress_data_type_0(std::uint64_t offset, void *buffer, std::uint32_t length);
- archive_file::error decompress_data_type_8(std::uint64_t offset, void *buffer, std::uint32_t length);
- archive_file::error decompress_data_type_14(std::uint64_t offset, void *buffer, std::uint32_t length);
+ std::error_condition decompress_data_type_0(std::uint64_t offset, void *buffer, std::size_t length) noexcept;
+ std::error_condition decompress_data_type_8(std::uint64_t offset, void *buffer, std::size_t length) noexcept;
+ std::error_condition decompress_data_type_14(std::uint64_t offset, void *buffer, std::size_t length) noexcept;
struct file_header
{
+ file_header() noexcept { }
+ file_header(file_header const &) = default;
+ file_header(file_header &&) noexcept = default;
+ file_header &operator=(file_header const &) = default;
+ file_header &operator=(file_header &&) noexcept = default;
+
std::uint16_t version_created; // version made by
std::uint16_t version_needed; // version needed to extract
std::uint16_t bit_flag; // general purpose bit flag
@@ -271,15 +332,15 @@ private:
static std::mutex s_cache_mutex;
const std::string m_filename; // copy of ZIP filename (for caching)
- osd_file::ptr m_file; // OSD file handle
- std::uint64_t m_length; // length of zip file
+ random_read::ptr m_file; // file handle
+ std::uint64_t m_length = 0; // length of zip file
ecd m_ecd; // end of central directory
std::vector<std::uint8_t> m_cd; // central directory raw data
- std::uint32_t m_cd_pos; // position in central directory
+ std::uint32_t m_cd_pos = 0; // position in central directory
file_header m_header; // current file header
- bool m_curr_is_dir; // current file is directory
+ bool m_curr_is_dir = false; // current file is directory
std::array<std::uint8_t, DECOMPRESS_BUFSIZE> m_buffer; // buffer for decompression
};
@@ -288,32 +349,32 @@ private:
class zip_file_wrapper : public archive_file
{
public:
- zip_file_wrapper(zip_file_impl::ptr &&impl) : m_impl(std::move(impl)) { assert(m_impl); }
+ zip_file_wrapper(zip_file_impl::ptr &&impl) noexcept : m_impl(std::move(impl)) { assert(m_impl); }
virtual ~zip_file_wrapper() { zip_file_impl::close(std::move(m_impl)); }
- virtual int first_file() override { return m_impl->first_file(); }
- virtual int next_file() override { return m_impl->next_file(); }
+ virtual int first_file() noexcept override { return m_impl->first_file(); }
+ virtual int next_file() noexcept override { return m_impl->next_file(); }
- virtual int search(std::uint32_t crc) override
+ virtual int search(std::uint32_t crc) noexcept override
{
return m_impl->search(crc);
}
- virtual int search(const std::string &filename, bool partialpath) override
+ virtual int search(std::string_view filename, bool partialpath) noexcept override
{
return m_impl->search(filename, partialpath);
}
- virtual int search(std::uint32_t crc, const std::string &filename, bool partialpath) override
+ virtual int search(std::uint32_t crc, std::string_view filename, bool partialpath) noexcept override
{
return m_impl->search(crc, filename, partialpath);
}
- virtual bool current_is_directory() const override { return m_impl->current_is_directory(); }
- virtual const std::string &current_name() const override { return m_impl->current_name(); }
- virtual std::uint64_t current_uncompressed_length() const override { return m_impl->current_uncompressed_length(); }
- virtual std::chrono::system_clock::time_point current_last_modified() const override { return m_impl->current_last_modified(); }
- virtual std::uint32_t current_crc() const override { return m_impl->current_crc(); }
+ virtual bool current_is_directory() const noexcept override { return m_impl->current_is_directory(); }
+ virtual const std::string &current_name() const noexcept override { return m_impl->current_name(); }
+ virtual std::uint64_t current_uncompressed_length() const noexcept override { return m_impl->current_uncompressed_length(); }
+ virtual std::chrono::system_clock::time_point current_last_modified() const noexcept override { return m_impl->current_last_modified(); }
+ virtual std::uint32_t current_crc() const noexcept override { return m_impl->current_crc(); }
- virtual error decompress(void *buffer, std::uint32_t length) override { return m_impl->decompress(buffer, length); }
+ virtual std::error_condition decompress(void *buffer, std::size_t length) noexcept override { return m_impl->decompress(buffer, length); }
private:
zip_file_impl::ptr m_impl;
@@ -323,19 +384,19 @@ private:
class reader_base
{
protected:
- reader_base(void const *buf) : m_buffer(reinterpret_cast<std::uint8_t const *>(buf)) { }
+ reader_base(void const *buf) noexcept : m_buffer(reinterpret_cast<std::uint8_t const *>(buf)) { }
- std::uint8_t read_byte(std::size_t offs) const
+ std::uint8_t read_byte(std::size_t offs) const noexcept
{
return m_buffer[offs];
}
- std::uint16_t read_word(std::size_t offs) const
+ std::uint16_t read_word(std::size_t offs) const noexcept
{
return
(std::uint16_t(m_buffer[offs + 1]) << 8) |
(std::uint16_t(m_buffer[offs + 0]) << 0);
}
- std::uint32_t read_dword(std::size_t offs) const
+ std::uint32_t read_dword(std::size_t offs) const noexcept
{
return
(std::uint32_t(m_buffer[offs + 3]) << 24) |
@@ -343,7 +404,7 @@ protected:
(std::uint32_t(m_buffer[offs + 1]) << 8) |
(std::uint32_t(m_buffer[offs + 0]) << 0);
}
- std::uint64_t read_qword(std::size_t offs) const
+ std::uint64_t read_qword(std::size_t offs) const noexcept
{
return
(std::uint64_t(m_buffer[offs + 7]) << 56) |
@@ -371,17 +432,17 @@ protected:
class extra_field_reader : private reader_base
{
public:
- extra_field_reader(void const *buf, std::size_t len) : reader_base(buf), m_length(len) { }
+ extra_field_reader(void const *buf, std::size_t len) noexcept : reader_base(buf), m_length(len) { }
- std::uint16_t header_id() const { return read_word(0x00); }
- std::uint16_t data_size() const { return read_word(0x02); }
- void const * data() const { return m_buffer + 0x04; }
- extra_field_reader next() const { return extra_field_reader(m_buffer + total_length(), m_length - total_length()); }
+ std::uint16_t header_id() const noexcept { return read_word(0x00); }
+ std::uint16_t data_size() const noexcept { return read_word(0x02); }
+ void const * data() const noexcept { return m_buffer + 0x04; }
+ extra_field_reader next() const noexcept { return extra_field_reader(m_buffer + total_length(), m_length - total_length()); }
- bool length_sufficient() const { return (m_length >= minimum_length()) && (m_length >= total_length()); }
+ bool length_sufficient() const noexcept { return (m_length >= minimum_length()) && (m_length >= total_length()); }
- std::size_t total_length() const { return minimum_length() + data_size(); }
- static std::size_t minimum_length() { return 0x04; }
+ std::size_t total_length() const noexcept { return minimum_length() + data_size(); }
+ static constexpr std::size_t minimum_length() { return 0x04; }
private:
std::size_t m_length;
@@ -391,131 +452,131 @@ private:
class local_file_header_reader : private reader_base
{
public:
- local_file_header_reader(void const *buf) : reader_base(buf) { }
-
- std::uint32_t signature() const { return read_dword(0x00); }
- std::uint8_t version_needed() const { return m_buffer[0x04]; }
- std::uint8_t os_needed() const { return m_buffer[0x05]; }
- std::uint16_t general_flag() const { return read_word(0x06); }
- std::uint16_t compression_method() const { return read_word(0x08); }
- std::uint16_t modified_time() const { return read_word(0x0a); }
- std::uint16_t modified_date() const { return read_word(0x0c); }
- std::uint32_t crc32() const { return read_dword(0x0e); }
- std::uint32_t compressed_size() const { return read_dword(0x12); }
- std::uint32_t uncompressed_size() const { return read_dword(0x16); }
- std::uint16_t file_name_length() const { return read_word(0x1a); }
- std::uint16_t extra_field_length() const { return read_word(0x1c); }
+ local_file_header_reader(void const *buf) noexcept : reader_base(buf) { }
+
+ std::uint32_t signature() const noexcept { return read_dword(0x00); }
+ std::uint8_t version_needed() const noexcept { return m_buffer[0x04]; }
+ std::uint8_t os_needed() const noexcept { return m_buffer[0x05]; }
+ std::uint16_t general_flag() const noexcept { return read_word(0x06); }
+ std::uint16_t compression_method() const noexcept { return read_word(0x08); }
+ std::uint16_t modified_time() const noexcept { return read_word(0x0a); }
+ std::uint16_t modified_date() const noexcept { return read_word(0x0c); }
+ std::uint32_t crc32() const noexcept { return read_dword(0x0e); }
+ std::uint32_t compressed_size() const noexcept { return read_dword(0x12); }
+ std::uint32_t uncompressed_size() const noexcept { return read_dword(0x16); }
+ std::uint16_t file_name_length() const noexcept { return read_word(0x1a); }
+ std::uint16_t extra_field_length() const noexcept { return read_word(0x1c); }
std::string file_name() const { return read_string(0x1e, file_name_length()); }
void file_name(std::string &result) const { read_string(result, 0x1e, file_name_length()); }
- extra_field_reader extra_field() const { return extra_field_reader(m_buffer + 0x1e + file_name_length(), extra_field_length()); }
+ extra_field_reader extra_field() const noexcept { return extra_field_reader(m_buffer + 0x1e + file_name_length(), extra_field_length()); }
- bool signature_correct() const { return signature() == 0x04034b50; }
+ bool signature_correct() const noexcept { return signature() == 0x04034b50; }
- std::size_t total_length() const { return minimum_length() + file_name_length() + extra_field_length(); }
- static std::size_t minimum_length() { return 0x1e; }
+ std::size_t total_length() const noexcept { return minimum_length() + file_name_length() + extra_field_length(); }
+ static constexpr std::size_t minimum_length() { return 0x1e; }
};
class central_dir_entry_reader : private reader_base
{
public:
- central_dir_entry_reader(void const *buf) : reader_base(buf) { }
-
- std::uint32_t signature() const { return read_dword(0x00); }
- std::uint8_t version_created() const { return m_buffer[0x04]; }
- std::uint8_t os_created() const { return m_buffer[0x05]; }
- std::uint8_t version_needed() const { return m_buffer[0x06]; }
- std::uint8_t os_needed() const { return m_buffer[0x07]; }
- std::uint16_t general_flag() const { return read_word(0x08); }
- std::uint16_t compression_method() const { return read_word(0x0a); }
- std::uint16_t modified_time() const { return read_word(0x0c); }
- std::uint16_t modified_date() const { return read_word(0x0e); }
- std::uint32_t crc32() const { return read_dword(0x10); }
- std::uint32_t compressed_size() const { return read_dword(0x14); }
- std::uint32_t uncompressed_size() const { return read_dword(0x18); }
- std::uint16_t file_name_length() const { return read_word(0x1c); }
- std::uint16_t extra_field_length() const { return read_word(0x1e); }
- std::uint16_t file_comment_length() const { return read_word(0x20); }
- std::uint16_t start_disk() const { return read_word(0x22); }
- std::uint16_t int_file_attr() const { return read_word(0x24); }
- std::uint32_t ext_file_attr() const { return read_dword(0x26); }
- std::uint32_t header_offset() const { return read_dword(0x2a); }
+ central_dir_entry_reader(void const *buf) noexcept : reader_base(buf) { }
+
+ std::uint32_t signature() const noexcept { return read_dword(0x00); }
+ std::uint8_t version_created() const noexcept { return m_buffer[0x04]; }
+ std::uint8_t os_created() const noexcept { return m_buffer[0x05]; }
+ std::uint8_t version_needed() const noexcept { return m_buffer[0x06]; }
+ std::uint8_t os_needed() const noexcept { return m_buffer[0x07]; }
+ std::uint16_t general_flag() const noexcept { return read_word(0x08); }
+ std::uint16_t compression_method() const noexcept { return read_word(0x0a); }
+ std::uint16_t modified_time() const noexcept { return read_word(0x0c); }
+ std::uint16_t modified_date() const noexcept { return read_word(0x0e); }
+ std::uint32_t crc32() const noexcept { return read_dword(0x10); }
+ std::uint32_t compressed_size() const noexcept { return read_dword(0x14); }
+ std::uint32_t uncompressed_size() const noexcept { return read_dword(0x18); }
+ std::uint16_t file_name_length() const noexcept { return read_word(0x1c); }
+ std::uint16_t extra_field_length() const noexcept { return read_word(0x1e); }
+ std::uint16_t file_comment_length() const noexcept { return read_word(0x20); }
+ std::uint16_t start_disk() const noexcept { return read_word(0x22); }
+ std::uint16_t int_file_attr() const noexcept { return read_word(0x24); }
+ std::uint32_t ext_file_attr() const noexcept { return read_dword(0x26); }
+ std::uint32_t header_offset() const noexcept { return read_dword(0x2a); }
std::string file_name() const { return read_string(0x2e, file_name_length()); }
void file_name(std::string &result) const { read_string(result, 0x2e, file_name_length()); }
- extra_field_reader extra_field() const { return extra_field_reader(m_buffer + 0x2e + file_name_length(), extra_field_length()); }
+ extra_field_reader extra_field() const noexcept { return extra_field_reader(m_buffer + 0x2e + file_name_length(), extra_field_length()); }
std::string file_comment() const { return read_string(0x2e + file_name_length() + extra_field_length(), file_comment_length()); }
void file_comment(std::string &result) const { read_string(result, 0x2e + file_name_length() + extra_field_length(), file_comment_length()); }
- bool signature_correct() const { return signature() == 0x02014b50; }
+ bool signature_correct() const noexcept { return signature() == 0x02014b50; }
- std::size_t total_length() const { return minimum_length() + file_name_length() + extra_field_length() + file_comment_length(); }
- static std::size_t minimum_length() { return 0x2e; }
+ std::size_t total_length() const noexcept { return minimum_length() + file_name_length() + extra_field_length() + file_comment_length(); }
+ static constexpr std::size_t minimum_length() { return 0x2e; }
};
class ecd64_reader : private reader_base
{
public:
- ecd64_reader(void const *buf) : reader_base(buf) { }
-
- std::uint32_t signature() const { return read_dword(0x00); }
- std::uint64_t ecd64_size() const { return read_qword(0x04); }
- std::uint8_t version_created() const { return m_buffer[0x0c]; }
- std::uint8_t os_created() const { return m_buffer[0x0d]; }
- std::uint8_t version_needed() const { return m_buffer[0x0e]; }
- std::uint8_t os_needed() const { return m_buffer[0x0f]; }
- std::uint32_t this_disk_no() const { return read_dword(0x10); }
- std::uint32_t dir_start_disk() const { return read_dword(0x14); }
- std::uint64_t dir_disk_entries() const { return read_qword(0x18); }
- std::uint64_t dir_total_entries() const { return read_qword(0x20); }
- std::uint64_t dir_size() const { return read_qword(0x28); }
- std::uint64_t dir_offset() const { return read_qword(0x30); }
- void const * extensible_data() const { return m_buffer + 0x38; }
-
- bool signature_correct() const { return signature() == 0x06064b50; }
-
- std::size_t total_length() const { return 0x0c + ecd64_size(); }
- static std::size_t minimum_length() { return 0x38; }
+ ecd64_reader(void const *buf) noexcept : reader_base(buf) { }
+
+ std::uint32_t signature() const noexcept { return read_dword(0x00); }
+ std::uint64_t ecd64_size() const noexcept { return read_qword(0x04); }
+ std::uint8_t version_created() const noexcept { return m_buffer[0x0c]; }
+ std::uint8_t os_created() const noexcept { return m_buffer[0x0d]; }
+ std::uint8_t version_needed() const noexcept { return m_buffer[0x0e]; }
+ std::uint8_t os_needed() const noexcept { return m_buffer[0x0f]; }
+ std::uint32_t this_disk_no() const noexcept { return read_dword(0x10); }
+ std::uint32_t dir_start_disk() const noexcept { return read_dword(0x14); }
+ std::uint64_t dir_disk_entries() const noexcept { return read_qword(0x18); }
+ std::uint64_t dir_total_entries() const noexcept { return read_qword(0x20); }
+ std::uint64_t dir_size() const noexcept { return read_qword(0x28); }
+ std::uint64_t dir_offset() const noexcept { return read_qword(0x30); }
+ void const * extensible_data() const noexcept { return m_buffer + 0x38; }
+
+ bool signature_correct() const noexcept { return signature() == 0x06064b50; }
+
+ std::size_t total_length() const noexcept { return 0x0c + ecd64_size(); }
+ static constexpr std::size_t minimum_length() { return 0x38; }
};
class ecd64_locator_reader : private reader_base
{
public:
- ecd64_locator_reader(void const *buf) : reader_base(buf) { }
+ ecd64_locator_reader(void const *buf) noexcept : reader_base(buf) { }
- std::uint32_t signature() const { return read_dword(0x00); }
- std::uint32_t ecd64_disk() const { return read_dword(0x04); }
- std::uint64_t ecd64_offset() const { return read_qword(0x08); }
- std::uint32_t total_disks() const { return read_dword(0x10); }
+ std::uint32_t signature() const noexcept { return read_dword(0x00); }
+ std::uint32_t ecd64_disk() const noexcept { return read_dword(0x04); }
+ std::uint64_t ecd64_offset() const noexcept { return read_qword(0x08); }
+ std::uint32_t total_disks() const noexcept { return read_dword(0x10); }
- bool signature_correct() const { return signature() == 0x07064b50; }
+ bool signature_correct() const noexcept { return signature() == 0x07064b50; }
- std::size_t total_length() const { return minimum_length(); }
- static std::size_t minimum_length() { return 0x14; }
+ std::size_t total_length() const noexcept { return minimum_length(); }
+ static constexpr std::size_t minimum_length() { return 0x14; }
};
class ecd_reader : private reader_base
{
public:
- ecd_reader(void const *buf) : reader_base(buf) { }
-
- std::uint32_t signature() const { return read_dword(0x00); }
- std::uint16_t this_disk_no() const { return read_word(0x04); }
- std::uint16_t dir_start_disk() const { return read_word(0x06); }
- std::uint16_t dir_disk_entries() const { return read_word(0x08); }
- std::uint16_t dir_total_entries() const { return read_word(0x0a); }
- std::uint32_t dir_size() const { return read_dword(0x0c); }
- std::uint32_t dir_offset() const { return read_dword(0x10); }
- std::uint16_t comment_length() const { return read_word(0x14); }
+ ecd_reader(void const *buf) noexcept : reader_base(buf) { }
+
+ std::uint32_t signature() const noexcept { return read_dword(0x00); }
+ std::uint16_t this_disk_no() const noexcept { return read_word(0x04); }
+ std::uint16_t dir_start_disk() const noexcept { return read_word(0x06); }
+ std::uint16_t dir_disk_entries() const noexcept { return read_word(0x08); }
+ std::uint16_t dir_total_entries() const noexcept { return read_word(0x0a); }
+ std::uint32_t dir_size() const noexcept { return read_dword(0x0c); }
+ std::uint32_t dir_offset() const noexcept { return read_dword(0x10); }
+ std::uint16_t comment_length() const noexcept { return read_word(0x14); }
std::string comment() const { return read_string(0x16, comment_length()); }
void comment(std::string &result) const { read_string(result, 0x16, comment_length()); }
- bool signature_correct() const { return signature() == 0x06054b50; }
+ bool signature_correct() const noexcept { return signature() == 0x06054b50; }
- std::size_t total_length() const { return minimum_length() + comment_length(); }
- static std::size_t minimum_length() { return 0x16; }
+ std::size_t total_length() const noexcept { return minimum_length() + comment_length(); }
+ static constexpr std::size_t minimum_length() { return 0x16; }
};
@@ -525,7 +586,7 @@ public:
template <typename T>
zip64_ext_info_reader(
T const &header,
- extra_field_reader const &field)
+ extra_field_reader const &field) noexcept
: reader_base(field.data())
, m_uncompressed_size(header.uncompressed_size())
, m_compressed_size(header.compressed_size())
@@ -538,13 +599,13 @@ public:
{
}
- std::uint64_t uncompressed_size() const { return ~m_uncompressed_size ? m_uncompressed_size : read_qword(0x00); }
- std::uint64_t compressed_size() const { return ~m_compressed_size ? m_compressed_size : read_qword(m_offs_compressed_size); }
- std::uint64_t header_offset() const { return ~m_header_offset ? m_header_offset : read_qword(m_offs_header_offset); }
- std::uint32_t start_disk() const { return ~m_start_disk ? m_start_disk : read_dword(m_offs_start_disk); }
+ std::uint64_t uncompressed_size() const noexcept { return ~m_uncompressed_size ? m_uncompressed_size : read_qword(0x00); }
+ std::uint64_t compressed_size() const noexcept { return ~m_compressed_size ? m_compressed_size : read_qword(m_offs_compressed_size); }
+ std::uint64_t header_offset() const noexcept { return ~m_header_offset ? m_header_offset : read_qword(m_offs_header_offset); }
+ std::uint32_t start_disk() const noexcept { return ~m_start_disk ? m_start_disk : read_dword(m_offs_start_disk); }
- std::size_t total_length() const { return minimum_length() + m_offs_end; }
- static std::size_t minimum_length() { return 0x00; }
+ std::size_t total_length() const noexcept { return minimum_length() + m_offs_end; }
+ static constexpr std::size_t minimum_length() { return 0x00; }
private:
std::uint32_t m_uncompressed_size;
@@ -562,15 +623,15 @@ private:
class utf8_path_reader : private reader_base
{
public:
- utf8_path_reader(extra_field_reader const &field) : reader_base(field.data()), m_length(field.data_size()) { }
+ utf8_path_reader(extra_field_reader const &field) noexcept : reader_base(field.data()), m_length(field.data_size()) { }
- std::uint8_t version() const { return m_buffer[0]; }
- std::uint32_t name_crc32() const { return read_dword(0x01); }
+ std::uint8_t version() const noexcept { return m_buffer[0]; }
+ std::uint32_t name_crc32() const noexcept { return read_dword(0x01); }
std::string unicode_name() const { return read_string(0x05, m_length - 0x05); }
void unicode_name(std::string &result) const { return read_string(result, 0x05, m_length - 0x05); }
- std::size_t total_length() const { return m_length; }
- static std::size_t minimum_length() { return 0x05; }
+ std::size_t total_length() const noexcept { return m_length; }
+ static constexpr std::size_t minimum_length() { return 0x05; }
private:
std::size_t m_length;
@@ -580,17 +641,17 @@ private:
class ntfs_tag_reader : private reader_base
{
public:
- ntfs_tag_reader(void const *buf, std::size_t len) : reader_base(buf), m_length(len) { }
+ ntfs_tag_reader(void const *buf, std::size_t len) noexcept : reader_base(buf), m_length(len) { }
- std::uint16_t tag() const { return read_word(0x00); }
- std::uint16_t size() const { return read_word(0x02); }
- void const * data() const { return m_buffer + 0x04; }
- ntfs_tag_reader next() const { return ntfs_tag_reader(m_buffer + total_length(), m_length - total_length()); }
+ std::uint16_t tag() const noexcept { return read_word(0x00); }
+ std::uint16_t size() const noexcept { return read_word(0x02); }
+ void const * data() const noexcept { return m_buffer + 0x04; }
+ ntfs_tag_reader next() const noexcept { return ntfs_tag_reader(m_buffer + total_length(), m_length - total_length()); }
- bool length_sufficient() const { return (m_length >= minimum_length()) && (m_length >= total_length()); }
+ bool length_sufficient() const noexcept { return (m_length >= minimum_length()) && (m_length >= total_length()); }
- std::size_t total_length() const { return minimum_length() + size(); }
- static std::size_t minimum_length() { return 0x04; }
+ std::size_t total_length() const noexcept { return minimum_length() + size(); }
+ static constexpr std::size_t minimum_length() { return 0x04; }
private:
std::size_t m_length;
@@ -600,13 +661,13 @@ private:
class ntfs_reader : private reader_base
{
public:
- ntfs_reader(extra_field_reader const &field) : reader_base(field.data()), m_length(field.data_size()) { }
+ ntfs_reader(extra_field_reader const &field) noexcept : reader_base(field.data()), m_length(field.data_size()) { }
- std::uint32_t reserved() const { return read_dword(0x00); }
- ntfs_tag_reader tag1() const { return ntfs_tag_reader(m_buffer + 0x04, m_length - 4); }
+ std::uint32_t reserved() const noexcept { return read_dword(0x00); }
+ ntfs_tag_reader tag1() const noexcept { return ntfs_tag_reader(m_buffer + 0x04, m_length - 4); }
- std::size_t total_length() const { return m_length; }
- static std::size_t minimum_length() { return 0x08; }
+ std::size_t total_length() const noexcept { return m_length; }
+ static constexpr std::size_t minimum_length() { return 0x08; }
private:
std::size_t m_length;
@@ -616,14 +677,14 @@ private:
class ntfs_times_reader : private reader_base
{
public:
- ntfs_times_reader(ntfs_tag_reader const &tag) : reader_base(tag.data()) { }
+ ntfs_times_reader(ntfs_tag_reader const &tag) noexcept : reader_base(tag.data()) { }
- std::uint64_t mtime() const { return read_qword(0x00); }
- std::uint64_t atime() const { return read_qword(0x08); }
- std::uint64_t ctime() const { return read_qword(0x10); }
+ std::uint64_t mtime() const noexcept { return read_qword(0x00); }
+ std::uint64_t atime() const noexcept { return read_qword(0x08); }
+ std::uint64_t ctime() const noexcept { return read_qword(0x10); }
- std::size_t total_length() const { return minimum_length(); }
- static std::size_t minimum_length() { return 0x18; }
+ std::size_t total_length() const noexcept { return minimum_length(); }
+ static constexpr std::size_t minimum_length() { return 0x18; }
};
@@ -632,16 +693,16 @@ class general_flag_reader
public:
general_flag_reader(std::uint16_t val) : m_value(val) { }
- bool encrypted() const { return bool(m_value & 0x0001); }
- bool implode_8k_dict() const { return bool(m_value & 0x0002); }
- bool implode_3_trees() const { return bool(m_value & 0x0004); }
- unsigned deflate_option() const { return unsigned((m_value >> 1) & 0x0003); }
- bool lzma_eos_mark() const { return bool(m_value & 0x0002); }
- bool use_descriptor() const { return bool(m_value & 0x0008); }
- bool patch_data() const { return bool(m_value & 0x0020); }
- bool strong_encryption() const { return bool(m_value & 0x0040); }
- bool utf8_encoding() const { return bool(m_value & 0x0800); }
- bool directory_encryption() const { return bool(m_value & 0x2000); }
+ bool encrypted() const noexcept { return bool(m_value & 0x0001); }
+ bool implode_8k_dict() const noexcept { return bool(m_value & 0x0002); }
+ bool implode_3_trees() const noexcept { return bool(m_value & 0x0004); }
+ unsigned deflate_option() const noexcept { return unsigned((m_value >> 1) & 0x0003); }
+ bool lzma_eos_mark() const noexcept { return bool(m_value & 0x0002); }
+ bool use_descriptor() const noexcept { return bool(m_value & 0x0008); }
+ bool patch_data() const noexcept { return bool(m_value & 0x0020); }
+ bool strong_encryption() const noexcept { return bool(m_value & 0x0040); }
+ bool utf8_encoding() const noexcept { return bool(m_value & 0x0800); }
+ bool directory_encryption() const noexcept { return bool(m_value & 0x2000); }
private:
std::uint16_t m_value;
@@ -653,6 +714,8 @@ private:
GLOBAL VARIABLES
***************************************************************************/
+archive_category_impl const f_archive_category_instance;
+
std::array<zip_file_impl::ptr, zip_file_impl::CACHE_SIZE> zip_file_impl::s_cache;
std::mutex zip_file_impl::s_cache_mutex;
@@ -663,33 +726,38 @@ std::mutex zip_file_impl::s_cache_mutex;
to the cache
-------------------------------------------------*/
-void zip_file_impl::close(ptr &&zip)
+void zip_file_impl::close(ptr &&zip) noexcept
{
- if (!zip) return;
+ // if the filename isn't empty, the cached directory can be reused
+ if (zip && !zip->m_filename.empty())
+ {
+ // close the open files
+ osd_printf_verbose("unzip: closing archive file %s and sending to cache\n", zip->m_filename);
+ zip->m_file.reset();
- // close the open files
- osd_printf_verbose("unzip: closing archive file %s and sending to cache\n", zip->m_filename);
- zip->m_file.reset();
+ // find the first nullptr entry in the cache
+ std::lock_guard<std::mutex> guard(s_cache_mutex);
+ std::size_t cachenum;
+ for (cachenum = 0; cachenum < s_cache.size(); cachenum++)
+ if (!s_cache[cachenum])
+ break;
- // find the first nullptr entry in the cache
- std::lock_guard<std::mutex> guard(s_cache_mutex);
- std::size_t cachenum;
- for (cachenum = 0; cachenum < s_cache.size(); cachenum++)
- if (!s_cache[cachenum])
- break;
+ // if no room left in the cache, free the bottommost entry
+ if (cachenum == s_cache.size())
+ {
+ cachenum--;
+ osd_printf_verbose("unzip: removing %s from cache to make space\n", s_cache[cachenum]->m_filename);
+ s_cache[cachenum].reset();
+ }
- // if no room left in the cache, free the bottommost entry
- if (cachenum == s_cache.size())
- {
- cachenum--;
- osd_printf_verbose("unzip: removing %s from cache to make space\n", s_cache[cachenum]->m_filename);
- s_cache[cachenum].reset();
+ // move everyone else down and place us at the top
+ for ( ; cachenum > 0; cachenum--)
+ s_cache[cachenum] = std::move(s_cache[cachenum - 1]);
+ s_cache[0] = std::move(zip);
}
- // move everyone else down and place us at the top
- for ( ; cachenum > 0; cachenum--)
- s_cache[cachenum] = std::move(s_cache[cachenum - 1]);
- s_cache[0] = std::move(zip);
+ // make sure it's cleaned up
+ zip.reset();
}
@@ -702,7 +770,7 @@ void zip_file_impl::close(ptr &&zip)
entry in the ZIP
-------------------------------------------------*/
-int zip_file_impl::search(std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname, bool partialpath)
+int zip_file_impl::search(std::uint32_t search_crc, std::string_view search_filename, bool matchcrc, bool matchname, bool partialpath) noexcept
{
// if we're at or past the end, we're done
while ((m_cd_pos + central_dir_entry_reader::minimum_length()) <= m_ecd.cd_size)
@@ -712,98 +780,123 @@ int zip_file_impl::search(std::uint32_t search_crc, const std::string &search_fi
if (!reader.signature_correct() || ((m_cd_pos + reader.total_length()) > m_ecd.cd_size))
break;
- // extract file header info
- m_header.version_created = reader.version_created();
- m_header.version_needed = reader.version_needed();
- m_header.bit_flag = reader.general_flag();
- m_header.compression = reader.compression_method();
- m_header.crc = reader.crc32();
- m_header.compressed_length = reader.compressed_size();
- m_header.uncompressed_length = reader.uncompressed_size();
- m_header.start_disk_number = reader.start_disk();
- m_header.local_header_offset = reader.header_offset();
-
- // don't immediately decode DOS timestamp - it's expensive
- m_header.modified_date = reader.modified_date();
- m_header.modified_time = reader.modified_time();
- m_header.modified_cached = false;
-
- // advance the position
- m_cd_pos += reader.total_length();
-
- // copy the filename
- bool is_utf8(general_flag_reader(m_header.bit_flag).utf8_encoding());
- reader.file_name(m_header.file_name);
-
- // walk the extra data
- for (auto extra = reader.extra_field(); extra.length_sufficient(); extra = extra.next())
+ // setting std::string can raise allocation exceptions
+ try
{
- // look for ZIP64 extended info
- if ((extra.header_id() == 0x0001) && (extra.data_size() >= zip64_ext_info_reader::minimum_length()))
+ // extract file header info
+ file_header header;
+ header.version_created = reader.version_created();
+ header.version_needed = reader.version_needed();
+ header.bit_flag = reader.general_flag();
+ header.compression = reader.compression_method();
+ header.crc = reader.crc32();
+ header.compressed_length = reader.compressed_size();
+ header.uncompressed_length = reader.uncompressed_size();
+ header.start_disk_number = reader.start_disk();
+ header.local_header_offset = reader.header_offset();
+
+ // don't immediately decode DOS timestamp - it's expensive
+ header.modified_date = reader.modified_date();
+ header.modified_time = reader.modified_time();
+ header.modified_cached = false;
+
+ // copy the filename
+ bool is_utf8(general_flag_reader(header.bit_flag).utf8_encoding());
+ reader.file_name(header.file_name);
+
+ // walk the extra data
+ for (auto extra = reader.extra_field(); extra.length_sufficient(); extra = extra.next())
{
- zip64_ext_info_reader const ext64(reader, extra);
- if (extra.data_size() >= ext64.total_length())
+ // look for ZIP64 extended info
+ if ((extra.header_id() == 0x0001) && (extra.data_size() >= zip64_ext_info_reader::minimum_length()))
{
- m_header.compressed_length = ext64.compressed_size();
- m_header.uncompressed_length = ext64.uncompressed_size();
- m_header.start_disk_number = ext64.start_disk();
- m_header.local_header_offset = ext64.header_offset();
+ zip64_ext_info_reader const ext64(reader, extra);
+ if (extra.data_size() >= ext64.total_length())
+ {
+ header.compressed_length = ext64.compressed_size();
+ header.uncompressed_length = ext64.uncompressed_size();
+ header.start_disk_number = ext64.start_disk();
+ header.local_header_offset = ext64.header_offset();
+ }
}
- }
- // look for Info-ZIP UTF-8 path
- if (!is_utf8 && (extra.header_id() == 0x7075) && (extra.data_size() >= utf8_path_reader::minimum_length()))
- {
- utf8_path_reader const utf8path(extra);
- if (utf8path.version() == 1)
+ // look for Info-ZIP UTF-8 path
+ if (!is_utf8 && (extra.header_id() == 0x7075) && (extra.data_size() >= utf8_path_reader::minimum_length()))
{
- auto const addr(m_header.file_name.empty() ? nullptr : &m_header.file_name[0]);
- auto const length(m_header.file_name.empty() ? 0 : m_header.file_name.length() * sizeof(m_header.file_name[0]));
- auto const crc(crc32_creator::simple(addr, length));
- if (utf8path.name_crc32() == crc.m_raw)
+ utf8_path_reader const utf8path(extra);
+ if (utf8path.version() == 1)
{
- utf8path.unicode_name(m_header.file_name);
- is_utf8 = true;
+ auto const addr(header.file_name.empty() ? nullptr : &header.file_name[0]);
+ auto const length(header.file_name.empty() ? 0 : header.file_name.length() * sizeof(header.file_name[0]));
+ auto const crc(crc32_creator::simple(addr, length));
+ if (utf8path.name_crc32() == crc.m_raw)
+ {
+ utf8path.unicode_name(header.file_name);
+ is_utf8 = true;
+ }
}
}
- }
- // look for NTFS extra field
- if ((extra.header_id() == 0x000a) && (extra.data_size() >= ntfs_reader::minimum_length()))
- {
- ntfs_reader const ntfs(extra);
- for (auto tag = ntfs.tag1(); tag.length_sufficient(); tag = tag.next())
+ // look for NTFS extra field
+ if ((extra.header_id() == 0x000a) && (extra.data_size() >= ntfs_reader::minimum_length()))
{
- if ((tag.tag() == 0x0001) && (tag.size() >= ntfs_times_reader::minimum_length()))
+ ntfs_reader const ntfs(extra);
+ for (auto tag = ntfs.tag1(); tag.length_sufficient(); tag = tag.next())
{
- ntfs_times_reader const times(tag);
- ntfs_duration const ticks(times.mtime());
- m_header.modified = system_clock_time_point_from_ntfs_duration(ticks);
- m_header.modified_cached = true;
+ if ((tag.tag() == 0x0001) && (tag.size() >= ntfs_times_reader::minimum_length()))
+ {
+ ntfs_times_reader const times(tag);
+ ntfs_duration const ticks(times.mtime());
+ try
+ {
+ header.modified = system_clock_time_point_from_ntfs_duration(ticks);
+ header.modified_cached = true;
+ }
+ catch (...)
+ {
+ // out-of-range exception - let it fall back to DOS-style timestamp
+ }
+ }
}
}
}
- }
- // FIXME: if (!is_utf8) convert filename to UTF8 (assume CP437 or something)
+ // FIXME: if (!is_utf8) convert filename to UTF8 (assume CP437 or something)
- // chop off trailing slash for directory entries
- bool const is_dir(!m_header.file_name.empty() && (m_header.file_name.back() == '/'));
- if (is_dir) m_header.file_name.resize(m_header.file_name.length() - 1);
+ // chop off trailing slash for directory entries
+ bool const is_dir(!header.file_name.empty() && (header.file_name.back() == '/'));
+ if (is_dir)
+ header.file_name.resize(header.file_name.length() - 1);
- // check to see if it matches query
- bool const crcmatch(search_crc == m_header.crc);
- auto const partialoffset(m_header.file_name.length() - search_filename.length());
- bool const partialpossible((m_header.file_name.length() > search_filename.length()) && (m_header.file_name[partialoffset - 1] == '/'));
- const bool namematch(
- !core_stricmp(search_filename.c_str(), m_header.file_name.c_str()) ||
- (partialpath && partialpossible && !core_stricmp(search_filename.c_str(), m_header.file_name.c_str() + partialoffset)));
+ // advance the position
+ m_header = std::move(header);
+ m_curr_is_dir = is_dir;
+ m_cd_pos += reader.total_length();
+ }
+ catch (...)
+ {
+ break;
+ }
- bool const found = ((!matchcrc && !matchname) || !is_dir) && (!matchcrc || crcmatch) && (!matchname || namematch);
- if (found)
+ // quick return if not required to match on name
+ if (!matchname)
{
- m_curr_is_dir = is_dir;
- return 0;
+ if (!matchcrc || ((search_crc == m_header.crc) && !m_curr_is_dir))
+ return 0;
+ }
+ else if (!m_curr_is_dir)
+ {
+ // check to see if it matches query
+ auto const partialoffset = m_header.file_name.length() - search_filename.length();
+ const bool namematch =
+ (search_filename.length() == m_header.file_name.length()) &&
+ (search_filename.empty() || !core_strnicmp(&search_filename[0], &m_header.file_name[0], search_filename.length()));
+ bool const partialmatch =
+ partialpath &&
+ ((m_header.file_name.length() > search_filename.length()) && (m_header.file_name[partialoffset - 1] == '/')) &&
+ (search_filename.empty() || !core_strnicmp(&search_filename[0], &m_header.file_name[partialoffset], search_filename.length()));
+ if ((!matchcrc || (search_crc == m_header.crc)) && (namematch || partialmatch))
+ return 0;
}
}
return -1;
@@ -815,11 +908,8 @@ int zip_file_impl::search(std::uint32_t search_crc, const std::string &search_fi
from a ZIP into the target buffer
-------------------------------------------------*/
-archive_file::error zip_file_impl::decompress(void *buffer, std::uint32_t length)
+std::error_condition zip_file_impl::decompress(void *buffer, std::size_t length) noexcept
{
- archive_file::error ziperr;
- std::uint64_t offset;
-
// if we don't have enough buffer, error
if (length < m_header.uncompressed_length)
{
@@ -835,33 +925,29 @@ archive_file::error zip_file_impl::decompress(void *buffer, std::uint32_t length
}
// get the compressed data offset
- ziperr = get_compressed_data_offset(offset);
- if (ziperr != archive_file::error::NONE)
+ std::uint64_t offset;
+ auto const ziperr = get_compressed_data_offset(offset);
+ if (ziperr)
return ziperr;
// handle compression types
switch (m_header.compression)
{
case 0:
- ziperr = decompress_data_type_0(offset, buffer, length);
- break;
+ return decompress_data_type_0(offset, buffer, length);
case 8:
- ziperr = decompress_data_type_8(offset, buffer, length);
- break;
+ return decompress_data_type_8(offset, buffer, length);
case 14:
- ziperr = decompress_data_type_14(offset, buffer, length);
- break;
+ return decompress_data_type_14(offset, buffer, length);
default:
osd_printf_error(
"unzip: %s in %s uses unsupported compression method %u\n",
- m_header.file_name.c_str(), m_filename.c_str(), m_header.compression);
- ziperr = archive_file::error::UNSUPPORTED;
- break;
+ m_header.file_name, m_filename, m_header.compression);
+ return archive_file::error::UNSUPPORTED;
}
- return ziperr;
}
@@ -874,16 +960,16 @@ archive_file::error zip_file_impl::decompress(void *buffer, std::uint32_t length
read_ecd - read the ECD data
-------------------------------------------------*/
-archive_file::error zip_file_impl::read_ecd()
+std::error_condition zip_file_impl::read_ecd() noexcept
{
// make sure the file handle is open
auto const ziperr = reopen();
- if (ziperr != archive_file::error::NONE)
+ if (ziperr)
return ziperr;
// we may need multiple tries
- osd_file::error error;
- std::uint32_t read_length;
+ std::error_condition filerr;
+ std::size_t read_length;
std::uint32_t buflen = 1024;
while (buflen < 65536)
{
@@ -893,19 +979,26 @@ archive_file::error zip_file_impl::read_ecd()
// allocate buffer
std::unique_ptr<std::uint8_t []> buffer;
- try { buffer.reset(new std::uint8_t[buflen + 1]); }
- catch (...)
+ buffer.reset(new (std::nothrow) std::uint8_t[buflen + 1]);
+ if (!buffer)
{
osd_printf_error("unzip: %s failed to allocate memory for ECD search\n", m_filename);
- return archive_file::error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
// read in one buffers' worth of data
- error = m_file->read(&buffer[0], m_length - buflen, buflen, read_length);
- if ((error != osd_file::error::NONE) || (read_length != buflen))
+ filerr = m_file->read_at(m_length - buflen, &buffer[0], buflen, read_length);
+ if (filerr)
+ {
+ osd_printf_error(
+ "unzip: error reading %s to search for ECD (%s:%d %s)\n",
+ m_filename, filerr.category().name(), filerr.value(), filerr.message());
+ return filerr;
+ }
+ if (read_length != buflen)
{
- osd_printf_error("unzip: %s error reading file to search for ECD (%d)\n", m_filename, int(error));
- return archive_file::error::FILE_ERROR;
+ osd_printf_error("unzip: unexpectedly reached end-of-file while reading %s to search for ECD\n", m_filename);
+ return archive_file::error::FILE_TRUNCATED;
}
// find the ECD signature
@@ -935,19 +1028,26 @@ archive_file::error zip_file_impl::read_ecd()
if ((m_length - buflen + offset) < ecd64_locator_reader::minimum_length())
{
osd_printf_verbose("unzip: %s too small to contain ZIP64 ECD locator\n", m_filename);
- return archive_file::error::NONE;
+ return std::error_condition();
}
// try to read the ZIP64 ECD locator
- error = m_file->read(
- &buffer[0],
+ filerr = m_file->read_at(
m_length - buflen + offset - ecd64_locator_reader::minimum_length(),
+ &buffer[0],
ecd64_locator_reader::minimum_length(),
read_length);
- if ((error != osd_file::error::NONE) || (read_length != ecd64_locator_reader::minimum_length()))
+ if (filerr)
+ {
+ osd_printf_error(
+ "unzip: error reading %s to search for ZIP64 ECD locator (%s:%d %s)\n",
+ m_filename, filerr.category().name(), filerr.value(), filerr.message());
+ return filerr;
+ }
+ if (read_length != ecd64_locator_reader::minimum_length())
{
- osd_printf_error("unzip: error reading %s to search for ZIP64 ECD locator (%d)\n", m_filename, int(error));
- return archive_file::error::FILE_ERROR;
+ osd_printf_error("unzip: unexpectedly reached end-of-file while reading %s to search for ZIP64 ECD locator\n", m_filename);
+ return archive_file::error::FILE_TRUNCATED;
}
// if the signature isn't correct, it's not a ZIP64 archive
@@ -955,7 +1055,7 @@ archive_file::error zip_file_impl::read_ecd()
if (!ecd64_loc_rd.signature_correct())
{
osd_printf_verbose("unzip: %s has no ZIP64 ECD locator\n", m_filename);
- return archive_file::error::NONE;
+ return std::error_condition();
}
// check that the ZIP64 ECD is in this segment (assuming this segment is the last segment)
@@ -966,11 +1066,13 @@ archive_file::error zip_file_impl::read_ecd()
}
// try to read the ZIP64 ECD
- error = m_file->read(&buffer[0], ecd64_loc_rd.ecd64_offset(), ecd64_reader::minimum_length(), read_length);
- if (error != osd_file::error::NONE)
+ filerr = m_file->read_at(ecd64_loc_rd.ecd64_offset(), &buffer[0], ecd64_reader::minimum_length(), read_length);
+ if (filerr)
{
- osd_printf_error("unzip: error reading %s ZIP64 ECD (%d)\n", m_filename, int(error));
- return archive_file::error::FILE_ERROR;
+ osd_printf_error(
+ "unzip: error reading %s ZIP64 ECD (%s:%d %s)\n",
+ m_filename, filerr.category().name(), filerr.value(), filerr.message());
+ return filerr;
}
if (read_length != ecd64_reader::minimum_length())
{
@@ -983,8 +1085,8 @@ archive_file::error zip_file_impl::read_ecd()
if (!ecd64_rd.signature_correct())
{
osd_printf_error(
- "unzip: %s ZIP64 ECD has incorrect signature 0x%08lx\n",
- m_filename.c_str(), long(ecd64_rd.signature()));
+ "unzip: %s ZIP64 ECD has incorrect signature 0x%08x\n",
+ m_filename, ecd64_rd.signature());
return archive_file::error::BAD_SIGNATURE;
}
if (ecd64_rd.total_length() < ecd64_reader::minimum_length())
@@ -996,7 +1098,7 @@ archive_file::error zip_file_impl::read_ecd()
{
osd_printf_error(
"unzip: %s ZIP64 ECD requires unsupported version %u.%u\n",
- m_filename.c_str(), unsigned(ecd64_rd.version_needed() / 10), unsigned(ecd64_rd.version_needed() % 10));
+ m_filename, ecd64_rd.version_needed() / 10, ecd64_rd.version_needed() % 10);
return archive_file::error::UNSUPPORTED;
}
osd_printf_verbose("unzip: found %s ZIP64 ECD\n", m_filename);
@@ -1009,7 +1111,7 @@ archive_file::error zip_file_impl::read_ecd()
m_ecd.cd_size = ecd64_rd.dir_size();
m_ecd.cd_start_disk_offset = ecd64_rd.dir_offset();
- return archive_file::error::NONE;
+ return std::error_condition();
}
// didn't find it; free this buffer and expand our search
@@ -1024,7 +1126,7 @@ archive_file::error zip_file_impl::read_ecd()
}
}
osd_printf_error("unzip: %s couldn't find ECD in last 64KiB\n", m_filename);
- return archive_file::error::OUT_OF_MEMORY;
+ return archive_file::error::UNSUPPORTED; // TODO: revisit this error code
}
@@ -1033,7 +1135,7 @@ archive_file::error zip_file_impl::read_ecd()
offset of the compressed data
-------------------------------------------------*/
-archive_file::error zip_file_impl::get_compressed_data_offset(std::uint64_t &offset)
+std::error_condition zip_file_impl::get_compressed_data_offset(std::uint64_t &offset) noexcept
{
// don't support a number of features
general_flag_reader const flags(m_header.bit_flag);
@@ -1046,7 +1148,7 @@ archive_file::error zip_file_impl::get_compressed_data_offset(std::uint64_t &off
{
osd_printf_error(
"unzip: %s in %s requires unsupported version %u.%u\n",
- m_header.file_name.c_str(), m_filename.c_str(), unsigned(m_header.version_needed / 10), unsigned(m_header.version_needed % 10));
+ m_header.file_name, m_filename, m_header.version_needed / 10, m_header.version_needed % 10);
return archive_file::error::UNSUPPORTED;
}
if (flags.encrypted() || flags.strong_encryption())
@@ -1062,24 +1164,24 @@ archive_file::error zip_file_impl::get_compressed_data_offset(std::uint64_t &off
// make sure the file handle is open
auto const ziperr = reopen();
- if (ziperr != archive_file::error::NONE)
+ if (ziperr)
return ziperr;
// now go read the fixed-sized part of the local file header
- std::uint32_t read_length;
- auto const error = m_file->read(&m_buffer[0], m_header.local_header_offset, local_file_header_reader::minimum_length(), read_length);
- if (error != osd_file::error::NONE)
+ std::size_t read_length;
+ std::error_condition const filerr = m_file->read_at(m_header.local_header_offset, &m_buffer[0], local_file_header_reader::minimum_length(), read_length);
+ if (filerr)
{
osd_printf_error(
- "unzip: error reading local file header for %s in %s (%d)\n",
- m_header.file_name.c_str(), m_filename.c_str(), int(error));
- return archive_file::error::FILE_ERROR;
+ "unzip: error reading local file header for %s in %s (%s:%d %s)\n",
+ m_header.file_name, m_filename, filerr.category().name(), filerr.value(), filerr.message());
+ return filerr;
}
if (read_length != local_file_header_reader::minimum_length())
{
osd_printf_error(
"unzip: unexpectedly reached end-of-file while reading local file header for %s in %s\n",
- m_header.file_name.c_str(), m_filename.c_str());
+ m_header.file_name, m_filename);
return archive_file::error::FILE_TRUNCATED;
}
@@ -1088,13 +1190,13 @@ archive_file::error zip_file_impl::get_compressed_data_offset(std::uint64_t &off
if (!reader.signature_correct())
{
osd_printf_error(
- "unzip: local file header for %s in %s has incorrect signature %04lx\n",
- m_header.file_name.c_str(), m_filename.c_str(), long(reader.signature()));
+ "unzip: local file header for %s in %s has incorrect signature %04x\n",
+ m_header.file_name, m_filename, reader.signature());
return archive_file::error::BAD_SIGNATURE;
}
offset = m_header.local_header_offset + reader.total_length();
- return archive_file::error::NONE;
+ return std::error_condition();
}
@@ -1108,24 +1210,28 @@ archive_file::error zip_file_impl::get_compressed_data_offset(std::uint64_t &off
type 0 data (which is uncompressed)
-------------------------------------------------*/
-archive_file::error zip_file_impl::decompress_data_type_0(std::uint64_t offset, void *buffer, std::uint32_t length)
+std::error_condition zip_file_impl::decompress_data_type_0(std::uint64_t offset, void *buffer, std::size_t length) noexcept
{
// the data is uncompressed; just read it
- std::uint32_t read_length(0);
- auto const filerr = m_file->read(buffer, offset, m_header.compressed_length, read_length);
- if (filerr != osd_file::error::NONE)
+ std::size_t read_length(0);
+ std::error_condition const filerr = m_file->read_at(offset, buffer, m_header.compressed_length, read_length);
+ if (filerr)
{
- osd_printf_error("unzip: error reading %s from %s (%d)\n", m_header.file_name, m_filename, int(filerr));
- return archive_file::error::FILE_ERROR;
+ osd_printf_error(
+ "unzip: error reading %s from %s (%s:%d %s)\n",
+ m_header.file_name, m_filename, filerr.category().name(), filerr.value(), filerr.message());
+ return filerr;
}
else if (read_length != m_header.compressed_length)
{
- osd_printf_error("unzip: unexpectedly reached end-of-file while reading %s from %s\n", m_header.file_name, m_filename);
+ osd_printf_error(
+ "unzip: unexpectedly reached end-of-file while reading %s from %s\n",
+ m_header.file_name, m_filename);
return archive_file::error::FILE_TRUNCATED;
}
else
{
- return archive_file::error::NONE;
+ return std::error_condition();
}
}
@@ -1135,8 +1241,23 @@ archive_file::error zip_file_impl::decompress_data_type_0(std::uint64_t offset,
type 8 data (which is deflated)
-------------------------------------------------*/
-archive_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset, void *buffer, std::uint32_t length)
+std::error_condition zip_file_impl::decompress_data_type_8(std::uint64_t offset, void *buffer, std::size_t length) noexcept
{
+ auto const convert_zerr =
+ [] (int e) -> std::error_condition
+ {
+ switch (e)
+ {
+ case Z_OK:
+ return std::error_condition();
+ case Z_ERRNO:
+ return std::error_condition(errno, std::generic_category());
+ case Z_MEM_ERROR:
+ return std::errc::not_enough_memory;
+ default:
+ return archive_file::error::DECOMPRESS_ERROR;
+ }
+ };
std::uint64_t input_remaining = m_header.compressed_length;
int zerr;
@@ -1153,38 +1274,39 @@ archive_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset,
zerr = inflateInit2(&stream, -MAX_WBITS);
if (zerr != Z_OK)
{
+ auto result = convert_zerr(zerr);
osd_printf_error(
"unzip: error allocating zlib stream to inflate %s from %s (%d)\n",
- m_header.file_name.c_str(), m_filename.c_str(), zerr);
- return archive_file::error::DECOMPRESS_ERROR;
+ m_header.file_name, m_filename, zerr);
+ return result;
}
// loop until we're done
while (true)
{
// read in the next chunk of data
- std::uint32_t read_length(0);
- auto const filerr = m_file->read(
- &m_buffer[0],
+ std::size_t read_length(0);
+ auto const filerr = m_file->read_at(
offset,
- std::uint32_t((std::min<std::uint64_t>)(input_remaining, m_buffer.size())),
+ &m_buffer[0],
+ std::size_t((std::min<std::uint64_t>)(input_remaining, m_buffer.size())),
read_length);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
osd_printf_error(
- "unzip: error reading compressed data for %s in %s (%d)\n",
- m_header.file_name.c_str(), m_filename.c_str(), int(filerr));
+ "unzip: error reading compressed data for %s in %s (%s:%d %s)\n",
+ m_header.file_name, m_filename, filerr.category().name(), filerr.value(), filerr.message());
inflateEnd(&stream);
- return archive_file::error::FILE_ERROR;
+ return filerr;
}
offset += read_length;
// if we read nothing, but still have data left, the file is truncated
- if ((read_length == 0) && (input_remaining > 0))
+ if (!read_length && input_remaining)
{
osd_printf_error(
"unzip: unexpectedly reached end-of-file while reading compressed data for %s in %s\n",
- m_header.file_name.c_str(), m_filename.c_str());
+ m_header.file_name, m_filename);
inflateEnd(&stream);
return archive_file::error::FILE_TRUNCATED;
}
@@ -1206,9 +1328,12 @@ archive_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset,
}
else if (zerr != Z_OK)
{
- osd_printf_error("unzip: error inflating %s from %s (%d)\n", m_header.file_name, m_filename, zerr);
+ auto result = convert_zerr(zerr);
+ osd_printf_error(
+ "unzip: error inflating %s from %s (%d)\n",
+ m_header.file_name, m_filename, zerr);
inflateEnd(&stream);
- return archive_file::error::DECOMPRESS_ERROR;
+ return result;
}
}
@@ -1216,20 +1341,23 @@ archive_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset,
zerr = inflateEnd(&stream);
if (zerr != Z_OK)
{
- osd_printf_error("unzip: error finishing inflation of %s from %s (%d)\n", m_header.file_name, m_filename, zerr);
- return archive_file::error::DECOMPRESS_ERROR;
+ auto result = convert_zerr(zerr);
+ osd_printf_error(
+ "unzip: error finishing inflation of %s from %s (%d)\n",
+ m_header.file_name, m_filename, zerr);
+ return result;
}
// if anything looks funny, report an error
- if ((stream.avail_out > 0) || (input_remaining > 0))
+ if (stream.avail_out || input_remaining)
{
osd_printf_error(
"unzip: inflation of %s from %s doesn't appear to have completed correctly\n",
- m_header.file_name.c_str(), m_filename.c_str());
+ m_header.file_name, m_filename);
return archive_file::error::DECOMPRESS_ERROR;
}
- return archive_file::error::NONE;
+ return std::error_condition();
}
@@ -1238,7 +1366,7 @@ archive_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset,
type 14 data (LZMA)
-------------------------------------------------*/
-archive_file::error zip_file_impl::decompress_data_type_14(std::uint64_t offset, void *buffer, std::uint32_t length)
+std::error_condition zip_file_impl::decompress_data_type_14(std::uint64_t offset, void *buffer, std::size_t length) noexcept
{
// two-byte version
// two-byte properties size (little-endian)
@@ -1253,15 +1381,15 @@ archive_file::error zip_file_impl::decompress_data_type_14(std::uint64_t offset,
SizeT output_remaining(length);
std::uint64_t input_remaining(m_header.compressed_length);
- std::uint32_t read_length;
- osd_file::error filerr;
+ std::size_t read_length;
+ std::error_condition filerr;
SRes lzerr;
ELzmaStatus lzstatus(LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK);
// reset the stream
ISzAlloc alloc_imp;
- alloc_imp.Alloc = [](void *p, std::size_t size) -> void * { return (size == 0) ? nullptr : std::malloc(size); };
- alloc_imp.Free = [](void *p, void *address) -> void { std::free(address); };
+ alloc_imp.Alloc = [] (void *p, std::size_t size) -> void * { return size ? std::malloc(size) : nullptr; };
+ alloc_imp.Free = [] (void *p, void *address) -> void { std::free(address); };
CLzmaDec stream;
LzmaDec_Construct(&stream);
@@ -1270,16 +1398,16 @@ archive_file::error zip_file_impl::decompress_data_type_14(std::uint64_t offset,
{
osd_printf_error(
"unzip:compressed data for %s in %s is too small to hold LZMA properties header\n",
- m_header.file_name.c_str(), m_filename.c_str());
+ m_header.file_name, m_filename);
return archive_file::error::DECOMPRESS_ERROR;
}
- filerr = m_file->read(&m_buffer[0], offset, 4, read_length);
- if (filerr != osd_file::error::NONE)
+ filerr = m_file->read_at(offset, &m_buffer[0], 4, read_length);
+ if (filerr)
{
osd_printf_error(
- "unzip: error reading LZMA properties header for %s in %s (%d)\n",
- m_header.file_name.c_str(), m_filename.c_str(), int(filerr));
- return archive_file::error::FILE_ERROR;
+ "unzip: error reading LZMA properties header for %s in %s (%s:%d %s)\n",
+ m_header.file_name, m_filename, filerr.category().name(), filerr.value(), filerr.message());
+ return filerr;
}
offset += read_length;
input_remaining -= read_length;
@@ -1287,7 +1415,7 @@ archive_file::error zip_file_impl::decompress_data_type_14(std::uint64_t offset,
{
osd_printf_error(
"unzip: unexpectedly reached end-of-file while reading LZMA properties header for %s in %s\n",
- m_header.file_name.c_str(), m_filename.c_str());
+ m_header.file_name, m_filename);
return archive_file::error::FILE_TRUNCATED;
}
std::uint16_t const props_size((std::uint16_t(m_buffer[3]) << 8) | std::uint16_t(m_buffer[2]));
@@ -1295,23 +1423,23 @@ archive_file::error zip_file_impl::decompress_data_type_14(std::uint64_t offset,
{
osd_printf_error(
"unzip: %s in %s has excessively large LZMA properties\n",
- m_header.file_name.c_str(), m_filename.c_str());
+ m_header.file_name, m_filename);
return archive_file::error::UNSUPPORTED;
}
else if (props_size > input_remaining)
{
osd_printf_error(
"unzip:compressed data for %s in %s is too small to hold LZMA properties\n",
- m_header.file_name.c_str(), m_filename.c_str());
+ m_header.file_name, m_filename);
return archive_file::error::DECOMPRESS_ERROR;
}
- filerr = m_file->read(&m_buffer[0], offset, props_size, read_length);
- if (filerr != osd_file::error::NONE)
+ filerr = m_file->read_at(offset, &m_buffer[0], props_size, read_length);
+ if (filerr)
{
osd_printf_error(
- "unzip: error reading LZMA properties for %s in %s (%d)\n",
- m_header.file_name.c_str(), m_filename.c_str(), int(filerr));
- return archive_file::error::FILE_ERROR;
+ "unzip: error reading LZMA properties for %s in %s (%s:%d %s)\n",
+ m_header.file_name, m_filename, filerr.category().name(), filerr.value(), filerr.message());
+ return filerr;
}
offset += read_length;
input_remaining -= read_length;
@@ -1319,7 +1447,7 @@ archive_file::error zip_file_impl::decompress_data_type_14(std::uint64_t offset,
{
osd_printf_error(
"unzip: unexpectedly reached end-of-file while reading LZMA properties for %s in %s\n",
- m_header.file_name.c_str(), m_filename.c_str());
+ m_header.file_name, m_filename);
return archive_file::error::FILE_TRUNCATED;
}
@@ -1329,14 +1457,21 @@ archive_file::error zip_file_impl::decompress_data_type_14(std::uint64_t offset,
{
osd_printf_error(
"unzip: memory error allocating LZMA decoder to decompress %s from %s\n",
- m_header.file_name.c_str(), m_filename.c_str());
- return archive_file::error::OUT_OF_MEMORY;
+ m_header.file_name, m_filename);
+ return std::errc::not_enough_memory;
+ }
+ else if (SZ_ERROR_UNSUPPORTED)
+ {
+ osd_printf_error(
+ "unzip: LZMA decoder does not support properties for %s in %s\n",
+ m_header.file_name, m_filename);
+ return archive_file::error::UNSUPPORTED;
}
else if (SZ_OK != lzerr)
{
osd_printf_error(
"unzip: error allocating LZMA decoder to decompress %s from %s (%d)\n",
- m_header.file_name.c_str(), m_filename.c_str(), int(lzerr));
+ m_header.file_name, m_filename, int(lzerr));
return archive_file::error::DECOMPRESS_ERROR;
}
LzmaDec_Init(&stream);
@@ -1345,28 +1480,28 @@ archive_file::error zip_file_impl::decompress_data_type_14(std::uint64_t offset,
while (0 < input_remaining)
{
// read in the next chunk of data
- filerr = m_file->read(
- &m_buffer[0],
+ filerr = m_file->read_at(
offset,
- std::uint32_t((std::min<std::uint64_t>)(input_remaining, m_buffer.size())),
+ &m_buffer[0],
+ std::size_t((std::min<std::uint64_t>)(input_remaining, m_buffer.size())),
read_length);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
osd_printf_error(
- "unzip: error reading compressed data for %s in %s (%d)\n",
- m_header.file_name.c_str(), m_filename.c_str(), int(filerr));
+ "unzip: error reading compressed data for %s in %s (%s)\n",
+ m_header.file_name, m_filename);
LzmaDec_Free(&stream, &alloc_imp);
- return archive_file::error::FILE_ERROR;
+ return filerr;
}
offset += read_length;
input_remaining -= read_length;
// if we read nothing, but still have data left, the file is truncated
- if ((0 == read_length) && (0 < input_remaining))
+ if (!read_length && input_remaining)
{
osd_printf_error(
"unzip: unexpectedly reached end-of-file while reading compressed data for %s in %s\n",
- m_header.file_name.c_str(), m_filename.c_str());
+ m_header.file_name, m_filename);
LzmaDec_Free(&stream, &alloc_imp);
return archive_file::error::FILE_TRUNCATED;
}
@@ -1381,7 +1516,7 @@ archive_file::error zip_file_impl::decompress_data_type_14(std::uint64_t offset,
&output_remaining,
reinterpret_cast<Byte const *>(&m_buffer[0]),
&len,
- ((0 == input_remaining) && eos_mark) ? LZMA_FINISH_END : LZMA_FINISH_ANY,
+ (!input_remaining && eos_mark) ? LZMA_FINISH_END : LZMA_FINISH_ANY,
&lzstatus);
if (SZ_OK != lzerr)
{
@@ -1397,25 +1532,25 @@ archive_file::error zip_file_impl::decompress_data_type_14(std::uint64_t offset,
// if anything looks funny, report an error
if (LZMA_STATUS_FINISHED_WITH_MARK == lzstatus)
{
- return archive_file::error::NONE;
+ return std::error_condition();
}
else if (eos_mark)
{
osd_printf_error(
"unzip: LZMA end mark not found for %s in %s (%d)\n",
- m_header.file_name.c_str(), m_filename.c_str(), int(lzstatus));
+ m_header.file_name, m_filename, int(lzstatus));
return archive_file::error::DECOMPRESS_ERROR;
}
else if (LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK != lzstatus)
{
osd_printf_error(
"unzip: LZMA decompression of %s from %s doesn't appear to have completed correctly (%d)\n",
- m_header.file_name.c_str(), m_filename.c_str(), int(lzstatus));
+ m_header.file_name, m_filename, int(lzstatus));
return archive_file::error::DECOMPRESS_ERROR;
}
else
{
- return archive_file::error::NONE;
+ return std::error_condition();
}
}
@@ -1427,7 +1562,7 @@ archive_file::error zip_file_impl::decompress_data_type_14(std::uint64_t offset,
un7z.cpp TRAMPOLINES
***************************************************************************/
-void m7z_file_cache_clear();
+void m7z_file_cache_clear() noexcept;
@@ -1439,7 +1574,7 @@ void m7z_file_cache_clear();
zip_file_open - opens a ZIP file for reading
-------------------------------------------------*/
-archive_file::error archive_file::open_zip(const std::string &filename, ptr &result)
+std::error_condition archive_file::open_zip(std::string_view filename, ptr &result) noexcept
{
// ensure we start with a nullptr result
result.reset();
@@ -1450,21 +1585,49 @@ archive_file::error archive_file::open_zip(const std::string &filename, ptr &res
if (!newimpl)
{
// allocate memory for the zip_file structure
- try { newimpl = std::make_unique<zip_file_impl>(filename); }
- catch (...) { return error::OUT_OF_MEMORY; }
- auto const ziperr = newimpl->initialize();
- if (ziperr != error::NONE) return ziperr;
+ try { newimpl = std::make_unique<zip_file_impl>(std::string(filename)); }
+ catch (...) { return std::errc::not_enough_memory; }
+ auto const err = newimpl->initialize();
+ if (err)
+ return err;
+ }
+
+ // allocate the archive API wrapper
+ result.reset(new (std::nothrow) zip_file_wrapper(std::move(newimpl)));
+ if (result)
+ {
+ return std::error_condition();
+ }
+ else
+ {
+ zip_file_impl::close(std::move(newimpl));
+ return std::errc::not_enough_memory;
}
+}
- try
+std::error_condition archive_file::open_zip(random_read::ptr &&file, ptr &result) noexcept
+{
+ // ensure we start with a nullptr result
+ result.reset();
+
+ // allocate memory for the zip_file structure
+ zip_file_impl::ptr newimpl(new (std::nothrow) zip_file_impl(std::move(file)));
+ if (!newimpl)
+ return std::errc::not_enough_memory;
+ auto const err = newimpl->initialize();
+ if (err)
+ return err;
+
+ // allocate the archive API wrapper
+ result.reset(new (std::nothrow) zip_file_wrapper(std::move(newimpl)));
+ if (result)
{
- result = std::make_unique<zip_file_wrapper>(std::move(newimpl));
- return error::NONE;
+ return std::error_condition();
}
- catch (...)
+ else
{
zip_file_impl::close(std::move(newimpl));
- return error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
}
@@ -1474,7 +1637,7 @@ archive_file::error archive_file::open_zip(const std::string &filename, ptr &res
cache and free all memory
-------------------------------------------------*/
-void archive_file::cache_clear()
+void archive_file::cache_clear() noexcept
{
zip_file_impl::cache_clear();
m7z_file_cache_clear();
@@ -1485,4 +1648,15 @@ archive_file::~archive_file()
{
}
+
+/*-------------------------------------------------
+ archive_category - gets the archive error
+ category instance
+-------------------------------------------------*/
+
+std::error_category const &archive_category() noexcept
+{
+ return f_archive_category_instance;
+}
+
} // namespace util
diff --git a/src/lib/util/unzip.h b/src/lib/util/unzip.h
index b1ddb7a27d1..2108eadee28 100644
--- a/src/lib/util/unzip.h
+++ b/src/lib/util/unzip.h
@@ -7,19 +7,24 @@
archive file management.
***************************************************************************/
+#ifndef MAME_LIB_UTIL_UNZIP_H
+#define MAME_LIB_UTIL_UNZIP_H
#pragma once
-#ifndef MAME_LIB_UTIL_UNZIP_H
-#define MAME_LIB_UTIL_UNZIP_H
+#include "utilfwd.h"
#include <chrono>
#include <cstdint>
#include <memory>
#include <string>
+#include <string_view>
+#include <system_error>
+#include <type_traits>
namespace util {
+
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
@@ -30,12 +35,9 @@ class archive_file
public:
// Error types
- enum class error
+ enum class error : int
{
- NONE = 0,
- OUT_OF_MEMORY,
- FILE_ERROR,
- BAD_SIGNATURE,
+ BAD_SIGNATURE = 1,
DECOMPRESS_ERROR,
FILE_TRUNCATED,
FILE_CORRUPT,
@@ -49,40 +51,54 @@ public:
/* ----- archive file access ----- */
// open a ZIP file and parse its central directory
- static error open_zip(const std::string &filename, ptr &zip);
+ static std::error_condition open_zip(std::string_view filename, ptr &result) noexcept;
+ static std::error_condition open_zip(std::unique_ptr<random_read> &&file, ptr &result) noexcept;
// open a 7Z file and parse its central directory
- static error open_7z(const std::string &filename, ptr &result);
+ static std::error_condition open_7z(std::string_view filename, ptr &result) noexcept;
+ static std::error_condition open_7z(std::unique_ptr<random_read> &&file, ptr &result) noexcept;
// close an archive file (may actually be left open due to caching)
virtual ~archive_file();
// clear out all open files from the cache
- static void cache_clear();
+ static void cache_clear() noexcept;
/* ----- contained file access ----- */
// iterating over files - returns negative on reaching end
- virtual int first_file() = 0;
- virtual int next_file() = 0;
+ virtual int first_file() noexcept = 0;
+ virtual int next_file() noexcept = 0;
// find a file index by crc, filename or both - returns non-negative on match
- virtual int search(std::uint32_t crc) = 0;
- virtual int search(const std::string &filename, bool partialpath) = 0;
- virtual int search(std::uint32_t crc, const std::string &filename, bool partialpath) = 0;
+ virtual int search(std::uint32_t crc) noexcept = 0;
+ virtual int search(std::string_view filename, bool partialpath) noexcept = 0;
+ virtual int search(std::uint32_t crc, std::string_view filename, bool partialpath) noexcept = 0;
// information on most recently found file
- virtual bool current_is_directory() const = 0;
- virtual const std::string &current_name() const = 0;
- virtual std::uint64_t current_uncompressed_length() const = 0;
- virtual std::chrono::system_clock::time_point current_last_modified() const = 0;
- virtual std::uint32_t current_crc() const = 0;
+ virtual bool current_is_directory() const noexcept = 0;
+ virtual const std::string &current_name() const noexcept = 0;
+ virtual std::uint64_t current_uncompressed_length() const noexcept = 0;
+ virtual std::chrono::system_clock::time_point current_last_modified() const noexcept = 0;
+ virtual std::uint32_t current_crc() const noexcept = 0;
// decompress the most recently found file in the ZIP
- virtual error decompress(void *buffer, std::uint32_t length) = 0;
+ virtual std::error_condition decompress(void *buffer, std::size_t length) noexcept = 0;
};
+
+// error category for archive errors
+std::error_category const &archive_category() noexcept;
+inline std::error_condition make_error_condition(archive_file::error err) noexcept { return std::error_condition(int(err), archive_category()); }
+
} // namespace util
+
+namespace std {
+
+template <> struct is_error_condition_enum<util::archive_file::error> : public std::true_type { };
+
+} // namespace std
+
#endif // MAME_LIB_UTIL_UNZIP_H
diff --git a/src/lib/util/utilfwd.h b/src/lib/util/utilfwd.h
new file mode 100644
index 00000000000..fefe0631c68
--- /dev/null
+++ b/src/lib/util/utilfwd.h
@@ -0,0 +1,45 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/**********************************************************************
+
+ utilfwd.h
+
+ Forward declarations of types
+
+**********************************************************************/
+#ifndef MAME_LIB_UTIL_UTILFWD_H
+#define MAME_LIB_UTIL_UTILFWD_H
+
+// chd.h
+class chd_file;
+
+
+namespace util {
+
+// corefile.h
+class core_file;
+
+// ioprocs.h
+class read_stream;
+class write_stream;
+class read_write_stream;
+class random_access;
+class random_read;
+class random_write;
+class random_read_write;
+
+// unzip.h
+class archive_file;
+
+} // namespace util
+
+
+namespace util::xml {
+
+// xmlfile.h
+class data_node;
+class file;
+
+} // namespace util::xml
+
+#endif // MAME_LIB_UTIL_UTILFWD_H
diff --git a/src/lib/util/zippath.cpp b/src/lib/util/zippath.cpp
index 023484010b8..f317319c8c3 100644
--- a/src/lib/util/zippath.cpp
+++ b/src/lib/util/zippath.cpp
@@ -9,13 +9,13 @@
***************************************************************************/
#include "zippath.h"
-#include "unzip.h"
-#include "corestr.h"
-#include <cstdlib>
+#include "corestr.h"
+#include "unzip.h"
#include <cassert>
#include <cctype>
+#include <cstdlib>
#include <forward_list>
#include <new>
@@ -192,7 +192,7 @@ int zippath_find_sub_path(archive_file &zipfile, std::string_view subpath, osd::
// true path and ZIP entry components
// -------------------------------------------------
-osd_file::error zippath_resolve(std::string_view path, osd::directory::entry::entry_type &entry_type, archive_file::ptr &zipfile, std::string &newpath)
+std::error_condition zippath_resolve(std::string_view path, osd::directory::entry::entry_type &entry_type, archive_file::ptr &zipfile, std::string &newpath)
{
newpath.clear();
@@ -238,13 +238,13 @@ osd_file::error zippath_resolve(std::string_view path, osd::directory::entry::en
if (current_entry_type == osd::directory::entry::entry_type::NONE)
{
entry_type = osd::directory::entry::entry_type::NONE;
- return osd_file::error::NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
}
// is this file a ZIP file?
if ((current_entry_type == osd::directory::entry::entry_type::FILE) &&
- ((is_zip_file(apath_trimmed) && (archive_file::open_zip(apath_trimmed, zipfile) == archive_file::error::NONE)) ||
- (is_7z_file(apath_trimmed) && (archive_file::open_7z(apath_trimmed, zipfile) == archive_file::error::NONE))))
+ ((is_zip_file(apath_trimmed) && !archive_file::open_zip(apath_trimmed, zipfile)) ||
+ (is_7z_file(apath_trimmed) && !archive_file::open_7z(apath_trimmed, zipfile))))
{
auto i = path.length() - apath.length();
while ((i > 0) && is_zip_path_separator(path[apath.length() + i - 1]))
@@ -254,53 +254,20 @@ osd_file::error zippath_resolve(std::string_view path, osd::directory::entry::en
// this was a true ZIP path - attempt to identify the type of path
zippath_find_sub_path(*zipfile, newpath, current_entry_type);
if (current_entry_type == osd::directory::entry::entry_type::NONE)
- return osd_file::error::NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
}
else
{
// this was a normal path
if (went_up)
- return osd_file::error::NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
newpath = path;
}
// success!
entry_type = current_entry_type;
- return osd_file::error::NONE;
-}
-
-
-// -------------------------------------------------
-// file_error_from_zip_error - translates a
-// osd_file::error to a zip_error
-// -------------------------------------------------
-
-osd_file::error file_error_from_zip_error(archive_file::error ziperr)
-{
- osd_file::error filerr;
- switch(ziperr)
- {
- case archive_file::error::NONE:
- filerr = osd_file::error::NONE;
- break;
- case archive_file::error::OUT_OF_MEMORY:
- filerr = osd_file::error::OUT_OF_MEMORY;
- break;
- case archive_file::error::BAD_SIGNATURE:
- case archive_file::error::DECOMPRESS_ERROR:
- case archive_file::error::FILE_TRUNCATED:
- case archive_file::error::FILE_CORRUPT:
- case archive_file::error::UNSUPPORTED:
- case archive_file::error::FILE_ERROR:
- filerr = osd_file::error::INVALID_DATA;
- break;
- case archive_file::error::BUFFER_TOO_SMALL:
- default:
- filerr = osd_file::error::FAILURE;
- break;
- }
- return filerr;
+ return std::error_condition();
}
@@ -309,27 +276,24 @@ osd_file::error file_error_from_zip_error(archive_file::error ziperr)
// from a zip file entry
// -------------------------------------------------
-osd_file::error create_core_file_from_zip(archive_file &zip, util::core_file::ptr &file)
+std::error_condition create_core_file_from_zip(archive_file &zip, util::core_file::ptr &file)
{
- osd_file::error filerr;
- archive_file::error ziperr;
+ // TODO: would be more efficient if we could open a memory-based core_file with uninitialised contents and decompress into it
+ std::error_condition filerr;
void *ptr = malloc(zip.current_uncompressed_length());
if (!ptr)
{
- filerr = osd_file::error::OUT_OF_MEMORY;
+ filerr = std::errc::not_enough_memory;
goto done;
}
- ziperr = zip.decompress(ptr, zip.current_uncompressed_length());
- if (ziperr != archive_file::error::NONE)
- {
- filerr = file_error_from_zip_error(ziperr);
+ filerr = zip.decompress(ptr, zip.current_uncompressed_length());
+ if (filerr)
goto done;
- }
filerr = util::core_file::open_ram_copy(ptr, zip.current_uncompressed_length(), OPEN_FLAG_READ, file);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
goto done;
done:
@@ -545,7 +509,7 @@ private:
// zippath_directory::open - opens a directory
// -------------------------------------------------
-osd_file::error zippath_directory::open(std::string_view path, ptr &directory)
+std::error_condition zippath_directory::open(std::string_view path, ptr &directory)
{
try
{
@@ -553,34 +517,34 @@ osd_file::error zippath_directory::open(std::string_view path, ptr &directory)
osd::directory::entry::entry_type entry_type;
archive_file::ptr zipfile;
std::string zipprefix;
- osd_file::error const err = zippath_resolve(path, entry_type, zipfile, zipprefix);
- if (osd_file::error::NONE != err)
+ std::error_condition const err = zippath_resolve(path, entry_type, zipfile, zipprefix);
+ if (err)
return err;
// we have to be a directory
if (osd::directory::entry::entry_type::DIR != entry_type)
- return osd_file::error::NOT_FOUND;
+ return std::errc::not_a_directory;
// was the result a ZIP?
if (zipfile)
{
directory = std::make_unique<archive_directory_impl>(std::move(zipfile), std::move(zipprefix));
- return osd_file::error::NONE;
+ return std::error_condition();
}
else
{
// a conventional directory
std::unique_ptr<filesystem_directory_impl> result(new filesystem_directory_impl(path));
if (!*result)
- return osd_file::error::FAILURE;
+ return std::errc::io_error; // TODO: any way to give a better error here?
directory = std::move(result);
- return osd_file::error::NONE;
+ return std::error_condition();
}
}
catch (std::bad_alloc const &)
{
- return osd_file::error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
}
@@ -681,7 +645,7 @@ std::string zippath_combine(const std::string &path1, const std::string &path2)
// -------------------------------------------------
/**
- * @fn osd_file::error zippath_fopen(std::string_view filename, uint32_t openflags, util::core_file::ptr &file, std::string &revised_path)
+ * @fn std::error_condition zippath_fopen(std::string_view filename, uint32_t openflags, util::core_file::ptr &file, std::string &revised_path)
*
* @brief Zippath fopen.
*
@@ -693,38 +657,35 @@ std::string zippath_combine(const std::string &path1, const std::string &path2)
* @return A osd_file::error.
*/
-osd_file::error zippath_fopen(std::string_view filename, uint32_t openflags, util::core_file::ptr &file, std::string &revised_path)
+std::error_condition zippath_fopen(std::string_view filename, uint32_t openflags, util::core_file::ptr &file, std::string &revised_path)
{
- osd_file::error filerr = osd_file::error::NOT_FOUND;
- archive_file::error ziperr;
+ std::error_condition filerr = std::errc::no_such_file_or_directory;
archive_file::ptr zip;
- int header;
- osd::directory::entry::entry_type entry_type;
- int len;
- /* first, set up the two types of paths */
+ // first, set up the two types of paths
std::string mainpath(filename);
std::string subpath;
file = nullptr;
- /* loop through */
- while((file == nullptr) && (mainpath.length() > 0)
- && ((openflags == OPEN_FLAG_READ) || subpath.empty()))
+ // loop through
+ while (!file && !mainpath.empty() && ((openflags == OPEN_FLAG_READ) || subpath.empty()))
{
- /* is the mainpath a ZIP path? */
+ // is the mainpath a ZIP path?
if (is_zip_file(mainpath) || is_7z_file(mainpath))
{
- /* this file might be a zip file - lets take a look */
- ziperr = is_zip_file(mainpath) ? archive_file::open_zip(mainpath, zip) : archive_file::open_7z(mainpath, zip);
- if (ziperr == archive_file::error::NONE)
+ // this file might be a zip file - lets take a look
+ std::error_condition const ziperr = is_zip_file(mainpath) ? archive_file::open_zip(mainpath, zip) : archive_file::open_7z(mainpath, zip);
+ if (!ziperr)
{
- /* it is a zip file - error if we're not opening for reading */
+ // it is a zip file - error if we're not opening for reading
if (openflags != OPEN_FLAG_READ)
{
- filerr = osd_file::error::ACCESS_DENIED;
+ filerr = std::errc::permission_denied;
goto done;
}
+ osd::directory::entry::entry_type entry_type;
+ int header;
if (!subpath.empty())
header = zippath_find_sub_path(*zip, subpath, entry_type);
else
@@ -732,20 +693,20 @@ osd_file::error zippath_fopen(std::string_view filename, uint32_t openflags, uti
if (header < 0)
{
- filerr = osd_file::error::NOT_FOUND;
+ filerr = std::errc::no_such_file_or_directory;
goto done;
}
- /* attempt to read the file */
+ // attempt to read the file
filerr = create_core_file_from_zip(*zip, file);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
goto done;
- /* update subpath, if appropriate */
+ // update subpath, if appropriate
if (subpath.empty())
subpath.assign(zip->current_name());
- /* we're done */
+ // we're done
goto done;
}
}
@@ -753,15 +714,15 @@ osd_file::error zippath_fopen(std::string_view filename, uint32_t openflags, uti
if (subpath.empty())
filerr = util::core_file::open(std::string(filename), openflags, file);
else
- filerr = osd_file::error::NOT_FOUND;
+ filerr = std::errc::no_such_file_or_directory;
- /* if we errored, then go up a directory */
- if (filerr != osd_file::error::NONE)
+ // if we errored, then go up a directory
+ if (filerr)
{
- /* go up a directory */
+ // go up a directory
auto temp = zippath_parent(mainpath);
- /* append to the sub path */
+ // append to the sub path
if (!subpath.empty())
{
std::string temp2;
@@ -774,8 +735,8 @@ osd_file::error zippath_fopen(std::string_view filename, uint32_t openflags, uti
mainpath = mainpath.substr(temp.length());
subpath.assign(mainpath);
}
- /* get the new main path, truncating path separators */
- len = temp.length();
+ // get the new main path, truncating path separators
+ auto len = temp.length();
while (len > 0 && is_zip_file_separator(temp[len - 1]))
len--;
temp = temp.substr(0, len);
@@ -784,14 +745,14 @@ osd_file::error zippath_fopen(std::string_view filename, uint32_t openflags, uti
}
done:
- /* store the revised path */
+ // store the revised path
revised_path.clear();
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
{
- /* canonicalize mainpath */
+ // canonicalize mainpath
std::string alloc_fullpath;
filerr = osd_get_full_path(alloc_fullpath, mainpath);
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
{
revised_path = alloc_fullpath;
if (!subpath.empty())
diff --git a/src/lib/util/zippath.h b/src/lib/util/zippath.h
index 1eb92aa1c1d..955c75cfc8f 100644
--- a/src/lib/util/zippath.h
+++ b/src/lib/util/zippath.h
@@ -18,6 +18,7 @@
#include <string>
#include <string_view>
+#include <system_error>
namespace util {
@@ -32,7 +33,7 @@ public:
typedef std::unique_ptr<zippath_directory> ptr;
// opens a directory
- static osd_file::error open(std::string_view path, ptr &directory);
+ static std::error_condition open(std::string_view path, ptr &directory);
// closes a directory
virtual ~zippath_directory();
@@ -63,7 +64,7 @@ std::string zippath_combine(const std::string &path1, const std::string &path2);
// ----- file operations -----
// opens a zip path file
-osd_file::error zippath_fopen(std::string_view filename, uint32_t openflags, util::core_file::ptr &file, std::string &revised_path);
+std::error_condition zippath_fopen(std::string_view filename, uint32_t openflags, util::core_file::ptr &file, std::string &revised_path);
} // namespace util
diff --git a/src/mame/drivers/aim65.cpp b/src/mame/drivers/aim65.cpp
index 94870fd4f11..703c35146cb 100644
--- a/src/mame/drivers/aim65.cpp
+++ b/src/mame/drivers/aim65.cpp
@@ -184,7 +184,7 @@ image_init_result aim65_state::load_cart(device_image_interface &image, generic_
if (size > 0x1000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported ROM size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported ROM size");
return image_init_result::FAIL;
}
@@ -193,7 +193,7 @@ image_init_result aim65_state::load_cart(device_image_interface &image, generic_
std::string errmsg = string_format(
"Attempted to load file with wrong extension\nSocket '%s' only accepts files with '.%s' extension",
slot_tag, slot_tag);
- image.seterror(IMAGE_ERROR_UNSPECIFIED, errmsg.c_str());
+ image.seterror(image_error::INVALIDIMAGE, errmsg.c_str());
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/alphatro.cpp b/src/mame/drivers/alphatro.cpp
index e07c89a1f3f..d6ec5f4bc9d 100644
--- a/src/mame/drivers/alphatro.cpp
+++ b/src/mame/drivers/alphatro.cpp
@@ -702,7 +702,7 @@ image_init_result alphatro_state::load_cart(device_image_interface &image, gener
if ((size != 0x4000) && (size != 0x2000))
{
- image.seterror(IMAGE_ERROR_UNSUPPORTED, "Invalid size, must be 8 or 16 K" );
+ image.seterror(image_error::INVALIDIMAGE, "Invalid size, must be 8 or 16 K" );
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/atom.cpp b/src/mame/drivers/atom.cpp
index d5cf875810b..d703f967a70 100644
--- a/src/mame/drivers/atom.cpp
+++ b/src/mame/drivers/atom.cpp
@@ -683,7 +683,7 @@ image_init_result atom_state::load_cart(device_image_interface &image, generic_s
if (size > 0x1000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported ROM size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported ROM size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/beta.cpp b/src/mame/drivers/beta.cpp
index 4639ec0fcde..0e543f91230 100644
--- a/src/mame/drivers/beta.cpp
+++ b/src/mame/drivers/beta.cpp
@@ -297,7 +297,7 @@ DEVICE_IMAGE_LOAD_MEMBER(beta_state::load_beta_eprom)
if (size != 0x800)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/binbug.cpp b/src/mame/drivers/binbug.cpp
index 1bcba2984a0..3855bc393aa 100644
--- a/src/mame/drivers/binbug.cpp
+++ b/src/mame/drivers/binbug.cpp
@@ -189,12 +189,12 @@ QUICKLOAD_LOAD_MEMBER(binbug_state::quickload_cb)
quick_length = image.length();
if (quick_length < 0x0444)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too short");
+ image.seterror(image_error::INVALIDIMAGE, "File too short");
image.message(" File too short");
}
else if (quick_length > 0x8000)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too long");
+ image.seterror(image_error::INVALIDIMAGE, "File too long");
image.message(" File too long");
}
else
@@ -203,12 +203,12 @@ QUICKLOAD_LOAD_MEMBER(binbug_state::quickload_cb)
read_ = image.fread( &quick_data[0], quick_length);
if (read_ != quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Cannot read the file");
+ image.seterror(image_error::INVALIDIMAGE, "Cannot read the file");
image.message(" Cannot read the file");
}
else if (quick_data[0] != 0xc4)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid header");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid header");
image.message(" Invalid header");
}
else
@@ -217,7 +217,7 @@ QUICKLOAD_LOAD_MEMBER(binbug_state::quickload_cb)
if (exec_addr >= quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Exec address beyond end of file");
+ image.seterror(image_error::INVALIDIMAGE, "Exec address beyond end of file");
image.message(" Exec address beyond end of file");
}
else
diff --git a/src/mame/drivers/cc40.cpp b/src/mame/drivers/cc40.cpp
index 3766231c469..6e737b9b134 100644
--- a/src/mame/drivers/cc40.cpp
+++ b/src/mame/drivers/cc40.cpp
@@ -196,7 +196,7 @@ DEVICE_IMAGE_LOAD_MEMBER(cc40_state::cart_load)
// max size is 4*32KB
if (size > 0x20000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid file size");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid file size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/cd2650.cpp b/src/mame/drivers/cd2650.cpp
index 01760a14fbd..cf8203a25fd 100644
--- a/src/mame/drivers/cd2650.cpp
+++ b/src/mame/drivers/cd2650.cpp
@@ -259,13 +259,13 @@ QUICKLOAD_LOAD_MEMBER(cd2650_state::quickload_cb)
int quick_length = image.length();
if (quick_length < 0x1500)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too short");
+ image.seterror(image_error::INVALIDIMAGE, "File too short");
image.message(" File too short");
}
else
if (quick_length > 0x8000)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too long");
+ image.seterror(image_error::INVALIDIMAGE, "File too long");
image.message(" File too long");
}
else
@@ -274,13 +274,13 @@ QUICKLOAD_LOAD_MEMBER(cd2650_state::quickload_cb)
int read_ = image.fread( &quick_data[0], quick_length);
if (read_ != quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Cannot read the file");
+ image.seterror(image_error::INVALIDIMAGE, "Cannot read the file");
image.message(" Cannot read the file");
}
else
if (quick_data[0] != 0x40)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid header");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid header");
image.message(" Invalid header");
}
else
@@ -289,7 +289,7 @@ QUICKLOAD_LOAD_MEMBER(cd2650_state::quickload_cb)
if (exec_addr >= quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Exec address beyond end of file");
+ image.seterror(image_error::INVALIDIMAGE, "Exec address beyond end of file");
image.message(" Exec address beyond end of file");
}
else
diff --git a/src/mame/drivers/d6800.cpp b/src/mame/drivers/d6800.cpp
index ca08bcbc118..1bffd36f07a 100644
--- a/src/mame/drivers/d6800.cpp
+++ b/src/mame/drivers/d6800.cpp
@@ -346,7 +346,7 @@ QUICKLOAD_LOAD_MEMBER(d6800_state::quickload_cb)
u32 quick_length = image.length();
if (quick_length > 0xe00)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File exceeds 3584 bytes");
+ image.seterror(image_error::INVALIDIMAGE, "File exceeds 3584 bytes");
image.message(" File exceeds 3584 bytes");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/elan_eu3a05.cpp b/src/mame/drivers/elan_eu3a05.cpp
index 29abd9ff08d..f4327818657 100644
--- a/src/mame/drivers/elan_eu3a05.cpp
+++ b/src/mame/drivers/elan_eu3a05.cpp
@@ -360,7 +360,7 @@ DEVICE_IMAGE_LOAD_MEMBER(elan_eu3a05_buzztime_state::cart_load)
if (size != 0x200000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/eti660.cpp b/src/mame/drivers/eti660.cpp
index 379cdb2d55b..5ffea04f6d2 100644
--- a/src/mame/drivers/eti660.cpp
+++ b/src/mame/drivers/eti660.cpp
@@ -325,7 +325,7 @@ QUICKLOAD_LOAD_MEMBER(eti660_state::quickload_cb)
read_ = image.fread( &quick_data[0], quick_length);
if (read_ != quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Cannot read the file");
+ image.seterror(image_error::INVALIDIMAGE, "Cannot read the file");
image.message(" Cannot read the file");
}
else
diff --git a/src/mame/drivers/force68k.cpp b/src/mame/drivers/force68k.cpp
index 47e7fe73f48..03d594ca831 100644
--- a/src/mame/drivers/force68k.cpp
+++ b/src/mame/drivers/force68k.cpp
@@ -514,7 +514,7 @@ image_init_result force68k_state::force68k_load_cart(device_image_interface &ima
if (size > 0x20000) // Max 128Kb
{
LOG("Cartridge size exceeding max size (128Kb): %d\n", size);
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Cartridge size exceeding max size (128Kb)");
+ image.seterror(image_error::INVALIDIMAGE, "Cartridge size exceeding max size (128Kb)");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/gameking.cpp b/src/mame/drivers/gameking.cpp
index 8d398756c38..737445f5928 100644
--- a/src/mame/drivers/gameking.cpp
+++ b/src/mame/drivers/gameking.cpp
@@ -261,7 +261,7 @@ DEVICE_IMAGE_LOAD_MEMBER(gameking_state::cart_load)
if (size > 0x100000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/hh_tms1k.cpp b/src/mame/drivers/hh_tms1k.cpp
index 8493a40b9a5..82e2eeb6042 100644
--- a/src/mame/drivers/hh_tms1k.cpp
+++ b/src/mame/drivers/hh_tms1k.cpp
@@ -2391,7 +2391,7 @@ DEVICE_IMAGE_LOAD_MEMBER(quizwizc_state::cart_load)
{
if (!image.loaded_through_softlist())
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Can only load through softwarelist");
+ image.seterror(image_error::UNSUPPORTED, "Can only load through softwarelist");
return image_init_result::FAIL;
}
@@ -2579,7 +2579,7 @@ DEVICE_IMAGE_LOAD_MEMBER(tc4_state::cart_load)
{
if (!image.loaded_through_softlist())
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Can only load through softwarelist");
+ image.seterror(image_error::UNSUPPORTED, "Can only load through softwarelist");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/homelab.cpp b/src/mame/drivers/homelab.cpp
index 3de88cb8ee7..8516773a6b2 100644
--- a/src/mame/drivers/homelab.cpp
+++ b/src/mame/drivers/homelab.cpp
@@ -683,7 +683,7 @@ QUICKLOAD_LOAD_MEMBER(homelab_state::quickload_cb)
u8 ch = image.fgetc();
if (ch != 0xA5)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid header");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid header");
image.message(" Invalid header");
return image_init_result::FAIL;
}
@@ -692,7 +692,7 @@ QUICKLOAD_LOAD_MEMBER(homelab_state::quickload_cb)
{
if (i >= (std::size(pgmname) - 1))
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File name too long");
+ image.seterror(image_error::INVALIDIMAGE, "File name too long");
image.message(" File name too long");
return image_init_result::FAIL;
}
@@ -706,7 +706,7 @@ QUICKLOAD_LOAD_MEMBER(homelab_state::quickload_cb)
if (image.fread(args, sizeof(args)) != sizeof(args))
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Unexpected EOF while getting file size");
+ image.seterror(image_error::INVALIDIMAGE, "Unexpected EOF while getting file size");
image.message(" Unexpected EOF while getting file size");
return image_init_result::FAIL;
}
@@ -717,7 +717,7 @@ QUICKLOAD_LOAD_MEMBER(homelab_state::quickload_cb)
if (quick_end > 0x7fff)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too large");
+ image.seterror(image_error::INVALIDIMAGE, "File too large");
image.message(" File too large");
return image_init_result::FAIL;
}
@@ -732,7 +732,7 @@ QUICKLOAD_LOAD_MEMBER(homelab_state::quickload_cb)
{
char message[512];
snprintf(message, std::size(message), "%s: Unexpected EOF while writing byte to %04X", pgmname, (unsigned) j);
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, message);
+ image.seterror(image_error::INVALIDIMAGE, message);
image.message("%s: Unexpected EOF while writing byte to %04X", pgmname, (unsigned) j);
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/hx20.cpp b/src/mame/drivers/hx20.cpp
index b877e8f86a7..708a7126bf1 100644
--- a/src/mame/drivers/hx20.cpp
+++ b/src/mame/drivers/hx20.cpp
@@ -835,7 +835,7 @@ DEVICE_IMAGE_LOAD_MEMBER(hx20_state::optrom_load)
if (size != 0x2000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported ROM size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported ROM size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/ibmpcjr.cpp b/src/mame/drivers/ibmpcjr.cpp
index 05d6714ac0a..38bf2f19424 100644
--- a/src/mame/drivers/ibmpcjr.cpp
+++ b/src/mame/drivers/ibmpcjr.cpp
@@ -467,7 +467,7 @@ image_init_result pcjr_state::load_cart(device_image_interface &image, generic_s
header_size = 0x200;
break;
default:
- image.seterror(IMAGE_ERROR_UNSUPPORTED, "Invalid header size" );
+ image.seterror(image_error::INVALIDIMAGE, "Invalid header size");
return image_init_result::FAIL;
}
if (size - header_size == 0xa000)
diff --git a/src/mame/drivers/instruct.cpp b/src/mame/drivers/instruct.cpp
index 1f14360e37e..fd3f3b9622b 100644
--- a/src/mame/drivers/instruct.cpp
+++ b/src/mame/drivers/instruct.cpp
@@ -356,13 +356,13 @@ QUICKLOAD_LOAD_MEMBER(instruct_state::quickload_cb)
quick_length = image.length();
if (quick_length < 0x0100)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too short");
+ image.seterror(image_error::INVALIDIMAGE, "File too short");
image.message(" File too short");
}
else
if (quick_length > 0x8000)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too long");
+ image.seterror(image_error::INVALIDIMAGE, "File too long");
image.message(" File too long");
}
else
@@ -371,12 +371,12 @@ QUICKLOAD_LOAD_MEMBER(instruct_state::quickload_cb)
read_ = image.fread( &quick_data[0], quick_length);
if (read_ != quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Cannot read the file");
+ image.seterror(image_error::INVALIDIMAGE, "Cannot read the file");
image.message(" Cannot read the file");
}
else if (quick_data[0] != 0xc5)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid header");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid header");
image.message(" Invalid header");
}
else
@@ -385,7 +385,7 @@ QUICKLOAD_LOAD_MEMBER(instruct_state::quickload_cb)
if (exec_addr >= quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Exec address beyond end of file");
+ image.seterror(image_error::INVALIDIMAGE, "Exec address beyond end of file");
image.message(" Exec address beyond end of file");
}
else
diff --git a/src/mame/drivers/jtc.cpp b/src/mame/drivers/jtc.cpp
index 506d620658d..9cfda169f3a 100644
--- a/src/mame/drivers/jtc.cpp
+++ b/src/mame/drivers/jtc.cpp
@@ -597,22 +597,22 @@ QUICKLOAD_LOAD_MEMBER(jtc_state::quickload_cb)
{
if (quick_length < 0x0088)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too short");
+ image.seterror(image_error::INVALIDIMAGE, "File too short");
image.message(" File too short");
}
else
if (quick_length > 0x8000)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too long");
+ image.seterror(image_error::INVALIDIMAGE, "File too long");
image.message(" File too long");
}
else
{
quick_data.resize(quick_length+1);
- u16 read_ = image.fread( &quick_data[0], quick_length);
+ u16 read_ = image.fread(&quick_data[0], quick_length);
if (read_ != quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Cannot read the file");
+ image.seterror(image_error::INVALIDIMAGE, "Cannot read the file");
image.message(" Cannot read the file");
}
else
@@ -621,7 +621,7 @@ QUICKLOAD_LOAD_MEMBER(jtc_state::quickload_cb)
quick_length = quick_data[0x14] * 256 + quick_data[0x13] - quick_addr + 0x81;
if (image.length() != quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid file header");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid file header");
image.message(" Invalid file header");
}
else
@@ -643,7 +643,7 @@ QUICKLOAD_LOAD_MEMBER(jtc_state::quickload_cb)
quick_addr = 0xe000;
if (quick_length > 0x8000)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too long");
+ image.seterror(image_error::INVALIDIMAGE, "File too long");
image.message(" File too long");
}
else
@@ -652,7 +652,7 @@ QUICKLOAD_LOAD_MEMBER(jtc_state::quickload_cb)
u16 read_ = image.fread( &quick_data[0], quick_length);
if (read_ != quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Cannot read the file");
+ image.seterror(image_error::INVALIDIMAGE, "Cannot read the file");
image.message(" Cannot read the file");
}
else
diff --git a/src/mame/drivers/jupace.cpp b/src/mame/drivers/jupace.cpp
index 05fd4f0a850..a822f1448da 100644
--- a/src/mame/drivers/jupace.cpp
+++ b/src/mame/drivers/jupace.cpp
@@ -179,7 +179,7 @@ SNAPSHOT_LOAD_MEMBER(ace_state::snapshot_cb)
if (m_ram->size() < 16*1024)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "At least 16KB RAM expansion required");
+ image.seterror(image_error::INVALIDIMAGE, "At least 16KB RAM expansion required");
image.message("At least 16KB RAM expansion required");
return image_init_result::FAIL;
}
@@ -216,7 +216,7 @@ SNAPSHOT_LOAD_MEMBER(ace_state::snapshot_cb)
if (!done)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "EOF marker not found");
+ image.seterror(image_error::INVALIDIMAGE, "EOF marker not found");
image.message("EOF marker not found");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/ldplayer.cpp b/src/mame/drivers/ldplayer.cpp
index e0d92cf5997..9afb99f9332 100644
--- a/src/mame/drivers/ldplayer.cpp
+++ b/src/mame/drivers/ldplayer.cpp
@@ -185,15 +185,15 @@ chd_file *ldplayer_state::get_disc()
{
// open the file itself via our search path
emu_file image_file(machine().options().media_path(), OPEN_FLAG_READ);
- osd_file::error filerr = image_file.open(dir->name);
- if (filerr == osd_file::error::NONE)
+ std::error_condition filerr = image_file.open(dir->name);
+ if (!filerr)
{
std::string fullpath(image_file.fullpath());
image_file.close();
// try to open the CHD
- if (machine().rom_load().set_disk_handle("laserdisc", fullpath.c_str()) == CHDERR_NONE)
+ if (!machine().rom_load().set_disk_handle("laserdisc", fullpath.c_str()))
{
m_filename.assign(dir->name);
found = true;
@@ -204,7 +204,8 @@ chd_file *ldplayer_state::get_disc()
}
// if we failed, pop a message and exit
- if (found == false) {
+ if (!found)
+ {
machine().ui().popup_time(10, "No valid image file found!\n");
return nullptr;
}
diff --git a/src/mame/drivers/lynx.cpp b/src/mame/drivers/lynx.cpp
index 2d1c00e9dfc..68a5e89ebc8 100644
--- a/src/mame/drivers/lynx.cpp
+++ b/src/mame/drivers/lynx.cpp
@@ -170,7 +170,7 @@ QUICKLOAD_LOAD_MEMBER(lynx_state::quickload_cb)
/* Check the image */
if (lynx_verify_cart((char*)header, LYNX_QUICKLOAD) != image_verify_result::PASS)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Not a valid Lynx file");
+ image.seterror(image_error::INVALIDIMAGE, "Not a valid Lynx file");
return image_init_result::FAIL;
}
@@ -182,7 +182,7 @@ QUICKLOAD_LOAD_MEMBER(lynx_state::quickload_cb)
if (image.fread( &data[0], length) != length)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid length in file header");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid length in file header");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/m68705prg.cpp b/src/mame/drivers/m68705prg.cpp
index 0bd877b0cf2..5bb9359813c 100644
--- a/src/mame/drivers/m68705prg.cpp
+++ b/src/mame/drivers/m68705prg.cpp
@@ -67,7 +67,7 @@ protected:
auto const actual(m_eprom_image->common_get_size("rom"));
if (desired > actual)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported EPROM size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported EPROM size");
return image_init_result::FAIL;
}
else
@@ -84,7 +84,7 @@ protected:
auto const actual(m_mcu_image->common_get_size("rom"));
if (desired != actual)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Incorrect internal MCU EPROM size");
+ image.seterror(image_error::INVALIDIMAGE, "Incorrect internal MCU EPROM size");
return image_init_result::FAIL;
}
else
diff --git a/src/mame/drivers/microvsn.cpp b/src/mame/drivers/microvsn.cpp
index 4447ded8659..9d830012994 100644
--- a/src/mame/drivers/microvsn.cpp
+++ b/src/mame/drivers/microvsn.cpp
@@ -188,7 +188,7 @@ DEVICE_IMAGE_LOAD_MEMBER(microvision_state::cart_load)
if (size != 0x400 && size != 0x800)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid ROM file size");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid ROM file size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/myvision.cpp b/src/mame/drivers/myvision.cpp
index 801f2611239..4005ca42bcd 100644
--- a/src/mame/drivers/myvision.cpp
+++ b/src/mame/drivers/myvision.cpp
@@ -158,7 +158,7 @@ DEVICE_IMAGE_LOAD_MEMBER( myvision_state::cart_load )
if (size != 0x4000 && size != 0x6000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/nascom1.cpp b/src/mame/drivers/nascom1.cpp
index 6f14e852191..040b84d54f1 100644
--- a/src/mame/drivers/nascom1.cpp
+++ b/src/mame/drivers/nascom1.cpp
@@ -367,7 +367,7 @@ SNAPSHOT_LOAD_MEMBER(nascom_state::snapshot_cb)
}
else
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported file format");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported file format");
return image_init_result::FAIL;
}
dummy = 0x00;
@@ -392,7 +392,7 @@ image_init_result nascom2_state::load_cart(device_image_interface &image, generi
{
if (slot->length() > 0x1000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported file size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported file size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/ngp.cpp b/src/mame/drivers/ngp.cpp
index c0e8e51e98d..4e045d22d9c 100644
--- a/src/mame/drivers/ngp.cpp
+++ b/src/mame/drivers/ngp.cpp
@@ -754,7 +754,7 @@ DEVICE_IMAGE_LOAD_MEMBER(ngp_state::load_ngp_cart)
if (size != 0x8000 && size != 0x80000 && size != 0x100000 && size != 0x200000 && size != 0x400000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/pegasus.cpp b/src/mame/drivers/pegasus.cpp
index 55eae153890..a8bd6934e77 100644
--- a/src/mame/drivers/pegasus.cpp
+++ b/src/mame/drivers/pegasus.cpp
@@ -427,7 +427,7 @@ image_init_result pegasus_state::load_cart(device_image_interface &image, generi
if (size > 0x1000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
@@ -443,7 +443,7 @@ image_init_result pegasus_state::load_cart(device_image_interface &image, generi
std::string errmsg = string_format(
"Attempted to load a file that does not work in this socket.\n"
"Please check \"Usage\" field in the software list for the correct socket(s) to use.");
- image.seterror(IMAGE_ERROR_UNSPECIFIED, errmsg.c_str());
+ image.seterror(image_error::INVALIDIMAGE, errmsg.c_str());
return image_init_result::FAIL;
}
}
diff --git a/src/mame/drivers/phunsy.cpp b/src/mame/drivers/phunsy.cpp
index fc5c5776fa5..25a260c9c5f 100644
--- a/src/mame/drivers/phunsy.cpp
+++ b/src/mame/drivers/phunsy.cpp
@@ -291,7 +291,7 @@ QUICKLOAD_LOAD_MEMBER(phunsy_state::quickload_cb)
int quick_length = image.length();
if (quick_length > 0x4000)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too long");
+ image.seterror(image_error::INVALIDIMAGE, "File too long");
image.message(" File too long");
}
else
diff --git a/src/mame/drivers/pipbug.cpp b/src/mame/drivers/pipbug.cpp
index dee8696c1b1..a7214dbb094 100644
--- a/src/mame/drivers/pipbug.cpp
+++ b/src/mame/drivers/pipbug.cpp
@@ -160,12 +160,12 @@ QUICKLOAD_LOAD_MEMBER(pipbug_state::quickload_cb)
quick_length = image.length();
if (quick_length < 0x0444)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too short");
+ image.seterror(image_error::INVALIDIMAGE, "File too short");
image.message(" File too short");
}
else if (quick_length > 0x8000)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too long");
+ image.seterror(image_error::INVALIDIMAGE, "File too long");
image.message(" File too long");
}
else
@@ -174,12 +174,12 @@ QUICKLOAD_LOAD_MEMBER(pipbug_state::quickload_cb)
read_ = image.fread( &quick_data[0], quick_length);
if (read_ != quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Cannot read the file");
+ image.seterror(image_error::INVALIDIMAGE, "Cannot read the file");
image.message(" Cannot read the file");
}
else if (quick_data[0] != 0xc4)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid header");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid header");
image.message(" Invalid header");
}
else
@@ -188,7 +188,7 @@ QUICKLOAD_LOAD_MEMBER(pipbug_state::quickload_cb)
if (exec_addr >= quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Exec address beyond end of file");
+ image.seterror(image_error::INVALIDIMAGE, "Exec address beyond end of file");
image.message(" Exec address beyond end of file");
}
else
diff --git a/src/mame/drivers/pokemini.cpp b/src/mame/drivers/pokemini.cpp
index d99f74beb14..297b491228b 100644
--- a/src/mame/drivers/pokemini.cpp
+++ b/src/mame/drivers/pokemini.cpp
@@ -1516,14 +1516,14 @@ DEVICE_IMAGE_LOAD_MEMBER( pokemini_state::cart_load )
/* Verify that the image is big enough */
if (size <= 0x2100)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid ROM image: ROM image is too small");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid ROM image: ROM image is too small");
return image_init_result::FAIL;
}
/* Verify that the image is not too big */
if (size > 0x1fffff)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid ROM image: ROM image is too big");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid ROM image: ROM image is too big");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/pv1000.cpp b/src/mame/drivers/pv1000.cpp
index 63b19c16975..f3dcef31f94 100644
--- a/src/mame/drivers/pv1000.cpp
+++ b/src/mame/drivers/pv1000.cpp
@@ -307,7 +307,7 @@ DEVICE_IMAGE_LOAD_MEMBER( pv1000_state::cart_load )
if (size != 0x2000 && size != 0x4000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/pv2000.cpp b/src/mame/drivers/pv2000.cpp
index d3080bfffc3..eefb89a8b02 100644
--- a/src/mame/drivers/pv2000.cpp
+++ b/src/mame/drivers/pv2000.cpp
@@ -373,7 +373,7 @@ DEVICE_IMAGE_LOAD_MEMBER( pv2000_state::cart_load )
if (size != 0x2000 && size != 0x4000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/ravens.cpp b/src/mame/drivers/ravens.cpp
index a557347644a..41171b74b79 100644
--- a/src/mame/drivers/ravens.cpp
+++ b/src/mame/drivers/ravens.cpp
@@ -322,12 +322,12 @@ QUICKLOAD_LOAD_MEMBER(ravens_base::quickload_cb)
quick_length = image.length();
if (quick_length < 0x0900)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too short");
+ image.seterror(image_error::INVALIDIMAGE, "File too short");
image.message(" File too short");
}
else if (quick_length > 0x8000)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too long");
+ image.seterror(image_error::INVALIDIMAGE, "File too long");
image.message(" File too long");
}
else
@@ -336,12 +336,12 @@ QUICKLOAD_LOAD_MEMBER(ravens_base::quickload_cb)
read_ = image.fread( &quick_data[0], quick_length);
if (read_ != quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Cannot read the file");
+ image.seterror(image_error::INVALIDIMAGE, "Cannot read the file");
image.message(" Cannot read the file");
}
else if (quick_data[0] != 0xc6)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid header");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid header");
image.message(" Invalid header");
}
else
@@ -350,7 +350,7 @@ QUICKLOAD_LOAD_MEMBER(ravens_base::quickload_cb)
if (exec_addr >= quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Exec address beyond end of file");
+ image.seterror(image_error::INVALIDIMAGE, "Exec address beyond end of file");
image.message(" Exec address beyond end of file");
}
else
diff --git a/src/mame/drivers/roland_cm32p.cpp b/src/mame/drivers/roland_cm32p.cpp
index e26027acef2..cefe4efe729 100644
--- a/src/mame/drivers/roland_cm32p.cpp
+++ b/src/mame/drivers/roland_cm32p.cpp
@@ -398,7 +398,7 @@ DEVICE_IMAGE_LOAD_MEMBER(cm32p_state::card_load)
uint32_t size = pcmcard->common_get_size("rom");
if (size > 0x080000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only up to 512K is supported");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only up to 512K is supported");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/rx78.cpp b/src/mame/drivers/rx78.cpp
index b7b3075130a..77696012e17 100644
--- a/src/mame/drivers/rx78.cpp
+++ b/src/mame/drivers/rx78.cpp
@@ -489,7 +489,7 @@ DEVICE_IMAGE_LOAD_MEMBER( rx78_state::cart_load )
if (size != 0x2000 && size != 0x4000 && size != 0x8000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/sag.cpp b/src/mame/drivers/sag.cpp
index 9a530c24bfd..8799ba83bb8 100644
--- a/src/mame/drivers/sag.cpp
+++ b/src/mame/drivers/sag.cpp
@@ -112,7 +112,7 @@ DEVICE_IMAGE_LOAD_MEMBER(sag_state::cart_load)
if (size != 0x1000 && size != 0x1100 && size != 0x2000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid ROM file size");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid ROM file size");
return image_init_result::FAIL;
}
@@ -125,7 +125,7 @@ DEVICE_IMAGE_LOAD_MEMBER(sag_state::cart_load)
// TMS1670 MCU
if (!image.loaded_through_softlist())
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Can only load TMS1670 type through softwarelist");
+ image.seterror(image_error::INVALIDIMAGE, "Can only load TMS1670 type through softwarelist");
return image_init_result::FAIL;
}
@@ -136,7 +136,7 @@ DEVICE_IMAGE_LOAD_MEMBER(sag_state::cart_load)
size = image.get_software_region_length("rom:mpla");
if (size != 867)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid MPLA file size");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid MPLA file size");
return image_init_result::FAIL;
}
memcpy(memregion("tms1k_cpu:mpla")->base(), image.get_software_region("rom:mpla"), size);
@@ -144,7 +144,7 @@ DEVICE_IMAGE_LOAD_MEMBER(sag_state::cart_load)
size = image.get_software_region_length("rom:opla");
if (size != 557)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid OPLA file size");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid OPLA file size");
return image_init_result::FAIL;
}
memcpy(memregion("tms1k_cpu:opla")->base(), image.get_software_region("rom:opla"), size);
diff --git a/src/mame/drivers/spg2xx_ican.cpp b/src/mame/drivers/spg2xx_ican.cpp
index 0398e13935e..d346c9ad549 100644
--- a/src/mame/drivers/spg2xx_ican.cpp
+++ b/src/mame/drivers/spg2xx_ican.cpp
@@ -430,7 +430,7 @@ DEVICE_IMAGE_LOAD_MEMBER(icanguit_state::cart_load_icanguit)
if (size < 0x800000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/spg2xx_smarttv.cpp b/src/mame/drivers/spg2xx_smarttv.cpp
index 27f042d8a7a..bc315ae4a43 100644
--- a/src/mame/drivers/spg2xx_smarttv.cpp
+++ b/src/mame/drivers/spg2xx_smarttv.cpp
@@ -193,7 +193,7 @@ DEVICE_IMAGE_LOAD_MEMBER(smarttv_state::cart_load_smarttv)
if (size > 0x800000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/spg2xx_telestory.cpp b/src/mame/drivers/spg2xx_telestory.cpp
index 972cf1206fb..b8a0dd24411 100644
--- a/src/mame/drivers/spg2xx_telestory.cpp
+++ b/src/mame/drivers/spg2xx_telestory.cpp
@@ -257,7 +257,7 @@ DEVICE_IMAGE_LOAD_MEMBER(telestory_state::cart_load_telestory)
if (size > 0x800000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/spg2xx_tvgogo.cpp b/src/mame/drivers/spg2xx_tvgogo.cpp
index df0bc746d07..b1bf613e7d0 100644
--- a/src/mame/drivers/spg2xx_tvgogo.cpp
+++ b/src/mame/drivers/spg2xx_tvgogo.cpp
@@ -210,7 +210,7 @@ DEVICE_IMAGE_LOAD_MEMBER(tvgogo_state::cart_load_tvgogo)
if (size > 0x800000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/spg2xx_vii.cpp b/src/mame/drivers/spg2xx_vii.cpp
index ab86e434895..9ed30031233 100644
--- a/src/mame/drivers/spg2xx_vii.cpp
+++ b/src/mame/drivers/spg2xx_vii.cpp
@@ -153,7 +153,7 @@ DEVICE_IMAGE_LOAD_MEMBER(vii_state::cart_load_vii)
if (size < 0x800000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/squale.cpp b/src/mame/drivers/squale.cpp
index e0b7dce8e0b..018f9a12903 100644
--- a/src/mame/drivers/squale.cpp
+++ b/src/mame/drivers/squale.cpp
@@ -629,7 +629,7 @@ DEVICE_IMAGE_LOAD_MEMBER( squale_state::cart_load )
if ( ! size || size > 0x10000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/studio2.cpp b/src/mame/drivers/studio2.cpp
index 44278fe4780..f51c62a7d79 100644
--- a/src/mame/drivers/studio2.cpp
+++ b/src/mame/drivers/studio2.cpp
@@ -604,7 +604,7 @@ DEVICE_IMAGE_LOAD_MEMBER( studio2_state::cart_load )
if (image.length() < 0x200)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid ROM file");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid ROM file");
return image_init_result::FAIL;
}
@@ -613,14 +613,14 @@ DEVICE_IMAGE_LOAD_MEMBER( studio2_state::cart_load )
// validate
if (strncmp((const char *)header, "RCA2", 4))
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Not an .ST2 file");
+ image.seterror(image_error::INVALIDIMAGE, "Not an .ST2 file");
return image_init_result::FAIL;
}
blocks = header[4];
if ((blocks < 2) || (blocks > 11))
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid .ST2 file");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid .ST2 file");
return image_init_result::FAIL;
}
@@ -654,7 +654,7 @@ DEVICE_IMAGE_LOAD_MEMBER( studio2_state::cart_load )
size = image.length();
if (size > 0x400)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
else
diff --git a/src/mame/drivers/supracan.cpp b/src/mame/drivers/supracan.cpp
index 9090c1c59de..524cfa70056 100644
--- a/src/mame/drivers/supracan.cpp
+++ b/src/mame/drivers/supracan.cpp
@@ -1922,7 +1922,7 @@ DEVICE_IMAGE_LOAD_MEMBER(supracan_state::cart_load)
if (size > 0x400000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/sv8000.cpp b/src/mame/drivers/sv8000.cpp
index d671302c563..5302f27a27e 100644
--- a/src/mame/drivers/sv8000.cpp
+++ b/src/mame/drivers/sv8000.cpp
@@ -207,7 +207,7 @@ DEVICE_IMAGE_LOAD_MEMBER( sv8000_state::cart_load )
if (size != 0x1000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Incorrect or not support cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Incorrect or not support cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/svision.cpp b/src/mame/drivers/svision.cpp
index ce3e08c94b1..52cf9b295b7 100644
--- a/src/mame/drivers/svision.cpp
+++ b/src/mame/drivers/svision.cpp
@@ -449,7 +449,7 @@ DEVICE_IMAGE_LOAD_MEMBER( svision_state::cart_load )
if (size > 0x80000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/ti74.cpp b/src/mame/drivers/ti74.cpp
index 3047da4e1b1..7d034c30ef1 100644
--- a/src/mame/drivers/ti74.cpp
+++ b/src/mame/drivers/ti74.cpp
@@ -148,7 +148,7 @@ DEVICE_IMAGE_LOAD_MEMBER(ti74_state::cart_load)
// max size is 32KB
if (size > 0x8000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid file size");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid file size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/timex.cpp b/src/mame/drivers/timex.cpp
index a5bb629ca0f..70b3bfb824f 100644
--- a/src/mame/drivers/timex.cpp
+++ b/src/mame/drivers/timex.cpp
@@ -608,12 +608,12 @@ DEVICE_IMAGE_LOAD_MEMBER( ts2068_state::cart_load )
if (size % 0x2000 != 9)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "File corrupted");
+ image.seterror(image_error::INVALIDIMAGE, "File corrupted");
return image_init_result::FAIL;
}
if (!image.loaded_through_softlist())
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Loading from softlist is not supported yet");
+ image.seterror(image_error::UNSUPPORTED, "Loading from softlist is not supported yet");
return image_init_result::FAIL;
}
@@ -628,7 +628,7 @@ DEVICE_IMAGE_LOAD_MEMBER( ts2068_state::cart_load )
if (chunks_in_file * 0x2000 + 0x09 != size)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "File corrupted");
+ image.seterror(image_error::INVALIDIMAGE, "File corrupted");
return image_init_result::FAIL;
}
@@ -652,7 +652,7 @@ DEVICE_IMAGE_LOAD_MEMBER( ts2068_state::cart_load )
break;
default:
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Cart type not supported");
+ image.seterror(image_error::INVALIDIMAGE, "Cart type not supported");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/tispeak.cpp b/src/mame/drivers/tispeak.cpp
index 707690af65a..b858d0e60c5 100644
--- a/src/mame/drivers/tispeak.cpp
+++ b/src/mame/drivers/tispeak.cpp
@@ -551,7 +551,7 @@ DEVICE_IMAGE_LOAD_MEMBER(tispeak_state::cart_load)
if (size > m_cart_max_size)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid file size");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid file size");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/vc4000.cpp b/src/mame/drivers/vc4000.cpp
index b3c8427ed8d..bace6ae8ab2 100644
--- a/src/mame/drivers/vc4000.cpp
+++ b/src/mame/drivers/vc4000.cpp
@@ -410,7 +410,7 @@ QUICKLOAD_LOAD_MEMBER(vc4000_state::quickload_cb)
read_ = image.fread( &quick_data[0], quick_length);
if (read_ != quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Cannot read the file");
+ image.seterror(image_error::INVALIDIMAGE, "Cannot read the file");
image.message(" Cannot read the file");
}
else
@@ -419,7 +419,7 @@ QUICKLOAD_LOAD_MEMBER(vc4000_state::quickload_cb)
{
if (quick_data[0] != 2)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid header");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid header");
image.message(" Invalid header");
}
else
@@ -429,13 +429,13 @@ QUICKLOAD_LOAD_MEMBER(vc4000_state::quickload_cb)
if (quick_length < 0x5)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too short");
+ image.seterror(image_error::INVALIDIMAGE, "File too short");
image.message(" File too short");
}
else
if ((quick_length + quick_addr - 5) > 0x1600)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too long");
+ image.seterror(image_error::INVALIDIMAGE, "File too long");
image.message(" File too long");
}
else
@@ -460,7 +460,7 @@ QUICKLOAD_LOAD_MEMBER(vc4000_state::quickload_cb)
{
if (quick_data[0] != 0)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid header");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid header");
image.message(" Invalid header");
}
else
@@ -469,19 +469,19 @@ QUICKLOAD_LOAD_MEMBER(vc4000_state::quickload_cb)
if (exec_addr >= quick_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Exec address beyond end of file");
+ image.seterror(image_error::INVALIDIMAGE, "Exec address beyond end of file");
image.message(" Exec address beyond end of file");
}
else
if (quick_length < 0x904)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too short");
+ image.seterror(image_error::INVALIDIMAGE, "File too short");
image.message(" File too short");
}
else
if (quick_length > 0x2000)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too long");
+ image.seterror(image_error::INVALIDIMAGE, "File too long");
image.message(" File too long");
}
else
diff --git a/src/mame/drivers/vtech1.cpp b/src/mame/drivers/vtech1.cpp
index 101f3b4a214..029c7417461 100644
--- a/src/mame/drivers/vtech1.cpp
+++ b/src/mame/drivers/vtech1.cpp
@@ -184,7 +184,7 @@ SNAPSHOT_LOAD_MEMBER(vtech1_base_state::snapshot_cb)
// verify
if (space.read_byte(addr) != to_write)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Insufficient RAM to load snapshot");
+ image.seterror(image_error::INVALIDIMAGE, "Insufficient RAM to load snapshot");
image.message("Insufficient RAM to load snapshot (%d bytes needed) [%s]", size, pgmname);
return image_init_result::FAIL;
@@ -214,7 +214,7 @@ SNAPSHOT_LOAD_MEMBER(vtech1_base_state::snapshot_cb)
break;
default:
- image.seterror(IMAGE_ERROR_UNSUPPORTED, "Snapshot format not supported.");
+ image.seterror(image_error::INVALIDIMAGE, "Snapshot format not supported.");
image.message("Snapshot format not supported.");
return image_init_result::FAIL;
}
diff --git a/src/mame/drivers/x07.cpp b/src/mame/drivers/x07.cpp
index f103a68e766..dcd9bb93ea1 100644
--- a/src/mame/drivers/x07.cpp
+++ b/src/mame/drivers/x07.cpp
@@ -1063,7 +1063,7 @@ DEVICE_IMAGE_LOAD_MEMBER( x07_state::card_load )
if (strcmp(card_type, "xp140"))
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported card type");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported card type");
return image_init_result::FAIL;
}
}
diff --git a/src/mame/drivers/z1013.cpp b/src/mame/drivers/z1013.cpp
index dd938204e1a..4cb97de983e 100644
--- a/src/mame/drivers/z1013.cpp
+++ b/src/mame/drivers/z1013.cpp
@@ -380,7 +380,7 @@ SNAPSHOT_LOAD_MEMBER(z1013_state::snapshot_cb)
{ }
else
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Not a Z1013 image");
+ image.seterror(image_error::INVALIDIMAGE, "Not a Z1013 image");
image.message(" Not a Z1013 image");
return image_init_result::FAIL;
}
@@ -392,7 +392,7 @@ SNAPSHOT_LOAD_MEMBER(z1013_state::snapshot_cb)
m_maincpu->set_state_int(Z80_PC, runaddr);
else
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Loaded but cannot run");
+ image.seterror(image_error::INVALIDIMAGE, "Loaded but cannot run");
image.message(" Loaded but cannot run");
}
diff --git a/src/mame/machine/amstrad.cpp b/src/mame/machine/amstrad.cpp
index c8b37acd746..f32b13830c1 100644
--- a/src/mame/machine/amstrad.cpp
+++ b/src/mame/machine/amstrad.cpp
@@ -3315,7 +3315,7 @@ DEVICE_IMAGE_LOAD_MEMBER(amstrad_state::amstrad_plus_cartridge)
logerror("IMG: raw CPC+ cartridge file\n");
if (size % 0x4000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Attempt to load a raw binary with some block smaller than 16kB in size");
+ image.seterror(image_error::INVALIDIMAGE, "Attempt to load a raw binary with some block smaller than 16kB in size");
return image_init_result::FAIL;
}
else
@@ -3346,7 +3346,7 @@ DEVICE_IMAGE_LOAD_MEMBER(amstrad_state::amstrad_plus_cartridge)
// Is RIFF format (*.cpr)
if (strncmp((char*)(header + 8), "AMS!", 4) != 0)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Not an Amstrad CPC cartridge image (despite RIFF header)");
+ image.seterror(image_error::INVALIDIMAGE, "Not an Amstrad CPC cartridge image (despite RIFF header)");
return image_init_result::FAIL;
}
diff --git a/src/mame/machine/electron.cpp b/src/mame/machine/electron.cpp
index ac6b9df4dc4..464f4f7a0da 100644
--- a/src/mame/machine/electron.cpp
+++ b/src/mame/machine/electron.cpp
@@ -654,7 +654,7 @@ image_init_result electronsp_state::load_rom(device_image_interface &image, gene
// socket accepts 8K and 16K ROM only
if (size != 0x2000 && size != 0x4000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported");
return image_init_result::FAIL;
}
diff --git a/src/mame/machine/gamecom.cpp b/src/mame/machine/gamecom.cpp
index 94ce240f443..727f4f8e8ab 100644
--- a/src/mame/machine/gamecom.cpp
+++ b/src/mame/machine/gamecom.cpp
@@ -627,7 +627,7 @@ image_init_result gamecom_state::common_load(device_image_interface &image, gene
if (size != 0x008000 && size != 0x040000 && size != 0x080000
&& size != 0x100000 && size != 0x1c0000 && size != 0x200000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
diff --git a/src/mame/machine/m1comm.cpp b/src/mame/machine/m1comm.cpp
index e43d5251845..64e763e41f7 100644
--- a/src/mame/machine/m1comm.cpp
+++ b/src/mame/machine/m1comm.cpp
@@ -560,7 +560,7 @@ int m1comm_device::read_frame(int dataSize)
// try to read a message
std::uint32_t recv = 0;
- osd_file::error filerr = m_line_rx->read(m_buffer0, 0, dataSize, recv);
+ std::error_condition filerr = m_line_rx->read(m_buffer0, 0, dataSize, recv);
if (recv > 0)
{
// check if message complete
@@ -581,14 +581,14 @@ int m1comm_device::read_frame(int dataSize)
togo -= recv;
offset += recv;
}
- else if (filerr == osd_file::error::NONE && recv == 0)
+ else if (!filerr && recv == 0)
{
togo = 0;
}
}
}
}
- else if (filerr == osd_file::error::NONE && recv == 0)
+ else if (!filerr && recv == 0)
{
if (m_linkalive == 0x01)
{
@@ -619,11 +619,11 @@ void m1comm_device::send_frame(int dataSize){
if (!m_line_tx)
return;
- osd_file::error filerr;
+ std::error_condition filerr;
std::uint32_t written;
filerr = m_line_tx->write(&m_buffer0, 0, dataSize, written);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
if (m_linkalive == 0x01)
{
diff --git a/src/mame/machine/m2comm.cpp b/src/mame/machine/m2comm.cpp
index 4008cd9fd3f..dd25325f6f6 100644
--- a/src/mame/machine/m2comm.cpp
+++ b/src/mame/machine/m2comm.cpp
@@ -632,7 +632,7 @@ int m2comm_device::read_frame(int dataSize)
// try to read a message
std::uint32_t recv = 0;
- osd_file::error filerr = m_line_rx->read(m_buffer0, 0, dataSize, recv);
+ std::error_condition filerr = m_line_rx->read(m_buffer0, 0, dataSize, recv);
if (recv > 0)
{
// check if message complete
@@ -653,14 +653,14 @@ int m2comm_device::read_frame(int dataSize)
togo -= recv;
offset += recv;
}
- else if (filerr == osd_file::error::NONE && recv == 0)
+ else if (!filerr && recv == 0)
{
togo = 0;
}
}
}
}
- else if (filerr == osd_file::error::NONE && recv == 0)
+ else if (!filerr && recv == 0)
{
if (m_linkalive == 0x01)
{
@@ -687,11 +687,11 @@ void m2comm_device::send_frame(int dataSize){
if (!m_line_tx)
return;
- osd_file::error filerr;
+ std::error_condition filerr;
std::uint32_t written;
filerr = m_line_tx->write(&m_buffer0, 0, dataSize, written);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
if (m_linkalive == 0x01)
{
diff --git a/src/mame/machine/mbee.cpp b/src/mame/machine/mbee.cpp
index a70c470c445..c6a9ec55763 100644
--- a/src/mame/machine/mbee.cpp
+++ b/src/mame/machine/mbee.cpp
@@ -731,7 +731,7 @@ image_init_result mbee_state::load_cart(device_image_interface &image, generic_s
// "mbp" roms
if ((size == 0) || (size > 0x4000))
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported ROM size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported ROM size");
return image_init_result::FAIL;
}
@@ -744,7 +744,7 @@ image_init_result mbee_state::load_cart(device_image_interface &image, generic_s
logerror ("Rom header = %02X %02X %02X\n", slot->read_rom(0), slot->read_rom(1), slot->read_rom(2));
if ((slot->read_rom(0) != 0xc3) || ((slot->read_rom(2) & 0xe0) != 0xc0))
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Not a PAK rom");
+ image.seterror(image_error::INVALIDIMAGE, "Not a PAK rom");
slot->call_unload();
return image_init_result::FAIL;
}
@@ -754,7 +754,7 @@ image_init_result mbee_state::load_cart(device_image_interface &image, generic_s
// "mbn" roms
if ((size == 0) || (size > 0x2000))
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported ROM size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported ROM size");
return image_init_result::FAIL;
}
m_pak_extended[pak_index] = (size > 0x1000) ? true : false;
@@ -768,7 +768,7 @@ image_init_result mbee_state::load_cart(device_image_interface &image, generic_s
{
if ((slot->read_rom(0) != 0xc3) || ((slot->read_rom(2) & 0xf0) != 0xe0))
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Not a NET rom");
+ image.seterror(image_error::INVALIDIMAGE, "Not a NET rom");
slot->call_unload();
return image_init_result::FAIL;
}
diff --git a/src/mame/machine/mtx.cpp b/src/mame/machine/mtx.cpp
index 8c0c086aab0..3cccaa3d7bf 100644
--- a/src/mame/machine/mtx.cpp
+++ b/src/mame/machine/mtx.cpp
@@ -397,7 +397,7 @@ DEVICE_IMAGE_LOAD_MEMBER( mtx_state::extrom_load )
if (size > 0x80000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported rom size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported rom size");
return image_init_result::FAIL;
}
@@ -417,7 +417,7 @@ DEVICE_IMAGE_LOAD_MEMBER( mtx_state::rompak_load )
if (size > 0x2000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size");
return image_init_result::FAIL;
}
@@ -441,7 +441,7 @@ SNAPSHOT_LOAD_MEMBER(mtx_state::snapshot_cb)
// verify first byte
if (data[0] != 0xff)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, nullptr);
+ image.seterror(image_error::INVALIDIMAGE, nullptr);
return image_init_result::FAIL;
}
@@ -488,7 +488,7 @@ QUICKLOAD_LOAD_MEMBER(mtx_state::quickload_cb)
if (image.length() < 4)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too short");
+ image.seterror(image_error::INVALIDIMAGE, "File too short");
return image_init_result::FAIL;
}
@@ -497,13 +497,13 @@ QUICKLOAD_LOAD_MEMBER(mtx_state::quickload_cb)
if (image.length() < code_length)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File too short");
+ image.seterror(image_error::INVALIDIMAGE, "File too short");
return image_init_result::FAIL;
}
if (code_base < 0x4000 || (code_base + code_length) >= 0x10000)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid code base and length");
+ image.seterror(image_error::INVALIDIMAGE, "Invalid code base and length");
return image_init_result::FAIL;
}
diff --git a/src/mame/machine/s32comm.cpp b/src/mame/machine/s32comm.cpp
index b53448b46d3..420b7d54471 100644
--- a/src/mame/machine/s32comm.cpp
+++ b/src/mame/machine/s32comm.cpp
@@ -266,7 +266,7 @@ int s32comm_device::read_frame(int dataSize)
// try to read a message
std::uint32_t recv = 0;
- osd_file::error filerr = m_line_rx->read(m_buffer0, 0, dataSize, recv);
+ std::error_condition filerr = m_line_rx->read(m_buffer0, 0, dataSize, recv);
if (recv > 0)
{
// check if message complete
@@ -287,14 +287,14 @@ int s32comm_device::read_frame(int dataSize)
togo -= recv;
offset += recv;
}
- else if (filerr == osd_file::error::NONE && recv == 0)
+ else if (!filerr && recv == 0)
{
togo = 0;
}
}
}
}
- else if (filerr == osd_file::error::NONE && recv == 0)
+ else if (!filerr && recv == 0)
{
if (m_linkalive == 0x01)
{
@@ -322,11 +322,11 @@ void s32comm_device::send_frame(int dataSize){
if (!m_line_tx)
return;
- osd_file::error filerr;
+ std::error_condition filerr;
std::uint32_t written;
filerr = m_line_tx->write(&m_buffer0, 0, dataSize, written);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
if (m_linkalive == 0x01)
{
diff --git a/src/mame/machine/sorcerer.cpp b/src/mame/machine/sorcerer.cpp
index d4eac2ac17d..84a696c1040 100644
--- a/src/mame/machine/sorcerer.cpp
+++ b/src/mame/machine/sorcerer.cpp
@@ -600,7 +600,7 @@ QUICKLOAD_LOAD_MEMBER(sorcerer_state::quickload_cb)
// check size
if (image.length() != 0x1001c)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Snapshot must be 65564 bytes");
+ image.seterror(image_error::INVALIDIMAGE, "Snapshot must be 65564 bytes");
image.message("Snapshot must be 65564 bytes");
return image_init_result::FAIL;
}
diff --git a/src/mame/machine/thomson.cpp b/src/mame/machine/thomson.cpp
index 16afac21ceb..f8201ded8da 100644
--- a/src/mame/machine/thomson.cpp
+++ b/src/mame/machine/thomson.cpp
@@ -281,7 +281,7 @@ DEVICE_IMAGE_LOAD_MEMBER( thomson_state::to7_cartridge )
m_thom_cart_nb_banks = 4;
else
{
- image.seterror(IMAGE_ERROR_UNSUPPORTED, string_format("Invalid cartridge size %u", size).c_str());
+ image.seterror(image_error::INVALIDIMAGE, string_format("Invalid cartridge size %u", size).c_str());
return image_init_result::FAIL;
}
@@ -289,7 +289,7 @@ DEVICE_IMAGE_LOAD_MEMBER( thomson_state::to7_cartridge )
{
if ( image.fread( pos, size ) != size )
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Read error");
+ image.seterror(image_error::INVALIDIMAGE, "Read error");
return image_init_result::FAIL;
}
}
@@ -1389,7 +1389,7 @@ DEVICE_IMAGE_LOAD_MEMBER( thomson_state::mo5_cartridge )
m_thom_cart_nb_banks = 4;
else
{
- image.seterror(IMAGE_ERROR_UNSUPPORTED, string_format("Invalid cartridge size %d", size).c_str());
+ image.seterror(image_error::INVALIDIMAGE, string_format("Invalid cartridge size %d", size).c_str());
return image_init_result::FAIL;
}
@@ -1397,7 +1397,7 @@ DEVICE_IMAGE_LOAD_MEMBER( thomson_state::mo5_cartridge )
{
if ( image.fread(pos, size ) != size )
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Read error");
+ image.seterror(image_error::INVALIDIMAGE, "Read error");
return image_init_result::FAIL;
}
}
diff --git a/src/mame/machine/vtech2.cpp b/src/mame/machine/vtech2.cpp
index 3ac1e62ce3f..0e8a2bea126 100644
--- a/src/mame/machine/vtech2.cpp
+++ b/src/mame/machine/vtech2.cpp
@@ -54,7 +54,7 @@ DEVICE_IMAGE_LOAD_MEMBER( vtech2_state::cart_load )
if (m_cart_size > 0x10000)
{
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Cartridge bigger than 64k");
+ image.seterror(image_error::INVALIDIMAGE, "Cartridge bigger than 64k");
m_cart_size = 0;
return image_init_result::FAIL;
}
diff --git a/src/mame/machine/z80bin.cpp b/src/mame/machine/z80bin.cpp
index ba24d545d1f..c14cf196819 100644
--- a/src/mame/machine/z80bin.cpp
+++ b/src/mame/machine/z80bin.cpp
@@ -23,7 +23,7 @@ image_init_result z80bin_load_file(device_image_interface &image, address_space
{
if (ch == EOF)
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Unexpected EOF while getting file name");
+ image.seterror(image_error::INVALIDIMAGE, "Unexpected EOF while getting file name");
image.message(" Unexpected EOF while getting file name");
return image_init_result::FAIL;
}
@@ -32,7 +32,7 @@ image_init_result z80bin_load_file(device_image_interface &image, address_space
{
if (i >= (std::size(pgmname) - 1))
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "File name too long");
+ image.seterror(image_error::INVALIDIMAGE, "File name too long");
image.message(" File name too long");
return image_init_result::FAIL;
}
@@ -46,7 +46,7 @@ image_init_result z80bin_load_file(device_image_interface &image, address_space
if (image.fread(args, sizeof(args)) != sizeof(args))
{
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Unexpected EOF while getting file size");
+ image.seterror(image_error::INVALIDIMAGE, "Unexpected EOF while getting file size");
image.message(" Unexpected EOF while getting file size");
return image_init_result::FAIL;
}
@@ -66,7 +66,7 @@ image_init_result z80bin_load_file(device_image_interface &image, address_space
if (image.fread(&data, 1) != 1)
{
snprintf(message, std::size(message), "%s: Unexpected EOF while writing byte to %04X", pgmname, (unsigned) j);
- image.seterror(IMAGE_ERROR_INVALIDIMAGE, message);
+ image.seterror(image_error::INVALIDIMAGE, message);
image.message("%s: Unexpected EOF while writing byte to %04X", pgmname, (unsigned) j);
return image_init_result::FAIL;
}
diff --git a/src/mame/video/midtunit.cpp b/src/mame/video/midtunit.cpp
index 4a74af2b188..7301e883fb6 100644
--- a/src/mame/video/midtunit.cpp
+++ b/src/mame/video/midtunit.cpp
@@ -902,7 +902,7 @@ void midtunit_video_device::log_bitmap(int command, int bpp, bool Skip)
char name_buf[256];
snprintf(name_buf, 255, "0x%08x.png", raw_offset);
auto const filerr = file.open(name_buf);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
return;
}
@@ -1029,7 +1029,7 @@ void midtunit_video_device::log_bitmap(int command, int bpp, bool Skip)
snprintf(name_buf, 255, "0x%08x.json", raw_offset);
auto const jsonerr = json.open(name_buf);
- if (jsonerr != osd_file::error::NONE)
+ if (jsonerr)
{
return;
}
diff --git a/src/osd/modules/debugger/debuggdbstub.cpp b/src/osd/modules/debugger/debuggdbstub.cpp
index 52289b9997d..6229e6ffba5 100644
--- a/src/osd/modules/debugger/debuggdbstub.cpp
+++ b/src/osd/modules/debugger/debuggdbstub.cpp
@@ -707,8 +707,8 @@ void debug_gdbstub::wait_for_debugger(device_t &device, bool firststop)
#endif
std::string socket_name = string_format("socket.localhost:%d", m_debugger_port);
- osd_file::error filerr = m_socket.open(socket_name);
- if ( filerr != osd_file::error::NONE )
+ std::error_condition const filerr = m_socket.open(socket_name);
+ if ( filerr )
fatalerror("gdbstub: failed to start listening on port %d\n", m_debugger_port);
osd_printf_info("gdbstub: listening on port %d\n", m_debugger_port);
diff --git a/src/osd/modules/debugger/debugimgui.cpp b/src/osd/modules/debugger/debugimgui.cpp
index 8c161792f9d..1046118899c 100644
--- a/src/osd/modules/debugger/debugimgui.cpp
+++ b/src/osd/modules/debugger/debugimgui.cpp
@@ -938,7 +938,7 @@ void debug_imgui::mount_image()
{
if(m_selected_file != nullptr)
{
- osd_file::error err;
+ std::error_condition err;
switch(m_selected_file->type)
{
case file_entry_type::DRIVE:
@@ -947,7 +947,7 @@ void debug_imgui::mount_image()
util::zippath_directory::ptr dir;
err = util::zippath_directory::open(m_selected_file->fullpath, dir);
}
- if(err == osd_file::error::NONE)
+ if(!err)
{
m_filelist_refresh = true;
strcpy(m_path,m_selected_file->fullpath.c_str());
@@ -989,8 +989,8 @@ void debug_imgui::refresh_filelist()
m_filelist_refresh = false;
util::zippath_directory::ptr dir;
- osd_file::error const err = util::zippath_directory::open(m_path,dir);
- if(err == osd_file::error::NONE)
+ std::error_condition const err = util::zippath_directory::open(m_path,dir);
+ if(!err)
{
int x = 0;
// add drives
diff --git a/src/osd/modules/file/posixdomain.cpp b/src/osd/modules/file/posixdomain.cpp
deleted file mode 100644
index 13d564d1738..00000000000
--- a/src/osd/modules/file/posixdomain.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert, R. Belmont, Vas Crabb
-//============================================================
-//
-// sdldomain.c - SDL socket (unix) access functions
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-//============================================================
-
-#include "posixfile.h"
-
-#include <cassert>
-#include <cerrno>
-#include <cstdio>
-#include <cstring>
-
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-
-namespace {
-char const *const posixfile_domain_identifier = "domain.";
-
-
-class posix_osd_domain : public osd_file
-{
-public:
- posix_osd_domain(posix_osd_domain const &) = delete;
- posix_osd_domain(posix_osd_domain &&) = delete;
- posix_osd_domain& operator=(posix_osd_domain const &) = delete;
- posix_osd_domain& operator=(posix_osd_domain &&) = delete;
-
- posix_osd_domain(int sock, bool listening)
- : m_sock(sock)
- , m_listening(listening)
- {
- assert(m_sock >= 0);
- }
-
- virtual ~posix_osd_domain()
- {
- ::close(m_sock);
- }
-
- virtual error read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
- {
- fd_set readfds;
- FD_ZERO(&readfds);
- FD_SET(m_sock, &readfds);
-
- struct timeval timeout;
- timeout.tv_sec = timeout.tv_usec = 0;
-
- if (select(m_sock + 1, &readfds, nullptr, nullptr, &timeout) < 0)
- {
- char line[80];
- std::sprintf(line, "%s : %s : %d ", __func__, __FILE__, __LINE__);
- std::perror(line);
- return errno_to_file_error(errno);
- }
- else if (FD_ISSET(m_sock, &readfds))
- {
- if (!m_listening)
- {
- // connected socket
- ssize_t const result = ::read(m_sock, buffer, count);
- if (result < 0)
- {
- return errno_to_file_error(errno);
- }
- else
- {
- actual = std::uint32_t(size_t(result));
- return error::NONE;
- }
- }
- else
- {
- // listening socket
- int const accepted = ::accept(m_sock, nullptr, nullptr);
- if (accepted < 0)
- {
- return errno_to_file_error(errno);
- }
- else
- {
- ::close(m_sock);
- m_sock = accepted;
- m_listening = false;
- actual = 0;
-
- return error::NONE;
- }
- }
- }
- else
- {
- return error::FAILURE;
- }
- }
-
- virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
- {
- ssize_t const result = ::write(m_sock, buffer, count);
- if (result < 0)
- return errno_to_file_error(errno);
-
- actual = std::uint32_t(size_t(result));
- return error::NONE;
- }
-
- virtual error truncate(std::uint64_t offset) override
- {
- // doesn't make sense on socket
- return error::INVALID_ACCESS;
- }
-
- virtual error flush() override
- {
- // there's no simple way to flush buffers on a socket anyway
- return error::NONE;
- }
-
-private:
- int m_sock;
- bool m_listening;
-};
-
-} // anonymous namespace
-
-
-bool posix_check_domain_path(std::string const &path)
-{
- if (strncmp(path.c_str(), posixfile_domain_identifier, strlen(posixfile_domain_identifier)) == 0)
- return true;
- return false;
-}
-
-
-osd_file::error posix_open_domain(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize)
-{
- struct sockaddr_un sau;
- memset(&sau, 0, sizeof(sau));
- sau.sun_family = AF_UNIX;
- strncpy(sau.sun_path, &path.c_str()[strlen(posixfile_domain_identifier)], sizeof(sau.sun_path)-1);
-
- int const sock = ::socket(AF_UNIX, SOCK_STREAM, 0);
- if (sock < 0)
- return errno_to_file_error(errno);
-
- fcntl(sock, F_SETFL, O_NONBLOCK);
-
- // listening socket support
- if (openflags & OPEN_FLAG_CREATE)
- {
- if (::bind(sock, reinterpret_cast<struct sockaddr const *>(&sau), sizeof(struct sockaddr_un)) < 0)
- {
- int const err = errno;
- ::close(sock);
- return errno_to_file_error(err);
- }
-
- // start to listen...
- if (::listen(sock, 1) < 0)
- {
- int const err = errno;
- ::close(sock);
- return errno_to_file_error(err);
- }
-
- // mark socket as "listening"
- try
- {
- file = std::make_unique<posix_osd_domain>(sock, true);
- filesize = 0;
- return osd_file::error::NONE;
- }
- catch (...)
- {
- ::close(sock);
- return osd_file::error::OUT_OF_MEMORY;
- }
- }
- else
- {
- if (::connect(sock, reinterpret_cast<struct sockaddr const *>(&sau), sizeof(struct sockaddr_un)) < 0)
- {
- ::close(sock);
- return osd_file::error::ACCESS_DENIED; // have to return this value or bitb won't try to bind on connect failure
- }
- try
- {
- file = std::make_unique<posix_osd_domain>(sock, false);
- filesize = 0;
- return osd_file::error::NONE;
- }
- catch (...)
- {
- ::close(sock);
- return osd_file::error::OUT_OF_MEMORY;
- }
- }
-}
diff --git a/src/osd/modules/file/posixfile.cpp b/src/osd/modules/file/posixfile.cpp
index ffdd4c4d477..b7c1cde7442 100644
--- a/src/osd/modules/file/posixfile.cpp
+++ b/src/osd/modules/file/posixfile.cpp
@@ -64,6 +64,7 @@
namespace {
+
//============================================================
// CONSTANTS
//============================================================
@@ -85,7 +86,7 @@ public:
posix_osd_file& operator=(posix_osd_file const &) = delete;
posix_osd_file& operator=(posix_osd_file &&) = delete;
- posix_osd_file(int fd) : m_fd(fd)
+ posix_osd_file(int fd) noexcept : m_fd(fd)
{
assert(m_fd >= 0);
}
@@ -95,7 +96,7 @@ public:
::close(m_fd);
}
- virtual error read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ virtual std::error_condition read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) noexcept override
{
ssize_t result;
@@ -103,20 +104,20 @@ public:
result = ::pread(m_fd, buffer, size_t(count), off_t(std::make_unsigned_t<off_t>(offset)));
#elif defined(WIN32) || defined(SDLMAME_NO64BITIO)
if (lseek(m_fd, off_t(std::make_unsigned_t<off_t>(offset)), SEEK_SET) < 0)
- return errno_to_file_error(errno)
+ return std::error_condition(errno, std::generic_category());
result = ::read(m_fd, buffer, size_t(count));
#else
result = ::pread64(m_fd, buffer, size_t(count), off64_t(offset));
#endif
if (result < 0)
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
actual = std::uint32_t(std::size_t(result));
- return error::NONE;
+ return std::error_condition();
}
- virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ virtual std::error_condition write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) noexcept override
{
ssize_t result;
@@ -124,20 +125,20 @@ public:
result = ::pwrite(m_fd, buffer, size_t(count), off_t(std::make_unsigned_t<off_t>(offset)));
#elif defined(WIN32) || defined(SDLMAME_NO64BITIO)
if (lseek(m_fd, off_t(std::make_unsigned_t<off_t>(offset)), SEEK_SET) < 0)
- return errno_to_file_error(errno)
+ return std::error_condition(errno, std::generic_category());
result = ::write(m_fd, buffer, size_t(count));
#else
result = ::pwrite64(m_fd, buffer, size_t(count), off64_t(offset));
#endif
if (result < 0)
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
actual = std::uint32_t(std::size_t(result));
- return error::NONE;
+ return std::error_condition();
}
- virtual error truncate(std::uint64_t offset) override
+ virtual std::error_condition truncate(std::uint64_t offset) noexcept override
{
int result;
@@ -148,15 +149,15 @@ public:
#endif
if (result < 0)
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
- return error::NONE;
+ return std::error_condition();
}
- virtual error flush() override
+ virtual std::error_condition flush() noexcept override
{
// no user-space buffering on unistd I/O
- return error::NONE;
+ return std::error_condition();
}
private:
@@ -168,7 +169,7 @@ private:
// is_path_separator
//============================================================
-bool is_path_separator(char c)
+bool is_path_separator(char c) noexcept
{
#if defined(WIN32)
return (c == PATHSEPCH) || (c == INVPATHSEPCH);
@@ -182,31 +183,36 @@ bool is_path_separator(char c)
// create_path_recursive
//============================================================
-osd_file::error create_path_recursive(std::string const &path)
+std::error_condition create_path_recursive(std::string_view path) noexcept
{
// if there's still a separator, and it's not the root, nuke it and recurse
auto const sep = path.rfind(PATHSEPCH);
- if ((sep != std::string::npos) && (sep > 0) && (path[sep - 1] != PATHSEPCH))
+ if ((sep != std::string_view::npos) && (sep > 0) && (path[sep - 1] != PATHSEPCH))
{
- osd_file::error const err = create_path_recursive(path.substr(0, sep));
- if (err != osd_file::error::NONE)
+ std::error_condition err = create_path_recursive(path.substr(0, sep));
+ if (err)
return err;
}
+ // need a NUL-terminated version of the subpath
+ std::string p;
+ try { p = path; }
+ catch (...) { return std::errc::not_enough_memory; }
+
// if the path already exists, we're done
struct stat st;
- if (!::stat(path.c_str(), &st))
- return osd_file::error::NONE;
+ if (!::stat(p.c_str(), &st))
+ return std::error_condition();
// create the path
#ifdef WIN32
- if (mkdir(path.c_str()) < 0)
+ if (mkdir(p.c_str()) < 0)
#else
- if (mkdir(path.c_str(), 0777) < 0)
+ if (mkdir(p.c_str(), 0777) < 0)
#endif
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
else
- return osd_file::error::NONE;
+ return std::error_condition();
}
} // anonymous namespace
@@ -216,7 +222,7 @@ osd_file::error create_path_recursive(std::string const &path)
// osd_file::open
//============================================================
-osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags, ptr &file, std::uint64_t &filesize)
+std::error_condition osd_file::open(std::string const &path, std::uint32_t openflags, ptr &file, std::uint64_t &filesize) noexcept
{
std::string dst;
if (posix_check_socket_path(path))
@@ -239,7 +245,7 @@ osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags,
}
else
{
- return error::INVALID_ACCESS;
+ return std::errc::invalid_argument;
}
#if defined(WIN32)
access |= O_BINARY;
@@ -251,7 +257,8 @@ osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags,
for (auto it = dst.begin(); it != dst.end(); ++it)
*it = (INVPATHSEPCH == *it) ? PATHSEPCH : *it;
#endif
- osd_subst_env(dst, dst);
+ try { osd_subst_env(dst, dst); }
+ catch (...) { return std::errc::not_enough_memory; }
// attempt to open the file
int fd = -1;
@@ -263,6 +270,9 @@ osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags,
if (fd < 0)
{
+ // save the error from the first attempt to open the file
+ std::error_condition openerr(errno, std::generic_category());
+
// create the path if necessary
if ((openflags & OPEN_FLAG_CREATE) && (openflags & OPEN_FLAG_CREATE_PATHS))
{
@@ -270,10 +280,10 @@ osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags,
if (pathsep != std::string::npos)
{
// create the path up to the file
- osd_file::error const error = create_path_recursive(dst.substr(0, pathsep));
+ std::error_condition const createrr = create_path_recursive(dst.substr(0, pathsep));
// attempt to reopen the file
- if (error == osd_file::error::NONE)
+ if (!createrr)
{
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(__HAIKU__) || defined(WIN32) || defined(SDLMAME_NO64BITIO) || defined(__ANDROID__)
fd = ::open(dst.c_str(), access, 0666);
@@ -281,13 +291,17 @@ osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags,
fd = ::open64(dst.c_str(), access, 0666);
#endif
}
+ if (fd < 0)
+ {
+ openerr.assign(errno, std::generic_category());
+ }
}
}
// if we still failed, clean up and free
if (fd < 0)
{
- return errno_to_file_error(errno);
+ return openerr;
}
}
@@ -300,22 +314,20 @@ osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags,
if (::fstat64(fd, &st) < 0)
#endif
{
- int const error = errno;
+ std::error_condition staterr(errno, std::generic_category());
::close(fd);
- return errno_to_file_error(error);
+ return staterr;
}
- filesize = std::uint64_t(std::make_unsigned_t<decltype(st.st_size)>(st.st_size));
- try
- {
- file = std::make_unique<posix_osd_file>(fd);
- return error::NONE;
- }
- catch (...)
+ osd_file::ptr result(new (std::nothrow) posix_osd_file(fd));
+ if (!result)
{
::close(fd);
- return error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
+ file = std::move(result);
+ filesize = std::uint64_t(std::make_unsigned_t<decltype(st.st_size)>(st.st_size));
+ return std::error_condition();
}
@@ -323,9 +335,9 @@ osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags,
// osd_file::openpty
//============================================================
-osd_file::error osd_file::openpty(ptr &file, std::string &name)
+std::error_condition osd_file::openpty(ptr &file, std::string &name) noexcept
{
- std::uint64_t filesize;
+ std::uint64_t filesize;
return posix_open_ptty(OPEN_FLAG_READ | OPEN_FLAG_WRITE, file, filesize, name);
}
@@ -334,12 +346,12 @@ osd_file::error osd_file::openpty(ptr &file, std::string &name)
// osd_file::remove
//============================================================
-osd_file::error osd_file::remove(std::string const &filename)
+std::error_condition osd_file::remove(std::string const &filename) noexcept
{
if (::unlink(filename.c_str()) < -1)
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
else
- return error::NONE;
+ return std::error_condition();
}
@@ -347,7 +359,7 @@ osd_file::error osd_file::remove(std::string const &filename)
// osd_get_physical_drive_geometry
//============================================================
-bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders, uint32_t *heads, uint32_t *sectors, uint32_t *bps)
+bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders, uint32_t *heads, uint32_t *sectors, uint32_t *bps) noexcept
{
return false; // no, no way, huh-uh, forget it
}
@@ -389,7 +401,7 @@ std::unique_ptr<osd::directory::entry> osd_stat(const std::string &path)
// osd_get_full_path
//============================================================
-osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
+std::error_condition osd_get_full_path(std::string &dst, std::string const &path) noexcept
{
try
{
@@ -398,49 +410,49 @@ osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
if (::_fullpath(&path_buffer[0], path.c_str(), MAX_PATH))
{
dst = &path_buffer[0];
- return osd_file::error::NONE;
+ return std::error_condition();
}
else
{
- return osd_file::error::FAILURE;
+ return std::errc::io_error; // TODO: better error reporting?
}
#else
std::unique_ptr<char, void (*)(void *)> canonical(::realpath(path.c_str(), nullptr), &std::free);
if (canonical)
{
dst = canonical.get();
- return osd_file::error::NONE;
+ return std::error_condition();
}
std::vector<char> path_buffer(PATH_MAX);
if (::realpath(path.c_str(), &path_buffer[0]))
{
dst = &path_buffer[0];
- return osd_file::error::NONE;
+ return std::error_condition();
}
else if (path[0] == PATHSEPCH)
{
dst = path;
- return osd_file::error::NONE;
+ return std::error_condition();
}
else
{
while (!::getcwd(&path_buffer[0], path_buffer.size()))
{
if (errno != ERANGE)
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
else
path_buffer.resize(path_buffer.size() * 2);
}
dst.assign(&path_buffer[0]).push_back(PATHSEPCH);
dst.append(path);
- return osd_file::error::NONE;
+ return std::error_condition();
}
#endif
}
catch (...)
{
- return osd_file::error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
}
@@ -449,7 +461,7 @@ osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
// osd_is_absolute_path
//============================================================
-bool osd_is_absolute_path(std::string const &path)
+bool osd_is_absolute_path(std::string const &path) noexcept
{
if (!path.empty() && is_path_separator(path[0]))
return true;
@@ -492,7 +504,7 @@ std::vector<std::string> osd_get_volume_names()
// osd_is_valid_filename_char
//============================================================
-bool osd_is_valid_filename_char(char32_t uchar)
+bool osd_is_valid_filename_char(char32_t uchar) noexcept
{
// The only one that's actually invalid is the slash
// The other two are just problematic because they're the escape character and path separator
@@ -512,7 +524,7 @@ bool osd_is_valid_filename_char(char32_t uchar)
// osd_is_valid_filepath_char
//============================================================
-bool osd_is_valid_filepath_char(char32_t uchar)
+bool osd_is_valid_filepath_char(char32_t uchar) noexcept
{
// One could argue that colon should be in here too because it functions as path separator
return uchar >= 0x20
@@ -527,39 +539,3 @@ bool osd_is_valid_filepath_char(char32_t uchar)
#endif
&& uchar_isvalid(uchar);
}
-
-
-//============================================================
-// errno_to_file_error
-//============================================================
-
-osd_file::error errno_to_file_error(int error)
-{
- switch (error)
- {
- case 0:
- return osd_file::error::NONE;
-
- case ENOENT:
- case ENOTDIR:
- return osd_file::error::NOT_FOUND;
-
- case EACCES:
- case EROFS:
-#ifndef WIN32
- case ETXTBSY:
-#endif
- case EEXIST:
- case EPERM:
- case EISDIR:
- case EINVAL:
- return osd_file::error::ACCESS_DENIED;
-
- case ENFILE:
- case EMFILE:
- return osd_file::error::TOO_MANY_FILES;
-
- default:
- return osd_file::error::FAILURE;
- }
-}
diff --git a/src/osd/modules/file/posixfile.h b/src/osd/modules/file/posixfile.h
index d47c03d691e..eb6f010859e 100644
--- a/src/osd/modules/file/posixfile.h
+++ b/src/osd/modules/file/posixfile.h
@@ -7,25 +7,29 @@
// SDLMAME by Olivier Galibert and R. Belmont
//
//============================================================
+#ifndef MAME_OSD_MODULES_FILE_POSIXFILE_H
+#define MAME_OSD_MODULES_FILE_POSIXFILE_H
+#pragma once
#include "osdfile.h"
#include <cstdint>
#include <string>
+#include <system_error>
//============================================================
// PROTOTYPES
//============================================================
-bool posix_check_socket_path(std::string const &path);
-osd_file::error posix_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize);
+bool posix_check_socket_path(std::string const &path) noexcept;
+std::error_condition posix_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize) noexcept;
-bool posix_check_domain_path(std::string const &path);
-osd_file::error posix_open_domain(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize);
+bool posix_check_domain_path(std::string const &path) noexcept;
+std::error_condition posix_open_domain(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize) noexcept;
-bool posix_check_ptty_path(std::string const &path);
-osd_file::error posix_open_ptty(std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize, std::string &name);
+bool posix_check_ptty_path(std::string const &path) noexcept;
+std::error_condition posix_open_ptty(std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize, std::string &name) noexcept;
-osd_file::error errno_to_file_error(int error);
+#endif // MAME_OSD_MODULES_FILE_POSIXFILE_H
diff --git a/src/osd/modules/file/posixptty.cpp b/src/osd/modules/file/posixptty.cpp
index 5ecb37057ad..57ff069a2ce 100644
--- a/src/osd/modules/file/posixptty.cpp
+++ b/src/osd/modules/file/posixptty.cpp
@@ -52,7 +52,7 @@ public:
posix_osd_ptty& operator=(posix_osd_ptty const &) = delete;
posix_osd_ptty& operator=(posix_osd_ptty &&) = delete;
- posix_osd_ptty(int fd) : m_fd(fd)
+ posix_osd_ptty(int fd) noexcept : m_fd(fd)
{
assert(m_fd >= 0);
}
@@ -62,36 +62,36 @@ public:
::close(m_fd);
}
- virtual error read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ virtual std::error_condition read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) noexcept override
{
ssize_t const result = ::read(m_fd, buffer, count);
if (result < 0)
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
actual = std::uint32_t(size_t(result));
- return error::NONE;
+ return std::error_condition();
}
- virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ virtual std::error_condition write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) noexcept override
{
ssize_t const result = ::write(m_fd, buffer, count);
if (result < 0)
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
actual = std::uint32_t(size_t(result));
- return error::NONE;
+ return std::error_condition();
}
- virtual error truncate(std::uint64_t offset) override
+ virtual std::error_condition truncate(std::uint64_t offset) noexcept override
{
// doesn't make sense on ptty
- return error::INVALID_ACCESS;
+ return std::errc::bad_file_descriptor;
}
- virtual error flush() override
+ virtual std::error_condition flush() noexcept override
{
// no userspace buffers on read/write
- return error::NONE;
+ return std::error_condition();
}
private:
@@ -101,17 +101,18 @@ private:
} // anonymous namespace
-bool posix_check_ptty_path(std::string const &path)
+bool posix_check_ptty_path(std::string const &path) noexcept
{
return strncmp(path.c_str(), posix_ptty_identifier, strlen(posix_ptty_identifier)) == 0;
}
-osd_file::error posix_open_ptty(std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize, std::string &name)
+std::error_condition posix_open_ptty(std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize, std::string &name) noexcept
{
#if defined(__ANDROID__)
- return osd_file::error::FAILURE;
+ return std::errc::not_supported; // TODO: revisit this error code
#else // defined(__ANDROID__)
+ // TODO: handling of the slave path is insecure - should use ptsname_r/ttyname_r in a loop
#if (defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__))
int access = O_NOCTTY;
if (openflags & OPEN_FLAG_WRITE)
@@ -119,11 +120,11 @@ osd_file::error posix_open_ptty(std::uint32_t openflags, osd_file::ptr &file, st
else if (openflags & OPEN_FLAG_READ)
access |= O_RDONLY;
else
- return osd_file::error::INVALID_ACCESS;
+ return std::errc::invalid_argument;
int const masterfd = ::posix_openpt(access);
if (masterfd < 0)
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
// grant access to slave device and check that it can be opened
char const *slavepath;
@@ -133,9 +134,9 @@ osd_file::error posix_open_ptty(std::uint32_t openflags, osd_file::ptr &file, st
((slavepath = ::ptsname(masterfd)) == nullptr) ||
((slavefd = ::open(slavepath, O_RDWR | O_NOCTTY)) < 0))
{
- int const err = errno;
+ std::error_condition err(errno, std::generic_category());
::close(masterfd);
- return errno_to_file_error(err);
+ return err;
}
// check that it's possible to stack BSD-compatibility STREAMS modules
@@ -143,20 +144,20 @@ osd_file::error posix_open_ptty(std::uint32_t openflags, osd_file::ptr &file, st
(::ioctl(slavefd, I_PUSH, "ldterm") < 0) ||
(::ioctl(slavefd, I_PUSH, "ttcompat") < 0))
{
- int const err = errno;
+ std::error_condition err(errno, std::generic_category());
::close(slavefd);
::close(masterfd);
- return errno_to_file_error(err);
+ return err;
}
#else
struct termios tios;
std::memset(&tios, 0, sizeof(tios));
- ::cfmakeraw(&tios);
+ ::cfmakeraw(&tios); // TODO: this is a non-standard BSDism - should set flags some other way
int masterfd = -1, slavefd = -1;
char slavepath[PATH_MAX];
if (::openpty(&masterfd, &slavefd, slavepath, &tios, nullptr) < 0)
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
#endif
::close(slavefd);
@@ -164,16 +165,16 @@ osd_file::error posix_open_ptty(std::uint32_t openflags, osd_file::ptr &file, st
int const oldflags = ::fcntl(masterfd, F_GETFL, 0);
if (oldflags < 0)
{
- int const err = errno;
+ std::error_condition err(errno, std::generic_category());
::close(masterfd);
- return errno_to_file_error(err);
+ return err;
}
if (::fcntl(masterfd, F_SETFL, oldflags | O_NONBLOCK) < 0)
{
- int const err = errno;
+ std::error_condition err(errno, std::generic_category());
::close(masterfd);
- return errno_to_file_error(err);
+ return err;
}
try
@@ -181,12 +182,12 @@ osd_file::error posix_open_ptty(std::uint32_t openflags, osd_file::ptr &file, st
name = slavepath;
file = std::make_unique<posix_osd_ptty>(masterfd);
filesize = 0;
- return osd_file::error::NONE;
+ return std::error_condition();
}
catch (...)
{
::close(masterfd);
- return osd_file::error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
#endif // defined(__ANDROID__)
}
diff --git a/src/osd/modules/file/posixsocket.cpp b/src/osd/modules/file/posixsocket.cpp
index 2ce5ad05d5c..4770e91c6a9 100644
--- a/src/osd/modules/file/posixsocket.cpp
+++ b/src/osd/modules/file/posixsocket.cpp
@@ -2,7 +2,8 @@
// copyright-holders:Olivier Galibert, R. Belmont, Vas Crabb
//============================================================
//
-// sdlsocket.c - SDL socket (inet) access functions
+// sdlsocket.c - SDL socket (inet, unix domain) access
+// functions
//
// SDLMAME by Olivier Galibert and R. Belmont
//
@@ -16,17 +17,21 @@
#include <cstring>
#include <arpa/inet.h>
+#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/time.h>
+#include <sys/un.h>
#include <unistd.h>
namespace {
+
char const *const posixfile_socket_identifier = "socket.";
+char const *const posixfile_domain_identifier = "domain.";
class posix_osd_socket : public osd_file
@@ -37,7 +42,7 @@ public:
posix_osd_socket& operator=(posix_osd_socket const &) = delete;
posix_osd_socket& operator=(posix_osd_socket &&) = delete;
- posix_osd_socket(int sock, bool listening)
+ posix_osd_socket(int sock, bool listening) noexcept
: m_sock(sock)
, m_listening(listening)
{
@@ -49,7 +54,7 @@ public:
::close(m_sock);
}
- virtual error read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ virtual std::error_condition read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) noexcept override
{
fd_set readfds;
FD_ZERO(&readfds);
@@ -58,12 +63,9 @@ public:
struct timeval timeout;
timeout.tv_sec = timeout.tv_usec = 0;
- if (select(m_sock + 1, &readfds, nullptr, nullptr, &timeout) < 0)
+ if (::select(m_sock + 1, &readfds, nullptr, nullptr, &timeout) < 0)
{
- char line[80];
- std::sprintf(line, "%s : %s : %d ", __func__, __FILE__, __LINE__);
- std::perror(line);
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
}
else if (FD_ISSET(m_sock, &readfds))
{
@@ -73,12 +75,12 @@ public:
ssize_t const result = ::read(m_sock, buffer, count);
if (result < 0)
{
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
}
else
{
actual = std::uint32_t(size_t(result));
- return error::NONE;
+ return std::error_condition();
}
}
else
@@ -87,7 +89,7 @@ public:
int const accepted = ::accept(m_sock, nullptr, nullptr);
if (accepted < 0)
{
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
}
else
{
@@ -96,36 +98,38 @@ public:
m_listening = false;
actual = 0;
- return error::NONE;
+ return std::error_condition();
}
}
}
else
{
- return error::FAILURE;
+ // no data available
+ actual = 0;
+ return std::error_condition();
}
}
- virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ virtual std::error_condition write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) noexcept override
{
ssize_t const result = ::write(m_sock, buffer, count);
if (result < 0)
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
actual = std::uint32_t(size_t(result));
- return error::NONE;
+ return std::error_condition();
}
- virtual error truncate(std::uint64_t offset) override
+ virtual std::error_condition truncate(std::uint64_t offset) noexcept override
{
// doesn't make sense on socket
- return error::INVALID_ACCESS;
+ return std::errc::bad_file_descriptor;
}
- virtual error flush() override
+ virtual std::error_condition flush() noexcept override
{
// there's no simple way to flush buffers on a socket anyway
- return error::NONE;
+ return std::error_condition();
}
private:
@@ -133,6 +137,54 @@ private:
bool m_listening;
};
+
+template <typename T>
+std::error_condition create_socket(T const &sa, int sock, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize) noexcept
+{
+ osd_file::ptr result;
+ if (openflags & OPEN_FLAG_CREATE)
+ {
+ // listening socket support
+ // bind socket...
+ if (::bind(sock, reinterpret_cast<struct sockaddr const *>(&sa), sizeof(sa)) < 0)
+ {
+ std::error_condition binderr(errno, std::generic_category());
+ ::close(sock);
+ return binderr;
+ }
+
+ // start to listen...
+ if (::listen(sock, 1) < 0)
+ {
+ std::error_condition lstnerr(errno, std::generic_category());
+ ::close(sock);
+ return lstnerr;
+ }
+
+ // mark socket as "listening"
+ result.reset(new (std::nothrow) posix_osd_socket(sock, true));
+ }
+ else
+ {
+ if (::connect(sock, reinterpret_cast<struct sockaddr const *>(&sa), sizeof(sa)) < 0)
+ {
+ std::error_condition connerr(errno, std::generic_category());
+ ::close(sock);
+ return connerr;
+ }
+ result.reset(new (std::nothrow) posix_osd_socket(sock, false));
+ }
+
+ if (!result)
+ {
+ ::close(sock);
+ return std::errc::not_enough_memory;
+ }
+ file = std::move(result);
+ filesize = 0;
+ return std::error_condition();
+}
+
} // anonymous namespace
@@ -141,7 +193,7 @@ private:
specification has the format "socket." host ":" port. Host may be simple
or fully qualified. Port must be between 1 and 65535.
*/
-bool posix_check_socket_path(std::string const &path)
+bool posix_check_socket_path(std::string const &path) noexcept
{
if (strncmp(path.c_str(), posixfile_socket_identifier, strlen(posixfile_socket_identifier)) == 0 &&
strchr(path.c_str(), ':') != nullptr) return true;
@@ -149,7 +201,15 @@ bool posix_check_socket_path(std::string const &path)
}
-osd_file::error posix_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize)
+bool posix_check_domain_path(std::string const &path) noexcept
+{
+ if (strncmp(path.c_str(), posixfile_domain_identifier, strlen(posixfile_domain_identifier)) == 0)
+ return true;
+ return false;
+}
+
+
+std::error_condition posix_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize) noexcept
{
char hostname[256];
int port;
@@ -157,7 +217,7 @@ osd_file::error posix_open_socket(std::string const &path, std::uint32_t openfla
struct hostent const *const localhost = ::gethostbyname(hostname);
if (!localhost)
- return osd_file::error::NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
struct sockaddr_in sai;
memset(&sai, 0, sizeof(sai));
@@ -167,75 +227,38 @@ osd_file::error posix_open_socket(std::string const &path, std::uint32_t openfla
int const sock = ::socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
- return errno_to_file_error(errno);
+ return std::error_condition(errno, std::generic_category());
int const flag = 1;
- if (::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<const char *>(&flag), sizeof(flag)) < 0)
+ if ((::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<const char *>(&flag), sizeof(flag)) < 0) ||
+ (::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char *>(&flag), sizeof(flag)) < 0))
{
- int const err = errno;
+ std::error_condition sockopterr(errno, std::generic_category());
::close(sock);
- return errno_to_file_error(err);
+ return sockopterr;
}
- if (::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char *>(&flag), sizeof(flag)) < 0)
- {
- int const err = errno;
- ::close(sock);
- return errno_to_file_error(err);
- }
+ return create_socket(sai, sock, openflags, file, filesize);
+}
- // listening socket support
- if (openflags & OPEN_FLAG_CREATE)
- {
- //printf("Listening for client at '%s' on port '%d'\n", hostname, port);
- // bind socket...
- if (::bind(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) < 0)
- {
- int const err = errno;
- ::close(sock);
- return errno_to_file_error(err);
- }
+std::error_condition posix_open_domain(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize) noexcept
+{
+ struct sockaddr_un sau;
+ memset(&sau, 0, sizeof(sau));
+ sau.sun_family = AF_UNIX;
+ strncpy(sau.sun_path, &path.c_str()[strlen(posixfile_domain_identifier)], sizeof(sau.sun_path)-1);
- // start to listen...
- if (::listen(sock, 1) < 0)
- {
- int const err = errno;
- ::close(sock);
- return errno_to_file_error(err);
- }
+ int const sock = ::socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0)
+ return std::error_condition(errno, std::generic_category());
- // mark socket as "listening"
- try
- {
- file = std::make_unique<posix_osd_socket>(sock, true);
- filesize = 0;
- return osd_file::error::NONE;
- }
- catch (...)
- {
- ::close(sock);
- return osd_file::error::OUT_OF_MEMORY;
- }
- }
- else
+ if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
{
- //printf("Connecting to server '%s' on port '%d'\n", hostname, port);
- if (::connect(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) < 0)
- {
- ::close(sock);
- return osd_file::error::ACCESS_DENIED; // have to return this value or bitb won't try to bind on connect failure
- }
- try
- {
- file = std::make_unique<posix_osd_socket>(sock, false);
- filesize = 0;
- return osd_file::error::NONE;
- }
- catch (...)
- {
- ::close(sock);
- return osd_file::error::OUT_OF_MEMORY;
- }
+ std::error_condition cntlerr(errno, std::generic_category());
+ ::close(sock);
+ return cntlerr;
}
+
+ return create_socket(sau, sock, openflags, file, filesize);
}
diff --git a/src/osd/modules/file/stdfile.cpp b/src/osd/modules/file/stdfile.cpp
index 96d7e53ebbe..4fd4662b884 100644
--- a/src/osd/modules/file/stdfile.cpp
+++ b/src/osd/modules/file/stdfile.cpp
@@ -10,12 +10,14 @@
#include "osdfile.h"
#include <cassert>
+#include <cerrno>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
+#include <limits>
#include <string>
-#include <cstdio> // for fileno
+#include <stdio.h> // for fileno
#include <unistd.h> // for ftruncate
@@ -25,7 +27,10 @@ class std_osd_file : public osd_file
{
public:
- std_osd_file(FILE *f) : m_file(f) { assert(m_file); }
+ std_osd_file(FILE *f) noexcept : m_file(f)
+ {
+ assert(m_file);
+ }
//============================================================
// osd_close
@@ -34,59 +39,81 @@ public:
virtual ~std_osd_file() override
{
// close the file handle
- if (m_file) std::fclose(m_file);
+ if (m_file)
+ std::fclose(m_file);
}
//============================================================
// osd_read
//============================================================
- virtual error read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ virtual std::error_condition read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) noexcept override
{
- // seek to the new location; note that most fseek implementations are limited to 32 bits
+ // seek to the new location; note that most fseek implementations are limited to the range of long int
+ if (std::numeric_limits<long>::max() < offset)
+ return std::errc::invalid_argument;
if (std::fseek(m_file, offset, SEEK_SET) < 0)
- return error::FAILURE;
+ return std::error_condition(errno, std::generic_category());
// perform the read
std::size_t const count = std::fread(buffer, 1, length, m_file);
+ if ((count < length) && std::ferror(m_file))
+ {
+ std::clearerr(m_file);
+ return std::error_condition(errno, std::generic_category());
+ }
actual = count;
- return error::NONE;
+ return std::error_condition();
}
//============================================================
// osd_write
//============================================================
- virtual error write(const void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ virtual std::error_condition write(const void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) noexcept override
{
- // seek to the new location; note that most fseek implementations are limited to 32 bits
+ // seek to the new location; note that most fseek implementations are limited to the range of long int
+ if (std::numeric_limits<long>::max() < offset)
+ return std::errc::invalid_argument;
if (std::fseek(m_file, offset, SEEK_SET) < 0)
- return error::FAILURE;
+ return std::error_condition(errno, std::generic_category());
// perform the write
std::size_t const count = std::fwrite(buffer, 1, length, m_file);
+ if (count < length)
+ {
+ std::clearerr(m_file);
+ return std::error_condition(errno, std::generic_category());
+ }
actual = count;
- return error::NONE;
+ return std::error_condition();
}
//============================================================
// osd_truncate
//============================================================
- error truncate(std::uint64_t offset) override
+ virtual std::error_condition truncate(std::uint64_t offset) noexcept override
{
- return (ftruncate(fileno(m_file), offset) < 0) ? error::FAILURE : error::NONE;
+ // this is present in POSIX but not C/C++
+ if (::ftruncate(::fileno(m_file), offset) < 0)
+ return std::error_condition(errno, std::generic_category());
+ else
+ return std::error_condition();
}
//============================================================
// osd_fflush
//============================================================
- virtual error flush() override
+ virtual std::error_condition flush() noexcept override
{
- return (std::fflush(m_file) == EOF) ? error::FAILURE : error::NONE;
+ if (!std::fflush(m_file))
+ return std::error_condition();
+ else
+ return std::error_condition(errno, std::generic_category());
}
private:
@@ -100,7 +127,7 @@ private:
// osd_open
//============================================================
-osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags, ptr &file, std::uint64_t &filesize)
+std::error_condition osd_file::open(std::string const &path, std::uint32_t openflags, ptr &file, std::uint64_t &filesize) noexcept
{
// based on the flags, choose a mode
const char *mode;
@@ -114,12 +141,12 @@ osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags,
else if (openflags & OPEN_FLAG_READ)
mode = "rb";
else
- return error::INVALID_ACCESS;
+ return std::errc::invalid_argument;
// open the file
FILE *const fileptr = std::fopen(path.c_str(), mode);
if (!fileptr)
- return error::NOT_FOUND;
+ return std::error_condition(errno, std::generic_category());
// get the size -- note that most fseek/ftell implementations are limited to 32 bits
long length;
@@ -127,21 +154,20 @@ osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags,
((length = std::ftell(fileptr)) < 0) ||
(std::fseek(fileptr, 0, SEEK_SET) < 0))
{
+ std::error_condition err(errno, std::generic_category());
std::fclose(fileptr);
- return error::FAILURE;
+ return err;
}
- try
- {
- file = std::make_unique<std_osd_file>(fileptr);
- filesize = std::int64_t(length);
- return error::NONE;
- }
- catch (...)
+ osd_file::ptr result(new (std::nothrow) std_osd_file(fileptr));
+ if (!result)
{
std::fclose(fileptr);
- return error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
+ file = std::move(result);
+ filesize = std::int64_t(length);
+ return std::error_condition();
}
@@ -149,9 +175,9 @@ osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags,
// osd_openpty
//============================================================
-osd_file::error osd_file::openpty(ptr &file, std::string &name)
+std::error_condition osd_file::openpty(ptr &file, std::string &name) noexcept
{
- return error::FAILURE;
+ return std::errc::not_supported;
}
@@ -159,9 +185,12 @@ osd_file::error osd_file::openpty(ptr &file, std::string &name)
// osd_rmfile
//============================================================
-osd_file::error osd_file::remove(std::string const &filename)
+std::error_condition osd_file::remove(std::string const &filename) noexcept
{
- return (std::remove(filename.c_str()) < 0) ? error::FAILURE : error::NONE;
+ if (!std::remove(filename.c_str()))
+ return std::error_condition();
+ else
+ return std::error_condition(errno, std::generic_category());
}
@@ -169,7 +198,7 @@ osd_file::error osd_file::remove(std::string const &filename)
// osd_get_physical_drive_geometry
//============================================================
-bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders, uint32_t *heads, uint32_t *sectors, uint32_t *bps)
+bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders, uint32_t *heads, uint32_t *sectors, uint32_t *bps) noexcept
{
// there is no standard way of doing this, so we always return false, indicating
// that a given path is not a physical drive
@@ -181,7 +210,7 @@ bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders,
// osd_uchar_from_osdchar
//============================================================
-int osd_uchar_from_osdchar(char32_t *uchar, const char *osdchar, size_t count)
+int osd_uchar_from_osdchar(char32_t *uchar, const char *osdchar, size_t count) noexcept
{
// we assume a standard 1:1 mapping of characters to the first 256 unicode characters
*uchar = (uint8_t)*osdchar;
@@ -221,13 +250,14 @@ osd_directory_entry *osd_stat(const std::string &path)
// osd_get_full_path
//============================================================
-osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
+std::error_condition osd_get_full_path(std::string &dst, std::string const &path) noexcept
{
// derive the full path of the file in an allocated string
// for now just fake it since we don't presume any underlying file system
- dst = path;
+ try { dst = path; }
+ catch (...) { return std::errc::not_enough_memory; }
- return osd_file::error::NONE;
+ return std::error_condition();
}
@@ -235,7 +265,7 @@ osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
// osd_is_absolute_path
//============================================================
-bool osd_is_absolute_path(std::string const &path)
+bool osd_is_absolute_path(std::string const &path) noexcept
{
// assume no for everything
return false;
diff --git a/src/osd/modules/file/winfile.cpp b/src/osd/modules/file/winfile.cpp
index 4c265be613d..be4fa6f70c3 100644
--- a/src/osd/modules/file/winfile.cpp
+++ b/src/osd/modules/file/winfile.cpp
@@ -6,7 +6,6 @@
//
//============================================================
-
#include "winfile.h"
// MAMEOS headers
@@ -45,7 +44,7 @@ public:
win_osd_file& operator=(win_osd_file const &) = delete;
win_osd_file& operator=(win_osd_file &&) = delete;
- win_osd_file(HANDLE handle) : m_handle(handle)
+ win_osd_file(HANDLE handle) noexcept : m_handle(handle)
{
assert(m_handle);
assert(INVALID_HANDLE_VALUE != m_handle);
@@ -57,7 +56,7 @@ public:
CloseHandle(m_handle);
}
- virtual error read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ virtual std::error_condition read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) noexcept override
{
// attempt to set the file pointer
LARGE_INTEGER largeOffset;
@@ -71,10 +70,10 @@ public:
return win_error_to_file_error(GetLastError());
actual = result;
- return error::NONE;
+ return std::error_condition();
}
- virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ virtual std::error_condition write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) noexcept override
{
// attempt to set the file pointer
LARGE_INTEGER largeOffset;
@@ -88,10 +87,10 @@ public:
return win_error_to_file_error(GetLastError());
actual = result;
- return error::NONE;
+ return std::error_condition();
}
- virtual error truncate(std::uint64_t offset) override
+ virtual std::error_condition truncate(std::uint64_t offset) noexcept override
{
// attempt to set the file pointer
LARGE_INTEGER largeOffset;
@@ -103,13 +102,13 @@ public:
if (!SetEndOfFile(m_handle))
return win_error_to_file_error(GetLastError());
else
- return error::NONE;
+ return std::error_condition();
}
- virtual error flush() override
+ virtual std::error_condition flush() noexcept override
{
// shouldn't be any userspace buffers on the file handle
- return error::NONE;
+ return std::error_condition();
}
private:
@@ -162,11 +161,11 @@ DWORD create_path_recursive(TCHAR *path)
// osd_open
//============================================================
-osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags, ptr &file, std::uint64_t &filesize)
+std::error_condition osd_file::open(std::string const &orig_path, uint32_t openflags, ptr &file, std::uint64_t &filesize) noexcept
{
std::string path;
try { osd_subst_env(path, orig_path); }
- catch (...) { return error::OUT_OF_MEMORY; }
+ catch (...) { return std::errc::not_enough_memory; }
if (win_check_socket_path(path))
return win_open_socket(path, openflags, file, filesize);
@@ -174,10 +173,11 @@ osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags,
return win_open_ptty(path, openflags, file, filesize);
// convert path to TCHAR
- osd::text::tstring t_path = osd::text::to_tstring(path);
+ osd::text::tstring t_path;
+ try { t_path = osd::text::to_tstring(path); }
+ catch (...) { return std::errc::not_enough_memory; }
- // convert the path into something Windows compatible (the actual interesting part appears
- // to have been commented out???)
+ // convert the path into something Windows compatible (the actual interesting part appears to have been commented out???)
for (auto iter = t_path.begin(); iter != t_path.end(); iter++)
*iter = /* ('/' == *iter) ? '\\' : */ *iter;
@@ -187,7 +187,8 @@ osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags,
{
disposition = (!is_path_to_physical_drive(path.c_str()) && (openflags & OPEN_FLAG_CREATE)) ? CREATE_ALWAYS : OPEN_EXISTING;
access = (openflags & OPEN_FLAG_READ) ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_WRITE;
- if (is_path_to_physical_drive(path.c_str())) access |= GENERIC_READ;
+ if (is_path_to_physical_drive(path.c_str()))
+ access |= GENERIC_READ;
sharemode = FILE_SHARE_READ;
}
else if (openflags & OPEN_FLAG_READ)
@@ -198,7 +199,7 @@ osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags,
}
else
{
- return error::INVALID_ACCESS;
+ return std::errc::invalid_argument;
}
// attempt to open the file
@@ -262,17 +263,15 @@ osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags,
}
}
- try
- {
- file = std::make_unique<win_osd_file>(h);
- filesize = (std::uint64_t(upper) << 32) | lower;
- return error::NONE;
- }
- catch (...)
+ osd_file::ptr result(new (std::nothrow) win_osd_file(h));
+ if (!result)
{
CloseHandle(h);
- return error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
+ file = std::move(result);
+ filesize = (std::uint64_t(upper) << 32) | lower;
+ return std::error_condition();
}
@@ -281,9 +280,9 @@ osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags,
// osd_openpty
//============================================================
-osd_file::error osd_file::openpty(ptr &file, std::string &name)
+std::error_condition osd_file::openpty(ptr &file, std::string &name) noexcept
{
- return error::FAILURE;
+ return std::errc::not_supported; // TODO: revisit this error code
}
@@ -292,11 +291,13 @@ osd_file::error osd_file::openpty(ptr &file, std::string &name)
// osd_rmfile
//============================================================
-osd_file::error osd_file::remove(std::string const &filename)
+std::error_condition osd_file::remove(std::string const &filename) noexcept
{
- osd::text::tstring tempstr = osd::text::to_tstring(filename);
+ osd::text::tstring tempstr;
+ try { tempstr = osd::text::to_tstring(filename); }
+ catch (...) { return std::errc::not_enough_memory; }
- error filerr = error::NONE;
+ std::error_condition filerr;
if (!DeleteFile(tempstr.c_str()))
filerr = win_error_to_file_error(GetLastError());
@@ -309,7 +310,7 @@ osd_file::error osd_file::remove(std::string const &filename)
// osd_get_physical_drive_geometry
//============================================================
-bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders, uint32_t *heads, uint32_t *sectors, uint32_t *bps)
+bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders, uint32_t *heads, uint32_t *sectors, uint32_t *bps) noexcept
{
DISK_GEOMETRY dg;
DWORD bytesRead;
@@ -321,10 +322,17 @@ bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders,
return false;
// do a create file on the drive
- auto t_filename = osd::text::to_tstring(filename);
- file = CreateFile(t_filename.c_str(), GENERIC_READ, FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, nullptr);
- if (file == INVALID_HANDLE_VALUE)
+ try
+ {
+ auto t_filename = osd::text::to_tstring(filename);
+ file = CreateFile(t_filename.c_str(), GENERIC_READ, FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, nullptr);
+ if (file == INVALID_HANDLE_VALUE)
+ return false;
+ }
+ catch (...)
+ {
return false;
+ }
// device I/O control should return the geometry
result = DeviceIoControl(file, IOCTL_DISK_GET_DRIVE_GEOMETRY, nullptr, 0, &dg, sizeof(dg), &bytesRead, nullptr);
@@ -399,22 +407,29 @@ std::unique_ptr<osd::directory::entry> osd_stat(const std::string &path)
// osd_get_full_path
//============================================================
-osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
+std::error_condition osd_get_full_path(std::string &dst, std::string const &path) noexcept
{
- // get the length of the full path
- std::wstring const w_path(osd::text::to_wstring(path));
- DWORD const length(GetFullPathNameW(w_path.c_str(), 0, nullptr, nullptr));
- if (!length)
- return win_error_to_file_error(GetLastError());
+ try
+ {
+ // get the length of the full path
+ std::wstring const w_path(osd::text::to_wstring(path));
+ DWORD const length(GetFullPathNameW(w_path.c_str(), 0, nullptr, nullptr));
+ if (!length)
+ return win_error_to_file_error(GetLastError());
- // allocate a buffer and get the canonical path
- std::unique_ptr<wchar_t []> buffer(std::make_unique<wchar_t []>(length));
- if (!GetFullPathNameW(w_path.c_str(), length, buffer.get(), nullptr))
- return win_error_to_file_error(GetLastError());
+ // allocate a buffer and get the canonical path
+ std::unique_ptr<wchar_t []> buffer(std::make_unique<wchar_t []>(length));
+ if (!GetFullPathNameW(w_path.c_str(), length, buffer.get(), nullptr))
+ return win_error_to_file_error(GetLastError());
- // convert the result back to UTF-8
- osd::text::from_wstring(dst, buffer.get());
- return osd_file::error::NONE;
+ // convert the result back to UTF-8
+ osd::text::from_wstring(dst, buffer.get());
+ return std::error_condition();
+ }
+ catch (...)
+ {
+ return std::errc::not_enough_memory; // the string conversions can throw bad_alloc
+ }
}
@@ -423,7 +438,7 @@ osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
// osd_is_absolute_path
//============================================================
-bool osd_is_absolute_path(std::string const &path)
+bool osd_is_absolute_path(std::string const &path) noexcept
{
return !PathIsRelativeW(osd::text::to_wstring(path).c_str());
}
@@ -493,7 +508,7 @@ std::vector<std::string> osd_get_volume_names()
// osd_is_valid_filename_char
//============================================================
-bool osd_is_valid_filename_char(char32_t uchar)
+bool osd_is_valid_filename_char(char32_t uchar) noexcept
{
return osd_is_valid_filepath_char(uchar)
&& uchar != '/'
@@ -507,7 +522,7 @@ bool osd_is_valid_filename_char(char32_t uchar)
// osd_is_valid_filepath_char
//============================================================
-bool osd_is_valid_filepath_char(char32_t uchar)
+bool osd_is_valid_filepath_char(char32_t uchar) noexcept
{
return uchar >= 0x20
&& uchar != '<'
@@ -526,39 +541,62 @@ bool osd_is_valid_filepath_char(char32_t uchar)
// win_error_to_file_error
//============================================================
-osd_file::error win_error_to_file_error(DWORD error)
+std::error_condition win_error_to_file_error(DWORD error) noexcept
{
- osd_file::error filerr;
-
- // convert a Windows error to a osd_file::error
+ // TODO: work out if there's a better way to do this
switch (error)
{
case ERROR_SUCCESS:
- filerr = osd_file::error::NONE;
- break;
+ return std::error_condition();
+
+ case ERROR_INVALID_HANDLE:
+ return std::errc::bad_file_descriptor;
case ERROR_OUTOFMEMORY:
- filerr = osd_file::error::OUT_OF_MEMORY;
- break;
+ return std::errc::not_enough_memory;
+
+ case ERROR_NOT_SUPPORTED:
+ return std::errc::not_supported;
case ERROR_FILE_NOT_FOUND:
- case ERROR_FILENAME_EXCED_RANGE:
case ERROR_PATH_NOT_FOUND:
case ERROR_INVALID_NAME:
- filerr = osd_file::error::NOT_FOUND;
- break;
+ return std::errc::no_such_file_or_directory;
- case ERROR_ACCESS_DENIED:
- filerr = osd_file::error::ACCESS_DENIED;
- break;
+ case ERROR_FILENAME_EXCED_RANGE:
+ return std::errc::filename_too_long;
+ case ERROR_ACCESS_DENIED:
case ERROR_SHARING_VIOLATION:
- filerr = osd_file::error::ALREADY_OPEN;
- break;
+ return std::errc::permission_denied;
+
+ case ERROR_ALREADY_EXISTS:
+ return std::errc::file_exists;
+
+ case ERROR_TOO_MANY_OPEN_FILES:
+ return std::errc::too_many_files_open;
+
+ case ERROR_WRITE_FAULT:
+ case ERROR_READ_FAULT:
+ return std::errc::io_error;
+
+ case ERROR_HANDLE_DISK_FULL:
+ case ERROR_DISK_FULL:
+ return std::errc::no_space_on_device;
+
+ case ERROR_PATH_BUSY:
+ case ERROR_BUSY:
+ return std::errc::device_or_resource_busy;
+
+ case ERROR_FILE_TOO_LARGE:
+ return std::errc::file_too_large;
+
+ case ERROR_INVALID_ACCESS:
+ case ERROR_NEGATIVE_SEEK:
+ case ERROR_BAD_ARGUMENTS:
+ return std::errc::invalid_argument;
default:
- filerr = osd_file::error::FAILURE;
- break;
+ return std::error_condition(error, std::system_category());
}
- return filerr;
}
diff --git a/src/osd/modules/file/winfile.h b/src/osd/modules/file/winfile.h
index 927cb299545..83f0814733d 100644
--- a/src/osd/modules/file/winfile.h
+++ b/src/osd/modules/file/winfile.h
@@ -5,13 +5,16 @@
// winfile.h - File access functions
//
//============================================================
-#ifndef MAME_OSD_WINDOWS_WINFILE_H
-#define MAME_OSD_WINDOWS_WINFILE_H
+#ifndef MAME_OSD_MODULES_FILE_WINFILE_H
+#define MAME_OSD_MODULES_FILE_WINFILE_H
+
+#pragma once
#include "osdfile.h"
#include <cstdint>
#include <string>
+#include <system_error>
#include <winsock2.h>
@@ -20,15 +23,15 @@
// PROTOTYPES
//============================================================
-bool win_init_sockets();
-void win_cleanup_sockets();
+bool win_init_sockets() noexcept;
+void win_cleanup_sockets() noexcept;
-bool win_check_socket_path(std::string const &path);
-osd_file::error win_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize);
+bool win_check_socket_path(std::string const &path) noexcept;
+std::error_condition win_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize) noexcept;
-bool win_check_ptty_path(std::string const &path);
-osd_file::error win_open_ptty(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize);
+bool win_check_ptty_path(std::string const &path) noexcept;
+std::error_condition win_open_ptty(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize) noexcept;
-osd_file::error win_error_to_file_error(DWORD error);
+std::error_condition win_error_to_file_error(DWORD error) noexcept;
-#endif // MAME_OSD_WINDOWS_WINFILE_H
+#endif // MAME_OSD_MODULES_FILE_WINFILE_H
diff --git a/src/osd/modules/file/winptty.cpp b/src/osd/modules/file/winptty.cpp
index 65650fd4bfe..7feeacce137 100644
--- a/src/osd/modules/file/winptty.cpp
+++ b/src/osd/modules/file/winptty.cpp
@@ -15,6 +15,7 @@
namespace {
+
char const *const winfile_ptty_identifier = "\\\\.\\pipe\\";
@@ -26,7 +27,7 @@ public:
win_osd_ptty& operator=(win_osd_ptty const &) = delete;
win_osd_ptty& operator=(win_osd_ptty &&) = delete;
- win_osd_ptty(HANDLE handle) : m_handle(handle)
+ win_osd_ptty(HANDLE handle) noexcept : m_handle(handle)
{
assert(m_handle);
assert(INVALID_HANDLE_VALUE != m_handle);
@@ -39,36 +40,36 @@ public:
CloseHandle(m_handle);
}
- virtual error read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ virtual std::error_condition read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) noexcept override
{
DWORD bytes_read;
if (!ReadFile(m_handle, buffer, count, &bytes_read, nullptr))
return win_error_to_file_error(GetLastError());
actual = bytes_read;
- return error::NONE;
+ return std::error_condition();
}
- virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ virtual std::error_condition write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) noexcept override
{
DWORD bytes_written;
if (!WriteFile(m_handle, buffer, count, &bytes_written, nullptr))
return win_error_to_file_error(GetLastError());
actual = bytes_written;
- return error::NONE;
+ return std::error_condition();
}
- virtual error truncate(std::uint64_t offset) override
+ virtual std::error_condition truncate(std::uint64_t offset) noexcept override
{
// doesn't make sense for a PTTY
- return error::INVALID_ACCESS;
+ return std::errc::bad_file_descriptor;
}
- virtual error flush() override
+ virtual std::error_condition flush() noexcept override
{
// don't want to wait for client to read all data as implied by FlushFileBuffers
- return error::NONE;
+ return std::error_condition();
}
private:
@@ -78,16 +79,18 @@ private:
} // anonymous namespace
-bool win_check_ptty_path(std::string const &path)
+bool win_check_ptty_path(std::string const &path) noexcept
{
if (strncmp(path.c_str(), winfile_ptty_identifier, strlen(winfile_ptty_identifier)) == 0) return true;
return false;
}
-osd_file::error win_open_ptty(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize)
+std::error_condition win_open_ptty(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize) noexcept
{
- osd::text::tstring t_name = osd::text::to_tstring(path);
+ osd::text::tstring t_name;
+ try { t_name = osd::text::to_tstring(path); }
+ catch (...) { return std::errc::not_enough_memory; }
HANDLE pipe = CreateFileW(t_name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
@@ -96,23 +99,22 @@ osd_file::error win_open_ptty(std::string const &path, std::uint32_t openflags,
if (openflags & OPEN_FLAG_CREATE)
pipe = CreateNamedPipe(t_name.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 1, 32, 32, 0, nullptr);
if (INVALID_HANDLE_VALUE == pipe)
- return osd_file::error::ACCESS_DENIED;
+ return win_error_to_file_error(GetLastError());
}
else
{
DWORD state = PIPE_NOWAIT;
SetNamedPipeHandleState(pipe, &state, nullptr, nullptr);
+ // TODO: check for error?
}
- try
- {
- file = std::make_unique<win_osd_ptty>(pipe);
- filesize = 0;
- return osd_file::error::NONE;
- }
- catch (...)
+ osd_file::ptr result(new (std::nothrow) win_osd_ptty(pipe));
+ if (!result)
{
CloseHandle(pipe);
- return osd_file::error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
+ file = std::move(result);
+ filesize = 0;
+ return std::error_condition();
}
diff --git a/src/osd/modules/file/winsocket.cpp b/src/osd/modules/file/winsocket.cpp
index 948e57db822..f818f3b1991 100644
--- a/src/osd/modules/file/winsocket.cpp
+++ b/src/osd/modules/file/winsocket.cpp
@@ -6,7 +6,6 @@
//
//============================================================
-
#include "winfile.h"
// MAMEOS headers
@@ -28,6 +27,7 @@
namespace {
+
char const *const winfile_socket_identifier = "socket.";
@@ -39,7 +39,7 @@ public:
win_osd_socket& operator=(win_osd_socket const &) = delete;
win_osd_socket& operator=(win_osd_socket &&) = delete;
- win_osd_socket(SOCKET s, bool l)
+ win_osd_socket(SOCKET s, bool l) noexcept
: m_socket(s)
, m_listening(l)
{
@@ -51,7 +51,7 @@ public:
closesocket(m_socket);
}
- virtual error read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ virtual std::error_condition read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) noexcept override
{
fd_set readfds;
FD_ZERO(&readfds);
@@ -62,10 +62,7 @@ public:
if (select(m_socket + 1, &readfds, nullptr, nullptr, &timeout) < 0)
{
- char line[80];
- std::sprintf(line, "win_read_socket : %s : %d ", __FILE__, __LINE__);
- std::perror(line);
- return error::FAILURE;
+ return wsa_error_to_file_error(WSAGetLastError());
}
else if (FD_ISSET(m_socket, &readfds))
{
@@ -80,7 +77,7 @@ public:
else
{
actual = result;
- return error::NONE;
+ return std::error_condition();
}
}
else
@@ -98,50 +95,82 @@ public:
m_listening = false;
actual = 0;
- return error::NONE;
+ return std::error_condition();
}
}
}
else
{
- return error::FAILURE;
+ // no data available
+ actual = 0;
+ return std::error_condition();
}
}
- virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ virtual std::error_condition write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) noexcept override
{
auto const result = send(m_socket, reinterpret_cast<const char *>(buffer), length, 0);
if (result < 0)
return wsa_error_to_file_error(WSAGetLastError());
actual = result;
- return error::NONE;
+ return std::error_condition();
}
- virtual error truncate(std::uint64_t offset) override
+ virtual std::error_condition truncate(std::uint64_t offset) noexcept override
{
// doesn't make sense for a socket
- return error::INVALID_ACCESS;
+ return std::errc::bad_file_descriptor;
}
- virtual error flush() override
+ virtual std::error_condition flush() noexcept override
{
// no buffers to flush
- return error::NONE;
+ return std::error_condition();
}
- static error wsa_error_to_file_error(int err)
+ static std::error_condition wsa_error_to_file_error(int err)
{
+ // TODO: determine if there's a better way to do this
switch (err)
{
- case 0: return error::NONE;
- case WSAEACCES: return error::ACCESS_DENIED;
- case WSAEADDRINUSE: return error::ALREADY_OPEN;
- case WSAEADDRNOTAVAIL: return error::NOT_FOUND;
- case WSAECONNREFUSED: return error::NOT_FOUND;
- case WSAEHOSTUNREACH: return error::NOT_FOUND;
- case WSAENETUNREACH: return error::NOT_FOUND;
- default: return error::FAILURE;
+ case 0: return std::error_condition();
+ case WSA_NOT_ENOUGH_MEMORY: return std::errc::not_enough_memory;
+ case WSA_INVALID_PARAMETER: return std::errc::invalid_argument;
+ case WSAEINTR: return std::errc::interrupted;
+ case WSAEBADF: return std::errc::bad_file_descriptor;
+ case WSAEACCES: return std::errc::permission_denied;
+ case WSAEFAULT: return std::errc::bad_address;
+ case WSAEINVAL: return std::errc::invalid_argument;
+ case WSAEMFILE: return std::errc::too_many_files_open;
+ case WSAENETRESET: return std::errc::network_reset;
+ case WSAECONNABORTED: return std::errc::connection_aborted;
+ case WSAEWOULDBLOCK: return std::errc::operation_would_block;
+ case WSAEINPROGRESS: return std::errc::operation_in_progress;
+ case WSAEALREADY: return std::errc::connection_already_in_progress;
+ case WSAENOTSOCK: return std::errc::not_a_socket;
+ case WSAEDESTADDRREQ: return std::errc::destination_address_required;
+ case WSAEMSGSIZE: return std::errc::message_size;
+ case WSAEPROTOTYPE: return std::errc::wrong_protocol_type;
+ case WSAENOPROTOOPT: return std::errc::no_protocol_option;
+ case WSAEPROTONOSUPPORT: return std::errc::protocol_not_supported;
+ case WSAEOPNOTSUPP: return std::errc::operation_not_supported;
+ case WSAEAFNOSUPPORT: return std::errc::address_family_not_supported;
+ case WSAEADDRINUSE: return std::errc::address_in_use;
+ case WSAEADDRNOTAVAIL: return std::errc::address_not_available;
+ case WSAENETDOWN: return std::errc::network_down;
+ case WSAENETUNREACH: return std::errc::network_unreachable;
+ case WSAECONNRESET: return std::errc::connection_reset;
+ case WSAENOBUFS: return std::errc::no_buffer_space;
+ case WSAEISCONN: return std::errc::already_connected;
+ case WSAENOTCONN: return std::errc::not_connected;
+ case WSAETIMEDOUT: return std::errc::timed_out;
+ case WSAECONNREFUSED: return std::errc::connection_refused;
+ case WSAEHOSTUNREACH: return std::errc::host_unreachable;
+ case WSAECANCELLED: return std::errc::operation_canceled;
+
+ // TODO: better default error code?
+ default: return std::errc::io_error;
}
}
@@ -153,7 +182,7 @@ private:
} // anonymous namespace
-bool win_init_sockets()
+bool win_init_sockets() noexcept
{
WSADATA wsaData;
WORD const version = MAKEWORD(2, 0);
@@ -179,13 +208,13 @@ bool win_init_sockets()
}
-void win_cleanup_sockets()
+void win_cleanup_sockets() noexcept
{
WSACleanup();
}
-bool win_check_socket_path(std::string const &path)
+bool win_check_socket_path(std::string const &path) noexcept
{
if (strncmp(path.c_str(), winfile_socket_identifier, strlen(winfile_socket_identifier)) == 0 &&
strchr(path.c_str(), ':') != nullptr) return true;
@@ -193,7 +222,7 @@ bool win_check_socket_path(std::string const &path)
}
-osd_file::error win_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize)
+std::error_condition win_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize) noexcept
{
char hostname[256];
int port;
@@ -201,7 +230,7 @@ osd_file::error win_open_socket(std::string const &path, std::uint32_t openflags
struct hostent const *const localhost = gethostbyname(hostname);
if (!localhost)
- return osd_file::error::NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
struct sockaddr_in sai;
memset(&sai, 0, sizeof(sai));
@@ -222,11 +251,12 @@ osd_file::error win_open_socket(std::string const &path, std::uint32_t openflags
}
// listening socket support
+ osd_file::ptr result;
if (openflags & OPEN_FLAG_CREATE)
{
//printf("Listening for client at '%s' on port '%d'\n", hostname, port);
// bind socket...
- if (bind(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) == SOCKET_ERROR)
+ if (bind(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(sai)) == SOCKET_ERROR)
{
int const err = WSAGetLastError();
closesocket(sock);
@@ -242,36 +272,26 @@ osd_file::error win_open_socket(std::string const &path, std::uint32_t openflags
}
// mark socket as "listening"
- try
- {
- file = std::make_unique<win_osd_socket>(sock, true);
- filesize = 0;
- return osd_file::error::NONE;
- }
- catch (...)
- {
- closesocket(sock);
- return osd_file::error::OUT_OF_MEMORY;
- }
+ result.reset(new (std::nothrow) win_osd_socket(sock, true));
}
else
{
//printf("Connecting to server '%s' on port '%d'\n", hostname, port);
- if (connect(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) == SOCKET_ERROR)
- {
- closesocket(sock);
- return osd_file::error::ACCESS_DENIED; // have to return this value or bitb won't try to bind on connect failure
- }
- try
- {
- file = std::make_unique<win_osd_socket>(sock, false);
- filesize = 0;
- return osd_file::error::NONE;
- }
- catch (...)
+ if (connect(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(sai)) == SOCKET_ERROR)
{
+ int const err = WSAGetLastError();
closesocket(sock);
- return osd_file::error::OUT_OF_MEMORY;
+ return win_osd_socket::wsa_error_to_file_error(err);
}
+ result.reset(new (std::nothrow) win_osd_socket(sock, false));
+ }
+
+ if (!result)
+ {
+ closesocket(sock);
+ return std::errc::not_enough_memory;
}
+ file = std::move(result);
+ filesize = 0;
+ return std::error_condition();
}
diff --git a/src/osd/modules/font/font_sdl.cpp b/src/osd/modules/font/font_sdl.cpp
index a17b87cdc13..5cad4a3fab8 100644
--- a/src/osd/modules/font/font_sdl.cpp
+++ b/src/osd/modules/font/font_sdl.cpp
@@ -90,7 +90,7 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name,
osd_printf_verbose("Searching font %s in -%s path/s\n", family, font_path);
//emu_file file(options().font_path(), OPEN_FLAG_READ);
emu_file file(font_path, OPEN_FLAG_READ);
- if (file.open(family) == osd_file::error::NONE)
+ if (!file.open(family))
{
std::string full_name = file.fullpath();
font = TTF_OpenFont_Magic(full_name, POINT_SIZE, 0);
@@ -193,7 +193,7 @@ bool osd_font_sdl::get_bitmap(char32_t chnum, bitmap_argb32 &bitmap, std::int32_
osd_font_sdl::TTF_Font_ptr osd_font_sdl::TTF_OpenFont_Magic(std::string const &name, int fsize, long index)
{
emu_file file(OPEN_FLAG_READ);
- if (file.open(name) == osd_file::error::NONE)
+ if (!file.open(name))
{
unsigned char const ttf_magic[] = { 0x00, 0x01, 0x00, 0x00, 0x00 };
unsigned char const ttc1_magic[] = { 0x74, 0x74, 0x63, 0x66, 0x00, 0x01, 0x00, 0x00 };
@@ -214,7 +214,7 @@ osd_font_sdl::TTF_Font_ptr osd_font_sdl::TTF_OpenFont_Magic(std::string const &n
bool osd_font_sdl::BDF_Check_Magic(std::string const &name)
{
emu_file file(OPEN_FLAG_READ);
- if (file.open(name) == osd_file::error::NONE)
+ if (!file.open(name))
{
unsigned char const magic[] = { 'S', 'T', 'A', 'R', 'T', 'F', 'O', 'N', 'T' };
unsigned char buffer[sizeof(magic)];
diff --git a/src/osd/modules/render/aviwrite.cpp b/src/osd/modules/render/aviwrite.cpp
index aff5429446e..ec6ce21c543 100644
--- a/src/osd/modules/render/aviwrite.cpp
+++ b/src/osd/modules/render/aviwrite.cpp
@@ -80,12 +80,12 @@ void avi_write::begin_avi_recording(const char *name)
// create a new temporary movie file
emu_file tempfile(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- const osd_file::error filerr = (!name || !name[0] || !std::strcmp(name, OSDOPTVAL_AUTO))
+ const std::error_condition filerr = (!name || !name[0] || !std::strcmp(name, OSDOPTVAL_AUTO))
? m_machine.video().open_next(tempfile, "avi")
: tempfile.open(name);
// if we succeeded, make a copy of the name and create the real file over top
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
{
const std::string fullpath = tempfile.fullpath();
tempfile.close();
diff --git a/src/osd/modules/render/bgfx/texturemanager.cpp b/src/osd/modules/render/bgfx/texturemanager.cpp
index 6c760c10203..f03d66e051a 100644
--- a/src/osd/modules/render/bgfx/texturemanager.cpp
+++ b/src/osd/modules/render/bgfx/texturemanager.cpp
@@ -59,7 +59,7 @@ bgfx_texture* texture_manager::create_png_texture(std::string path, std::string
{
bitmap_argb32 bitmap;
emu_file file(path, OPEN_FLAG_READ);
- if (file.open(file_name) == osd_file::error::NONE)
+ if (!file.open(file_name))
{
render_load_png(bitmap, file);
file.close();
diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp
index 0137e23acce..6aa69383233 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.cpp
+++ b/src/osd/modules/render/d3d/d3dhlsl.cpp
@@ -353,8 +353,8 @@ void shaders::render_snapshot(IDirect3DSurface9 *surface)
}
emu_file file(machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = machine->video().open_next(file, "png");
- if (filerr != osd_file::error::NONE)
+ std::error_condition const filerr = machine->video().open_next(file, "png");
+ if (filerr)
return;
// add two text entries describing the image
@@ -722,7 +722,7 @@ int shaders::create_resources()
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
emu_file file(machine->options().art_path(), OPEN_FLAG_READ);
- if (file.open(options->shadow_mask_texture) == osd_file::error::NONE)
+ if (!file.open(options->shadow_mask_texture))
{
render_load_png(shadow_bitmap, file);
file.close();
@@ -747,7 +747,7 @@ int shaders::create_resources()
d3d->get_texture_manager()->m_texture_list.push_back(std::move(tex));
}
- if (file.open(options->lut_texture) == osd_file::error::NONE)
+ if (!file.open(options->lut_texture))
{
render_load_png(lut_bitmap, file);
file.close();
@@ -770,7 +770,7 @@ int shaders::create_resources()
d3d->get_texture_manager()->m_texture_list.push_back(std::move(tex));
}
- if (file.open(options->ui_lut_texture) == osd_file::error::NONE)
+ if (!file.open(options->ui_lut_texture))
{
render_load_png(ui_lut_bitmap, file);
file.close();
diff --git a/src/osd/osdfile.h b/src/osd/osdfile.h
index ffd4346d7c0..bc3efbde805 100644
--- a/src/osd/osdfile.h
+++ b/src/osd/osdfile.h
@@ -16,6 +16,7 @@
#include <cstdint>
#include <memory>
#include <string>
+#include <system_error>
#include <vector>
@@ -61,47 +62,6 @@ constexpr uint32_t OPEN_FLAG_NO_PRELOAD = 0x0010;
class osd_file
{
public:
- /// \brief Result of a file operation
- ///
- /// Returned by most members of osd_file, and also used by other
- /// classes that access files or other file-like resources.
- enum class error
- {
- /// Operation completed successfully.
- NONE,
-
- /// Operation failed, but there is no more specific code to
- /// describe the failure.
- FAILURE,
-
- /// Operation failed due to an error allocating memory.
- OUT_OF_MEMORY,
-
- /// The requested file, path or resource was not found.
- NOT_FOUND,
-
- /// Current permissions do not allow the requested access.
- ACCESS_DENIED,
-
- /// Requested access is not permitted because the file or
- /// resource is currently open for exclusive access.
- ALREADY_OPEN,
-
- /// Request cannot be completed due to resource exhaustion
- /// (maximum number of open files or other objects has been
- /// reached).
- TOO_MANY_FILES,
-
- /// The request cannot be completed because invalid data was
- /// encountered (for example an inconsistent filesystem, or a
- /// corrupt archive file).
- INVALID_DATA,
-
- /// The requested access mode is invalid, or not appropriate for
- /// the file or resource.
- INVALID_ACCESS
- };
-
/// \brief Smart pointer to a file handle
typedef std::unique_ptr<osd_file> ptr;
@@ -129,7 +89,7 @@ public:
/// Will be zero for stream-like objects (e.g. TCP sockets or
/// named pipes).
/// \return Result of the operation.
- static error open(std::string const &path, std::uint32_t openflags, ptr &file, std::uint64_t &filesize);
+ static std::error_condition open(std::string const &path, std::uint32_t openflags, ptr &file, std::uint64_t &filesize) noexcept;
/// \brief Create a new pseudo-terminal (PTY) pair
///
@@ -140,7 +100,7 @@ public:
/// pseudo-terminal if the operation succeeds. Not valid if the
/// operation fails.
/// \return Result of the operation.
- static error openpty(ptr &file, std::string &name);
+ static std::error_condition openpty(ptr &file, std::string &name) noexcept;
/// \brief Close an open file
virtual ~osd_file() { }
@@ -161,7 +121,7 @@ public:
/// \param [out] actual Receives the number of bytes read if the
/// operation succeeds. Not valid if the operation fails.
/// \return Result of the operation.
- virtual error read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) = 0;
+ virtual std::error_condition read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) noexcept = 0;
/// \brief Write to an open file
///
@@ -176,26 +136,26 @@ public:
/// \param [out] actual Receives the number of bytes written if the
/// operation succeeds. Not valid if the operation fails.
/// \return Result of the operation.
- virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) = 0;
+ virtual std::error_condition write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) noexcept = 0;
/// \brief Change the size of an open file
///
/// \param [in] offset Desired size of the file.
/// \return Result of the operation.
- virtual error truncate(std::uint64_t offset) = 0;
+ virtual std::error_condition truncate(std::uint64_t offset) noexcept = 0;
/// \brief Flush file buffers
///
/// This flushes any data cached by the application, but does not
/// guarantee that all prior writes have reached persistent storage.
/// \return Result of the operation.
- virtual error flush() = 0;
+ virtual std::error_condition flush() noexcept = 0;
/// \brief Delete a file
///
/// \param [in] filename Path to the file to delete.
/// \return Result of the operation.
- static error remove(std::string const &filename);
+ static std::error_condition remove(std::string const &filename) noexcept;
};
@@ -217,21 +177,21 @@ public:
/// \return true if the filename points to a physical drive and if the
/// values pointed to by cylinders, heads, sectors, and bps are valid;
/// false in any other case
-bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders, uint32_t *heads, uint32_t *sectors, uint32_t *bps);
+bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders, uint32_t *heads, uint32_t *sectors, uint32_t *bps) noexcept;
/// \brief Is the given character legal for filenames?
///
/// \param [in] uchar The character to check.
/// \return Whether this character is legal in a filename.
-bool osd_is_valid_filename_char(char32_t uchar);
+bool osd_is_valid_filename_char(char32_t uchar) noexcept;
/// \brief Is the given character legal for paths?
///
/// \param [in] uchar The character to check.
/// \return Whether this character is legal in a file path.
-bool osd_is_valid_filepath_char(char32_t uchar);
+bool osd_is_valid_filepath_char(char32_t uchar) noexcept;
/***************************************************************************
@@ -301,14 +261,14 @@ std::unique_ptr<osd::directory::entry> osd_stat(std::string const &path);
///
/// \param [in] path The path in question.
/// \return true if the path is absolute, false otherwise.
-bool osd_is_absolute_path(const std::string &path);
+bool osd_is_absolute_path(const std::string &path) noexcept;
/// \brief Retrieves the full path.
/// \param [in] path The path in question.
/// \param [out] dst Reference to receive new path.
/// \return File error.
-osd_file::error osd_get_full_path(std::string &dst, std::string const &path);
+std::error_condition osd_get_full_path(std::string &dst, std::string const &path) noexcept;
/// \brief Retrieves the volume name.
diff --git a/src/tools/castool.cpp b/src/tools/castool.cpp
index e03a15203d5..896c0bde5c2 100644
--- a/src/tools/castool.cpp
+++ b/src/tools/castool.cpp
@@ -53,6 +53,7 @@
#include "formats/zx81_p.h"
#include "corestr.h"
+#include "ioprocs.h"
#include <cassert>
#include <cctype>
@@ -162,7 +163,6 @@ int CLIB_DECL main(int argc, char *argv[])
int found =0;
const cassette_image::Format * const *selected_formats = nullptr;
cassette_image::ptr cassette;
- FILE *f;
if (argc > 1)
{
@@ -188,21 +188,26 @@ int CLIB_DECL main(int argc, char *argv[])
return -1;
}
- f = fopen(argv[3], "rb");
+ FILE *f = fopen(argv[3], "rb");
if (!f) {
fprintf(stderr, "File %s not found.\n",argv[3]);
return -1;
}
- if (cassette_image::open_choices(f, &stdio_ioprocs, get_extension(argv[3]), selected_formats, cassette_image::FLAG_READONLY, cassette) != cassette_image::error::SUCCESS) {
+ auto io = util::stdio_read_write(f, 0x00);
+ f = nullptr;
+ if (!io) {
+ fprintf(stderr, "Out of memory.\n");
+ return -1;
+ }
+
+ if (cassette_image::open_choices(std::move(io), get_extension(argv[3]), selected_formats, cassette_image::FLAG_READONLY, cassette) != cassette_image::error::SUCCESS) {
fprintf(stderr, "Invalid format of input file.\n");
- fclose(f);
return -1;
}
cassette->dump(argv[4]);
cassette.reset();
- fclose(f);
goto theend;
}
}
diff --git a/src/tools/chdman.cpp b/src/tools/chdman.cpp
index 835a87c18c3..e0243ce7277 100644
--- a/src/tools/chdman.cpp
+++ b/src/tools/chdman.cpp
@@ -294,8 +294,8 @@ public:
return 0;
if (offset + length > m_maxoffset)
length = m_maxoffset - offset;
- chd_error err = m_file.read_bytes(offset, dest, length);
- if (err != CHDERR_NONE)
+ std::error_condition err = m_file.read_bytes(offset, dest, length);
+ if (err)
throw err;
// if we have TOC - detect audio sectors and swap data
@@ -385,9 +385,9 @@ public:
{
m_file.reset();
m_lastfile = m_info.track[tracknum].fname;
- osd_file::error filerr = util::core_file::open(m_lastfile, OPEN_FLAG_READ, m_file);
- if (filerr != osd_file::error::NONE)
- report_error(1, "Error opening input file (%s)'", m_lastfile.c_str());
+ std::error_condition const filerr = util::core_file::open(m_lastfile, OPEN_FLAG_READ, m_file);
+ if (filerr)
+ report_error(1, "Error opening input file (%s): %s", m_lastfile, filerr.message());
}
// iterate over frames
@@ -411,9 +411,9 @@ public:
{
m_file.reset();
m_lastfile = m_info.track[tracknum+1].fname;
- osd_file::error filerr = util::core_file::open(m_lastfile, OPEN_FLAG_READ, m_file);
- if (filerr != osd_file::error::NONE)
- report_error(1, "Error opening input file (%s)'", m_lastfile.c_str());
+ std::error_condition const filerr = util::core_file::open(m_lastfile, OPEN_FLAG_READ, m_file);
+ if (filerr)
+ report_error(1, "Error opening input file (%s): %s", m_lastfile, filerr.message());
}
if (src_frame_start < src_track_end)
@@ -430,7 +430,7 @@ public:
: src_frame_start, SEEK_SET);
uint32_t count = m_file->read(dest, bytesperframe);
if (count != bytesperframe)
- report_error(1, "Error reading input file (%s)'", m_lastfile.c_str());
+ report_error(1, "Error reading input file (%s)'", m_lastfile);
}
// swap if appropriate
@@ -1035,18 +1035,18 @@ static void parse_input_chd_parameters(const parameters_map &params, chd_file &i
auto input_chd_parent_str = params.find(OPTION_INPUT_PARENT);
if (input_chd_parent_str != params.end())
{
- chd_error err = input_parent_chd.open(input_chd_parent_str->second->c_str());
- if (err != CHDERR_NONE)
- report_error(1, "Error opening parent CHD file (%s): %s", input_chd_parent_str->second->c_str(), chd_file::error_string(err));
+ std::error_condition err = input_parent_chd.open(*input_chd_parent_str->second);
+ if (err)
+ report_error(1, "Error opening parent CHD file (%s): %s", *input_chd_parent_str->second, err.message());
}
// process input file
auto input_chd_str = params.find(OPTION_INPUT);
if (input_chd_str != params.end())
{
- chd_error err = input_chd.open(input_chd_str->second->c_str(), writeable, input_parent_chd.opened() ? &input_parent_chd : nullptr);
- if (err != CHDERR_NONE)
- report_error(1, "Error opening CHD file (%s): %s", input_chd_str->second->c_str(), chd_file::error_string(err));
+ std::error_condition err = input_chd.open(*input_chd_str->second, writeable, input_parent_chd.opened() ? &input_parent_chd : nullptr);
+ if (err)
+ report_error(1, "Error opening CHD file (%s): %s", *input_chd_str->second, err.message());
}
}
@@ -1102,8 +1102,8 @@ static void check_existing_output_file(const parameters_map &params, const char
if (params.find(OPTION_OUTPUT_FORCE) == params.end())
{
util::core_file::ptr file;
- osd_file::error filerr = util::core_file::open(filename, OPEN_FLAG_READ, file);
- if (filerr == osd_file::error::NONE)
+ std::error_condition const filerr = util::core_file::open(filename, OPEN_FLAG_READ, file);
+ if (!filerr)
{
file.reset();
report_error(1, "Error: file already exists (%s)\nUse --force (or -f) to force overwriting", filename);
@@ -1123,9 +1123,9 @@ static std::string *parse_output_chd_parameters(const parameters_map &params, ch
auto output_chd_parent_str = params.find(OPTION_OUTPUT_PARENT);
if (output_chd_parent_str != params.end())
{
- chd_error err = output_parent_chd.open(output_chd_parent_str->second->c_str());
- if (err != CHDERR_NONE)
- report_error(1, "Error opening parent CHD file (%s): %s", output_chd_parent_str->second->c_str(), chd_file::error_string(err));
+ std::error_condition err = output_parent_chd.open(*output_chd_parent_str->second);
+ if (err)
+ report_error(1, "Error opening parent CHD file (%s): %s", *output_chd_parent_str->second, err.message());
}
// process output file
@@ -1180,10 +1180,10 @@ static void parse_compression(const parameters_map &params, chd_codec_type compr
{
std::string name(*compression_str->second, start, (end == -1) ? -1 : end - start);
if (name.length() != 4)
- report_error(1, "Invalid compressor '%s' specified", name.c_str());
+ report_error(1, "Invalid compressor '%s' specified", name);
chd_codec_type type = CHD_MAKE_TAG(name[0], name[1], name[2], name[3]);
if (!chd_codec_list::codec_exists(type))
- report_error(1, "Invalid compressor '%s' specified", name.c_str());
+ report_error(1, "Invalid compressor '%s' specified", name);
compression[index++] = type;
if (end == -1)
break;
@@ -1257,16 +1257,16 @@ static void compress_common(chd_file_compressor &chd)
// loop until done
double complete, ratio;
- chd_error err;
- while ((err = chd.compress_continue(complete, ratio)) == CHDERR_WALKING_PARENT || err == CHDERR_COMPRESSING)
- if (err == CHDERR_WALKING_PARENT)
+ std::error_condition err;
+ while ((err = chd.compress_continue(complete, ratio)) == chd_file::error::WALKING_PARENT || err == chd_file::error::COMPRESSING)
+ if (err == chd_file::error::WALKING_PARENT)
progress(false, "Examining parent, %.1f%% complete... \r", 100.0 * complete);
else
progress(false, "Compressing, %.1f%% complete... (ratio=%.1f%%) \r", 100.0 * complete, 100.0 * ratio);
// handle errors
- if (err != CHDERR_NONE)
- report_error(1, "Error during compression: %-40s", chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error during compression: %-40s", err.message());
// final progress update
progress(true, "Compression complete ... final ratio = %.1f%% \n", 100.0 * ratio);
@@ -1447,15 +1447,17 @@ static void do_info(parameters_map &params)
// output cmpression and size information
chd_codec_type compression[4] = { input_chd.compression(0), input_chd.compression(1), input_chd.compression(2), input_chd.compression(3) };
+ uint64_t filesize = 0;
+ input_chd.file().length(filesize);
printf("Logical size: %s bytes\n", big_int_string(input_chd.logical_bytes()).c_str());
printf("Hunk Size: %s bytes\n", big_int_string(input_chd.hunk_bytes()).c_str());
printf("Total Hunks: %s\n", big_int_string(input_chd.hunk_count()).c_str());
printf("Unit Size: %s bytes\n", big_int_string(input_chd.unit_bytes()).c_str());
printf("Total Units: %s\n", big_int_string(input_chd.unit_count()).c_str());
printf("Compression: %s\n", compression_string(compression).c_str());
- printf("CHD size: %s bytes\n", big_int_string(static_cast<util::core_file &>(input_chd).size()).c_str());
+ printf("CHD size: %s bytes\n", big_int_string(filesize).c_str());
if (compression[0] != CHD_CODEC_NONE)
- printf("Ratio: %.1f%%\n", 100.0 * double(static_cast<util::core_file &>(input_chd).size()) / double(input_chd.logical_bytes()));
+ printf("Ratio: %.1f%%\n", 100.0 * double(filesize) / double(input_chd.logical_bytes()));
// add SHA1 output
util::sha1_t overall = input_chd.sha1();
@@ -1477,8 +1479,8 @@ static void do_info(parameters_map &params)
// get the indexed metadata item; stop when we hit an error
chd_metadata_tag metatag;
uint8_t metaflags;
- chd_error err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index, buffer, metatag, metaflags);
- if (err != CHDERR_NONE)
+ std::error_condition err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index, buffer, metatag, metaflags);
+ if (err)
break;
// determine our index
@@ -1523,9 +1525,9 @@ static void do_info(parameters_map &params)
// get info on this hunk
chd_codec_type codec;
uint32_t compbytes;
- chd_error err = input_chd.hunk_info(hunknum, codec, compbytes);
- if (err != CHDERR_NONE)
- report_error(1, "Error getting info on hunk %d: %s", hunknum, chd_file::error_string(err));
+ std::error_condition err = input_chd.hunk_info(hunknum, codec, compbytes);
+ if (err)
+ report_error(1, "Error getting info on hunk %d: %s", hunknum, err.message());
// decode into our data
if (codec > CHD_CODEC_MINI)
@@ -1603,9 +1605,9 @@ static void do_verify(parameters_map &params)
// determine how much to read
uint32_t bytes_to_read = (std::min<uint64_t>)(buffer.size(), input_chd.logical_bytes() - offset);
- chd_error err = input_chd.read_bytes(offset, &buffer[0], bytes_to_read);
- if (err != CHDERR_NONE)
- report_error(1, "Error reading CHD file (%s): %s", params.find(OPTION_INPUT)->second->c_str(), chd_file::error_string(err));
+ std::error_condition err = input_chd.read_bytes(offset, &buffer[0], bytes_to_read);
+ if (err)
+ report_error(1, "Error reading CHD file (%s): %s", *params.find(OPTION_INPUT)->second, err.message());
// add to the checksum
rawsha1.append(&buffer[0], bytes_to_read);
@@ -1665,9 +1667,9 @@ static void do_create_raw(parameters_map &params)
auto input_file_str = params.find(OPTION_INPUT);
if (input_file_str != params.end())
{
- osd_file::error filerr = util::core_file::open(*input_file_str->second, OPEN_FLAG_READ, input_file);
- if (filerr != osd_file::error::NONE)
- report_error(1, "Unable to open file (%s)", input_file_str->second->c_str());
+ std::error_condition const filerr = util::core_file::open(*input_file_str->second, OPEN_FLAG_READ, input_file);
+ if (filerr)
+ report_error(1, "Unable to open file (%s): %s", *input_file_str->second, filerr.message());
}
// process output CHD
@@ -1720,13 +1722,13 @@ static void do_create_raw(parameters_map &params)
{
// create the new CHD
std::unique_ptr<chd_file_compressor> chd(new chd_rawfile_compressor(*input_file, input_start, input_end));
- chd_error err;
+ std::error_condition err;
if (output_parent.opened())
err = chd->create(output_chd_str->c_str(), input_end - input_start, hunk_size, compression, output_parent);
else
err = chd->create(output_chd_str->c_str(), input_end - input_start, hunk_size, unit_size, compression);
- if (err != CHDERR_NONE)
- report_error(1, "Error creating CHD file (%s): %s", output_chd_str->c_str(), chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error creating CHD file (%s): %s", output_chd_str, err.message());
// if we have a parent, copy forward all the metadata
if (output_parent.opened())
@@ -1758,9 +1760,9 @@ static void do_create_hd(parameters_map &params)
auto input_file_str = params.find(OPTION_INPUT);
if (input_file_str != params.end())
{
- osd_file::error filerr = util::core_file::open(*input_file_str->second, OPEN_FLAG_READ, input_file);
- if (filerr != osd_file::error::NONE)
- report_error(1, "Unable to open file (%s)", input_file_str->second->c_str());
+ std::error_condition const filerr = util::core_file::open(*input_file_str->second, OPEN_FLAG_READ, input_file);
+ if (filerr)
+ report_error(1, "Unable to open file (%s): %s", *input_file_str->second, filerr.message());
}
// process output CHD
@@ -1833,13 +1835,13 @@ static void do_create_hd(parameters_map &params)
if (ident_str != params.end())
{
// load the file
- osd_file::error filerr = util::core_file::load(ident_str->second->c_str(), identdata);
- if (filerr != osd_file::error::NONE)
- report_error(1, "Error reading ident file (%s)", ident_str->second->c_str());
+ std::error_condition const filerr = util::core_file::load(*ident_str->second, identdata);
+ if (filerr)
+ report_error(1, "Error reading ident file (%s): %s", *ident_str->second, filerr.message());
// must be at least 14 bytes; extract CHS data from there
if (identdata.size() < 14)
- report_error(1, "Ident file '%s' is invalid (too short)", ident_str->second->c_str());
+ report_error(1, "Ident file '%s' is invalid (too short)", *ident_str->second);
cylinders = (identdata[3] << 8) | identdata[2];
heads = (identdata[7] << 8) | identdata[6];
sectors = (identdata[13] << 8) | identdata[12];
@@ -1870,7 +1872,7 @@ static void do_create_hd(parameters_map &params)
if (output_parent.opened() && cylinders == 0)
{
std::string metadata;
- if (output_parent.read_metadata(HARD_DISK_METADATA_TAG, 0, metadata) != CHDERR_NONE)
+ if (output_parent.read_metadata(HARD_DISK_METADATA_TAG, 0, metadata))
report_error(1, "Unable to find hard disk metadata in parent CHD");
if (sscanf(metadata.c_str(), HARD_DISK_METADATA_FORMAT, &cylinders, &heads, &sectors, &sector_size) != 4)
report_error(1, "Error parsing hard disk metadata in parent CHD");
@@ -1917,26 +1919,26 @@ static void do_create_hd(parameters_map &params)
std::unique_ptr<chd_file_compressor> chd;
if (input_file) chd.reset(new chd_rawfile_compressor(*input_file, input_start, input_end));
else chd.reset(new chd_zero_compressor(input_start, input_end));
- chd_error err;
+ std::error_condition err;
if (output_parent.opened())
err = chd->create(output_chd_str->c_str(), uint64_t(totalsectors) * uint64_t(sector_size), hunk_size, compression, output_parent);
else
err = chd->create(output_chd_str->c_str(), uint64_t(totalsectors) * uint64_t(sector_size), hunk_size, sector_size, compression);
- if (err != CHDERR_NONE)
- report_error(1, "Error creating CHD file (%s): %s", output_chd_str->c_str(), chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error creating CHD file (%s): %s", output_chd_str, err.message());
// add the standard hard disk metadata
std::string metadata = string_format(HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sector_size);
err = chd->write_metadata(HARD_DISK_METADATA_TAG, 0, metadata);
- if (err != CHDERR_NONE)
- report_error(1, "Error adding hard disk metadata: %s", chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error adding hard disk metadata: %s", err.message());
// write the ident if present
if (!identdata.empty())
{
err = chd->write_metadata(HARD_DISK_IDENT_METADATA_TAG, 0, identdata);
- if (err != CHDERR_NONE)
- report_error(1, "Error adding hard disk metadata: %s", chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error adding hard disk metadata: %s", err.message());
}
// compress it generically
@@ -1967,9 +1969,9 @@ static void do_create_cd(parameters_map &params)
auto input_file_str = params.find(OPTION_INPUT);
if (input_file_str != params.end())
{
- chd_error err = chdcd_parse_toc(input_file_str->second->c_str(), toc, track_info);
- if (err != CHDERR_NONE)
- report_error(1, "Error parsing input file (%s: %s)\n", input_file_str->second->c_str(), chd_file::error_string(err));
+ std::error_condition err = chdcd_parse_toc(input_file_str->second->c_str(), toc, track_info);
+ if (err)
+ report_error(1, "Error parsing input file (%s: %s)\n", *input_file_str->second, err.message());
}
// process output CHD
@@ -2016,18 +2018,18 @@ static void do_create_cd(parameters_map &params)
{
// create the new CD
chd = new chd_cd_compressor(toc, track_info);
- chd_error err;
+ std::error_condition err;
if (output_parent.opened())
err = chd->create(output_chd_str->c_str(), uint64_t(totalsectors) * uint64_t(CD_FRAME_SIZE), hunk_size, compression, output_parent);
else
err = chd->create(output_chd_str->c_str(), uint64_t(totalsectors) * uint64_t(CD_FRAME_SIZE), hunk_size, CD_FRAME_SIZE, compression);
- if (err != CHDERR_NONE)
- report_error(1, "Error creating CHD file (%s): %s", output_chd_str->c_str(), chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error creating CHD file (%s): %s", *output_chd_str, err.message());
// add the standard CD metadata; we do this even if we have a parent because it might be different
err = cdrom_write_metadata(chd, &toc);
- if (err != CHDERR_NONE)
- report_error(1, "Error adding CD metadata: %s", chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error adding CD metadata: %s", err.message());
// compress it generically
compress_common(*chd);
@@ -2059,7 +2061,7 @@ static void do_create_ld(parameters_map &params)
{
avi_file::error avierr = avi_file::open(*input_file_str->second, input_file);
if (avierr != avi_file::error::NONE)
- report_error(1, "Error opening AVI file (%s): %s\n", input_file_str->second->c_str(), avi_file::error_string(avierr));
+ report_error(1, "Error opening AVI file (%s): %s\n", *input_file_str->second, avi_file::error_string(avierr));
}
const avi_file::movie_info &aviinfo = input_file->get_movie_info();
@@ -2133,19 +2135,19 @@ static void do_create_ld(parameters_map &params)
{
// create the new CHD
chd = new chd_avi_compressor(*input_file, info, input_start, input_end);
- chd_error err;
+ std::error_condition err;
if (output_parent.opened())
err = chd->create(output_chd_str->c_str(), uint64_t(input_end - input_start) * hunk_size, hunk_size, compression, output_parent);
else
err = chd->create(output_chd_str->c_str(), uint64_t(input_end - input_start) * hunk_size, hunk_size, info.bytes_per_frame, compression);
- if (err != CHDERR_NONE)
- report_error(1, "Error creating CHD file (%s): %s", output_chd_str->c_str(), chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error creating CHD file (%s): %s", *output_chd_str, err.message());
// write the core A/V metadata
std::string metadata = string_format(AV_METADATA_FORMAT, info.fps_times_1million / 1000000, info.fps_times_1million % 1000000, info.width, info.height, info.interlaced, info.channels, info.rate);
err = chd->write_metadata(AV_METADATA_TAG, 0, metadata);
- if (err != CHDERR_NONE)
- report_error(1, "Error adding AV metadata: %s\n", chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error adding AV metadata: %s\n", err.message());
// create the compressor and then run it generically
compress_common(*chd);
@@ -2154,8 +2156,8 @@ static void do_create_ld(parameters_map &params)
if (info.height == 524/2 || info.height == 624/2)
{
err = chd->write_metadata(AV_LD_METADATA_TAG, 0, chd->ldframedata(), 0);
- if (err != CHDERR_NONE)
- report_error(1, "Error adding AVLD metadata: %s\n", chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error adding AVLD metadata: %s\n", err.message());
}
delete chd;
}
@@ -2202,15 +2204,15 @@ static void do_copy(parameters_map &params)
chd_codec_type compression[4];
{
std::vector<uint8_t> metadata;
- if (input_chd.read_metadata(HARD_DISK_METADATA_TAG, 0, metadata) == CHDERR_NONE)
+ if (!input_chd.read_metadata(HARD_DISK_METADATA_TAG, 0, metadata))
memcpy(compression, s_default_hd_compression, sizeof(compression));
- else if (input_chd.read_metadata(AV_METADATA_TAG, 0, metadata) == CHDERR_NONE)
+ else if (!input_chd.read_metadata(AV_METADATA_TAG, 0, metadata))
memcpy(compression, s_default_ld_compression, sizeof(compression));
- else if (input_chd.read_metadata(CDROM_OLD_METADATA_TAG, 0, metadata) == CHDERR_NONE ||
- input_chd.read_metadata(CDROM_TRACK_METADATA_TAG, 0, metadata) == CHDERR_NONE ||
- input_chd.read_metadata(CDROM_TRACK_METADATA2_TAG, 0, metadata) == CHDERR_NONE ||
- input_chd.read_metadata(GDROM_OLD_METADATA_TAG, 0, metadata) == CHDERR_NONE ||
- input_chd.read_metadata(GDROM_TRACK_METADATA_TAG, 0, metadata) == CHDERR_NONE)
+ else if (!input_chd.read_metadata(CDROM_OLD_METADATA_TAG, 0, metadata) ||
+ !input_chd.read_metadata(CDROM_TRACK_METADATA_TAG, 0, metadata) ||
+ !input_chd.read_metadata(CDROM_TRACK_METADATA2_TAG, 0, metadata) ||
+ !input_chd.read_metadata(GDROM_OLD_METADATA_TAG, 0, metadata) ||
+ !input_chd.read_metadata(GDROM_TRACK_METADATA_TAG, 0, metadata))
memcpy(compression, s_default_cd_compression, sizeof(compression));
else
memcpy(compression, s_default_raw_compression, sizeof(compression));
@@ -2240,13 +2242,13 @@ static void do_copy(parameters_map &params)
{
// create the new CHD
chd = new chd_chdfile_compressor(input_chd, input_start, input_end);
- chd_error err;
+ std::error_condition err;
if (output_parent.opened())
err = chd->create(output_chd_str->c_str(), input_end - input_start, hunk_size, compression, output_parent);
else
err = chd->create(output_chd_str->c_str(), input_end - input_start, hunk_size, input_chd.unit_bytes(), compression);
- if (err != CHDERR_NONE)
- report_error(1, "Error creating CHD file (%s): %s", output_chd_str->c_str(), chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error creating CHD file (%s): %s", *output_chd_str, err.message());
// clone all the metadata, upgrading where appropriate
std::vector<uint8_t> metadata;
@@ -2255,7 +2257,7 @@ static void do_copy(parameters_map &params)
uint32_t index = 0;
bool redo_cd = false;
bool cdda_swap = false;
- for (err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index++, metadata, metatag, metaflags); err == CHDERR_NONE; err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index++, metadata, metatag, metaflags))
+ for (err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index++, metadata, metatag, metaflags); !err; err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index++, metadata, metatag, metaflags))
{
// if this is an old CD-CHD tag, note that we want to re-do it
if (metatag == CDROM_OLD_METADATA_TAG || metatag == CDROM_TRACK_METADATA_TAG)
@@ -2272,8 +2274,8 @@ static void do_copy(parameters_map &params)
// otherwise, clone it
err = chd->write_metadata(metatag, CHDMETAINDEX_APPEND, metadata, metaflags);
- if (err != CHDERR_NONE)
- report_error(1, "Error writing cloned metadata: %s", chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error writing cloned metadata: %s", err.message());
}
// if we need to re-do the CD metadata, do it now
@@ -2284,8 +2286,8 @@ static void do_copy(parameters_map &params)
report_error(1, "Error upgrading CD metadata");
const cdrom_toc *toc = cdrom_get_toc(cdrom);
err = cdrom_write_metadata(chd, toc);
- if (err != CHDERR_NONE)
- report_error(1, "Error writing upgraded CD metadata: %s", chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error writing upgraded CD metadata: %s", err.message());
if (cdda_swap)
chd->m_toc = toc;
}
@@ -2342,9 +2344,9 @@ static void do_extract_raw(parameters_map &params)
try
{
// process output file
- osd_file::error filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file);
- if (filerr != osd_file::error::NONE)
- report_error(1, "Unable to open file (%s)", output_file_str->second->c_str());
+ std::error_condition const filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file);
+ if (filerr)
+ report_error(1, "Unable to open file (%s): %s", *output_file_str->second, filerr.message());
// copy all data
std::vector<uint8_t> buffer((TEMP_BUFFER_SIZE / input_chd.hunk_bytes()) * input_chd.hunk_bytes());
@@ -2354,14 +2356,14 @@ static void do_extract_raw(parameters_map &params)
// determine how much to read
uint32_t bytes_to_read = (std::min<uint64_t>)(buffer.size(), input_end - offset);
- chd_error err = input_chd.read_bytes(offset, &buffer[0], bytes_to_read);
- if (err != CHDERR_NONE)
- report_error(1, "Error reading CHD file (%s): %s", params.find(OPTION_INPUT)->second->c_str(), chd_file::error_string(err));
+ std::error_condition err = input_chd.read_bytes(offset, &buffer[0], bytes_to_read);
+ if (err)
+ report_error(1, "Error reading CHD file (%s): %s", *params.find(OPTION_INPUT)->second, err.message());
// write to the output
uint32_t 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());
+ report_error(1, "Error writing to file; check disk space (%s)", *output_file_str->second);
// advance
offset += bytes_to_read;
@@ -2446,16 +2448,16 @@ static void do_extract_cd(parameters_map &params)
}
// process output file
- osd_file::error filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, output_toc_file);
- if (filerr != osd_file::error::NONE)
- report_error(1, "Unable to open file (%s)", output_file_str->second->c_str());
+ std::error_condition filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, output_toc_file);
+ if (filerr)
+ report_error(1, "Unable to open file (%s): %s", *output_file_str->second, filerr.message());
// process output BIN file
if (mode != MODE_GDI)
{
filerr = util::core_file::open(*output_bin_file_str, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file);
- if (filerr != osd_file::error::NONE)
- report_error(1, "Unable to open file (%s)", output_bin_file_str->c_str());
+ if (filerr)
+ report_error(1, "Unable to open file (%s): %s", *output_bin_file_str, filerr.message());
}
// determine total frames
@@ -2490,8 +2492,8 @@ static void do_extract_cd(parameters_map &params)
output_bin_file.reset();
filerr = util::core_file::open(trackbin_name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file);
- if (filerr != osd_file::error::NONE)
- report_error(1, "Unable to open file (%s)", trackbin_name.c_str());
+ if (filerr)
+ report_error(1, "Unable to open file (%s): %s", trackbin_name, filerr.message());
outputoffs = 0;
}
@@ -2555,7 +2557,7 @@ static void do_extract_cd(parameters_map &params)
output_bin_file->seek(outputoffs, SEEK_SET);
uint32_t 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));
+ report_error(1, "Error writing frame %d to file (%s): %s\n", frame, *output_file_str->second, "Write error");
outputoffs += bufferoffs;
bufferoffs = 0;
}
@@ -2595,8 +2597,8 @@ static void do_extract_ld(parameters_map &params)
// read core metadata
std::string metadata;
- chd_error err = input_chd.read_metadata(AV_METADATA_TAG, 0, metadata);
- if (err != CHDERR_NONE)
+ std::error_condition err = input_chd.read_metadata(AV_METADATA_TAG, 0, metadata);
+ if (err)
report_error(1, "Unable to find A/V metadata in the input CHD");
// parse the metadata
@@ -2666,7 +2668,7 @@ static void do_extract_ld(parameters_map &params)
// process output file
avi_file::error avierr = avi_file::create(*output_file_str->second, info, output_file);
if (avierr != avi_file::error::NONE)
- report_error(1, "Unable to open file (%s)", output_file_str->second->c_str());
+ report_error(1, "Unable to open file (%s)", *output_file_str->second);
// create the codec configuration
avhuff_decoder::config avconfig;
@@ -2693,11 +2695,12 @@ static void do_extract_ld(parameters_map &params)
input_chd.codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &avconfig);
// read the hunk into the buffers
- chd_error err = input_chd.read_hunk(framenum, nullptr);
- if (err != CHDERR_NONE)
+ std::error_condition err = input_chd.read_hunk(framenum, nullptr);
+ if (err)
{
- uint64_t filepos = static_cast<util::core_file &>(input_chd).tell();
- report_error(1, "Error reading hunk %d at offset %d from CHD file (%s): %s\n", framenum, filepos, params.find(OPTION_INPUT)->second->c_str(), chd_file::error_string(err));
+ uint64_t filepos = ~uint64_t(0);
+ input_chd.file().tell(filepos);
+ report_error(1, "Error reading hunk %d at offset %d from CHD file (%s): %s\n", framenum, filepos, *params.find(OPTION_INPUT)->second, err.message());
}
// write audio
@@ -2705,7 +2708,7 @@ static void do_extract_ld(parameters_map &params)
{
avi_file::error avierr = output_file->append_sound_samples(chnum, avconfig.audio[chnum], actsamples, 0);
if (avierr != avi_file::error::NONE)
- report_error(1, "Error writing samples for hunk %d to file (%s): %s\n", framenum, output_file_str->second->c_str(), avi_file::error_string(avierr));
+ report_error(1, "Error writing samples for hunk %d to file (%s): %s\n", framenum, *output_file_str->second, avi_file::error_string(avierr));
}
// write video
@@ -2713,7 +2716,7 @@ static void do_extract_ld(parameters_map &params)
{
avi_file::error avierr = output_file->append_video_frame(fullbitmap);
if (avierr != avi_file::error::NONE)
- report_error(1, "Error writing video for hunk %d to file (%s): %s\n", framenum, output_file_str->second->c_str(), avi_file::error_string(avierr));
+ report_error(1, "Error writing video for hunk %d to file (%s): %s\n", framenum, *output_file_str->second, avi_file::error_string(avierr));
}
}
@@ -2773,9 +2776,9 @@ static void do_add_metadata(parameters_map &params)
std::vector<uint8_t> file;
if (file_str != params.end())
{
- osd_file::error filerr = util::core_file::load(file_str->second->c_str(), file);
- if (filerr != osd_file::error::NONE)
- report_error(1, "Error reading metadata file (%s)", file_str->second->c_str());
+ std::error_condition const filerr = util::core_file::load(*file_str->second, file);
+ if (filerr)
+ report_error(1, "Error reading metadata file (%s): %s", *file_str->second, filerr.message());
}
// make sure we have one or the other
@@ -2799,13 +2802,13 @@ static void do_add_metadata(parameters_map &params)
printf("Data: %s (%d bytes)\n", file_str->second->c_str(), int(file.size()));
// write the metadata
- chd_error err;
+ std::error_condition err;
if (text_str != params.end())
err = input_chd.write_metadata(tag, index, text, flags);
else
err = input_chd.write_metadata(tag, index, file, flags);
- if (err != CHDERR_NONE)
- report_error(1, "Error adding metadata: %s", chd_file::error_string(err));
+ if (err)
+ report_error(1, "Error adding metadata: %s", err.message());
else
printf("Metadata added\n");
}
@@ -2843,9 +2846,9 @@ static void do_del_metadata(parameters_map &params)
printf("Index: %d\n", index);
// write the metadata
- chd_error err = input_chd.delete_metadata(tag, index);
- if (err != CHDERR_NONE)
- report_error(1, "Error removing metadata: %s", chd_file::error_string(err));
+ std::error_condition err = input_chd.delete_metadata(tag, index);
+ if (err)
+ report_error(1, "Error removing metadata: %s", err.message());
else
printf("Metadata removed\n");
}
@@ -2884,9 +2887,9 @@ static void do_dump_metadata(parameters_map &params)
// write the metadata
std::vector<uint8_t> buffer;
- chd_error err = input_chd.read_metadata(tag, index, buffer);
- if (err != CHDERR_NONE)
- report_error(1, "Error reading metadata: %s", chd_file::error_string(err));
+ std::error_condition err = input_chd.read_metadata(tag, index, buffer);
+ if (err)
+ report_error(1, "Error reading metadata: %s", err.message());
// catch errors so we can close & delete the output file
util::core_file::ptr output_file;
@@ -2895,14 +2898,14 @@ static void do_dump_metadata(parameters_map &params)
// create the file
if (output_file_str != params.end())
{
- osd_file::error filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file);
- if (filerr != osd_file::error::NONE)
- report_error(1, "Unable to open file (%s)", output_file_str->second->c_str());
+ std::error_condition const filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file);
+ if (filerr)
+ report_error(1, "Unable to open file (%s): %s", *output_file_str->second, filerr.message());
// output the metadata
uint32_t 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());
+ report_error(1, "Error writing file (%s)", *output_file_str->second);
output_file.reset();
// provide some feedback
@@ -3056,9 +3059,9 @@ int CLIB_DECL main(int argc, char *argv[])
(*s_command.handler)(parameters);
return 0;
}
- catch (chd_error &err)
+ catch (std::error_condition const &err)
{
- fprintf(stderr, "CHD error occurred (main): %s\n", chd_file::error_string(err));
+ fprintf(stderr, "CHD error occurred (main): %s\n", err.message().c_str());
return 1;
}
catch (fatal_error &err)
diff --git a/src/tools/floptool.cpp b/src/tools/floptool.cpp
index 6e9e2097233..f021e084a62 100644
--- a/src/tools/floptool.cpp
+++ b/src/tools/floptool.cpp
@@ -6,17 +6,19 @@
***************************************************************************/
-#include <cstdio>
-#include <cstring>
+#include "image_handler.h"
+
+#include "corestr.h"
+#include "ioprocs.h"
+
+#include <cassert>
#include <cctype>
+#include <cstdarg>
+#include <cstdio>
#include <cstdlib>
+#include <cstring>
#include <ctime>
-#include <cstdarg>
-#include <cassert>
-#include <map>
-#include "image_handler.h"
-#include "corestr.h"
static formats_table formats;
diff --git a/src/tools/image_handler.cpp b/src/tools/image_handler.cpp
index abb45de2db3..a520383846d 100644
--- a/src/tools/image_handler.cpp
+++ b/src/tools/image_handler.cpp
@@ -4,10 +4,16 @@
// Image generic handler class and helpers
#include "image_handler.h"
+
#include "formats/all.h"
#include "formats/fsblk_vec.h"
#include "formats/fs_unformatted.h"
+#include "ioprocs.h"
+#include "ioprocsfill.h"
+#include "ioprocsvec.h"
+
+
// Fatalerror implementation
emu_fatalerror::emu_fatalerror(util::format_argument_pack<std::ostream> const &args)
@@ -21,70 +27,6 @@ emu_fatalerror::emu_fatalerror(int _exitcode, util::format_argument_pack<std::os
{
}
-// io_generic from vector<u8>
-
-static void ram_closeproc(void *file)
-{
- auto f = (iofile_ram *)file;
- delete f;
-}
-
-static int ram_seekproc(void *file, int64_t offset, int whence)
-{
- auto f = (iofile_ram *)file;
- switch(whence) {
- case SEEK_SET: f->pos = offset; break;
- case SEEK_CUR: f->pos += offset; break;
- case SEEK_END: f->pos = f->data->size() + offset; break;
- }
-
- if(whence == SEEK_CUR)
- f->pos = std::max<int64_t>(f->pos, 0);
- else
- f->pos = std::clamp<int64_t>(f->pos, 0, f->data->size());
- return 0;
-}
-
-static size_t ram_readproc(void *file, void *buffer, size_t length)
-{
- auto f = (iofile_ram *)file;
- size_t l = std::min<std::common_type_t<size_t, int64_t> >(length, f->data->size() - f->pos);
- memcpy(buffer, f->data->data() + f->pos, l);
- return l;
-}
-
-static size_t ram_writeproc(void *file, const void *buffer, size_t length)
-{
- auto f = (iofile_ram *)file;
- size_t l = std::max<std::common_type_t<size_t, int64_t> >(f->pos + length, f->data->size());
- f->data->resize(l);
- memcpy(f->data->data() + f->pos, buffer, length);
- return length;
-}
-
-static uint64_t ram_filesizeproc(void *file)
-{
- auto f = (iofile_ram *)file;
- return f->data->size();
-}
-
-
-static const io_procs iop_ram = {
- ram_closeproc,
- ram_seekproc,
- ram_readproc,
- ram_writeproc,
- ram_filesizeproc
-};
-
-io_generic *ram_open(std::vector<u8> &data)
-{
- iofile_ram *f = new iofile_ram;
- f->data = &data;
- f->pos = 0;
- return new io_generic({ &iop_ram, f });
-}
-
// Format enumeration
@@ -304,45 +246,37 @@ std::vector<std::pair<u8, const floppy_format_info *>> image_handler::identify(c
std::vector<std::pair<u8, const floppy_format_info *>> res;
std::vector<uint32_t> variants;
- std::string msg = util::string_format("Error opening %s for reading", m_on_disk_path);
FILE *f = fopen(m_on_disk_path.c_str(), "rb");
if (!f) {
+ std::string msg = util::string_format("Error opening %s for reading", m_on_disk_path);
perror(msg.c_str());
return res;
}
- io_generic io;
- io.file = f;
- io.procs = &stdio_ioprocs_noclose;
- io.filler = 0xff;
+ auto io = util::stdio_read(f, 0xff);
for(const auto &e : formats.floppy_format_info_by_key) {
- u8 score = e.second->m_format->identify(&io, floppy_image::FF_UNKNOWN, variants);
+ u8 score = e.second->m_format->identify(*io, floppy_image::FF_UNKNOWN, variants);
if(score)
res.emplace_back(std::make_pair(score, e.second));
}
- fclose(f);
-
return res;
}
bool image_handler::floppy_load(const floppy_format_info *format)
{
std::vector<uint32_t> variants;
- std::string msg = util::string_format("Error opening %s for reading", m_on_disk_path);
FILE *f = fopen(m_on_disk_path.c_str(), "rb");
if (!f) {
+ std::string msg = util::string_format("Error opening %s for reading", m_on_disk_path);
perror(msg.c_str());
return true;
}
- io_generic io;
- io.file = f;
- io.procs = &stdio_ioprocs_noclose;
- io.filler = 0xff;
+ auto io = util::stdio_read(f, 0xff);
- return !format->m_format->load(&io, floppy_image::FF_UNKNOWN, variants, &m_floppy_image);
+ return !format->m_format->load(*io, floppy_image::FF_UNKNOWN, variants, &m_floppy_image);
}
bool image_handler::floppy_save(const floppy_format_info *format)
@@ -355,12 +289,9 @@ bool image_handler::floppy_save(const floppy_format_info *format)
return true;
}
- io_generic io;
- io.file = f;
- io.procs = &stdio_ioprocs_noclose;
- io.filler = 0xff;
+ auto io = util::stdio_read_write(f, 0xff);
- return !format->m_format->save(&io, variants, &m_floppy_image);
+ return !format->m_format->save(*io, variants, &m_floppy_image);
}
void image_handler::floppy_create(const floppy_create_info *format, fs_meta_data meta)
@@ -372,14 +303,13 @@ void image_handler::floppy_create(const floppy_create_info *format, fs_meta_data
auto fs = format->m_manager->mount(blockdev);
fs->format(meta);
- auto iog = ram_open(img);
auto source_format = format->m_type();
- source_format->load(iog, floppy_image::FF_UNKNOWN, variants, &m_floppy_image);
+ auto io = util::ram_read(img.data(), img.size(), 0xff);
+ source_format->load(*io, floppy_image::FF_UNKNOWN, variants, &m_floppy_image);
delete source_format;
- delete iog;
-
- } else
+ } else {
fs_unformatted::format(format->m_key, &m_floppy_image);
+ }
}
bool image_handler::floppy_mount_fs(const filesystem_format *format)
@@ -390,11 +320,10 @@ bool image_handler::floppy_mount_fs(const filesystem_format *format)
std::vector<uint32_t> variants;
m_floppy_fs_converter = ci->m_type;
m_sector_image.clear();
- auto iog = ram_open(m_sector_image);
auto load_format = m_floppy_fs_converter();
- load_format->save(iog, variants, &m_floppy_image);
+ util::random_read_write_fill_wrapper<util::vector_read_write_adapter<u8>, 0xff> io(m_sector_image);
+ load_format->save(io, variants, &m_floppy_image);
delete load_format;
- delete iog;
}
if(ci->m_image_size == m_sector_image.size())
@@ -425,11 +354,10 @@ bool image_handler::hd_mount_fs(const filesystem_format *format)
void image_handler::fs_to_floppy()
{
std::vector<uint32_t> variants;
- auto iog = ram_open(m_sector_image);
+ auto io = util::ram_read(m_sector_image.data(), m_sector_image.size(), 0xff);
auto format = m_floppy_fs_converter();
- format->load(iog, floppy_image::FF_UNKNOWN, variants, &m_floppy_image);
+ format->load(*io, floppy_image::FF_UNKNOWN, variants, &m_floppy_image);
delete format;
- delete iog;
}
std::vector<std::string> image_handler::path_split(std::string path) const
diff --git a/src/tools/image_handler.h b/src/tools/image_handler.h
index f004bd7d91f..d9a861bb3fd 100644
--- a/src/tools/image_handler.h
+++ b/src/tools/image_handler.h
@@ -3,27 +3,26 @@
// Image generic handler class and helpers
-#ifndef TOOLS_IMAGE_HANDLER_H
-#define TOOLS_IMAGE_HANDLER_H
+#ifndef MAME_TOOLS_IMAGE_HANDLER_H
+#define MAME_TOOLS_IMAGE_HANDLER_H
+
+#pragma once
#include "../emu/emucore.h"
+
#include "formats/fsmgr.h"
+#include <cstdint>
#include <map>
-#include <vector>
#include <memory>
+#include <string>
+#include <vector>
+
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
-struct iofile_ram {
- std::vector<u8> *data;
- int64_t pos;
-};
-
-io_generic *ram_open(std::vector<u8> &data);
-
struct floppy_format_info {
floppy_image_format_t *m_format;
std::string m_category;
@@ -117,5 +116,4 @@ private:
};
-#endif
-
+#endif // MAME_TOOLS_IMAGE_HANDLER_H
diff --git a/src/tools/imgtool/iflopimg.cpp b/src/tools/imgtool/iflopimg.cpp
index f6e79e6cd5d..951b75978e8 100644
--- a/src/tools/imgtool/iflopimg.cpp
+++ b/src/tools/imgtool/iflopimg.cpp
@@ -8,10 +8,15 @@
*********************************************************************/
+#include "iflopimg.h"
+
#include "imgtool.h"
-#include "formats/flopimg.h"
#include "library.h"
-#include "iflopimg.h"
+
+#include "formats/flopimg.h"
+
+#include "ioprocs.h"
+
imgtoolerr_t imgtool_floppy_error(floperr_t err)
{
@@ -40,57 +45,6 @@ imgtoolerr_t imgtool_floppy_error(floperr_t err)
/*********************************************************************
- Imgtool ioprocs
-*********************************************************************/
-
-static void imgtool_floppy_closeproc(void *file)
-{
- delete reinterpret_cast<imgtool::stream *>(file);
-}
-
-static int imgtool_floppy_seekproc(void *file, int64_t offset, int whence)
-{
- reinterpret_cast<imgtool::stream *>(file)->seek(offset, whence);
- return 0;
-}
-
-static size_t imgtool_floppy_readproc(void *file, void *buffer, size_t length)
-{
- return reinterpret_cast<imgtool::stream *>(file)->read(buffer, length);
-}
-
-static size_t imgtool_floppy_writeproc(void *file, const void *buffer, size_t length)
-{
- reinterpret_cast<imgtool::stream *>(file)->write(buffer, length);
- return length;
-}
-
-static uint64_t imgtool_floppy_filesizeproc(void *file)
-{
- return reinterpret_cast<imgtool::stream *>(file)->size();
-}
-
-static const struct io_procs imgtool_ioprocs =
-{
- imgtool_floppy_closeproc,
- imgtool_floppy_seekproc,
- imgtool_floppy_readproc,
- imgtool_floppy_writeproc,
- imgtool_floppy_filesizeproc
-};
-
-static const struct io_procs imgtool_noclose_ioprocs =
-{
- nullptr,
- imgtool_floppy_seekproc,
- imgtool_floppy_readproc,
- imgtool_floppy_writeproc,
- imgtool_floppy_filesizeproc
-};
-
-
-
-/*********************************************************************
Imgtool handlers
*********************************************************************/
@@ -102,11 +56,10 @@ struct imgtool_floppy_image
-static imgtoolerr_t imgtool_floppy_open_internal(imgtool::image &image, imgtool::stream::ptr &&stream, int noclose)
+static imgtoolerr_t imgtool_floppy_open_internal(imgtool::image &image, imgtool::stream::ptr &&stream)
{
floperr_t ferr;
imgtoolerr_t err = IMGTOOLERR_SUCCESS;
- imgtool::stream *f = nullptr;
struct imgtool_floppy_image *fimg;
const imgtool_class *imgclass;
const struct FloppyFormat *format;
@@ -117,18 +70,13 @@ static imgtoolerr_t imgtool_floppy_open_internal(imgtool::image &image, imgtool:
format = (const struct FloppyFormat *) imgclass->derived_param;
open = (imgtoolerr_t (*)(imgtool::image &, imgtool::stream *)) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_FLOPPY_OPEN);
- // extract the pointer
- f = stream.release();
-
// open up the floppy
- ferr = floppy_open(f, noclose ? &imgtool_noclose_ioprocs : &imgtool_ioprocs,
- "", format, FLOPPY_FLAGS_READWRITE, &fimg->floppy);
+ ferr = floppy_open(imgtool::stream_read_write(std::move(stream), 0xff), "", format, FLOPPY_FLAGS_READWRITE, &fimg->floppy);
if (ferr)
{
err = imgtool_floppy_error(ferr);
goto done;
}
- f = nullptr; // the floppy object has the stream now
if (open)
{
@@ -138,8 +86,6 @@ static imgtoolerr_t imgtool_floppy_open_internal(imgtool::image &image, imgtool:
}
done:
- if (f)
- delete f;
if (err && fimg->floppy)
{
floppy_close(fimg->floppy);
@@ -152,7 +98,7 @@ done:
static imgtoolerr_t imgtool_floppy_open(imgtool::image &image, imgtool::stream::ptr &&stream)
{
- return imgtool_floppy_open_internal(image, std::move(stream), false);
+ return imgtool_floppy_open_internal(image, std::move(stream));
}
@@ -161,7 +107,6 @@ static imgtoolerr_t imgtool_floppy_create(imgtool::image &image, imgtool::stream
{
floperr_t ferr;
imgtoolerr_t err = IMGTOOLERR_SUCCESS;
- imgtool::stream *f = nullptr;
struct imgtool_floppy_image *fimg;
const imgtool_class *imgclass;
const struct FloppyFormat *format;
@@ -174,17 +119,13 @@ static imgtoolerr_t imgtool_floppy_create(imgtool::image &image, imgtool::stream
create = (imgtoolerr_t (*)(imgtool::image &, imgtool::stream *, util::option_resolution *)) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_FLOPPY_CREATE);
open = (imgtoolerr_t (*)(imgtool::image &, imgtool::stream *)) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_FLOPPY_OPEN);
- // extract the pointer
- f = stream.release();
-
// open up the floppy
- ferr = floppy_create(f, &imgtool_ioprocs, format, opts, &fimg->floppy);
+ ferr = floppy_create(imgtool::stream_read_write(std::move(stream), 0xff), format, opts, &fimg->floppy);
if (ferr)
{
err = imgtool_floppy_error(ferr);
goto done;
}
- f = nullptr; // the floppy object has the stream now
// do we have to do extra stuff when creating the image?
if (create)
@@ -203,8 +144,6 @@ static imgtoolerr_t imgtool_floppy_create(imgtool::image &image, imgtool::stream
}
done:
- if (f)
- delete f;
if (err && fimg->floppy)
{
floppy_close(fimg->floppy);
diff --git a/src/tools/imgtool/iflopimg.h b/src/tools/imgtool/iflopimg.h
index 078a1247ae3..d27ba952e16 100644
--- a/src/tools/imgtool/iflopimg.h
+++ b/src/tools/imgtool/iflopimg.h
@@ -7,13 +7,16 @@
Bridge code for Imgtool into the standard floppy code
*********************************************************************/
+#ifndef MAME_TOOLS_IMGTOOL_IFLOPIMG_H
+#define MAME_TOOLS_IMGTOOL_IFLOPIMG_H
-#ifndef IFLOPIMG_H
-#define IFLOPIMG_H
+#pragma once
-#include "formats/flopimg.h"
#include "library.h"
+#include "formats/flopimg.h"
+
+
/***************************************************************************
Prototypes
@@ -38,4 +41,4 @@ imgtoolerr_t imgtool_floppy_write_sector_from_stream(imgtool::image &img, int he
void *imgtool_floppy_extrabytes(imgtool::image &img);
-#endif /* IFLOPIMG_H */
+#endif // MAME_TOOLS_IMGTOOL_IFLOPIMG_H
diff --git a/src/tools/imgtool/imghd.cpp b/src/tools/imgtool/imghd.cpp
index 45ac262a9ba..8e077295b93 100644
--- a/src/tools/imgtool/imghd.cpp
+++ b/src/tools/imgtool/imghd.cpp
@@ -9,34 +9,21 @@
Raphael Nabet 2003
*/
+#include "imghd.h"
#include "imgtool.h"
#include "harddisk.h"
-#include "imghd.h"
-static imgtoolerr_t map_chd_error(chd_error chderr)
+static imgtoolerr_t map_chd_error(std::error_condition chderr)
{
- imgtoolerr_t err;
-
- switch(chderr)
- {
- case CHDERR_NONE:
- err = IMGTOOLERR_SUCCESS;
- break;
- case CHDERR_OUT_OF_MEMORY:
- err = IMGTOOLERR_OUTOFMEMORY;
- break;
- case CHDERR_FILE_NOT_WRITEABLE:
- err = IMGTOOLERR_READONLY;
- break;
- case CHDERR_NOT_SUPPORTED:
- err = IMGTOOLERR_UNIMPLEMENTED;
- break;
- default:
- err = IMGTOOLERR_UNEXPECTED;
- break;
- }
- return err;
+ if (!chderr)
+ return IMGTOOLERR_SUCCESS;
+ else if (std::errc::not_enough_memory == chderr)
+ return IMGTOOLERR_OUTOFMEMORY;
+ else if (chd_file::error::FILE_NOT_WRITEABLE == chderr)
+ return IMGTOOLERR_READONLY;
+ else
+ return IMGTOOLERR_UNEXPECTED;
}
@@ -50,7 +37,7 @@ imgtoolerr_t imghd_create(imgtool::stream &stream, uint32_t hunksize, uint32_t c
{
imgtoolerr_t err = IMGTOOLERR_SUCCESS;
chd_file chd;
- chd_error rc;
+ std::error_condition rc;
chd_codec_type compression[4] = { CHD_CODEC_NONE };
/* sanity check args -- see parse_hunk_size() in src/lib/util/chd.cpp */
@@ -73,8 +60,8 @@ imgtoolerr_t imghd_create(imgtool::stream &stream, uint32_t hunksize, uint32_t c
const uint64_t logicalbytes = (uint64_t)cylinders * heads * sectors * seclen;
/* create the new hard drive */
- rc = chd.create(*stream.core_file(), logicalbytes, hunksize, seclen, compression);
- if (rc != CHDERR_NONE)
+ rc = chd.create(stream_read_write(stream, 0), logicalbytes, hunksize, seclen, compression);
+ if (rc)
{
err = map_chd_error(rc);
return err;
@@ -82,8 +69,8 @@ imgtoolerr_t imghd_create(imgtool::stream &stream, uint32_t hunksize, uint32_t c
/* write the metadata */
const std::string metadata = util::string_format(HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, seclen);
- err = (imgtoolerr_t)chd.write_metadata(HARD_DISK_METADATA_TAG, 0, metadata);
- if (rc != CHDERR_NONE)
+ rc = chd.write_metadata(HARD_DISK_METADATA_TAG, 0, metadata);
+ if (rc)
{
err = map_chd_error(rc);
return err;
@@ -118,12 +105,12 @@ imgtoolerr_t imghd_create(imgtool::stream &stream, uint32_t hunksize, uint32_t c
*/
imgtoolerr_t imghd_open(imgtool::stream &stream, struct mess_hard_disk_file *hard_disk)
{
- chd_error chderr;
+ std::error_condition chderr;
imgtoolerr_t err = IMGTOOLERR_SUCCESS;
hard_disk->hard_disk = nullptr;
- chderr = hard_disk->chd.open(*stream.core_file(), !stream.is_read_only());
+ chderr = hard_disk->chd.open(stream_read_write(stream, 0), !stream.is_read_only());
if (chderr)
{
err = map_chd_error(chderr);
@@ -174,9 +161,8 @@ void imghd_close(struct mess_hard_disk_file *disk)
*/
imgtoolerr_t imghd_read(struct mess_hard_disk_file *disk, uint32_t lbasector, void *buffer)
{
- uint32_t reply;
- reply = hard_disk_read(disk->hard_disk, lbasector, buffer);
- return (imgtoolerr_t)(reply ? IMGTOOLERR_SUCCESS : map_chd_error((chd_error)reply));
+ uint32_t reply = hard_disk_read(disk->hard_disk, lbasector, buffer);
+ return reply ? IMGTOOLERR_SUCCESS : IMGTOOLERR_READERROR;
}
@@ -188,9 +174,8 @@ imgtoolerr_t imghd_read(struct mess_hard_disk_file *disk, uint32_t lbasector, vo
*/
imgtoolerr_t imghd_write(struct mess_hard_disk_file *disk, uint32_t lbasector, const void *buffer)
{
- uint32_t reply;
- reply = hard_disk_write(disk->hard_disk, lbasector, buffer);
- return (imgtoolerr_t)(reply ? IMGTOOLERR_SUCCESS : map_chd_error((chd_error)reply));
+ uint32_t reply = hard_disk_write(disk->hard_disk, lbasector, buffer);
+ return reply ? IMGTOOLERR_SUCCESS : IMGTOOLERR_WRITEERROR;
}
diff --git a/src/tools/imgtool/imghd.h b/src/tools/imgtool/imghd.h
index d4ae341af1e..0eadc6e2eb3 100644
--- a/src/tools/imgtool/imghd.h
+++ b/src/tools/imgtool/imghd.h
@@ -11,8 +11,11 @@
#ifndef IMGHD_H
#define IMGHD_H
+#include "stream.h"
+
#include "harddisk.h"
+
struct mess_hard_disk_file
{
imgtool::stream *stream;
diff --git a/src/tools/imgtool/imgtool.cpp b/src/tools/imgtool/imgtool.cpp
index 841147ae26e..ce4dd22d186 100644
--- a/src/tools/imgtool/imgtool.cpp
+++ b/src/tools/imgtool/imgtool.cpp
@@ -8,14 +8,18 @@
***************************************************************************/
+#include "imgtool.h"
+#include "library.h"
+#include "modules.h"
+
+#include "formats/imageutl.h"
+
+#include "corefile.h"
+
#include <cstring>
#include <cctype>
#include <iostream>
-#include "imgtool.h"
-#include "formats/imageutl.h"
-#include "library.h"
-#include "modules.h"
/***************************************************************************
diff --git a/src/tools/imgtool/library.h b/src/tools/imgtool/library.h
index 7406cc2e526..f0e0532e502 100644
--- a/src/tools/imgtool/library.h
+++ b/src/tools/imgtool/library.h
@@ -4,29 +4,31 @@
library.h
- Code relevant to the Imgtool library; analogous to the MESS/MAME driver
- list.
+ Code relevant to the Imgtool library; analogous to the MAME driver list.
- Unlike MESS and MAME which have static driver lists, Imgtool has a
- concept of a library and this library is built at startup time.
+ Unlike MAME which has a static driver lists, Imgtool has a concept of a
+ library and this library is built at startup time.
dynamic for which modules are added to. This makes "dynamic" modules
much easier
****************************************************************************/
+#ifndef MAME_TOOLS_IMGTOOL_LIBRARY_H
+#define MAME_TOOLS_IMGTOOL_LIBRARY_H
-#ifndef LIBRARY_H
-#define LIBRARY_H
+#pragma once
-#include <ctime>
-#include <list>
-#include <chrono>
+#include "charconv.h"
+#include "stream.h"
#include "corestr.h"
#include "opresolv.h"
-#include "stream.h"
-#include "unicode.h"
-#include "charconv.h"
#include "timeconv.h"
+#include "unicode.h"
+
+#include <chrono>
+#include <ctime>
+#include <list>
+
namespace imgtool
{
@@ -542,4 +544,4 @@ private:
} // namespace imgtool
-#endif // LIBRARY_H
+#endif // MAME_TOOLS_IMGTOOL_LIBRARY_H
diff --git a/src/tools/imgtool/main.cpp b/src/tools/imgtool/main.cpp
index 75fcd52e7a2..77b3d8c6874 100644
--- a/src/tools/imgtool/main.cpp
+++ b/src/tools/imgtool/main.cpp
@@ -11,6 +11,8 @@
#include "imgtool.h"
#include "main.h"
#include "modules.h"
+
+#include "corefile.h"
#include "strformat.h"
#include <cstdio>
diff --git a/src/tools/imgtool/modules/hp85_tape.cpp b/src/tools/imgtool/modules/hp85_tape.cpp
index 0198b6251dd..fa32042efd3 100644
--- a/src/tools/imgtool/modules/hp85_tape.cpp
+++ b/src/tools/imgtool/modules/hp85_tape.cpp
@@ -7,12 +7,16 @@
HP-85 tape format
*********************************************************************/
-
#include "imgtool.h"
-#include "formats/imageutl.h"
+
#include "formats/hti_tape.h"
+#include "formats/imageutl.h"
+
+#include "ioprocs.h"
+
#include <iostream>
+
// Constants
static constexpr unsigned CHARS_PER_FNAME = 6; // Characters in a filename
static constexpr unsigned CHARS_PER_EXT = 4; // Characters in (simulated) file extension
@@ -158,48 +162,13 @@ void tape_image_85::format_img(void)
finalize_allocation();
}
-namespace {
- int my_seekproc(void *file, int64_t offset, int whence)
- {
- reinterpret_cast<imgtool::stream *>(file)->seek(offset, whence);
- return 0;
- }
-
- size_t my_readproc(void *file, void *buffer, size_t length)
- {
- return reinterpret_cast<imgtool::stream *>(file)->read(buffer, length);
- }
-
- size_t my_writeproc(void *file, const void *buffer, size_t length)
- {
- reinterpret_cast<imgtool::stream *>(file)->write(buffer, length);
- return length;
- }
-
- uint64_t my_filesizeproc(void *file)
- {
- return reinterpret_cast<imgtool::stream *>(file)->size();
- }
-
- const struct io_procs my_stream_procs = {
- nullptr,
- my_seekproc,
- my_readproc,
- my_writeproc,
- my_filesizeproc
- };
-}
-
imgtoolerr_t tape_image_85::load_from_file(imgtool::stream *stream)
{
- io_generic io;
- io.file = (void *)stream;
- io.procs = &my_stream_procs;
- io.filler = 0;
-
- if (!image.load_tape(&io)) {
+ auto io = imgtool::stream_read(*stream, 0);
+ if (!io || !image.load_tape(*io)) {
return IMGTOOLERR_READERROR;
}
+ io.reset();
// Prevent track boundary crossing when reading directory
file_track_1 = 0;
@@ -422,12 +391,7 @@ imgtoolerr_t tape_image_85::save_to_file(imgtool::stream *stream)
file_0.clear();
save_sif_file(track , pos , dir.size() + 1 , file_0);
- io_generic io;
- io.file = (void *)stream;
- io.procs = &my_stream_procs;
- io.filler = 0;
-
- image.save_tape(&io);
+ image.save_tape(*imgtool::stream_read_write(*stream, 0));
return IMGTOOLERR_SUCCESS;
}
diff --git a/src/tools/imgtool/modules/hp9845_tape.cpp b/src/tools/imgtool/modules/hp9845_tape.cpp
index 7a3e90b08d1..a1ae0377180 100644
--- a/src/tools/imgtool/modules/hp9845_tape.cpp
+++ b/src/tools/imgtool/modules/hp9845_tape.cpp
@@ -108,11 +108,16 @@
these special characters.
*********************************************************************/
-#include <bitset>
-
#include "imgtool.h"
-#include "formats/imageutl.h"
+
#include "formats/hti_tape.h"
+#include "formats/imageutl.h"
+
+#include "corefile.h"
+#include "ioprocs.h"
+
+#include <bitset>
+
// Constants
#define SECTOR_LEN 256 // Bytes in a sector
@@ -291,49 +296,16 @@ void tape_image_t::format_img(void)
dirty = true;
}
-static int my_seekproc(void *file, int64_t offset, int whence)
-{
- reinterpret_cast<imgtool::stream *>(file)->seek(offset, whence);
- return 0;
-}
-
-static size_t my_readproc(void *file, void *buffer, size_t length)
-{
- return reinterpret_cast<imgtool::stream *>(file)->read(buffer, length);
-}
-
-static size_t my_writeproc(void *file, const void *buffer, size_t length)
-{
- reinterpret_cast<imgtool::stream *>(file)->write(buffer, length);
- return length;
-}
-
-static uint64_t my_filesizeproc(void *file)
-{
- return reinterpret_cast<imgtool::stream *>(file)->size();
-}
-
-static const struct io_procs my_stream_procs = {
- nullptr,
- my_seekproc,
- my_readproc,
- my_writeproc,
- my_filesizeproc
-};
-
imgtoolerr_t tape_image_t::load_from_file(imgtool::stream *stream)
{
hti_format_t inp_image;
inp_image.set_image_format(hti_format_t::HTI_DELTA_MOD_16_BITS);
- io_generic io;
- io.file = (void *)stream;
- io.procs = &my_stream_procs;
- io.filler = 0;
-
- if (!inp_image.load_tape(&io)) {
+ auto io = imgtool::stream_read(*stream, 0);
+ if (!io || !inp_image.load_tape(*io)) {
return IMGTOOLERR_READERROR;
}
+ io.reset();
unsigned exp_sector = 0;
unsigned last_sector_on_track = SECTORS_PER_TRACK;
@@ -523,12 +495,7 @@ imgtoolerr_t tape_image_t::save_to_file(imgtool::stream *stream)
}
}
- io_generic io;
- io.file = (void *)stream;
- io.procs = &my_stream_procs;
- io.filler = 0;
-
- out_image.save_tape(&io);
+ out_image.save_tape(*imgtool::stream_read_write(*stream, 0));
return IMGTOOLERR_SUCCESS;
}
diff --git a/src/tools/imgtool/stream.cpp b/src/tools/imgtool/stream.cpp
index bb0d95614f3..ed9814e504a 100644
--- a/src/tools/imgtool/stream.cpp
+++ b/src/tools/imgtool/stream.cpp
@@ -8,19 +8,178 @@
***************************************************************************/
+#include "stream.h"
+
+#include "imgtool.h"
+
+#include "corefile.h"
+#include "ioprocs.h"
+#include "unzip.h"
+
+#include <cassert>
#include <cstdio>
#include <cstring>
-#include <zlib.h>
-#include "unzip.h"
-#include "imgtool.h"
+#include <zlib.h> // for crc32
+
+
+namespace imgtool {
+
+namespace {
+
+class stream_read_wrapper : public virtual util::random_read
+{
+public:
+ stream_read_wrapper(stream::ptr &&stream, std::uint8_t filler) noexcept
+ : m_stream(stream.release())
+ , m_filler(filler)
+ , m_close(true)
+ {
+ assert(m_stream);
+ }
+
+ stream_read_wrapper(stream &stream, std::uint8_t filler) noexcept
+ : m_stream(&stream)
+ , m_filler(filler)
+ , m_close(false)
+ {
+ }
+
+ virtual ~stream_read_wrapper()
+ {
+ if (m_close)
+ delete m_stream;
+ }
+
+ virtual std::error_condition seek(std::int64_t offset, int whence) noexcept override
+ {
+ m_stream->seek(offset, whence);
+ return std::error_condition();
+ }
+
+ virtual std::error_condition tell(std::uint64_t &result) noexcept override
+ {
+ result = m_stream->tell();
+ return std::error_condition();
+ }
+
+ virtual std::error_condition length(std::uint64_t &result) noexcept override
+ {
+ result = m_stream->size();
+ return std::error_condition();
+ }
+
+ virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ actual = m_stream->read(buffer, length);
+ if (actual < length)
+ std::memset(reinterpret_cast<std::uint8_t *>(buffer) + actual, m_filler, length - actual);
+ return std::error_condition();
+ }
+
+ virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ std::uint64_t const pos = m_stream->tell();
+ m_stream->seek(offset, SEEK_SET);
+ actual = m_stream->read(buffer, length);
+ m_stream->seek(pos, SEEK_SET);
+ if (actual < length)
+ std::memset(reinterpret_cast<std::uint8_t *>(buffer) + actual, m_filler, length - actual);
+ return std::error_condition();
+ }
+
+protected:
+ stream *const m_stream;
+ std::uint8_t m_filler;
+ bool const m_close;
+};
+
+
+class stream_read_write_wrapper : public stream_read_wrapper, public util::random_read_write
+{
+public:
+ using stream_read_wrapper::stream_read_wrapper;
+
+ virtual std::error_condition finalize() noexcept override
+ {
+ return std::error_condition();
+ }
+
+ virtual std::error_condition flush() noexcept override
+ {
+ return std::error_condition();
+ }
+
+ virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ std::uint64_t const pos = m_stream->tell();
+ std::uint64_t size = m_stream->size();
+ if (size < pos)
+ {
+ m_stream->seek(size, SEEK_SET);
+ size += m_stream->fill(m_filler, pos - size);
+ }
+ actual = (size >= pos) ? m_stream->write(buffer, length) : 0U;
+ return (actual == length) ? std::error_condition() : std::errc::io_error;
+ }
+
+ virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ {
+ std::uint64_t const pos = m_stream->tell();
+ std::uint64_t size = m_stream->size();
+ if (offset > size)
+ {
+ m_stream->seek(size, SEEK_SET);
+ size += m_stream->fill(m_filler, offset - size);
+ }
+ else
+ {
+ m_stream->seek(offset, SEEK_SET);
+ }
+ actual = (size >= offset) ? m_stream->write(buffer, length) : 0U;
+ m_stream->seek(pos, SEEK_SET);
+ return (actual == length) ? std::error_condition() : std::errc::io_error;
+ }
+};
+
+} // anonymous namespace
+
+
+util::random_read::ptr stream_read(stream::ptr &&s, std::uint8_t filler) noexcept
+{
+ util::random_read::ptr result;
+ if (s)
+ result.reset(new (std::nothrow) stream_read_wrapper(std::move(s), filler));
+ return result;
+}
+
+util::random_read::ptr stream_read(stream &s, std::uint8_t filler) noexcept
+{
+ util::random_read::ptr result(new (std::nothrow) stream_read_wrapper(s, filler));
+ return result;
+}
+
+util::random_read_write::ptr stream_read_write(stream::ptr &&s, std::uint8_t filler) noexcept
+{
+ util::random_read_write::ptr result;
+ if (s)
+ result.reset(new (std::nothrow) stream_read_write_wrapper(std::move(s), filler));
+ return result;
+}
+
+util::random_read_write::ptr stream_read_write(stream &s, std::uint8_t filler) noexcept
+{
+ util::random_read_write::ptr result(new (std::nothrow) stream_read_write_wrapper(s, filler));
+ return result;
+}
+
//-------------------------------------------------
// ctor
//-------------------------------------------------
-imgtool::stream::stream(bool wp)
+stream::stream(bool wp)
: imgtype(IMG_FILE)
, write_protect(wp)
, position(0)
@@ -35,7 +194,7 @@ imgtool::stream::stream(bool wp)
// ctor
//-------------------------------------------------
-imgtool::stream::stream(bool wp, util::core_file::ptr &&f)
+stream::stream(bool wp, util::core_file::ptr &&f)
: imgtype(IMG_FILE)
, write_protect(wp)
, position(0)
@@ -50,7 +209,7 @@ imgtool::stream::stream(bool wp, util::core_file::ptr &&f)
// ctor
//-------------------------------------------------
-imgtool::stream::stream(bool wp, std::size_t size)
+stream::stream(bool wp, std::size_t size)
: imgtype(IMG_MEM)
, write_protect(wp)
, position(0)
@@ -65,7 +224,7 @@ imgtool::stream::stream(bool wp, std::size_t size)
// ctor
//-------------------------------------------------
-imgtool::stream::stream(bool wp, std::size_t size, void *buf)
+stream::stream(bool wp, std::size_t size, void *buf)
: imgtype(IMG_MEM)
, write_protect(wp)
, position(0)
@@ -80,7 +239,7 @@ imgtool::stream::stream(bool wp, std::size_t size, void *buf)
// dtor
//-------------------------------------------------
-imgtool::stream::~stream()
+stream::~stream()
{
if (buffer)
free(buffer);
@@ -91,39 +250,39 @@ imgtool::stream::~stream()
// open_zip
//-------------------------------------------------
-imgtool::stream::ptr imgtool::stream::open_zip(const std::string &zipname, const char *subname, int read_or_write)
+stream::ptr stream::open_zip(const std::string &zipname, const char *subname, int read_or_write)
{
if (read_or_write)
- return imgtool::stream::ptr();
+ return stream::ptr();
/* check to see if the file exists */
FILE *f = fopen(zipname.c_str(), "r");
if (!f)
- return imgtool::stream::ptr();
+ return stream::ptr();
fclose(f);
- imgtool::stream::ptr imgfile(new imgtool::stream(true));
+ stream::ptr imgfile(new stream(true));
imgfile->imgtype = IMG_MEM;
util::archive_file::ptr z;
util::archive_file::open_zip(zipname, z);
if (!z)
- return imgtool::stream::ptr();
+ return stream::ptr();
int zipent = z->first_file();
while ((zipent >= 0) && subname && strcmp(subname, z->current_name().c_str()))
zipent = z->next_file();
if (zipent < 0)
- return imgtool::stream::ptr();
+ return stream::ptr();
imgfile->filesize = z->current_uncompressed_length();
imgfile->buffer = reinterpret_cast<std::uint8_t *>(malloc(z->current_uncompressed_length()));
if (!imgfile->buffer)
- return imgtool::stream::ptr();
+ return stream::ptr();
- if (z->decompress(imgfile->buffer, z->current_uncompressed_length()) != util::archive_file::error::NONE)
- return imgtool::stream::ptr();
+ if (z->decompress(imgfile->buffer, z->current_uncompressed_length()))
+ return stream::ptr();
return imgfile;
}
@@ -134,7 +293,7 @@ imgtool::stream::ptr imgtool::stream::open_zip(const std::string &zipname, const
// open
//-------------------------------------------------
-imgtool::stream::ptr imgtool::stream::open(const std::string &filename, int read_or_write)
+stream::ptr stream::open(const std::string &filename, int read_or_write)
{
static const uint32_t write_modes[] =
{
@@ -143,7 +302,7 @@ imgtool::stream::ptr imgtool::stream::open(const std::string &filename, int read
OPEN_FLAG_READ | OPEN_FLAG_WRITE,
OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE
};
- imgtool::stream::ptr s;
+ stream::ptr s;
char c;
// maybe we are just a ZIP?
@@ -152,13 +311,13 @@ imgtool::stream::ptr imgtool::stream::open(const std::string &filename, int read
util::core_file::ptr f = nullptr;
auto const filerr = util::core_file::open(filename, write_modes[read_or_write], f);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
if (!read_or_write)
{
int const len = filename.size();
- /* can't open the file; try opening ZIP files with other names */
+ // can't open the file; try opening ZIP files with other names
std::vector<char> buf(len + 1);
strcpy(&buf[0], filename.c_str());
@@ -177,11 +336,11 @@ imgtool::stream::ptr imgtool::stream::open(const std::string &filename, int read
return s;
}
- /* ah well, it was worth a shot */
- return imgtool::stream::ptr();
+ // ah well, it was worth a shot
+ return stream::ptr();
}
- imgtool::stream::ptr imgfile(new imgtool::stream(read_or_write ? false : true, std::move(f)));
+ stream::ptr imgfile(new stream(read_or_write ? false : true, std::move(f)));
// normal file
return imgfile;
@@ -192,11 +351,11 @@ imgtool::stream::ptr imgtool::stream::open(const std::string &filename, int read
// open_write_stream
//-------------------------------------------------
-imgtool::stream::ptr imgtool::stream::open_write_stream(int size)
+stream::ptr stream::open_write_stream(int size)
{
- imgtool::stream::ptr imgfile(new imgtool::stream(false, size));
+ stream::ptr imgfile(new stream(false, size));
if (!imgfile->buffer)
- return imgtool::stream::ptr();
+ return stream::ptr();
return imgfile;
}
@@ -206,9 +365,9 @@ imgtool::stream::ptr imgtool::stream::open_write_stream(int size)
// open_mem
//-------------------------------------------------
-imgtool::stream::ptr imgtool::stream::open_mem(void *buf, size_t sz)
+stream::ptr stream::open_mem(void *buf, size_t sz)
{
- imgtool::stream::ptr imgfile(new imgtool::stream(false, sz, buf));
+ stream::ptr imgfile(new stream(false, sz, buf));
return imgfile;
}
@@ -218,7 +377,7 @@ imgtool::stream::ptr imgtool::stream::open_mem(void *buf, size_t sz)
// core_file
//-------------------------------------------------
-util::core_file *imgtool::stream::core_file()
+util::core_file *stream::core_file()
{
return (imgtype == IMG_FILE) ? file.get() : nullptr;
}
@@ -228,7 +387,7 @@ util::core_file *imgtool::stream::core_file()
// read
//-------------------------------------------------
-uint32_t imgtool::stream::read(void *buf, uint32_t sz)
+uint32_t stream::read(void *buf, uint32_t sz)
{
uint32_t result = 0;
@@ -262,7 +421,7 @@ uint32_t imgtool::stream::read(void *buf, uint32_t sz)
// write
//-------------------------------------------------
-uint32_t imgtool::stream::write(const void *buf, uint32_t sz)
+uint32_t stream::write(const void *buf, uint32_t sz)
{
void *new_buffer;
uint32_t result = 0;
@@ -317,7 +476,7 @@ uint32_t imgtool::stream::write(const void *buf, uint32_t sz)
// size
//-------------------------------------------------
-uint64_t imgtool::stream::size() const
+uint64_t stream::size() const
{
return filesize;
}
@@ -327,7 +486,7 @@ uint64_t imgtool::stream::size() const
// getptr
//-------------------------------------------------
-void *imgtool::stream::getptr()
+void *stream::getptr()
{
void *ptr;
@@ -349,7 +508,7 @@ void *imgtool::stream::getptr()
// seek
//-------------------------------------------------
-int imgtool::stream::seek(int64_t pos, int where)
+int stream::seek(int64_t pos, int where)
{
switch(where)
{
@@ -377,7 +536,7 @@ int imgtool::stream::seek(int64_t pos, int where)
// tell
//-------------------------------------------------
-uint64_t imgtool::stream::tell()
+uint64_t stream::tell()
{
return position;
}
@@ -387,7 +546,7 @@ uint64_t imgtool::stream::tell()
// transfer
//-------------------------------------------------
-uint64_t imgtool::stream::transfer(imgtool::stream &dest, imgtool::stream &source, uint64_t sz)
+uint64_t stream::transfer(stream &dest, stream &source, uint64_t sz)
{
uint64_t result = 0;
uint64_t readsz;
@@ -407,7 +566,7 @@ uint64_t imgtool::stream::transfer(imgtool::stream &dest, imgtool::stream &sourc
// transfer_all
//-------------------------------------------------
-uint64_t imgtool::stream::transfer_all(imgtool::stream &dest, imgtool::stream &source)
+uint64_t stream::transfer_all(stream &dest, stream &source)
{
return transfer(dest, source, source.size());
}
@@ -417,7 +576,7 @@ uint64_t imgtool::stream::transfer_all(imgtool::stream &dest, imgtool::stream &s
// crc
//-------------------------------------------------
-int imgtool::stream::crc(unsigned long *result)
+int stream::crc(unsigned long *result)
{
size_t sz;
void *ptr;
@@ -451,12 +610,12 @@ int imgtool::stream::crc(unsigned long *result)
// file_crc
//-------------------------------------------------
-int imgtool::stream::file_crc(const char *fname, unsigned long *result)
+int stream::file_crc(const char *fname, unsigned long *result)
{
int err;
- imgtool::stream::ptr f;
+ stream::ptr f;
- f = imgtool::stream::open(fname, OSD_FOPEN_READ);
+ f = stream::open(fname, OSD_FOPEN_READ);
if (!f)
return IMGTOOLERR_FILENOTFOUND;
@@ -469,7 +628,7 @@ int imgtool::stream::file_crc(const char *fname, unsigned long *result)
// fill
//-------------------------------------------------
-uint64_t imgtool::stream::fill(unsigned char b, uint64_t sz)
+uint64_t stream::fill(unsigned char b, uint64_t sz)
{
uint64_t outsz;
char buf[1024];
@@ -490,7 +649,7 @@ uint64_t imgtool::stream::fill(unsigned char b, uint64_t sz)
// is_read_only
//-------------------------------------------------
-bool imgtool::stream::is_read_only()
+bool stream::is_read_only()
{
return write_protect;
}
@@ -500,7 +659,7 @@ bool imgtool::stream::is_read_only()
// putc
//-------------------------------------------------
-uint32_t imgtool::stream::putc(char c)
+uint32_t stream::putc(char c)
{
return write(&c, 1);
}
@@ -510,7 +669,7 @@ uint32_t imgtool::stream::putc(char c)
// puts
//-------------------------------------------------
-uint32_t imgtool::stream::puts(const char *s)
+uint32_t stream::puts(const char *s)
{
return write(s, strlen(s));
}
@@ -520,7 +679,7 @@ uint32_t imgtool::stream::puts(const char *s)
// printf
//-------------------------------------------------
-uint32_t imgtool::stream::printf(const char *fmt, ...)
+uint32_t stream::printf(const char *fmt, ...)
{
va_list va;
char buf[256];
@@ -531,3 +690,5 @@ uint32_t imgtool::stream::printf(const char *fmt, ...)
return puts(buf);
}
+
+} // namespace imgtool
diff --git a/src/tools/imgtool/stream.h b/src/tools/imgtool/stream.h
index 73d0dcb494d..e7cfca9e425 100644
--- a/src/tools/imgtool/stream.h
+++ b/src/tools/imgtool/stream.h
@@ -7,78 +7,91 @@
Code for implementing Imgtool streams
***************************************************************************/
+#ifndef MAME_TOOLS_IMGTOOL_STREAM_H
+#define MAME_TOOLS_IMGTOOL_STREAM_H
-#ifndef STREAM_H
-#define STREAM_H
+#pragma once
#include "imgterrs.h"
-#include "corefile.h"
+
+#include "utilfwd.h"
+
#include "osdcomm.h"
-namespace imgtool
+#include <cstdint>
+#include <memory>
+#include <string>
+
+
+namespace imgtool {
+
+class stream
{
- class stream
+public:
+ typedef std::unique_ptr<stream> ptr;
+
+ ~stream();
+
+ static imgtool::stream::ptr open(const std::string &filename, int read_or_write); /* similar params to mame_fopen */
+ static imgtool::stream::ptr open_write_stream(int filesize);
+ static imgtool::stream::ptr open_mem(void *buf, size_t sz);
+
+ util::core_file *core_file();
+ uint32_t read(void *buf, uint32_t sz);
+ uint32_t write(const void *buf, uint32_t sz);
+ uint64_t size() const;
+ int seek(int64_t pos, int where);
+ uint64_t tell();
+ void *getptr();
+ uint32_t putc(char c);
+ uint32_t puts(const char *s);
+ uint32_t printf(const char *fmt, ...) ATTR_PRINTF(2, 3);
+
+ // transfers sz bytes from source to dest
+ static uint64_t transfer(imgtool::stream &dest, imgtool::stream &source, uint64_t sz);
+ static uint64_t transfer_all(imgtool::stream &dest, imgtool::stream &source);
+
+ // fills sz bytes with b
+ uint64_t fill(unsigned char b, uint64_t sz);
+
+ // returns the CRC of a file
+ int crc(unsigned long *result);
+ static int file_crc(const char *fname, unsigned long *result);
+
+ // returns whether a stream is read only or not
+ bool is_read_only();
+
+private:
+ enum imgtype_t
{
- public:
- typedef std::unique_ptr<stream> ptr;
-
- ~stream();
-
- static imgtool::stream::ptr open(const std::string &filename, int read_or_write); /* similar params to mame_fopen */
- static imgtool::stream::ptr open_write_stream(int filesize);
- static imgtool::stream::ptr open_mem(void *buf, size_t sz);
-
- util::core_file *core_file();
- uint32_t read(void *buf, uint32_t sz);
- uint32_t write(const void *buf, uint32_t sz);
- uint64_t size() const;
- int seek(int64_t pos, int where);
- uint64_t tell();
- void *getptr();
- uint32_t putc(char c);
- uint32_t puts(const char *s);
- uint32_t printf(const char *fmt, ...) ATTR_PRINTF(2, 3);
-
- // transfers sz bytes from source to dest
- static uint64_t transfer(imgtool::stream &dest, imgtool::stream &source, uint64_t sz);
- static uint64_t transfer_all(imgtool::stream &dest, imgtool::stream &source);
-
- // fills sz bytes with b
- uint64_t fill(unsigned char b, uint64_t sz);
-
- // returns the CRC of a file
- int crc(unsigned long *result);
- static int file_crc(const char *fname, unsigned long *result);
-
- // returns whether a stream is read only or not
- bool is_read_only();
-
- private:
- enum imgtype_t
- {
- IMG_FILE,
- IMG_MEM
- };
-
- imgtype_t imgtype;
- bool write_protect;
- std::uint64_t position;
- std::uint64_t filesize;
-
- util::core_file::ptr file;
- std::uint8_t *buffer;
-
- // ctors
- stream(bool wp);
- stream(bool wp, util::core_file::ptr &&f);
- stream(bool wp, std::size_t size);
- stream(bool wp, std::size_t size, void *buf);
-
- // private methods
- static stream::ptr open_zip(const std::string &zipname, const char *subname, int read_or_write);
+ IMG_FILE,
+ IMG_MEM
};
-}
+ imgtype_t imgtype;
+ bool write_protect;
+ std::uint64_t position;
+ std::uint64_t filesize;
+
+ std::unique_ptr<util::core_file> file;
+ std::uint8_t *buffer;
+
+ // ctors
+ stream(bool wp);
+ stream(bool wp, std::unique_ptr<util::core_file> &&f);
+ stream(bool wp, std::size_t size);
+ stream(bool wp, std::size_t size, void *buf);
+
+ // private methods
+ static stream::ptr open_zip(const std::string &zipname, const char *subname, int read_or_write);
+};
+
+
+std::unique_ptr<util::random_read> stream_read(stream::ptr &&s, std::uint8_t filler) noexcept;
+std::unique_ptr<util::random_read> stream_read(stream &s, std::uint8_t filler) noexcept;
+std::unique_ptr<util::random_read_write> stream_read_write(stream::ptr &&s, std::uint8_t filler) noexcept;
+std::unique_ptr<util::random_read_write> stream_read_write(stream &s, std::uint8_t filler) noexcept;
+} // namespace imgtool
-#endif /* STREAM_H */
+#endif // MAME_TOOLS_IMGTOOL_STREAM_H
diff --git a/src/tools/ldresample.cpp b/src/tools/ldresample.cpp
index a7dd165c2f9..f7c5fc8b923 100644
--- a/src/tools/ldresample.cpp
+++ b/src/tools/ldresample.cpp
@@ -8,17 +8,18 @@
****************************************************************************/
-#include <cstdio>
-#include <cctype>
-#include <cstdlib>
-#include <cmath>
-#include <new>
-#include <cassert>
+#include "avhuff.h"
#include "bitmap.h"
#include "chd.h"
-#include "avhuff.h"
#include "vbiparse.h"
+#include <cassert>
+#include <cctype>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <new>
+
//**************************************************************************
@@ -156,22 +157,22 @@ inline uint32_t sample_number_to_field(const movie_info &info, uint32_t samplenu
// information about it
//-------------------------------------------------
-static chd_error open_chd(chd_file &file, const char *filename, movie_info &info)
+static std::error_condition open_chd(chd_file &file, const char *filename, movie_info &info)
{
// open the file
- chd_error chderr = file.open(filename);
- if (chderr != CHDERR_NONE)
+ std::error_condition chderr = file.open(filename);
+ if (chderr)
{
- fprintf(stderr, "Error opening CHD file: %s\n", chd_file::error_string(chderr));
+ fprintf(stderr, "Error opening CHD file: %s\n", chderr.message().c_str());
return chderr;
}
// get the metadata
std::string metadata;
chderr = file.read_metadata(AV_METADATA_TAG, 0, metadata);
- if (chderr != CHDERR_NONE)
+ if (chderr)
{
- fprintf(stderr, "Error getting A/V metadata: %s\n", chd_file::error_string(chderr));
+ fprintf(stderr, "Error getting A/V metadata: %s\n", chderr.message().c_str());
return chderr;
}
@@ -180,7 +181,7 @@ static chd_error open_chd(chd_file &file, const char *filename, movie_info &info
if (sscanf(metadata.c_str(), AV_METADATA_FORMAT, &fps, &fpsfrac, &width, &height, &interlaced, &channels, &rate) != 7)
{
fprintf(stderr, "Improperly formatted metadata\n");
- return CHDERR_INVALID_DATA;
+ return chd_file::error::INVALID_METADATA;
}
// extract movie info
@@ -197,7 +198,7 @@ static chd_error open_chd(chd_file &file, const char *filename, movie_info &info
info.bitmap.resize(info.width, info.height);
info.lsound.resize(info.samplerate);
info.rsound.resize(info.samplerate);
- return CHDERR_NONE;
+ return std::error_condition();
}
@@ -205,28 +206,28 @@ static chd_error open_chd(chd_file &file, const char *filename, movie_info &info
// create_chd - create a new CHD file
//-------------------------------------------------
-static chd_error create_chd(chd_file_compressor &file, const char *filename, chd_file &source, const movie_info &info)
+static std::error_condition create_chd(chd_file_compressor &file, const char *filename, chd_file &source, const movie_info &info)
{
// create the file
chd_codec_type compression[4] = { CHD_CODEC_AVHUFF };
- chd_error chderr = file.create(filename, source.logical_bytes(), source.hunk_bytes(), source.unit_bytes(), compression);
- if (chderr != CHDERR_NONE)
+ std::error_condition chderr = file.create(filename, source.logical_bytes(), source.hunk_bytes(), source.unit_bytes(), compression);
+ if (chderr)
{
- fprintf(stderr, "Error creating new CHD file: %s\n", chd_file::error_string(chderr));
+ fprintf(stderr, "Error creating new CHD file: %s\n", chderr.message().c_str());
return chderr;
}
// clone the metadata
chderr = file.clone_all_metadata(source);
- if (chderr != CHDERR_NONE)
+ if (chderr)
{
- fprintf(stderr, "Error cloning metadata: %s\n", chd_file::error_string(chderr));
+ fprintf(stderr, "Error cloning metadata: %s\n", chderr.message().c_str());
return chderr;
}
// begin compressing
file.compress_begin();
- return CHDERR_NONE;
+ return std::error_condition();
}
@@ -248,8 +249,8 @@ static bool read_chd(chd_file &file, uint32_t field, movie_info &info, uint32_t
file.codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &avconfig);
// read the field
- chd_error chderr = file.read_hunk(field, nullptr);
- return (chderr == CHDERR_NONE);
+ std::error_condition chderr = file.read_hunk(field, nullptr);
+ return !chderr;
}
@@ -524,8 +525,8 @@ int main(int argc, char *argv[])
// open the source file
chd_file srcfile;
movie_info info;
- chd_error err = open_chd(srcfile, srcfilename, info);
- if (err != CHDERR_NONE)
+ std::error_condition err = open_chd(srcfile, srcfilename, info);
+ if (err)
{
fprintf(stderr, "Unable to open file '%s'\n", srcfilename);
return 1;
@@ -563,7 +564,7 @@ int main(int argc, char *argv[])
// loop over all the fields in the source file
double progress, ratio;
osd_ticks_t last_update = 0;
- while (dstfile.compress_continue(progress, ratio) == CHDERR_COMPRESSING)
+ while (dstfile.compress_continue(progress, ratio) == chd_file::error::COMPRESSING)
if (osd_ticks() - last_update > osd_ticks_per_second() / 4)
{
last_update = osd_ticks();
diff --git a/src/tools/ldverify.cpp b/src/tools/ldverify.cpp
index e8df214734c..bb95c3fbad4 100644
--- a/src/tools/ldverify.cpp
+++ b/src/tools/ldverify.cpp
@@ -8,18 +8,19 @@
****************************************************************************/
-#include <cstdio>
-#include <cstdlib>
-#include <cctype>
-#include <new>
-#include <cassert>
-#include "coretmpl.h"
-#include "aviio.h"
#include "avhuff.h"
+#include "aviio.h"
#include "bitmap.h"
#include "chd.h"
+#include "coretmpl.h"
#include "vbiparse.h"
+#include <cassert>
+#include <cctype>
+#include <cstdio>
+#include <cstdlib>
+#include <new>
+
//**************************************************************************
@@ -174,10 +175,10 @@ static void *open_chd(const char *filename, movie_info &info)
auto chd = new chd_file;
// open the file
- chd_error chderr = chd->open(filename);
- if (chderr != CHDERR_NONE)
+ std::error_condition chderr = chd->open(filename);
+ if (chderr)
{
- fprintf(stderr, "Error opening CHD file: %s\n", chd_file::error_string(chderr));
+ fprintf(stderr, "Error opening CHD file: %s\n", chderr.message().c_str());
delete chd;
return nullptr;
}
@@ -185,9 +186,9 @@ static void *open_chd(const char *filename, movie_info &info)
// get the metadata
std::string metadata;
chderr = chd->read_metadata(AV_METADATA_TAG, 0, metadata);
- if (chderr != CHDERR_NONE)
+ if (chderr)
{
- fprintf(stderr, "Error getting A/V metadata: %s\n", chd_file::error_string(chderr));
+ fprintf(stderr, "Error getting A/V metadata: %s\n", chderr.message().c_str());
delete chd;
return nullptr;
}
@@ -251,8 +252,8 @@ static int read_chd(void *file, int frame, bitmap_yuy16 &bitmap, int16_t *lsound
chdfile->codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &avconfig);
// read the frame
- chd_error chderr = chdfile->read_hunk(frame * interlace_factor + fieldnum, nullptr);
- if (chderr != CHDERR_NONE)
+ std::error_condition chderr = chdfile->read_hunk(frame * interlace_factor + fieldnum, nullptr);
+ if (chderr)
return false;
// account for samples read
diff --git a/src/tools/pngcmp.cpp b/src/tools/pngcmp.cpp
index 43fc9324a06..624023425af 100644
--- a/src/tools/pngcmp.cpp
+++ b/src/tools/pngcmp.cpp
@@ -73,15 +73,15 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img
bitmap_argb32 finalbitmap;
int width, height, maxwidth;
util::core_file::ptr file;
- osd_file::error filerr;
+ std::error_condition filerr;
util::png_error pngerr;
int error = 100;
/* open the source image */
filerr = util::core_file::open(imgfile1, OPEN_FLAG_READ, file);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
- printf("Could not open %s (%d)\n", imgfile1.c_str(), int(filerr));
+ printf("Could not open %s (%s)\n", imgfile1.c_str(), filerr.message().c_str());
goto error;
}
@@ -96,9 +96,9 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img
/* open the source image */
filerr = util::core_file::open(imgfile2, OPEN_FLAG_READ, file);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
- printf("Could not open %s (%d)\n", imgfile2.c_str(), int(filerr));
+ printf("Could not open %s (%s)\n", imgfile2.c_str(), filerr.message().c_str());
goto error;
}
@@ -171,9 +171,9 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img
/* write the final PNG */
filerr = util::core_file::open(outfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
- printf("Could not open %s (%d)\n", outfilename.c_str(), int(filerr));
+ printf("Could not open %s (%s)\n", outfilename.c_str(), filerr.message().c_str());
goto error;
}
pngerr = util::png_write_bitmap(*file, nullptr, finalbitmap, 0, nullptr);
diff --git a/src/tools/regrep.cpp b/src/tools/regrep.cpp
index a8877c54899..b0072accfab 100644
--- a/src/tools/regrep.cpp
+++ b/src/tools/regrep.cpp
@@ -239,7 +239,7 @@ int main(int argc, char *argv[])
/* read the template file into an astring */
std::string tempheader;
- if (util::core_file::load(tempfilename.c_str(), &buffer, bufsize) == osd_file::error::NONE)
+ if (!util::core_file::load(tempfilename.c_str(), &buffer, bufsize))
{
tempheader.assign((const char *)buffer, bufsize);
free(buffer);
@@ -569,7 +569,7 @@ static util::core_file::ptr create_file_and_output_header(std::string &filename,
util::core_file::ptr file;
/* create the indexfile */
- if (util::core_file::open(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, file) != osd_file::error::NONE)
+ if (util::core_file::open(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, file))
return util::core_file::ptr();
/* print a header */
@@ -730,7 +730,7 @@ static int compare_screenshots(summary_file *curfile)
if (curfile->status[listnum] == STATUS_SUCCESS)
{
std::string fullname;
- osd_file::error filerr;
+ std::error_condition filerr;
util::core_file::ptr file;
/* get the filename for the image */
@@ -740,7 +740,7 @@ static int compare_screenshots(summary_file *curfile)
filerr = util::core_file::open(fullname, OPEN_FLAG_READ, file);
/* if that failed, look in the old location */
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
/* get the filename for the image */
fullname = string_format("%s" PATH_SEPARATOR "snap" PATH_SEPARATOR "_%s.png", lists[listnum].dir, curfile->name);
@@ -750,7 +750,7 @@ static int compare_screenshots(summary_file *curfile)
}
/* if that worked, load the file */
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
{
util::png_read_bitmap(*file, bitmaps[listnum]);
file.reset();
@@ -838,7 +838,7 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir,
int width, height, maxwidth;
int bitmapcount = 0;
util::core_file::ptr file;
- osd_file::error filerr;
+ std::error_condition filerr;
util::png_error pngerr;
int error = -1;
int starty;
@@ -855,7 +855,7 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir,
/* open the source image */
filerr = util::core_file::open(tempname, OPEN_FLAG_READ, file);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
goto error;
/* load the source image */
@@ -926,7 +926,7 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir,
/* write the final PNG */
filerr = util::core_file::open(dstfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
goto error;
pngerr = util::png_write_bitmap(*file, nullptr, finalbitmap, 0, nullptr);
file.reset();
diff --git a/src/tools/romcmp.cpp b/src/tools/romcmp.cpp
index 4862f74a769..b65889c70a1 100644
--- a/src/tools/romcmp.cpp
+++ b/src/tools/romcmp.cpp
@@ -8,25 +8,20 @@
***************************************************************************/
+#include "hash.h"
+#include "path.h"
#include "unzip.h"
+
#include "osdfile.h"
#include "osdcomm.h"
-#include "hash.h"
#include <cstdarg>
#include <cstdlib>
+#include <memory>
#define MAX_FILES 1000
-#ifndef MAX_FILENAME_LEN
-#define MAX_FILENAME_LEN 255
-#endif
-
-#ifndef PATH_DELIM
-#define PATH_DELIM '/'
-#endif
-
/* compare modes when one file is twice as long as the other */
@@ -105,382 +100,383 @@ static void compatiblemodes(int mode,int *start,int *end)
struct fileinfo
{
- char name[MAX_FILENAME_LEN+1];
+ std::string name;
int size;
- unsigned char *buf; /* file is read in here */
+ std::unique_ptr<unsigned char []> buf; // file is read in here
int listed;
-};
-
-static fileinfo files[2][MAX_FILES];
-static float matchscore[MAX_FILES][MAX_FILES][TOTAL_MODES][TOTAL_MODES];
-static bool is_ascii_char(int ch)
-{
- return (ch >= 0x20 && ch < 0x7f) || (ch == '\n') || (ch == '\r') || (ch == '\t');
-}
-
-static void checkintegrity(const fileinfo *file, int side, bool all_hashes)
-{
- if (file->buf == nullptr) return;
-
- if (all_hashes)
+ static constexpr bool is_ascii_char(int ch)
{
- util::crc32_creator crc32;
- util::sha1_creator sha1;
- util::sum16_creator sum16;
- crc32.append(file->buf, file->size);
- sha1.append(file->buf, file->size);
- sum16.append(file->buf, file->size);
- printf("%-23s %-23s [0x%x] CRC(%s) SHA1(%s) SUM(%s)\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "", file->size,
- crc32.finish().as_string().c_str(), sha1.finish().as_string().c_str(), sum16.finish().as_string().c_str());
- side = 0;
+ return (ch >= 0x20 && ch < 0x7f) || (ch == '\n') || (ch == '\r') || (ch == '\t');
}
- /* check for bad data lines */
- unsigned mask0 = 0x0000;
- unsigned mask1 = 0xffff;
- bool is_ascii = true;
- for (unsigned i = 0; i < file->size; i += 2)
+ void checkintegrity(int side, bool all_hashes) const
{
- is_ascii = is_ascii && is_ascii_char(file->buf[i]);
- mask0 |= file->buf[i] << 8;
- mask1 &= (file->buf[i] << 8) | 0x00ff;
- if (i < file->size - 1)
+ if (!buf)
+ return;
+
+ if (all_hashes)
{
- is_ascii = is_ascii && is_ascii_char(file->buf[i+1]);
- mask0 |= file->buf[i+1];
- mask1 &= file->buf[i+1] | 0xff00;
+ util::crc32_creator crc32;
+ util::sha1_creator sha1;
+ util::sum16_creator sum16;
+ crc32.append(buf.get(), size);
+ sha1.append(buf.get(), size);
+ sum16.append(buf.get(), size);
+ printf("%-23s %-23s [0x%x] CRC(%s) SHA1(%s) SUM(%s)\n",
+ (side & 1) ? name.c_str() : "",
+ (side & 2) ? name.c_str() : "",
+ size,
+ crc32.finish().as_string().c_str(),
+ sha1.finish().as_string().c_str(),
+ sum16.finish().as_string().c_str());
+ side = 0;
}
- if (mask0 == 0xffff && mask1 == 0x0000) break;
- }
-
- if (is_ascii && mask0 == 0x7f7f && mask1 == 0)
- {
- printf("%-23s %-23s ASCII TEXT FILE\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- return;
- }
- if (mask0 != 0xffff || mask1 != 0x0000)
- {
- int fixedmask;
- int bits;
+ // check for bad data lines
+ unsigned mask0 = 0x0000;
+ unsigned mask1 = 0xffff;
- fixedmask = (~mask0 | mask1) & 0xffff;
+ bool is_ascii = true;
+ for (unsigned i = 0; i < size; i += 2)
+ {
+ is_ascii = is_ascii && is_ascii_char(buf[i]);
+ mask0 |= buf[i] << 8;
+ mask1 &= (buf[i] << 8) | 0x00ff;
+ if (i < size - 1)
+ {
+ is_ascii = is_ascii && is_ascii_char(buf[i+1]);
+ mask0 |= buf[i+1];
+ mask1 &= buf[i+1] | 0xff00;
+ }
+ if (mask0 == 0xffff && mask1 == 0x0000) break;
+ }
- if (((mask0 >> 8) & 0xff) == (mask0 & 0xff) && ((mask1 >> 8) & 0xff) == (mask1 & 0xff))
- bits = 8;
- else bits = 16;
+ if (is_ascii && mask0 == 0x7f7f && mask1 == 0)
+ {
+ printf("%-23s %-23s ASCII TEXT FILE\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ return;
+ }
- printf("%-23s %-23s FIXED BITS (", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- for (int i = 0; i < bits; i++)
+ if (mask0 != 0xffff || mask1 != 0x0000)
{
- if (~mask0 & 0x8000) printf("0");
- else if (mask1 & 0x8000) printf("1");
- else printf("x");
+ int fixedmask;
+ int bits;
- mask0 <<= 1;
- mask1 <<= 1;
- }
- printf(")\n");
+ fixedmask = (~mask0 | mask1) & 0xffff;
- /* if the file contains a fixed value, we don't need to do the other */
- /* validity checks */
- if (fixedmask == 0xffff || fixedmask == 0x00ff || fixedmask == 0xff00)
- return;
- }
+ if (((mask0 >> 8) & 0xff) == (mask0 & 0xff) && ((mask1 >> 8) & 0xff) == (mask1 & 0xff))
+ bits = 8;
+ else bits = 16;
- unsigned addrbit = 1;
- unsigned addrmirror = 0;
- while (addrbit <= file->size/2)
- {
- unsigned i = 0;
- for (i = 0; i < file->size; i++)
+ printf("%-23s %-23s FIXED BITS (", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ for (int i = 0; i < bits; i++)
+ {
+ if (~mask0 & 0x8000) printf("0");
+ else if (mask1 & 0x8000) printf("1");
+ else printf("x");
+
+ mask0 <<= 1;
+ mask1 <<= 1;
+ }
+ printf(")\n");
+
+ /* if the file contains a fixed value, we don't need to do the other */
+ /* validity checks */
+ if (fixedmask == 0xffff || fixedmask == 0x00ff || fixedmask == 0xff00)
+ return;
+ }
+
+ unsigned addrbit = 1;
+ unsigned addrmirror = 0;
+ while (addrbit <= size/2)
{
- if ((i ^ addrbit) < file->size && file->buf[i] != file->buf[i ^ addrbit]) break;
+ unsigned i = 0;
+ for (i = 0; i < size; i++)
+ {
+ if ((i ^ addrbit) < size && buf[i] != buf[i ^ addrbit]) break;
+ }
+
+ if (i == size)
+ addrmirror |= addrbit;
+
+ addrbit <<= 1;
}
- if (i == file->size)
- addrmirror |= addrbit;
+ if (addrmirror != 0)
+ {
+ if (addrmirror == size/2)
+ {
+ printf("%-23s %-23s 1ST AND 2ND HALF IDENTICAL\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ util::hash_collection hash;
+ hash.begin();
+ hash.buffer(buf.get(), size / 2);
+ hash.end();
+ printf("%-23s %-23s %s\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "", hash.attribute_string().c_str());
+ }
+ else
+ {
+ printf("%-23s %-23s BADADDR", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ for (int i = 0; i < 24; i++)
+ {
+ if (size <= (1<<(23-i))) printf(" ");
+ else if (addrmirror & 0x800000) printf("-");
+ else printf("x");
+ addrmirror <<= 1;
+ }
+ printf("\n");
+ }
+ return;
+ }
- addrbit <<= 1;
- }
+ unsigned sizemask = 1;
+ while (sizemask < size - 1)
+ sizemask = (sizemask << 1) | 1;
- if (addrmirror != 0)
- {
- if (addrmirror == file->size/2)
+ mask0 = 0x000000;
+ mask1 = sizemask;
+ for (unsigned i = 0; i < size; i++)
{
- printf("%-23s %-23s 1ST AND 2ND HALF IDENTICAL\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- util::hash_collection hash;
- hash.begin();
- hash.buffer(file->buf, file->size / 2);
- hash.end();
- printf("%-23s %-23s %s\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "", hash.attribute_string().c_str());
+ if (buf[i] != 0xff)
+ {
+ mask0 |= i;
+ mask1 &= i;
+ if (mask0 == sizemask && mask1 == 0x00) break;
+ }
}
- else
+
+ if (mask0 != sizemask || mask1 != 0x00)
{
- printf("%-23s %-23s BADADDR", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
+ printf("%-23s %-23s ", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
for (int i = 0; i < 24; i++)
{
- if (file->size <= (1<<(23-i))) printf(" ");
- else if (addrmirror & 0x800000) printf("-");
+ if (size <= (1<<(23-i))) printf(" ");
+ else if (~mask0 & 0x800000) printf("1");
+ else if (mask1 & 0x800000) printf("0");
else printf("x");
- addrmirror <<= 1;
+ mask0 <<= 1;
+ mask1 <<= 1;
}
- printf("\n");
+ printf(" = 0xFF\n");
+
+ return;
}
- return;
- }
- unsigned sizemask = 1;
- while (sizemask < file->size - 1)
- sizemask = (sizemask << 1) | 1;
- mask0 = 0x000000;
- mask1 = sizemask;
- for (unsigned i = 0; i < file->size; i++)
- {
- if (file->buf[i] != 0xff)
+ mask0 = 0x000000;
+ mask1 = sizemask;
+ for (unsigned i = 0; i < size; i++)
{
- mask0 |= i;
- mask1 &= i;
- if (mask0 == sizemask && mask1 == 0x00) break;
+ if (buf[i] != 0x00)
+ {
+ mask0 |= i;
+ mask1 &= i;
+ if (mask0 == sizemask && mask1 == 0x00) break;
+ }
}
- }
- if (mask0 != sizemask || mask1 != 0x00)
- {
- printf("%-23s %-23s ", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- for (int i = 0; i < 24; i++)
+ if (mask0 != sizemask || mask1 != 0x00)
{
- if (file->size <= (1<<(23-i))) printf(" ");
- else if (~mask0 & 0x800000) printf("1");
- else if (mask1 & 0x800000) printf("0");
- else printf("x");
- mask0 <<= 1;
- mask1 <<= 1;
- }
- printf(" = 0xFF\n");
-
- return;
- }
+ printf("%-23s %-23s ", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ for (int i = 0; i < 24; i++)
+ {
+ if (size <= (1<<(23-i))) printf(" ");
+ else if ((mask0 & 0x800000) == 0) printf("1");
+ else if (mask1 & 0x800000) printf("0");
+ else printf("x");
+ mask0 <<= 1;
+ mask1 <<= 1;
+ }
+ printf(" = 0x00\n");
+ return;
+ }
- mask0 = 0x000000;
- mask1 = sizemask;
- for (unsigned i = 0; i < file->size; i++)
- {
- if (file->buf[i] != 0x00)
+ mask0 = 0xff;
+ for (unsigned i = 0; i < size/4 && mask0 != 0x00; i++)
{
- mask0 |= i;
- mask1 &= i;
- if (mask0 == sizemask && mask1 == 0x00) break;
+ if (buf[ 2*i ] != 0x00) mask0 &= ~0x01;
+ if (buf[ 2*i ] != 0xff) mask0 &= ~0x02;
+ if (buf[ 2*i+1] != 0x00) mask0 &= ~0x04;
+ if (buf[ 2*i+1] != 0xff) mask0 &= ~0x08;
+ if (buf[size/2 + 2*i ] != 0x00) mask0 &= ~0x10;
+ if (buf[size/2 + 2*i ] != 0xff) mask0 &= ~0x20;
+ if (buf[size/2 + 2*i+1] != 0x00) mask0 &= ~0x40;
+ if (buf[size/2 + 2*i+1] != 0xff) mask0 &= ~0x80;
}
+
+ if (mask0 & 0x01) printf("%-23s %-23s 1ST HALF = 00xx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x02) printf("%-23s %-23s 1ST HALF = FFxx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x04) printf("%-23s %-23s 1ST HALF = xx00\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x08) printf("%-23s %-23s 1ST HALF = xxFF\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x10) printf("%-23s %-23s 2ND HALF = 00xx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x20) printf("%-23s %-23s 2ND HALF = FFxx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x40) printf("%-23s %-23s 2ND HALF = xx00\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x80) printf("%-23s %-23s 2ND HALF = xxFF\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
}
- if (mask0 != sizemask || mask1 != 0x00)
+ int usedbytes(int mode) const
{
- printf("%-23s %-23s ", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- for (int i = 0; i < 24; i++)
+ switch (mode)
{
- if (file->size <= (1<<(23-i))) printf(" ");
- else if ((mask0 & 0x800000) == 0) printf("1");
- else if (mask1 & 0x800000) printf("0");
- else printf("x");
- mask0 <<= 1;
- mask1 <<= 1;
+ case MODE_A:
+ case MODE_NIB1:
+ case MODE_NIB2:
+ return size;
+ case MODE_12:
+ case MODE_22:
+ case MODE_E:
+ case MODE_O:
+ return size / 2;
+ case MODE_14:
+ case MODE_24:
+ case MODE_34:
+ case MODE_44:
+ case MODE_E12:
+ case MODE_O12:
+ case MODE_E22:
+ case MODE_O22:
+ return size / 4;
+ default:
+ return 0;
}
- printf(" = 0x00\n");
-
- return;
}
- mask0 = 0xff;
- for (unsigned i = 0; i < file->size/4 && mask0 != 0x00; i++)
+ void basemultmask(int mode, int &base, int &mult, int &mask) const
{
- if (file->buf[ 2*i ] != 0x00) mask0 &= ~0x01;
- if (file->buf[ 2*i ] != 0xff) mask0 &= ~0x02;
- if (file->buf[ 2*i+1] != 0x00) mask0 &= ~0x04;
- if (file->buf[ 2*i+1] != 0xff) mask0 &= ~0x08;
- if (file->buf[file->size/2 + 2*i ] != 0x00) mask0 &= ~0x10;
- if (file->buf[file->size/2 + 2*i ] != 0xff) mask0 &= ~0x20;
- if (file->buf[file->size/2 + 2*i+1] != 0x00) mask0 &= ~0x40;
- if (file->buf[file->size/2 + 2*i+1] != 0xff) mask0 &= ~0x80;
- }
+ mult = 1;
+ if (mode >= MODE_E)
+ mult = 2;
- if (mask0 & 0x01) printf("%-23s %-23s 1ST HALF = 00xx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x02) printf("%-23s %-23s 1ST HALF = FFxx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x04) printf("%-23s %-23s 1ST HALF = xx00\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x08) printf("%-23s %-23s 1ST HALF = xxFF\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x10) printf("%-23s %-23s 2ND HALF = 00xx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x20) printf("%-23s %-23s 2ND HALF = FFxx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x40) printf("%-23s %-23s 2ND HALF = xx00\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x80) printf("%-23s %-23s 2ND HALF = xxFF\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
-}
-
-
-static int usedbytes(const fileinfo *file,int mode)
-{
- switch (mode)
- {
- case MODE_A:
- case MODE_NIB1:
- case MODE_NIB2:
- return file->size;
- case MODE_12:
- case MODE_22:
- case MODE_E:
- case MODE_O:
- return file->size / 2;
- case MODE_14:
- case MODE_24:
- case MODE_34:
- case MODE_44:
- case MODE_E12:
- case MODE_O12:
- case MODE_E22:
- case MODE_O22:
- return file->size / 4;
- default:
- return 0;
+ switch (mode)
+ {
+ case MODE_A:
+ case MODE_12:
+ case MODE_14:
+ case MODE_E:
+ case MODE_E12:
+ base = 0; mask = 0xff; break;
+ case MODE_NIB1:
+ base = 0; mask = 0x0f; break;
+ case MODE_NIB2:
+ base = 0; mask = 0xf0; break;
+ case MODE_O:
+ case MODE_O12:
+ base = 1; mask = 0xff; break;
+ case MODE_22:
+ case MODE_E22:
+ base = size / 2; mask = 0xff; break;
+ case MODE_O22:
+ base = 1 + size / 2; mask = 0xff; break;
+ case MODE_24:
+ base = size / 4; mask = 0xff; break;
+ case MODE_34:
+ base = 2*size / 4; mask = 0xff; break;
+ case MODE_44:
+ base = 3*size / 4; mask = 0xff; break;
+ }
}
-}
-
-static void basemultmask(const fileinfo *file,int mode,int *base,int *mult,int *mask)
-{
- *mult = 1;
- if (mode >= MODE_E) *mult = 2;
- switch (mode)
+ float compare(const fileinfo &file2, int mode1, int mode2) const
{
- case MODE_A:
- case MODE_12:
- case MODE_14:
- case MODE_E:
- case MODE_E12:
- *base = 0; *mask = 0xff; break;
- case MODE_NIB1:
- *base = 0; *mask = 0x0f; break;
- case MODE_NIB2:
- *base = 0; *mask = 0xf0; break;
- case MODE_O:
- case MODE_O12:
- *base = 1; *mask = 0xff; break;
- case MODE_22:
- case MODE_E22:
- *base = file->size / 2; *mask = 0xff; break;
- case MODE_O22:
- *base = 1 + file->size / 2; *mask = 0xff; break;
- case MODE_24:
- *base = file->size / 4; *mask = 0xff; break;
- case MODE_34:
- *base = 2*file->size / 4; *mask = 0xff; break;
- case MODE_44:
- *base = 3*file->size / 4; *mask = 0xff; break;
- }
-}
-
-static float filecompare(const fileinfo *file1,const fileinfo *file2,int mode1,int mode2)
-{
- int i;
- int match = 0;
- int size1,size2;
- int base1=0,base2=0,mult1=0,mult2=0,mask1=0,mask2=0;
+ if (!buf || !file2.buf)
+ return 0.0;
+ int const size1 = usedbytes(mode1);
+ int const size2 = file2.usedbytes(mode2);
- if (file1->buf == nullptr || file2->buf == nullptr) return 0.0;
+ if (size1 != size2)
+ return 0.0;
- size1 = usedbytes(file1,mode1);
- size2 = usedbytes(file2,mode2);
+ int base1=0, base2=0, mult1=0, mult2=0, mask1=0, mask2=0;
+ basemultmask(mode1, base1, mult1, mask1);
+ file2.basemultmask(mode2, base2, mult2, mask2);
- if (size1 != size2) return 0.0;
-
- basemultmask(file1,mode1,&base1,&mult1,&mask1);
- basemultmask(file2,mode2,&base2,&mult2,&mask2);
-
- if (mask1 == mask2)
- {
- if (mask1 == 0xff)
- {
- /* normal compare */
- for (i = 0;i < size1;i++)
- if (file1->buf[base1 + mult1 * i] == file2->buf[base2 + mult2 * i]) match++;
- }
- else
+ int match = 0;
+ if (mask1 == mask2)
{
- /* nibble compare, abort if other half is not empty */
- for (i = 0;i < size1;i++)
+ if (mask1 == 0xff)
+ {
+ // normal compare
+ for (int i = 0; i < size1; i++)
+ if (buf[base1 + mult1 * i] == file2.buf[base2 + mult2 * i]) match++;
+ }
+ else
{
- if (((file1->buf[base1 + mult1 * i] & ~mask1) != (0x00 & ~mask1) &&
- (file1->buf[base1 + mult1 * i] & ~mask1) != (0xff & ~mask1)) ||
- ((file2->buf[base1 + mult1 * i] & ~mask2) != (0x00 & ~mask2) &&
- (file2->buf[base1 + mult1 * i] & ~mask2) != (0xff & ~mask2)))
+ // nibble compare, abort if other half is not empty
+ for (int i = 0; i < size1; i++)
{
- match = 0;
- break;
+ if (((buf[base1 + mult1 * i] & ~mask1) != (0x00 & ~mask1) &&
+ (buf[base1 + mult1 * i] & ~mask1) != (0xff & ~mask1)) ||
+ ((file2.buf[base1 + mult1 * i] & ~mask2) != (0x00 & ~mask2) &&
+ (file2.buf[base1 + mult1 * i] & ~mask2) != (0xff & ~mask2)))
+ {
+ match = 0;
+ break;
+ }
+ if ((buf[base1 + mult1 * i] & mask1) == (file2.buf[base2 + mult2 * i] & mask2)) match++;
}
- if ((file1->buf[base1 + mult1 * i] & mask1) == (file2->buf[base2 + mult2 * i] & mask2)) match++;
}
}
- }
- return (float)match / size1;
-}
+ return float(match) / size1;
+ }
+ void readfile(const char *path)
+ {
+ std::string fullname(path ? path : "");
+ util::path_append(fullname, name);
-static void readfile(const char *path,fileinfo *file)
-{
- osd_file::error filerr;
- uint64_t filesize;
- uint32_t actual;
- char fullname[256];
- osd_file::ptr f;
+ buf.reset(new (std::nothrow) unsigned char [size]);
+ if (!buf)
+ {
+ printf("%s: out of memory!\n", name.c_str());
+ return;
+ }
- if (path)
- {
- char delim[2] = { PATH_DELIM, '\0' };
- strcpy(fullname,path);
- strcat(fullname,delim);
- }
- else fullname[0] = 0;
- strcat(fullname,file->name);
+ std::error_condition filerr;
+ osd_file::ptr f;
+ uint64_t filesize;
- if ((file->buf = (unsigned char *)malloc(file->size)) == nullptr)
- {
- printf("%s: out of memory!\n",file->name);
- return;
- }
+ filerr = osd_file::open(fullname, OPEN_FLAG_READ, f, filesize);
+ if (filerr)
+ {
+ printf("%s: error %s\n", fullname.c_str(), filerr.message().c_str());
+ return;
+ }
- filerr = osd_file::open(fullname, OPEN_FLAG_READ, f, filesize);
- if (filerr != osd_file::error::NONE)
- {
- printf("%s: error %d\n", fullname, int(filerr));
- return;
+ uint32_t actual;
+ filerr = f->read(buf.get(), 0, size, actual);
+ if (filerr)
+ {
+ printf("%s: error %s\n", fullname.c_str(), filerr.message().c_str());
+ return;
+ }
}
- filerr = f->read(file->buf, 0, file->size, actual);
- if (filerr != osd_file::error::NONE)
+ void free()
{
- printf("%s: error %d\n", fullname, int(filerr));
- return;
+ buf.reset();
}
-}
-
+};
-static void freefile(fileinfo *file)
-{
- free(file->buf);
- file->buf = nullptr;
-}
+static fileinfo files[2][MAX_FILES];
+static float matchscore[MAX_FILES][MAX_FILES][TOTAL_MODES][TOTAL_MODES];
-static void printname(const fileinfo *file1,const fileinfo *file2,float score,int mode1,int mode2)
+static void printname(const fileinfo *file1, const fileinfo *file2, float score, int mode1, int mode2)
{
- printf("%-12s %s %-12s %s ",file1 ? file1->name : "",modenames[mode1],file2 ? file2->name : "",modenames[mode2]);
+ printf(
+ "%-12s %s %-12s %s ",
+ file1 ? file1->name.c_str() : "",
+ modenames[mode1],
+ file2 ? file2->name.c_str() : "",
+ modenames[mode2]);
if (score == 0.0f) printf("NO MATCH\n");
else if (score == 1.0f) printf("IDENTICAL\n");
- else printf("%3.6f%%\n",(double) (score*100));
+ else printf("%3.6f%%\n", double(score*100));
}
@@ -496,24 +492,23 @@ static int load_files(int i, int *found, const char *path)
while ((d = dir->read()) != nullptr)
{
const char *d_name = d->name;
- char buf[255+1];
+ const std::string buf(util::path_concat(path, d_name)); // FIXME: is this even used for anything?
- sprintf(buf, "%s%c%s", path, PATH_DELIM, d_name);
if (d->type == osd::directory::entry::entry_type::FILE)
{
uint64_t size = d->size;
while (size && (size & 1) == 0) size >>= 1;
//if (size & ~1)
- // printf("%-23s %-23s ignored (not a ROM)\n",i ? "" : d_name,i ? d_name : "");
+ // printf("%-23s %-23s ignored (not a ROM)\n", i ? "" : d_name, i ? d_name : "");
//else
{
- strcpy(files[i][found[i]].name,d_name);
+ files[i][found[i]].name = d_name;
files[i][found[i]].size = d->size;
- readfile(path,&files[i][found[i]]);
+ files[i][found[i]].readfile(path);
files[i][found[i]].listed = 0;
if (found[i] >= MAX_FILES)
{
- printf("%s: max of %d files exceeded\n",path,MAX_FILES);
+ printf("%s: max of %d files exceeded\n", path, MAX_FILES);
break;
}
found[i]++;
@@ -522,15 +517,13 @@ static int load_files(int i, int *found, const char *path)
}
dir.reset();
}
-
- /* if not, try to open as a ZIP file */
else
{
+ /* if not, try to open as a ZIP file */
util::archive_file::ptr zip;
/* wasn't a directory, so try to open it as a zip file */
- if ((util::archive_file::open_zip(path, zip) != util::archive_file::error::NONE) &&
- (util::archive_file::open_7z(path, zip) != util::archive_file::error::NONE))
+ if (util::archive_file::open_zip(path, zip) && util::archive_file::open_7z(path, zip))
{
printf("Error, cannot open zip file '%s' !\n", path);
return 1;
@@ -552,26 +545,26 @@ static int load_files(int i, int *found, const char *path)
}
else
{
- fileinfo *file = &files[i][found[i]];
+ fileinfo &file = files[i][found[i]];
const char *delim = strrchr(zip->current_name().c_str(), '/');
if (delim)
- strcpy (file->name,delim+1);
+ file.name = delim + 1;
else
- strcpy(file->name,zip->current_name().c_str());
- file->size = zip->current_uncompressed_length();
- if ((file->buf = (unsigned char *)malloc(file->size)) == nullptr)
- printf("%s: out of memory!\n",file->name);
+ file.name = zip->current_name();
+ file.size = zip->current_uncompressed_length();
+ file.buf.reset(new (std::nothrow) unsigned char [file.size]);
+ if (!file.buf)
+ {
+ printf("%s: out of memory!\n", file.name.c_str());
+ }
else
{
- if (zip->decompress(file->buf, file->size) != util::archive_file::error::NONE)
- {
- free(file->buf);
- file->buf = nullptr;
- }
+ if (zip->decompress(file.buf.get(), file.size))
+ file.free();
}
- file->listed = 0;
+ file.listed = 0;
if (found[i] >= MAX_FILES)
{
printf("%s: max of %d files exceeded\n",path,MAX_FILES);
@@ -612,13 +605,8 @@ int CLIB_DECL main(int argc,char *argv[])
}
{
- int found[2];
- int i,j,mode1,mode2;
- int besti,bestj;
-
-
- found[0] = found[1] = 0;
- for (i = 0;i < 2;i++)
+ int found[2] = { 0, 0 };
+ for (int i = 0; i < 2; i++)
{
if (argc > i+1)
{
@@ -633,26 +621,26 @@ int CLIB_DECL main(int argc,char *argv[])
else
printf("%d files\n",found[0]);
- for (i = 0; i < 2; i++)
+ for (int i = 0; i < 2; i++)
{
- for (j = 0; j < found[i]; j++)
+ for (int j = 0; j < found[i]; j++)
{
- checkintegrity(&files[i][j], 1 << i, all_hashes);
+ files[i][j].checkintegrity(1 << i, all_hashes);
}
}
if (argc < 3)
{
- /* find duplicates in one dir */
- for (i = 0;i < found[0];i++)
+ // find duplicates in one dir
+ for (int i = 0;i < found[0];i++)
{
- for (j = i+1;j < found[0];j++)
+ for (int j = i+1;j < found[0];j++)
{
- for (mode1 = 0;mode1 < total_modes;mode1++)
+ for (int mode1 = 0;mode1 < total_modes;mode1++)
{
- for (mode2 = 0;mode2 < total_modes;mode2++)
+ for (int mode2 = 0;mode2 < total_modes;mode2++)
{
- if (filecompare(&files[0][i],&files[0][j],mode1,mode2) == 1.0f)
+ if (files[0][i].compare(files[0][j],mode1,mode2) == 1.0f)
printname(&files[0][i],&files[0][j],1.0,mode1,mode2);
}
}
@@ -661,40 +649,38 @@ int CLIB_DECL main(int argc,char *argv[])
}
else
{
- /* compare two dirs */
- for (i = 0;i < found[0];i++)
+ // compare two dirs
+ for (int i = 0;i < found[0];i++)
{
- for (j = 0;j < found[1];j++)
+ for (int j = 0;j < found[1];j++)
{
fprintf(stderr,"%2d%%\r",100*(i*found[1]+j)/(found[0]*found[1]));
- for (mode1 = 0;mode1 < total_modes;mode1++)
+ for (int mode1 = 0;mode1 < total_modes;mode1++)
{
- for (mode2 = 0;mode2 < total_modes;mode2++)
+ for (int mode2 = 0;mode2 < total_modes;mode2++)
{
- matchscore[i][j][mode1][mode2] = filecompare(&files[0][i],&files[1][j],mode1,mode2);
+ matchscore[i][j][mode1][mode2] = files[0][i].compare(files[1][j],mode1,mode2);
}
}
}
}
fprintf(stderr," \r");
+ int besti;
do
{
- float bestscore;
- int bestmode1,bestmode2;
-
besti = -1;
- bestj = -1;
- bestscore = 0.0;
- bestmode1 = bestmode2 = -1;
+ int bestj = -1;
+ float bestscore = 0.0;
+ int bestmode1 = -1, bestmode2 = -1;
- for (mode1 = 0;mode1 < total_modes;mode1++)
+ for (int mode1 = 0;mode1 < total_modes;mode1++)
{
- for (mode2 = 0;mode2 < total_modes;mode2++)
+ for (int mode2 = 0;mode2 < total_modes;mode2++)
{
- for (i = 0;i < found[0];i++)
+ for (int i = 0;i < found[0];i++)
{
- for (j = 0;j < found[1];j++)
+ for (int j = 0;j < found[1];j++)
{
if (matchscore[i][j][mode1][mode2] > bestscore
|| (matchscore[i][j][mode1][mode2] == 1.0f && mode2 == 0 && bestmode2 > 0))
@@ -721,17 +707,17 @@ int CLIB_DECL main(int argc,char *argv[])
matchscore[besti][bestj][bestmode1][bestmode2] = 0.0;
/* remove all matches using the same sections with a worse score */
- for (j = 0;j < found[1];j++)
+ for (int j = 0;j < found[1];j++)
{
- for (mode2 = 0;mode2 < total_modes;mode2++)
+ for (int mode2 = 0;mode2 < total_modes;mode2++)
{
if (matchscore[besti][j][bestmode1][mode2] < bestscore)
matchscore[besti][j][bestmode1][mode2] = 0.0;
}
}
- for (i = 0;i < found[0];i++)
+ for (int i = 0;i < found[0];i++)
{
- for (mode1 = 0;mode1 < total_modes;mode1++)
+ for (int mode1 = 0;mode1 < total_modes;mode1++)
{
if (matchscore[i][bestj][mode1][bestmode2] < bestscore)
matchscore[i][bestj][mode1][bestmode2] = 0.0;
@@ -740,49 +726,50 @@ int CLIB_DECL main(int argc,char *argv[])
/* remove all matches using incompatible sections */
compatiblemodes(bestmode1,&start,&end);
- for (j = 0;j < found[1];j++)
+ for (int j = 0;j < found[1];j++)
{
- for (mode2 = 0;mode2 < total_modes;mode2++)
+ for (int mode2 = 0;mode2 < total_modes;mode2++)
{
- for (mode1 = 0;mode1 < start;mode1++)
+ for (int mode1 = 0;mode1 < start;mode1++)
matchscore[besti][j][mode1][mode2] = 0.0;
- for (mode1 = end+1;mode1 < total_modes;mode1++)
+ for (int mode1 = end+1;mode1 < total_modes;mode1++)
matchscore[besti][j][mode1][mode2] = 0.0;
}
}
compatiblemodes(bestmode2,&start,&end);
- for (i = 0;i < found[0];i++)
+ for (int i = 0;i < found[0];i++)
{
- for (mode1 = 0;mode1 < total_modes;mode1++)
+ for (int mode1 = 0;mode1 < total_modes;mode1++)
{
- for (mode2 = 0;mode2 < start;mode2++)
+ for (int mode2 = 0;mode2 < start;mode2++)
matchscore[i][bestj][mode1][mode2] = 0.0;
- for (mode2 = end+1;mode2 < total_modes;mode2++)
+ for (int mode2 = end+1;mode2 < total_modes;mode2++)
matchscore[i][bestj][mode1][mode2] = 0.0;
}
}
}
- } while (besti != -1);
+ }
+ while (besti != -1);
- for (i = 0;i < found[0];i++)
+ for (int i = 0;i < found[0];i++)
{
if (files[0][i].listed == 0) printname(&files[0][i],nullptr,0.0,0,0);
}
- for (i = 0;i < found[1];i++)
+ for (int i = 0;i < found[1];i++)
{
if (files[1][i].listed == 0) printname(nullptr,&files[1][i],0.0,0,0);
}
}
- for (i = 0;i < found[0];i++)
+ for (int i = 0;i < found[0];i++)
{
- freefile(&files[0][i]);
+ files[0][i].free();
}
- for (i = 0;i < found[1];i++)
+ for (int i = 0;i < found[1];i++)
{
- freefile(&files[1][i]);
+ files[1][i].free();
}
}
diff --git a/src/tools/split.cpp b/src/tools/split.cpp
index f8a8eb79234..24953c3d7cd 100644
--- a/src/tools/split.cpp
+++ b/src/tools/split.cpp
@@ -66,7 +66,7 @@ static int split_file(const char *filename, const char *basename, uint32_t split
void *splitbuffer = nullptr;
int index, partnum;
uint64_t totallength;
- osd_file::error filerr;
+ std::error_condition filerr;
int error = 1;
// convert split size to MB
@@ -79,7 +79,7 @@ static int split_file(const char *filename, const char *basename, uint32_t split
// open the file for read
filerr = util::core_file::open(filename, OPEN_FLAG_READ, infile);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
fprintf(stderr, "Fatal error: unable to open file '%s'\n", filename);
goto cleanup;
@@ -117,7 +117,7 @@ static int split_file(const char *filename, const char *basename, uint32_t split
// create the split file
filerr = util::core_file::open(splitfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, splitfile);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
fprintf(stderr, "Fatal error: unable to create split file '%s'\n", splitfilename.c_str());
goto cleanup;
@@ -153,7 +153,7 @@ static int split_file(const char *filename, const char *basename, uint32_t split
// create it
filerr = util::core_file::open(outfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
printf("\n");
fprintf(stderr, "Fatal error: unable to create output file '%s'\n", outfilename.c_str());
@@ -216,7 +216,7 @@ static int join_file(const char *filename, const char *outname, int write_output
std::string basepath;
util::core_file::ptr outfile, infile, splitfile;
void *splitbuffer = nullptr;
- osd_file::error filerr;
+ std::error_condition filerr;
uint32_t splitsize;
char buffer[256];
int error = 1;
@@ -224,7 +224,7 @@ static int join_file(const char *filename, const char *outname, int write_output
// open the file for read
filerr = util::core_file::open(filename, OPEN_FLAG_READ, splitfile);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
fprintf(stderr, "Fatal error: unable to open file '%s'\n", filename);
goto cleanup;
@@ -264,7 +264,7 @@ static int join_file(const char *filename, const char *outname, int write_output
{
// don't overwrite the original!
filerr = util::core_file::open(outfilename, OPEN_FLAG_READ, outfile);
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
{
outfile.reset();
fprintf(stderr, "Fatal error: output file '%s' already exists\n", outfilename.c_str());
@@ -273,7 +273,7 @@ static int join_file(const char *filename, const char *outname, int write_output
// open the output for write
filerr = util::core_file::open(outfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
fprintf(stderr, "Fatal error: unable to create file '%s'\n", outfilename.c_str());
goto cleanup;
@@ -301,7 +301,7 @@ static int join_file(const char *filename, const char *outname, int write_output
// read the file's contents
infilename.insert(0, basepath);
filerr = util::core_file::load(infilename.c_str(), &splitbuffer, length);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
{
printf("\n");
fprintf(stderr, "Fatal error: unable to load file '%s'\n", infilename.c_str());
diff --git a/src/tools/srcclean.cpp b/src/tools/srcclean.cpp
index 052d2a37334..340217c7768 100644
--- a/src/tools/srcclean.cpp
+++ b/src/tools/srcclean.cpp
@@ -2254,13 +2254,13 @@ int main(int argc, char *argv[])
{
// open the file
util::core_file::ptr infile;
- osd_file::error const err(util::core_file::open(argv[i], OPEN_FLAG_READ, infile));
- if (osd_file::error::NONE != err)
+ std::error_condition const err(util::core_file::open(argv[i], OPEN_FLAG_READ, infile));
+ if (err)
{
if (affected)
std::cerr << std::endl;
affected = true;
- util::stream_format(std::cerr, "Can't open %1$s\n", argv[i]);
+ util::stream_format(std::cerr, "Can't open %1$s (%2$s)\n", argv[i], err.message());
++failures;
continue;
}
diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp
index 14e7dbf2c6d..5395bc6ae01 100644
--- a/src/tools/unidasm.cpp
+++ b/src/tools/unidasm.cpp
@@ -1219,9 +1219,9 @@ int main(int argc, char *argv[])
void *data = nullptr;
u32 length = 0;
if(std::strcmp(opts.filename, "-") != 0) {
- osd_file::error filerr = util::core_file::load(opts.filename, &data, length);
- if(filerr != osd_file::error::NONE) {
- std::fprintf(stderr, "Error opening file '%s'\n", opts.filename);
+ std::error_condition filerr = util::core_file::load(opts.filename, &data, length);
+ if(filerr) {
+ std::fprintf(stderr, "Error opening file '%s' (%s)\n", opts.filename, filerr.message().c_str());
return 1;
}
}