summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/util/ioprocs.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/util/ioprocs.h')
-rw-r--r--src/lib/util/ioprocs.h377
1 files changed, 377 insertions, 0 deletions
diff --git a/src/lib/util/ioprocs.h b/src/lib/util/ioprocs.h
new file mode 100644
index 00000000000..9e2c29d2a14
--- /dev/null
+++ b/src/lib/util/ioprocs.h
@@ -0,0 +1,377 @@
+// 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>
+#include <tuple>
+#include <utility>
+
+
+// FIXME: make a proper place for OSD forward declarations
+class osd_file;
+
+
+namespace util {
+
+/// \defgroup ioprocs Generic I/O interfaces
+/// \{
+
+/// \brief Interface to an input stream
+///
+/// Represents a stream producing a sequence of bytes with no further
+/// structure.
+/// \sa write_stream read_write_stream random_read
+class read_stream
+{
+public:
+ using ptr = std::unique_ptr<read_stream>;
+
+ virtual ~read_stream() = default;
+
+ /// \brief Read from the current position in the stream
+ ///
+ /// Reads up to the specified number of bytes from the stream into
+ /// the supplied buffer. May read less than the requested number of
+ /// bytes if the end of the stream is reached or an error occurs.
+ /// If the stream supports seeking, reading starts at the current
+ /// position in the stream, and the current position is incremented
+ /// by the number of bytes read.
+ /// \param [out] buffer Destination buffer. Must be large enough to
+ /// hold the requested number of bytes.
+ /// \param [in] length Maximum number of bytes to read.
+ /// \param [out] actual Number of bytes actually read. Will always
+ /// be less than or equal to the requested length.
+ /// \return An error condition if reading stopped due to an error.
+ virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept = 0;
+};
+
+
+/// \brief Interface to an output stream
+///
+/// Represents a stream that accepts a sequence of bytes with no further
+/// structure.
+/// \sa read_stream read_write_stream random_write
+class write_stream
+{
+public:
+ using ptr = std::unique_ptr<write_stream>;
+
+ virtual ~write_stream() = default;
+
+ /// \brief Finish writing data
+ ///
+ /// Performs any tasks necessary to finish writing data to the
+ /// stream and guarantee that the written data can be read in its
+ /// entirety. Further writes may not be possible.
+ /// \return An error condition if the operation fails.
+ virtual std::error_condition finalize() noexcept = 0;
+
+ /// \brief Flush application-side caches
+ ///
+ /// Flushes any caches to the underlying stream. Success does not
+ /// guarantee that data has reached persistent storage.
+ /// \return An error condition if flushing caches fails.
+ virtual std::error_condition flush() noexcept = 0;
+
+ /// \brief Write at the current position in the stream
+ ///
+ /// Writes up to the specified number of bytes from the supplied
+ /// buffer to the stream. May write less than the requested number
+ /// of bytes if an error occurs. If the stream supports seeking,
+ /// writing starts at the current position in the stream, and the
+ /// current position is incremented by the number of bytes written.
+ /// \param [in] buffer Buffer containing the data to write. Must
+ /// contain at least the specified number of bytes.
+ /// \param [in] length Number of bytes to write.
+ /// \param [out] actual Number of bytes actually written. Will
+ /// always be less than or equal to the requested length.
+ /// \return An error condition if writing stopped due to an error.
+ virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept = 0;
+};
+
+
+/// \brief Interface to an I/O stream
+///
+/// Represents an object that acts as both a source of and sink for byte
+/// sequences.
+/// \sa read_stream write_stream random_read_write
+class read_write_stream : public virtual read_stream, public virtual write_stream
+{
+public:
+ using ptr = std::unique_ptr<read_write_stream>;
+};
+
+
+/// \brief Interface to a byte sequence that supports seeking
+///
+/// Provides an interface for controlling the position within a byte
+/// sequence that supports seeking.
+/// \sa random_read random_write random_read_write
+class random_access
+{
+public:
+ virtual ~random_access() = default;
+
+ /// \brief Set the position in the stream
+ ///
+ /// Sets the position for the next read or write operation. It may
+ /// be possible to set the position beyond the end of the stream.
+ /// \param [in] offset The offset in bytes, relative to the position
+ /// specified by the whence parameter.
+ /// \param [in] whence One of SEEK_SET, SEEK_CUR or SEEK_END, to
+ /// interpret the offset parameter relative to the beginning of
+ /// the stream, the current position in the stream, or the end of
+ /// the stream, respectively.
+ /// \return An error condition of the operation failed.
+ virtual std::error_condition seek(std::int64_t offset, int whence) noexcept = 0;
+
+ /// \brief Get the current position in the stream
+ ///
+ /// Gets the position in the stream for the next read or write
+ /// operation. The position may be beyond the end of the stream.
+ /// \param [out] result The position in bytes relative to the
+ /// beginning of the stream. Not valid if the operation fails.
+ /// \return An error condition if the operation failed.
+ virtual std::error_condition tell(std::uint64_t &result) noexcept = 0;
+
+ /// \brief Get the length of the stream
+ ///
+ /// Gets the current length of the stream.
+ /// \param [out] result The length of the stream in bytes. Not
+ /// valid if the operation fails.
+ /// \return An error condtion if the operation failed.
+ virtual std::error_condition length(std::uint64_t &result) noexcept = 0;
+};
+
+
+/// \brief Interface to a random-access byte input sequence
+///
+/// Provides an interface for reading from arbitrary positions within a
+/// byte sequence. No further structure is provided.
+/// \sa read_stream random_write random_read_write
+class random_read : public virtual read_stream, public virtual random_access
+{
+public:
+ using ptr = std::unique_ptr<random_read>;
+
+ /// \brief Read from specified position
+ ///
+ /// Reads up to the specified number of bytes into the supplied
+ /// buffer. If seeking is supported, reading starts at the
+ /// specified position and the current position is unaffected. May
+ /// read less than the requested number of bytes if the end of the
+ /// stream is encountered or an error occurs.
+ /// \param [in] offset The position to start reading from, specified
+ /// as a number of bytes from the beginning of the stream.
+ /// \param [out] buffer Destination buffer. Must be large enough to
+ /// hold the requested number of bytes.
+ /// \param [in] length Maximum number of bytes to read.
+ /// \param [out] actual Number of bytes actually read. Will always
+ /// be less than or equal to the requested length.
+ /// \return An error condition if seeking failed or reading stopped
+ /// due to an error.
+ virtual std::error_condition read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept = 0;
+};
+
+
+/// \brief Interface to a random-access byte output sequence
+///
+/// Provides an interface for writing to arbitrary positions within a
+/// byte sequence. No further structure is provided.
+/// \sa write_stream random_read random_read_write
+class random_write : public virtual write_stream, public virtual random_access
+{
+public:
+ using ptr = std::unique_ptr<random_write>;
+
+ /// \brief Write at specified position
+ ///
+ /// Writes up to the specified number of bytes from the supplied
+ /// buffer. If seeking is supported, writing starts at the
+ /// specified position and the current position is unaffected. May
+ /// write less than the requested number of bytes if an error
+ /// occurs.
+ /// \param [in] offset The position to start writing at, specified
+ /// as a number of bytes from the beginning of the stream.
+ /// \param [in] buffer Buffer containing the data to write. Must
+ /// contain at least the specified number of bytes.
+ /// \param [in] length Number of bytes to write.
+ /// \param [out] actual Number of bytes actually written. Will
+ /// always be less than or equal to the requested length.
+ /// \return An error condition if seeking failed or writing stopped
+ /// due to an error.
+ virtual std::error_condition write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept = 0;
+};
+
+
+/// \brief Interface to a random-access read/write byte sequence
+///
+/// Provides an interface for reading from and writing to arbitrary
+/// positions within a byte sequence. No further structure is provided.
+/// \sa random_read random_write read_write_stream
+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>;
+};
+
+
+/// \brief Read from the current position in the stream
+///
+/// Reads up to the specified number of bytes from the stream into the
+/// supplied buffer, continuing if interrupted by asynchronous signals.
+/// May read less than the requested number of bytes if the end of the
+/// stream is reached or an error occurs. If the stream supports
+/// seeking, reading starts at the current position in the stream, and
+/// the current position is incremented by the number of bytes read.
+/// The operation may not be atomic if it is interrupted before the
+/// requested number of bytes is read.
+/// \param [in] stream The stream to read from.
+/// \param [out] buffer Destination buffer. Must be large enough to
+/// hold the requested number of bytes.
+/// \param [in] length Maximum number of bytes to read.
+/// \return A pair containing an error condition if reading stopped due
+/// to an error, and the actual number of bytes read.
+std::pair<std::error_condition, std::size_t> read(read_stream &stream, void *buffer, std::size_t length) noexcept;
+
+/// \brief Allocate memory and read from the current position in the
+/// stream
+///
+/// Allocates the specified number of bytes and then reads up to that
+/// number of bytes from the stream into the newly allocated buffer,
+/// continuing if interrupted by asynchronous signals. May read less
+/// than the requested number of bytes if the end of the stream is
+/// reached or an error occurs. If the stream supports seeking,
+/// reading starts at the current position in the stream, and the
+/// current position is incremented by the number of bytes read. The
+/// operation may not be atomic if it is interrupted before the
+/// requested number of bytes is read. No data will be read if
+/// allocation fails.
+/// \param [in] stream The stream to read from.
+/// hold the requested number of bytes.
+/// \param [in] length Maximum number of bytes to read.
+/// \return A tuple containing an error condition if allocation failed
+/// or reading stopped due to an error, the allocated buffer, and the
+/// actual number of bytes read.
+std::tuple<std::error_condition, std::unique_ptr<std::uint8_t []>, std::size_t> read(read_stream &stream, std::size_t length) noexcept;
+
+/// \brief Read from the specified position
+///
+/// Reads up to the specified number of bytes from the stream into the
+/// supplied buffer, continuing if interrupted by asynchronous signals.
+/// May read less than the requested number of bytes if the end of the
+/// stream is reached or an error occurs. If seeking is supported,
+/// reading starts at the specified position and the current position is
+/// unaffected. The operation may not be atomic if it is interrupted
+/// before the requested number of bytes is read.
+/// \param [in] stream The stream to read from.
+/// \param [in] offset The position to start reading from, specified as
+/// a number of bytes from the beginning of the stream.
+/// \param [out] buffer Destination buffer. Must be large enough to
+/// hold the requested number of bytes.
+/// \param [in] length Maximum number of bytes to read.
+/// \return A pair containing an error condition if reading stopped due
+/// to an error, and the actual number of bytes read.
+std::pair<std::error_condition, std::size_t> read_at(random_read &stream, std::uint64_t offset, void *buffer, std::size_t length) noexcept;
+
+/// \brief Allocate memory and read from the specified position
+///
+/// Allocates the specified number of bytes and then reads up to that
+/// number of bytes from the stream into the newly allocated buffer,
+/// continuing if interrupted by asynchronous signals. May read less
+/// than the requested number of bytes if the end of the stream is
+/// reached or an error occurs. If seeking is supported, reading
+/// starts at the specified position and the current position is
+/// unaffected. The operation may not be atomic if it is interrupted
+/// before the requested number of bytes is read. No data will be read
+/// if allocation fails.
+/// \param [in] stream The stream to read from.
+/// \param [in] offset The position to start reading from, specified as
+/// a number of bytes from the beginning of the stream.
+/// \param [out] buffer Destination buffer. Must be large enough to
+/// hold the requested number of bytes.
+/// \param [in] length Maximum number of bytes to read.
+/// \return A tuple containing an error condition if allocation failed
+/// or reading stopped due to an error, the allocated buffer, and the
+/// actual number of bytes read.
+std::tuple<std::error_condition, std::unique_ptr<std::uint8_t []>, std::size_t> read_at(random_read &stream, std::uint64_t offset, std::size_t length) noexcept;
+
+/// \brief Write at the current position in the stream
+///
+/// Writes up to the specified number of bytes from the supplied
+/// buffer to the stream, continuing if interrupted by asynchronous
+/// signals. May write less than the requested number of bytes if an
+/// error occurs. If the stream supports seeking, writing starts at the
+/// current position in the stream, and the current position is
+/// incremented by the number of bytes written. The operation may not
+/// be atomic if it is interrupted before the requested number of bytes
+/// is written.
+/// \param [in] stream The stream to write to.
+/// \param [in] buffer Buffer containing the data to write. Must
+/// contain at least the specified number of bytes.
+/// \param [in] length Number of bytes to write.
+/// \return A pair containing an error condition if writing stopped due
+/// to an error, and the actual number of bytes written.
+std::pair<std::error_condition, std::size_t> write(write_stream &stream, void const *buffer, std::size_t length) noexcept;
+
+/// \brief Write at specified position
+///
+/// Writes up to the specified number of bytes from the supplied buffer,
+/// continuing if interrupted by asynchronous signals. If seeking is
+/// supported, writing starts at the specified position and the current
+/// position is unaffected. May write less than the requested number
+/// of bytes if an error occurs. The operation may not be atomic if it
+/// is interrupted before the requested number of bytes is written.
+/// \param [in] stream The stream to write to.
+/// \param [in] offset The position to start writing at, specified as a
+/// number of bytes from the beginning of the stream.
+/// \param [in] buffer Buffer containing the data to write. Must
+/// contain at least the specified number of bytes.
+/// \param [in] length Number of bytes to write.
+/// \return A pair containing an error condition if writing stopped due
+/// to an error, and the actual number of bytes written.
+std::pair<std::error_condition, std::size_t> write_at(random_write &stream, std::uint64_t offset, void const *buffer, std::size_t length) noexcept;
+
+/// \}
+
+
+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;
+
+} // namespace util
+
+#endif // MAME_LIB_UTIL_IOPROCS_H