diff options
author | Max Kellermann <mk@cm4all.com> | 2019-11-18 21:25:04 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2019-12-17 20:21:11 +0100 |
commit | a72878c5b9b1ff5dc3fc87767ce46a43e764e3bc (patch) | |
tree | 72cfb2ee73753b12b87b6c1458e5759809e608ba | |
parent | bd4df1ae5deb6a01b31cc4a2cc971f29a80302d8 (diff) |
io/FileDescriptor: add method FullRead()
-rw-r--r-- | src/system/FileDescriptor.cxx | 22 | ||||
-rw-r--r-- | src/system/FileDescriptor.hxx | 8 | ||||
-rw-r--r-- | 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 1f6bf0808..2e53c8086 100644 --- a/src/system/FileDescriptor.cxx +++ b/src/system/FileDescriptor.cxx @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 Max Kellermann <max.kellermann@gmail.com> + * Copyright 2012-2019 Max Kellermann <max.kellermann@gmail.com> * * 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 <assert.h> +#include <stdint.h> #include <sys/stat.h> #include <fcntl.h> @@ -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 <max.kellermann@gmail.com> + * Copyright 2012-2019 Max Kellermann <max.kellermann@gmail.com> * * 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 @@ -80,21 +80,6 @@ WriteOrThrow(FileDescriptor fd, const void *buffer, size_t size) } 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<uint8_t> src) { while (!src.empty()) { @@ -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; } |