diff --git a/src/input/MemoryInputStream.cxx b/src/input/MemoryInputStream.cxx new file mode 100644 index 000000000..4cac0dc3a --- /dev/null +++ b/src/input/MemoryInputStream.cxx @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The Music Player Daemon Project + +#include "MemoryInputStream.hxx" + +#include <algorithm> // for std::copy() + +void +MemoryInputStream::Seek(std::unique_lock<Mutex> &, + offset_type new_offset) +{ + if (std::cmp_greater(new_offset, src.size())) + throw std::runtime_error{"Bad offset"}; + + offset = new_offset; +} + +size_t +MemoryInputStream::Read(std::unique_lock<Mutex> &, std::span<std::byte> dest) +{ + const std::size_t _offset = static_cast<std::size_t>(offset); + std::size_t remaining = src.size() - _offset; + std::size_t nbytes = std::min(dest.size(), remaining); + + const auto s = src.subspan(_offset, nbytes); + std::copy(s.begin(), s.end(), dest.begin()); + return nbytes; +} diff --git a/src/input/MemoryInputStream.hxx b/src/input/MemoryInputStream.hxx new file mode 100644 index 000000000..7d6c4ec51 --- /dev/null +++ b/src/input/MemoryInputStream.hxx @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The Music Player Daemon Project + +#include "InputStream.hxx" + +class MemoryInputStream final : public InputStream { + std::span<const std::byte> src; + +public: + MemoryInputStream(const char *_uri, Mutex &_mutex, + std::span<const std::byte> _src) noexcept + :InputStream(_uri, _mutex), src(_src) + { + size = src.size(); + seekable = true; + SetReady(); + } + + /* virtual methods from InputStream */ + + [[nodiscard]] bool IsEOF() const noexcept override { + return GetOffset() >= GetSize(); + } + + size_t Read(std::unique_lock<Mutex> &lock, + std::span<std::byte> dest) override; + void Seek(std::unique_lock<Mutex> &lock, + offset_type offset) override; +}; diff --git a/src/input/meson.build b/src/input/meson.build index 8050d17aa..b1f6b78b8 100644 --- a/src/input/meson.build +++ b/src/input/meson.build @@ -23,6 +23,7 @@ input_basic = static_library( 'input_basic', 'AsyncInputStream.cxx', 'LastInputStream.cxx', + 'MemoryInputStream.cxx', 'ProxyInputStream.cxx', 'RewindInputStream.cxx', 'TextInputStream.cxx',