io/Reader: use std::span
This commit is contained in:
parent
b9704715fb
commit
7ccc4ddf0d
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -15,7 +15,7 @@ class BufferedReader {
|
||||||
|
|
||||||
Reader &reader;
|
Reader &reader;
|
||||||
|
|
||||||
DynamicFifoBuffer<char> buffer;
|
DynamicFifoBuffer<std::byte> buffer;
|
||||||
|
|
||||||
bool eof = false;
|
bool eof = false;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue