io/OutputStream: use std::span
This commit is contained in:
parent
e72d27566c
commit
8ba68fdb47
|
@ -18,6 +18,6 @@ EncoderToOutputStream(OutputStream &os, Encoder &encoder)
|
|||
|
||||
/* write everything to the stream */
|
||||
|
||||
os.Write(r.data(), r.size());
|
||||
os.Write(r);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "BufferedOutputStream.hxx"
|
||||
#include "OutputStream.hxx"
|
||||
#include "util/SpanCast.hxx"
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
|
@ -16,33 +17,33 @@
|
|||
#endif
|
||||
|
||||
bool
|
||||
BufferedOutputStream::AppendToBuffer(const void *data, std::size_t size) noexcept
|
||||
BufferedOutputStream::AppendToBuffer(std::span<const std::byte> src) noexcept
|
||||
{
|
||||
auto r = buffer.Write();
|
||||
if (r.size() < size)
|
||||
auto w = buffer.Write();
|
||||
if (w.size() < src.size())
|
||||
return false;
|
||||
|
||||
memcpy(r.data(), data, size);
|
||||
buffer.Append(size);
|
||||
std::copy(src.begin(), src.end(), w.begin());
|
||||
buffer.Append(src.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BufferedOutputStream::Write(const void *data, std::size_t size)
|
||||
BufferedOutputStream::Write(std::span<const std::byte> src)
|
||||
{
|
||||
/* try to append to the current buffer */
|
||||
if (AppendToBuffer(data, size))
|
||||
if (AppendToBuffer(src))
|
||||
return;
|
||||
|
||||
/* not enough room in the buffer - flush it */
|
||||
Flush();
|
||||
|
||||
/* see if there's now enough room */
|
||||
if (AppendToBuffer(data, size))
|
||||
if (AppendToBuffer(src))
|
||||
return;
|
||||
|
||||
/* too large for the buffer: direct write */
|
||||
os.Write(data, size);
|
||||
os.Write(src);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -56,7 +57,7 @@ BufferedOutputStream::VFmt(fmt::string_view format_str, fmt::format_args args)
|
|||
#else
|
||||
fmt::vformat_to(b, format_str, args);
|
||||
#endif
|
||||
return Write(b.data(), b.size());
|
||||
return Write(std::as_bytes(std::span{b.data(), b.size()}));
|
||||
}
|
||||
|
||||
#ifdef _UNICODE
|
||||
|
@ -107,6 +108,6 @@ BufferedOutputStream::Flush()
|
|||
if (r.empty())
|
||||
return;
|
||||
|
||||
os.Write(r.data(), r.size());
|
||||
os.Write(r);
|
||||
buffer.Consume(r.size());
|
||||
}
|
||||
|
|
|
@ -43,11 +43,7 @@ public:
|
|||
/**
|
||||
* Write the contents of a buffer.
|
||||
*/
|
||||
void Write(const void *data, std::size_t size);
|
||||
|
||||
void Write(std::span<const std::byte> src) {
|
||||
Write(src.data(), src.size());
|
||||
}
|
||||
void Write(std::span<const std::byte> src);
|
||||
|
||||
/**
|
||||
* Write the given object. Note that this is only safe with
|
||||
|
@ -55,7 +51,7 @@ public:
|
|||
*/
|
||||
template<typename T>
|
||||
void WriteT(const T &value) {
|
||||
Write(&value, sizeof(value));
|
||||
Write(std::as_bytes(std::span{&value, 1}));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,7 +111,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
bool AppendToBuffer(const void *data, std::size_t size) noexcept;
|
||||
bool AppendToBuffer(std::span<const std::byte> src) noexcept;
|
||||
|
||||
#ifdef _UNICODE
|
||||
void WriteWideToUTF8(std::wstring_view src);
|
||||
|
|
|
@ -114,15 +114,15 @@ FileOutputStream::Tell() const noexcept
|
|||
}
|
||||
|
||||
void
|
||||
FileOutputStream::Write(const void *data, size_t size)
|
||||
FileOutputStream::Write(std::span<const std::byte> src)
|
||||
{
|
||||
assert(IsDefined());
|
||||
|
||||
DWORD nbytes;
|
||||
if (!WriteFile(handle, data, size, &nbytes, nullptr))
|
||||
if (!WriteFile(handle, src.data(), src.size(), &nbytes, nullptr))
|
||||
throw FmtLastError("Failed to write to {}", GetPath());
|
||||
|
||||
if (size_t(nbytes) != size)
|
||||
if (size_t(nbytes) != src.size())
|
||||
throw FmtLastError(DWORD{ERROR_DISK_FULL},
|
||||
"Failed to write to {}",
|
||||
GetPath());
|
||||
|
@ -246,14 +246,14 @@ FileOutputStream::Tell() const noexcept
|
|||
}
|
||||
|
||||
void
|
||||
FileOutputStream::Write(const void *data, size_t size)
|
||||
FileOutputStream::Write(std::span<const std::byte> src)
|
||||
{
|
||||
assert(IsDefined());
|
||||
|
||||
ssize_t nbytes = fd.Write(data, size);
|
||||
ssize_t nbytes = fd.Write(src.data(), src.size());
|
||||
if (nbytes < 0)
|
||||
throw FmtErrno("Failed to write to {}", GetPath());
|
||||
else if ((size_t)nbytes < size)
|
||||
else if ((size_t)nbytes < src.size())
|
||||
throw FmtErrno(ENOSPC, "Failed to write to {}", GetPath());
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ public:
|
|||
uint64_t Tell() const noexcept;
|
||||
|
||||
/* virtual methods from class OutputStream */
|
||||
void Write(const void *data, size_t size) override;
|
||||
void Write(std::span<const std::byte> src) override;
|
||||
|
||||
/**
|
||||
* Flush all data written to this object to disk (but does not
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#define OUTPUT_STREAM_HXX
|
||||
|
||||
#include <cstddef>
|
||||
#include <span>
|
||||
|
||||
class OutputStream {
|
||||
public:
|
||||
|
@ -14,7 +15,7 @@ public:
|
|||
/**
|
||||
* Throws std::exception on error.
|
||||
*/
|
||||
virtual void Write(const void *data, std::size_t size) = 0;
|
||||
virtual void Write(std::span<const std::byte> src) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,8 +15,8 @@ public:
|
|||
explicit StdioOutputStream(FILE *_file) noexcept:file(_file) {}
|
||||
|
||||
/* virtual methods from class OutputStream */
|
||||
void Write(const void *data, size_t size) override {
|
||||
fwrite(data, 1, size, file);
|
||||
void Write(std::span<const std::byte> src) override {
|
||||
fwrite(src.data(), 1, src.size(), file);
|
||||
|
||||
/* this class is debug-only and ignores errors */
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ GzipOutputStream::SyncFlush()
|
|||
if (z.next_out == output)
|
||||
break;
|
||||
|
||||
next.Write(output, z.next_out - output);
|
||||
next.Write(std::as_bytes(std::span{output}.first(z.next_out - output)));
|
||||
} while (z.avail_out == 0);
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ GzipOutputStream::Finish()
|
|||
|
||||
int result = deflate(&z, Z_FINISH);
|
||||
if (z.next_out > output)
|
||||
next.Write(output, z.next_out - output);
|
||||
next.Write(std::as_bytes(std::span{output}.first(z.next_out - output)));
|
||||
|
||||
if (result == Z_STREAM_END)
|
||||
break;
|
||||
|
@ -75,13 +75,13 @@ GzipOutputStream::Finish()
|
|||
}
|
||||
|
||||
void
|
||||
GzipOutputStream::Write(const void *_data, size_t size)
|
||||
GzipOutputStream::Write(std::span<const std::byte> src)
|
||||
{
|
||||
/* zlib's API requires non-const input pointer */
|
||||
void *data = const_cast<void *>(_data);
|
||||
void *data = const_cast<std::byte *>(src.data());
|
||||
|
||||
z.next_in = reinterpret_cast<Bytef *>(data);
|
||||
z.avail_in = size;
|
||||
z.avail_in = src.size();
|
||||
|
||||
while (z.avail_in > 0) {
|
||||
Bytef output[65536];
|
||||
|
@ -93,6 +93,6 @@ GzipOutputStream::Write(const void *_data, size_t size)
|
|||
throw ZlibError(result);
|
||||
|
||||
if (z.next_out > output)
|
||||
next.Write(output, z.next_out - output);
|
||||
next.Write(std::as_bytes(std::span{output}.first(z.next_out - output)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
void Finish();
|
||||
|
||||
/* virtual methods from class OutputStream */
|
||||
void Write(const void *data, size_t size) override;
|
||||
void Write(std::span<const std::byte> src) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,7 +17,7 @@ static bool
|
|||
Copy(OutputStream &dest, int src)
|
||||
{
|
||||
while (true) {
|
||||
uint8_t buffer[8192];
|
||||
std::byte buffer[8192];
|
||||
ssize_t nbytes = read(src, buffer, sizeof(buffer));
|
||||
if (nbytes < 0) {
|
||||
fprintf(stderr, "Failed to read from stdin: %s\n",
|
||||
|
@ -28,7 +28,7 @@ Copy(OutputStream &dest, int src)
|
|||
if (nbytes == 0)
|
||||
return true;
|
||||
|
||||
dest.Write(buffer, nbytes);
|
||||
dest.Write(std::span{buffer}.first(nbytes));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@ static void
|
|||
Copy(OutputStream &dest, Reader &src)
|
||||
{
|
||||
while (true) {
|
||||
char buffer[4096];
|
||||
std::byte buffer[4096];
|
||||
size_t nbytes = src.Read(buffer, sizeof(buffer));
|
||||
if (nbytes == 0)
|
||||
break;
|
||||
|
||||
dest.Write(buffer, nbytes);
|
||||
dest.Write(std::span{buffer}.first(nbytes));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ static void
|
|||
Copy(OutputStream &dest, int src)
|
||||
{
|
||||
while (true) {
|
||||
char buffer[4096];
|
||||
std::byte buffer[4096];
|
||||
ssize_t nbytes = read(src, buffer, sizeof(buffer));
|
||||
if (nbytes <= 0) {
|
||||
if (nbytes < 0)
|
||||
|
@ -23,7 +23,7 @@ Copy(OutputStream &dest, int src)
|
|||
return;
|
||||
}
|
||||
|
||||
dest.Write(buffer, nbytes);
|
||||
dest.Write(std::span{buffer}.first(nbytes));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue