diff options
Diffstat (limited to 'src/lib/util/chd.h')
-rw-r--r-- | src/lib/util/chd.h | 345 |
1 files changed, 176 insertions, 169 deletions
diff --git a/src/lib/util/chd.h b/src/lib/util/chd.h index 254a99daae1..671f4bdbd01 100644 --- a/src/lib/util/chd.h +++ b/src/lib/util/chd.h @@ -2,26 +2,27 @@ // copyright-holders:Aaron Giles /*************************************************************************** - chd.h - 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 "coretmpl.h" -#include "corestr.h" -#include <string> -#include "bitmap.h" -#include "corefile.h" -#include "hashing.h" #include "chdcodec.h" +#include "hashing.h" +#include "ioprocs.h" + +#include "osdcore.h" + #include <atomic> +#include <functional> +#include <memory> +#include <string> +#include <string_view> +#include <system_error> + /*************************************************************************** @@ -193,86 +194,52 @@ //************************************************************************** // 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 DVD metafata +constexpr chd_metadata_tag DVD_METADATA_TAG = CHD_MAKE_TAG('D', 'V', 'D', ' '); + // 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'); @@ -280,9 +247,6 @@ enum chd_error // TYPE DEFINITIONS //************************************************************************** -class chd_codec; - - // ======================> chd_file // core file class @@ -292,151 +256,183 @@ 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 + }; + + using open_parent_func = std::function<std::unique_ptr<chd_file> (util::sha1_t const &)>; + // construction/destruction chd_file(); virtual ~chd_file(); - // operators - operator util::core_file &() { return *m_file; } - // getters - bool opened() const { return (m_file != nullptr); } - uint32_t version() const { return m_version; } - uint64_t logical_bytes() const { return m_logicalbytes; } - uint32_t hunk_bytes() const { return m_hunkbytes; } - uint32_t hunk_count() const { return m_hunkcount; } - uint32_t unit_bytes() const { return m_unitbytes; } - uint64_t unit_count() const { return m_unitcount; } - bool compressed() const { return (m_compression[0] != CHD_CODEC_NONE); } - chd_codec_type compression(int index) const { return m_compression[index]; } - chd_file *parent() const { return m_parent; } - 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); + util::random_read &file(); + bool opened() const noexcept { return bool(m_file); } + uint32_t version() const noexcept { return m_version; } + uint64_t logical_bytes() const noexcept { return m_logicalbytes; } + uint32_t hunk_bytes() const noexcept { return m_hunkbytes; } + uint32_t hunk_count() const noexcept { return m_hunkcount; } + uint32_t unit_bytes() const noexcept { return m_unitbytes; } + uint64_t unit_count() const noexcept { return m_unitcount; } + bool compressed() const noexcept { return (m_compression[0] != CHD_CODEC_NONE); } + chd_codec_type compression(int index) const noexcept { return m_compression[index]; } + chd_file *parent() const noexcept { return m_parent.get(); } + bool parent_missing() const noexcept; + util::sha1_t sha1() const noexcept; + util::sha1_t raw_sha1() const noexcept; + util::sha1_t parent_sha1() const noexcept; + 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); + std::error_condition set_raw_sha1(util::sha1_t rawdata) noexcept; + std::error_condition set_parent_sha1(util::sha1_t parent) noexcept; // 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, const chd_codec_type (&compression)[4]); + std::error_condition create(util::random_read_write::ptr &&file, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t unitbytes, const chd_codec_type (&compression)[4]); + std::error_condition create(std::string_view filename, uint64_t logicalbytes, uint32_t hunkbytes, const chd_codec_type (&compression)[4], chd_file &parent); + std::error_condition create(util::random_read_write::ptr &&file, uint64_t logicalbytes, uint32_t hunkbytes, const 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, const open_parent_func &open_parent = nullptr); + std::error_condition open(util::random_read_write::ptr &&file, bool writeable = false, chd_file *parent = nullptr, const open_parent_func &open_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 codec_process_hunk(uint32_t hunknum); + 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); + std::error_condition codec_configure(chd_codec_type codec, int param, void *config); - // static helpers - static const char *error_string(chd_error err); + // typing + std::error_condition check_is_hd() const noexcept; + std::error_condition check_is_cd() const noexcept; + std::error_condition check_is_gd() const noexcept; + std::error_condition check_is_dvd() const noexcept; + std::error_condition check_is_av() const noexcept; private: struct metadata_entry; struct metadata_hash; // inline helpers - uint64_t be_read(const uint8_t *base, int numbytes); - void be_write(uint8_t *base, uint64_t value, int numbytes); - util::sha1_t be_read_sha1(const uint8_t *base); - void be_write_sha1(uint8_t *base, util::sha1_t value); - void file_read(uint64_t offset, void *dest, uint32_t length); - void file_write(uint64_t offset, const void *source, uint32_t length); + util::sha1_t be_read_sha1(const uint8_t *base) const noexcept; + void be_write_sha1(uint8_t *base, util::sha1_t value) noexcept; + std::error_condition file_read(uint64_t offset, void *dest, uint32_t length) const noexcept; + std::error_condition file_write(uint64_t offset, const void *source, uint32_t length) noexcept; uint64_t file_append(const void *source, uint32_t length, uint32_t alignment = 0); - uint8_t bits_for_value(uint64_t value); + static uint8_t bits_for_value(uint64_t value) noexcept; // internal helpers uint32_t guess_unitbytes(); 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, const open_parent_func &open_parent); void create_open_common(); - void verify_proper_compression_append(uint32_t hunknum); + std::error_condition verify_proper_compression_append(uint32_t hunknum) const noexcept; void hunk_write_compressed(uint32_t hunknum, int8_t compression, const uint8_t *compressed, uint32_t complength, util::crc16_t crc16); void hunk_copy_from_self(uint32_t hunknum, uint32_t otherhunk); void hunk_copy_from_parent(uint32_t hunknum, uint64_t parentunit); - bool metadata_find(chd_metadata_tag metatag, int32_t metaindex, metadata_entry &metaentry, bool resume = false); - void metadata_set_previous_next(uint64_t prevoffset, uint64_t nextoffset); + std::error_condition metadata_find(chd_metadata_tag metatag, int32_t metaindex, metadata_entry &metaentry, bool resume = false) const noexcept; + std::error_condition metadata_set_previous_next(uint64_t prevoffset, uint64_t nextoffset) noexcept; void metadata_update_hash(); 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 + std::shared_ptr<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? }; @@ -452,7 +448,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 @@ -469,28 +465,28 @@ private: // operations void reset(); - uint64_t find(util::crc16_t crc16, util::sha1_t sha1); + uint64_t find(util::crc16_t crc16, util::sha1_t sha1) const noexcept; 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 }; @@ -554,8 +550,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 @@ -564,20 +560,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 - bool m_read_error; // error during reading? + uint64_t m_read_queue_offset;// next offset to enqueue + uint64_t m_read_done_offset; // next offset that will complete + std::error_condition m_read_error; // error during reading, if any // 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 |