diff --git a/src/system/FileDescriptor.cxx b/src/system/FileDescriptor.cxx index 1f6bf0808..2e53c8086 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 @@ -285,6 +287,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 92cdddce6..5fabd17dd 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 @@ -233,6 +233,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 0515b1b4e..116907cee 100644 --- a/test/run_filter.cxx +++ b/test/run_filter.cxx @@ -79,21 +79,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) { @@ -124,7 +109,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; }