diff options
author | Max Kellermann <mk@cm4all.com> | 2019-11-18 21:25:04 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2020-09-07 20:07:47 +0200 |
commit | 398281cd76f398b6db1a5f7bc8bed9d11374a465 (patch) | |
tree | 7c0bd460a4fe63648dbcecb1044776b4d06d43e6 | |
parent | 88446ccde961cde1ec21ec6036fef2f2b81af3b4 (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 51a57512b..35f84470f 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> @@ -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 <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 @@ -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 @@ -81,21 +81,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()) { @@ -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; } |