diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/input/ProxyInputStream.cxx | 97 | ||||
-rw-r--r-- | src/input/ProxyInputStream.hxx | 64 | ||||
-rw-r--r-- | src/input/plugins/RewindInputPlugin.cxx | 73 |
4 files changed, 176 insertions, 59 deletions
diff --git a/Makefile.am b/Makefile.am index 3eab3043e..b065eb539 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1032,6 +1032,7 @@ libinput_a_SOURCES = \ src/input/InputPlugin.hxx \ src/input/TextInputStream.cxx src/input/TextInputStream.hxx \ src/input/ThreadInputStream.cxx src/input/ThreadInputStream.hxx \ + src/input/ProxyInputStream.cxx src/input/ProxyInputStream.hxx \ src/input/plugins/RewindInputPlugin.cxx src/input/plugins/RewindInputPlugin.hxx \ src/input/plugins/FileInputPlugin.cxx src/input/plugins/FileInputPlugin.hxx diff --git a/src/input/ProxyInputStream.cxx b/src/input/ProxyInputStream.cxx new file mode 100644 index 000000000..7b6e9f937 --- /dev/null +++ b/src/input/ProxyInputStream.cxx @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "ProxyInputStream.hxx" +#include "tag/Tag.hxx" + +#include <assert.h> + +ProxyInputStream::ProxyInputStream(InputStream *_input) + :InputStream(_input->GetURI(), _input->mutex, _input->cond), + input(*_input) {} + +ProxyInputStream::~ProxyInputStream() +{ + delete &input; +} + +void +ProxyInputStream::CopyAttributes() +{ + if (input.IsReady()) { + if (!IsReady()) { + if (input.HasMimeType()) + SetMimeType(input.GetMimeType()); + + size = input.GetSize(); + seekable = input.IsSeekable(); + SetReady(); + } + + offset = input.GetOffset(); + } +} + +bool +ProxyInputStream::Check(Error &error) +{ + return input.Check(error); +} + +void +ProxyInputStream::Update() +{ + input.Update(); + CopyAttributes(); +} + +bool +ProxyInputStream::Seek(offset_type new_offset, int whence, Error &error) +{ + bool success = input.Seek(new_offset, whence, error); + CopyAttributes(); + return success; +} + +bool +ProxyInputStream::IsEOF() +{ + return input.IsEOF(); +} + +Tag * +ProxyInputStream::ReadTag() +{ + return input.ReadTag(); +} + +bool +ProxyInputStream::IsAvailable() +{ + return input.IsAvailable(); +} + +size_t +ProxyInputStream::Read(void *ptr, size_t read_size, Error &error) +{ + size_t nbytes = input.Read(ptr, read_size, error); + CopyAttributes(); + return nbytes; +} diff --git a/src/input/ProxyInputStream.hxx b/src/input/ProxyInputStream.hxx new file mode 100644 index 000000000..b2049fbc0 --- /dev/null +++ b/src/input/ProxyInputStream.hxx @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_PROXY_INPUT_STREAM_HXX +#define MPD_PROXY_INPUT_STREAM_HXX + +#include "InputStream.hxx" + +struct Tag; + +/** + * An #InputStream that forwards all methods call to another + * #InputStream instance. This can be used as a base class to + * override selected methods. + */ +class ProxyInputStream : public InputStream { +protected: + InputStream &input; + +public: + gcc_nonnull_all + ProxyInputStream(InputStream *_input); + + virtual ~ProxyInputStream(); + + ProxyInputStream(const ProxyInputStream &) = delete; + ProxyInputStream &operator=(const ProxyInputStream &) = delete; + + /* virtual methods from InputStream */ + bool Check(Error &error) override; + void Update() override; + bool Seek(offset_type new_offset, int whence, Error &error) override; + bool IsEOF() override; + Tag *ReadTag() override; + bool IsAvailable() override; + size_t Read(void *ptr, size_t read_size, Error &error) override; + +protected: + /** + * Copy public attributes from the underlying input stream to the + * "rewind" input stream. This function is called when a method of + * the underlying stream has returned, which may have modified these + * attributes. + */ + void CopyAttributes(); +}; + +#endif diff --git a/src/input/plugins/RewindInputPlugin.cxx b/src/input/plugins/RewindInputPlugin.cxx index 2c4679cbe..c18799c64 100644 --- a/src/input/plugins/RewindInputPlugin.cxx +++ b/src/input/plugins/RewindInputPlugin.cxx @@ -19,14 +19,12 @@ #include "config.h" #include "RewindInputPlugin.hxx" -#include "../InputStream.hxx" +#include "../ProxyInputStream.hxx" #include <assert.h> #include <string.h> -class RewindInputStream final : public InputStream { - InputStream *input; - +class RewindInputStream final : public ProxyInputStream { /** * The read position within the buffer. Undefined as long as * ReadingFromBuffer() returns false. @@ -50,36 +48,19 @@ class RewindInputStream final : public InputStream { public: RewindInputStream(InputStream *_input) - :InputStream(_input->GetURI(), - _input->mutex, _input->cond), - input(_input), tail(0) { - } - - ~RewindInputStream() { - delete input; + :ProxyInputStream(_input), + tail(0) { } /* virtual methods from InputStream */ - bool Check(Error &error) override { - return input->Check(error); - } - void Update() override { if (!ReadingFromBuffer()) - CopyAttributes(); + ProxyInputStream::Update(); } bool IsEOF() override { - return !ReadingFromBuffer() && input->IsEOF(); - } - - Tag *ReadTag() override { - return input->ReadTag(); - } - - bool IsAvailable() override { - return input->IsAvailable(); + return !ReadingFromBuffer() && ProxyInputStream::IsEOF(); } size_t Read(void *ptr, size_t size, Error &error) override; @@ -91,30 +72,7 @@ private: * buffer contain more data for the next read operation? */ bool ReadingFromBuffer() const { - return tail > 0 && offset < input->GetOffset(); - } - - /** - * Copy public attributes from the underlying input stream to the - * "rewind" input stream. This function is called when a method of - * the underlying stream has returned, which may have modified these - * attributes. - */ - void CopyAttributes() { - const InputStream *src = input; - - assert(src != this); - - if (!IsReady() && src->IsReady()) { - if (src->HasMimeType()) - SetMimeType(src->GetMimeType()); - - size = src->GetSize(); - seekable = src->IsSeekable(); - SetReady(); - } - - offset = src->GetOffset(); + return tail > 0 && offset < input.GetOffset(); } }; @@ -125,7 +83,7 @@ RewindInputStream::Read(void *ptr, size_t read_size, Error &error) /* buffered read */ assert(head == (size_t)offset); - assert(tail == (size_t)input->GetOffset()); + assert(tail == (size_t)input.GetOffset()); if (read_size > tail - head) read_size = tail - head; @@ -138,9 +96,9 @@ RewindInputStream::Read(void *ptr, size_t read_size, Error &error) } else { /* pass method call to underlying stream */ - size_t nbytes = input->Read(ptr, read_size, error); + size_t nbytes = input.Read(ptr, read_size, error); - if (input->GetOffset() > (offset_type)sizeof(buffer)) + if (input.GetOffset() > (offset_type)sizeof(buffer)) /* disable buffering */ tail = 0; else if (tail == (size_t)offset) { @@ -149,7 +107,7 @@ RewindInputStream::Read(void *ptr, size_t read_size, Error &error) memcpy(buffer + tail, ptr, nbytes); tail += nbytes; - assert(tail == (size_t)input->GetOffset()); + assert(tail == (size_t)input.GetOffset()); } CopyAttributes(); @@ -158,7 +116,7 @@ RewindInputStream::Read(void *ptr, size_t read_size, Error &error) } } -inline bool +bool RewindInputStream::Seek(offset_type new_offset, int whence, Error &error) { @@ -170,21 +128,18 @@ RewindInputStream::Seek(offset_type new_offset, int whence, assert(!ReadingFromBuffer() || head == (size_t)offset); - assert(tail == (size_t)input->GetOffset()); + assert(tail == (size_t)input.GetOffset()); head = (size_t)new_offset; offset = new_offset; return true; } else { - bool success = input->Seek(new_offset, whence, error); - CopyAttributes(); - /* disable the buffer, because input has left the buffered range now */ tail = 0; - return success; + return ProxyInputStream::Seek(new_offset, whence, error); } } |