From 398281cd76f398b6db1a5f7bc8bed9d11374a465 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 18 Nov 2019 21:25:04 +0100 Subject: [PATCH] io/FileDescriptor: add method FullRead() --- src/system/FileDescriptor.cxx | 22 +++++++++++++++++++++- src/system/FileDescriptor.hxx | 8 +++++++- test/run_filter.cxx | 17 +---------------- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/system/FileDescriptor.cxx b/src/system/FileDescriptor.cxx index 51a57512b..35f84470f 100644 --- a/src/system/FileDescriptor.cxx +++ b/src/system/FileDescriptor.cxx @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 Max Kellermann + * Copyright 2012-2019 Max Kellermann * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,8 +28,10 @@ */ #include "FileDescriptor.hxx" +#include "system/Error.hxx" #include +#include #include #include @@ -278,6 +280,24 @@ FileDescriptor::GetSize() const noexcept : -1; } +void +FileDescriptor::FullRead(void *_buffer, size_t length) +{ + uint8_t *buffer = (uint8_t *)_buffer; + + while (length > 0) { + ssize_t nbytes = Read(buffer, length); + if (nbytes <= 0) { + if (nbytes < 0) + throw MakeErrno("Failed to read"); + throw std::runtime_error("Unexpected end of file"); + } + + buffer += nbytes; + length -= nbytes; + } +} + #ifndef _WIN32 int diff --git a/src/system/FileDescriptor.hxx b/src/system/FileDescriptor.hxx index 11e32caf3..b3839c71b 100644 --- a/src/system/FileDescriptor.hxx +++ b/src/system/FileDescriptor.hxx @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 Max Kellermann + * Copyright 2012-2019 Max Kellermann * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -227,6 +227,12 @@ public: return ::read(fd, buffer, length); } + /** + * Read until all of the given buffer has been filled. Throws + * on error. + */ + void FullRead(void *buffer, size_t length); + ssize_t Write(const void *buffer, size_t length) noexcept { return ::write(fd, buffer, length); } diff --git a/test/run_filter.cxx b/test/run_filter.cxx index c6b6f9bff..40dce22c2 100644 --- a/test/run_filter.cxx +++ b/test/run_filter.cxx @@ -80,21 +80,6 @@ WriteOrThrow(FileDescriptor fd, const void *buffer, size_t size) return nbytes; } -static void -FullRead(FileDescriptor fd, void *_buffer, size_t size) -{ - auto buffer = (uint8_t *)_buffer; - - while (size > 0) { - size_t nbytes = ReadOrThrow(fd, buffer, size); - if (nbytes == 0) - throw std::runtime_error("Premature end of input"); - - buffer += nbytes; - size -= nbytes; - } -} - static void FullWrite(FileDescriptor fd, ConstBuffer src) { @@ -125,7 +110,7 @@ ReadFrames(FileDescriptor fd, void *_buffer, size_t size, size_t frame_size) const size_t modulo = nbytes % frame_size; if (modulo > 0) { size_t rest = frame_size - modulo; - FullRead(fd, buffer + nbytes, rest); + fd.FullRead(buffer + nbytes, rest); nbytes += rest; }