From 8ba68fdb4736ad8e4e30190005c1f30147ea1a05 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 15 May 2023 11:00:21 +0200 Subject: [PATCH] io/OutputStream: use std::span --- src/encoder/ToOutputStream.cxx | 2 +- src/io/BufferedOutputStream.cxx | 23 ++++++++++++----------- src/io/BufferedOutputStream.hxx | 10 +++------- src/io/FileOutputStream.cxx | 12 ++++++------ src/io/FileOutputStream.hxx | 2 +- src/io/OutputStream.hxx | 3 ++- src/io/StdioOutputStream.hxx | 4 ++-- src/lib/zlib/GzipOutputStream.cxx | 12 ++++++------ src/lib/zlib/GzipOutputStream.hxx | 2 +- test/WriteFile.cxx | 4 ++-- test/run_gunzip.cxx | 4 ++-- test/run_gzip.cxx | 4 ++-- 12 files changed, 40 insertions(+), 42 deletions(-) diff --git a/src/encoder/ToOutputStream.cxx b/src/encoder/ToOutputStream.cxx index dfa235d67..f87453339 100644 --- a/src/encoder/ToOutputStream.cxx +++ b/src/encoder/ToOutputStream.cxx @@ -18,6 +18,6 @@ EncoderToOutputStream(OutputStream &os, Encoder &encoder) /* write everything to the stream */ - os.Write(r.data(), r.size()); + os.Write(r); } } diff --git a/src/io/BufferedOutputStream.cxx b/src/io/BufferedOutputStream.cxx index 52dfdd4df..0c706e8b7 100644 --- a/src/io/BufferedOutputStream.cxx +++ b/src/io/BufferedOutputStream.cxx @@ -3,6 +3,7 @@ #include "BufferedOutputStream.hxx" #include "OutputStream.hxx" +#include "util/SpanCast.hxx" #include @@ -16,33 +17,33 @@ #endif bool -BufferedOutputStream::AppendToBuffer(const void *data, std::size_t size) noexcept +BufferedOutputStream::AppendToBuffer(std::span 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 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()); } diff --git a/src/io/BufferedOutputStream.hxx b/src/io/BufferedOutputStream.hxx index f37c99884..65548d963 100644 --- a/src/io/BufferedOutputStream.hxx +++ b/src/io/BufferedOutputStream.hxx @@ -43,11 +43,7 @@ public: /** * Write the contents of a buffer. */ - void Write(const void *data, std::size_t size); - - void Write(std::span src) { - Write(src.data(), src.size()); - } + void Write(std::span src); /** * Write the given object. Note that this is only safe with @@ -55,7 +51,7 @@ public: */ template 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 src) noexcept; #ifdef _UNICODE void WriteWideToUTF8(std::wstring_view src); diff --git a/src/io/FileOutputStream.cxx b/src/io/FileOutputStream.cxx index 58cde80ac..cd9cc667f 100644 --- a/src/io/FileOutputStream.cxx +++ b/src/io/FileOutputStream.cxx @@ -114,15 +114,15 @@ FileOutputStream::Tell() const noexcept } void -FileOutputStream::Write(const void *data, size_t size) +FileOutputStream::Write(std::span 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 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()); } diff --git a/src/io/FileOutputStream.hxx b/src/io/FileOutputStream.hxx index a47e4233d..da79c92bd 100644 --- a/src/io/FileOutputStream.hxx +++ b/src/io/FileOutputStream.hxx @@ -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 src) override; /** * Flush all data written to this object to disk (but does not diff --git a/src/io/OutputStream.hxx b/src/io/OutputStream.hxx index 681335a2d..72e485f45 100644 --- a/src/io/OutputStream.hxx +++ b/src/io/OutputStream.hxx @@ -5,6 +5,7 @@ #define OUTPUT_STREAM_HXX #include +#include 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 src) = 0; }; #endif diff --git a/src/io/StdioOutputStream.hxx b/src/io/StdioOutputStream.hxx index e8a73743a..55f4b7c23 100644 --- a/src/io/StdioOutputStream.hxx +++ b/src/io/StdioOutputStream.hxx @@ -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 src) override { + fwrite(src.data(), 1, src.size(), file); /* this class is debug-only and ignores errors */ } diff --git a/src/lib/zlib/GzipOutputStream.cxx b/src/lib/zlib/GzipOutputStream.cxx index db5d51b46..19ae7c694 100644 --- a/src/lib/zlib/GzipOutputStream.cxx +++ b/src/lib/zlib/GzipOutputStream.cxx @@ -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 src) { /* zlib's API requires non-const input pointer */ - void *data = const_cast(_data); + void *data = const_cast(src.data()); z.next_in = reinterpret_cast(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))); } } diff --git a/src/lib/zlib/GzipOutputStream.hxx b/src/lib/zlib/GzipOutputStream.hxx index a258d14ef..8f9ecfc82 100644 --- a/src/lib/zlib/GzipOutputStream.hxx +++ b/src/lib/zlib/GzipOutputStream.hxx @@ -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 src) override; }; #endif diff --git a/test/WriteFile.cxx b/test/WriteFile.cxx index a78ef15b7..5f86e1d8d 100644 --- a/test/WriteFile.cxx +++ b/test/WriteFile.cxx @@ -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)); } } diff --git a/test/run_gunzip.cxx b/test/run_gunzip.cxx index 3cc313b04..5cc5bb969 100644 --- a/test/run_gunzip.cxx +++ b/test/run_gunzip.cxx @@ -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)); } } diff --git a/test/run_gzip.cxx b/test/run_gzip.cxx index d75b3d745..bbdca7533 100644 --- a/test/run_gzip.cxx +++ b/test/run_gzip.cxx @@ -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)); } }