io/Reader: use std::span

This commit is contained in:
Max Kellermann 2023-10-05 10:25:16 +02:00
parent b9704715fb
commit 7ccc4ddf0d
19 changed files with 52 additions and 51 deletions

View File

@ -4,8 +4,8 @@
#include "Reader.hxx" #include "Reader.hxx"
#include "DecoderAPI.hxx" #include "DecoderAPI.hxx"
size_t std::size_t
DecoderReader::Read(void *data, size_t size) DecoderReader::Read(std::span<std::byte> dest)
{ {
return decoder_read(client, is, data, size); return decoder_read(client, is, dest.data(), dest.size());
} }

View File

@ -30,7 +30,7 @@ public:
} }
/* virtual methods from class Reader */ /* virtual methods from class Reader */
size_t Read(void *data, size_t size) override; std::size_t Read(std::span<std::byte> dest) override;
}; };
#endif #endif

View File

@ -60,7 +60,7 @@ static constexpr unsigned rom_size = 8192;
static void loadRom(const Path rom_path, uint8_t *dump) static void loadRom(const Path rom_path, uint8_t *dump)
{ {
FileReader romDump(rom_path); FileReader romDump(rom_path);
if (romDump.Read(dump, rom_size) != rom_size) if (romDump.Read(std::as_writable_bytes(std::span{dump, rom_size})) != rom_size)
throw FmtRuntimeError("Could not load rom dump '{}'", rom_path); throw FmtRuntimeError("Could not load rom dump '{}'", rom_path);
} }

View File

@ -4,10 +4,10 @@
#include "Reader.hxx" #include "Reader.hxx"
#include "InputStream.hxx" #include "InputStream.hxx"
size_t std::size_t
InputStreamReader::Read(void *data, size_t size) InputStreamReader::Read(std::span<std::byte> dest)
{ {
size_t nbytes = is.LockRead(data, size); size_t nbytes = is.LockRead(dest.data(), dest.size());
assert(nbytes > 0 || is.IsEOF()); assert(nbytes > 0 || is.IsEOF());
return nbytes; return nbytes;

View File

@ -20,7 +20,7 @@ public:
:is(_is) {} :is(_is) {}
/* virtual methods from class Reader */ /* virtual methods from class Reader */
size_t Read(void *data, size_t size) override; std::size_t Read(std::span<std::byte> dest) override;
}; };
#endif #endif

View File

@ -78,7 +78,7 @@ FileInputStream::Read(std::unique_lock<Mutex> &,
{ {
const ScopeUnlock unlock(mutex); const ScopeUnlock unlock(mutex);
nbytes = reader.Read(ptr, read_size); nbytes = reader.Read({static_cast<std::byte *>(ptr), read_size});
} }
if (nbytes == 0 && !IsEOF()) if (nbytes == 0 && !IsEOF())

View File

@ -26,7 +26,7 @@ BufferedReader::Fill(bool need_more)
assert(!w.empty()); assert(!w.empty());
} }
std::size_t nbytes = reader.Read(w.data(), w.size()); std::size_t nbytes = reader.Read(w);
if (nbytes == 0) { if (nbytes == 0) {
eof = true; eof = true;
return !need_more; return !need_more;
@ -95,9 +95,9 @@ BufferedReader::ReadLine()
} }
/* terminate the last line */ /* terminate the last line */
w[0] = 0; w[0] = {};
char *line = buffer.Read().data(); char *line = reinterpret_cast<char *>(buffer.Read().data());
buffer.Clear(); buffer.Clear();
++line_number; ++line_number;
return line; return line;

View File

@ -15,7 +15,7 @@ class BufferedReader {
Reader &reader; Reader &reader;
DynamicFifoBuffer<char> buffer; DynamicFifoBuffer<std::byte> buffer;
bool eof = false; bool eof = false;

View File

@ -30,12 +30,12 @@ FileReader::GetFileInfo() const
} }
std::size_t std::size_t
FileReader::Read(void *data, std::size_t size) FileReader::Read(std::span<std::byte> dest)
{ {
assert(IsDefined()); assert(IsDefined());
DWORD nbytes; DWORD nbytes;
if (!ReadFile(handle, data, size, &nbytes, nullptr)) if (!ReadFile(handle, dest.data(), dest.size(), &nbytes, nullptr))
throw FmtLastError("Failed to read from {}", path); throw FmtLastError("Failed to read from {}", path);
return nbytes; return nbytes;
@ -82,11 +82,11 @@ FileReader::GetFileInfo() const
} }
std::size_t std::size_t
FileReader::Read(void *data, std::size_t size) FileReader::Read(std::span<std::byte> dest)
{ {
assert(IsDefined()); assert(IsDefined());
ssize_t nbytes = fd.Read(data, size); ssize_t nbytes = fd.Read(dest);
if (nbytes < 0) if (nbytes < 0)
throw FmtErrno("Failed to read from {}", path); throw FmtErrno("Failed to read from {}", path);

View File

@ -100,5 +100,5 @@ public:
void Skip(off_t offset); void Skip(off_t offset);
/* virtual methods from class Reader */ /* virtual methods from class Reader */
std::size_t Read(void *data, std::size_t size) override; std::size_t Read(std::span<std::byte> dest) override;
}; };

View File

@ -17,8 +17,7 @@ PeekReader::Peek(size_t size)
assert(buffer_position == 0); assert(buffer_position == 0);
do { do {
size_t nbytes = next.Read(buffer + buffer_size, size_t nbytes = next.Read(std::span{buffer}.first(buffer_size).subspan(size));
size - buffer_size);
if (nbytes == 0) if (nbytes == 0)
return nullptr; return nullptr;
@ -29,15 +28,17 @@ PeekReader::Peek(size_t size)
} }
size_t size_t
PeekReader::Read(void *data, size_t size) PeekReader::Read(std::span<std::byte> dest)
{ {
size_t buffer_remaining = buffer_size - buffer_position; auto src = std::span{buffer}.first(buffer_size).subspan(buffer_position);
if (buffer_remaining > 0) { if (!src.empty()) {
size_t nbytes = std::min(buffer_remaining, size); if (dest.size() < src.size())
memcpy(data, buffer + buffer_position, nbytes); src = src.first(dest.size());
buffer_position += nbytes;
return nbytes; std::copy(src.begin(), src.end(), dest.begin());
buffer_position += src.size();
return src.size();
} }
return next.Read(data, size); return next.Read(dest);
} }

View File

@ -18,7 +18,7 @@ class PeekReader final : public Reader {
size_t buffer_size = 0, buffer_position = 0; size_t buffer_size = 0, buffer_position = 0;
uint8_t buffer[64]; std::byte buffer[64];
public: public:
explicit PeekReader(Reader &_next) explicit PeekReader(Reader &_next)
@ -27,7 +27,7 @@ public:
const void *Peek(size_t size); const void *Peek(size_t size);
/* virtual methods from class Reader */ /* virtual methods from class Reader */
size_t Read(void *data, size_t size) override; size_t Read(std::span<std::byte> dest) override;
}; };
#endif #endif

View File

@ -5,6 +5,7 @@
#define READER_HXX #define READER_HXX
#include <cstddef> #include <cstddef>
#include <span>
#include <type_traits> #include <type_traits>
/** /**
@ -25,14 +26,13 @@ public:
* @return the number of bytes read into the given buffer or 0 * @return the number of bytes read into the given buffer or 0
* on end-of-stream * on end-of-stream
*/ */
[[gnu::nonnull]] virtual std::size_t Read(std::span<std::byte> dest) = 0;
virtual std::size_t Read(void *data, std::size_t size) = 0;
template<typename T> template<typename T>
requires std::is_standard_layout_v<T> && std::is_trivially_copyable_v<T> requires std::is_standard_layout_v<T> && std::is_trivially_copyable_v<T>
void ReadT(T &dest) { void ReadT(T &dest) {
// TODO check return value // TODO check return value
Read(&dest, sizeof(dest)); Read(std::as_writable_bytes(std::span{&dest, 1}));
} }
}; };

View File

@ -7,11 +7,11 @@
bool bool
OggSyncState::Feed(size_t size) OggSyncState::Feed(size_t size)
{ {
char *buffer = ogg_sync_buffer(&oy, size); std::byte *buffer = reinterpret_cast<std::byte *>(ogg_sync_buffer(&oy, size));
if (buffer == nullptr) if (buffer == nullptr)
return false; return false;
size_t nbytes = reader.Read(buffer, size); size_t nbytes = reader.Read({buffer, size});
if (nbytes == 0) if (nbytes == 0)
return false; return false;

View File

@ -32,12 +32,12 @@ AutoGunzipReader::Detect()
next = &peek; next = &peek;
} }
size_t std::size_t
AutoGunzipReader::Read(void *data, size_t size) AutoGunzipReader::Read(std::span<std::byte> dest)
{ {
if (next == nullptr) if (next == nullptr)
Detect(); Detect();
assert(next != nullptr); assert(next != nullptr);
return next->Read(data, size); return next->Read(dest);
} }

View File

@ -24,7 +24,7 @@ public:
~AutoGunzipReader() noexcept; ~AutoGunzipReader() noexcept;
/* virtual methods from class Reader */ /* virtual methods from class Reader */
size_t Read(void *data, size_t size) override; std::size_t Read(std::span<std::byte> dest) override;
private: private:
void Detect(); void Detect();

View File

@ -24,7 +24,7 @@ GunzipReader::FillBuffer()
auto w = buffer.Write(); auto w = buffer.Write();
assert(!w.empty()); assert(!w.empty());
std::size_t nbytes = next.Read(w.data(), w.size()); std::size_t nbytes = next.Read(w);
if (nbytes == 0) if (nbytes == 0)
return false; return false;
@ -33,13 +33,13 @@ GunzipReader::FillBuffer()
} }
std::size_t std::size_t
GunzipReader::Read(void *data, std::size_t size) GunzipReader::Read(std::span<std::byte> dest)
{ {
if (eof) if (eof)
return 0; return 0;
z.next_out = (Bytef *)data; z.next_out = (Bytef *)dest.data();
z.avail_out = size; z.avail_out = dest.size();
while (true) { while (true) {
int flush = Z_NO_FLUSH; int flush = Z_NO_FLUSH;
@ -52,19 +52,19 @@ GunzipReader::Read(void *data, std::size_t size)
flush = Z_FINISH; flush = Z_FINISH;
} }
z.next_in = r.data(); z.next_in = reinterpret_cast<Bytef *>(r.data());
z.avail_in = r.size(); z.avail_in = r.size();
int result = inflate(&z, flush); int result = inflate(&z, flush);
if (result == Z_STREAM_END) { if (result == Z_STREAM_END) {
eof = true; eof = true;
return size - z.avail_out; return dest.size() - z.avail_out;
} else if (result != Z_OK) } else if (result != Z_OK)
throw ZlibError(result); throw ZlibError(result);
buffer.Consume(r.size() - z.avail_in); buffer.Consume(r.size() - z.avail_in);
if (z.avail_out < size) if (z.avail_out < dest.size())
return size - z.avail_out; return dest.size() - z.avail_out;
} }
} }

View File

@ -19,7 +19,7 @@ class GunzipReader final : public Reader {
z_stream z; z_stream z;
StaticFifoBuffer<Bytef, 65536> buffer; StaticFifoBuffer<std::byte, 65536> buffer;
public: public:
/** /**
@ -34,7 +34,7 @@ public:
} }
/* virtual methods from class Reader */ /* virtual methods from class Reader */
std::size_t Read(void *data, std::size_t size) override; std::size_t Read(std::span<std::byte> dest) override;
private: private:
bool FillBuffer(); bool FillBuffer();

View File

@ -16,7 +16,7 @@ Copy(OutputStream &dest, Reader &src)
{ {
while (true) { while (true) {
std::byte buffer[4096]; std::byte buffer[4096];
size_t nbytes = src.Read(buffer, sizeof(buffer)); std::size_t nbytes = src.Read(buffer);
if (nbytes == 0) if (nbytes == 0)
break; break;