1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
|
// 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 {
/// \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(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(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_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_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>;
};
/// \}
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
|