input/rewind: move code to class ProxyInputStream
This commit is contained in:
		| @@ -1032,6 +1032,7 @@ libinput_a_SOURCES = \ | |||||||
| 	src/input/InputPlugin.hxx \ | 	src/input/InputPlugin.hxx \ | ||||||
| 	src/input/TextInputStream.cxx src/input/TextInputStream.hxx \ | 	src/input/TextInputStream.cxx src/input/TextInputStream.hxx \ | ||||||
| 	src/input/ThreadInputStream.cxx src/input/ThreadInputStream.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/RewindInputPlugin.cxx src/input/plugins/RewindInputPlugin.hxx \ | ||||||
| 	src/input/plugins/FileInputPlugin.cxx src/input/plugins/FileInputPlugin.hxx | 	src/input/plugins/FileInputPlugin.cxx src/input/plugins/FileInputPlugin.hxx | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										97
									
								
								src/input/ProxyInputStream.cxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								src/input/ProxyInputStream.cxx
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||||
|  | } | ||||||
							
								
								
									
										64
									
								
								src/input/ProxyInputStream.hxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/input/ProxyInputStream.hxx
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
| @@ -19,14 +19,12 @@ | |||||||
|  |  | ||||||
| #include "config.h" | #include "config.h" | ||||||
| #include "RewindInputPlugin.hxx" | #include "RewindInputPlugin.hxx" | ||||||
| #include "../InputStream.hxx" | #include "../ProxyInputStream.hxx" | ||||||
|  |  | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  |  | ||||||
| class RewindInputStream final : public InputStream { | class RewindInputStream final : public ProxyInputStream { | ||||||
| 	InputStream *input; |  | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * The read position within the buffer.  Undefined as long as | 	 * The read position within the buffer.  Undefined as long as | ||||||
| 	 * ReadingFromBuffer() returns false. | 	 * ReadingFromBuffer() returns false. | ||||||
| @@ -50,36 +48,19 @@ class RewindInputStream final : public InputStream { | |||||||
|  |  | ||||||
| public: | public: | ||||||
| 	RewindInputStream(InputStream *_input) | 	RewindInputStream(InputStream *_input) | ||||||
| 		:InputStream(_input->GetURI(), | 		:ProxyInputStream(_input), | ||||||
| 			     _input->mutex, _input->cond), | 		 tail(0) { | ||||||
| 		 input(_input), tail(0) { |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	~RewindInputStream() { |  | ||||||
| 		delete input; |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* virtual methods from InputStream */ | 	/* virtual methods from InputStream */ | ||||||
|  |  | ||||||
| 	bool Check(Error &error) override { |  | ||||||
| 		return input->Check(error); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void Update() override { | 	void Update() override { | ||||||
| 		if (!ReadingFromBuffer()) | 		if (!ReadingFromBuffer()) | ||||||
| 			CopyAttributes(); | 			ProxyInputStream::Update(); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool IsEOF() override { | 	bool IsEOF() override { | ||||||
| 		return !ReadingFromBuffer() && input->IsEOF(); | 		return !ReadingFromBuffer() && ProxyInputStream::IsEOF(); | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	Tag *ReadTag() override { |  | ||||||
| 		return input->ReadTag(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	bool IsAvailable() override { |  | ||||||
| 		return input->IsAvailable(); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	size_t Read(void *ptr, size_t size, Error &error) override; | 	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? | 	 * buffer contain more data for the next read operation? | ||||||
| 	 */ | 	 */ | ||||||
| 	bool ReadingFromBuffer() const { | 	bool ReadingFromBuffer() const { | ||||||
| 		return tail > 0 && offset < input->GetOffset(); | 		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(); |  | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -125,7 +83,7 @@ RewindInputStream::Read(void *ptr, size_t read_size, Error &error) | |||||||
| 		/* buffered read */ | 		/* buffered read */ | ||||||
|  |  | ||||||
| 		assert(head == (size_t)offset); | 		assert(head == (size_t)offset); | ||||||
| 		assert(tail == (size_t)input->GetOffset()); | 		assert(tail == (size_t)input.GetOffset()); | ||||||
|  |  | ||||||
| 		if (read_size > tail - head) | 		if (read_size > tail - head) | ||||||
| 			read_size = tail - head; | 			read_size = tail - head; | ||||||
| @@ -138,9 +96,9 @@ RewindInputStream::Read(void *ptr, size_t read_size, Error &error) | |||||||
| 	} else { | 	} else { | ||||||
| 		/* pass method call to underlying stream */ | 		/* 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 */ | 			/* disable buffering */ | ||||||
| 			tail = 0; | 			tail = 0; | ||||||
| 		else if (tail == (size_t)offset) { | 		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); | 			memcpy(buffer + tail, ptr, nbytes); | ||||||
| 			tail += nbytes; | 			tail += nbytes; | ||||||
|  |  | ||||||
| 			assert(tail == (size_t)input->GetOffset()); | 			assert(tail == (size_t)input.GetOffset()); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		CopyAttributes(); | 		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, | RewindInputStream::Seek(offset_type new_offset, int whence, | ||||||
| 			Error &error) | 			Error &error) | ||||||
| { | { | ||||||
| @@ -170,21 +128,18 @@ RewindInputStream::Seek(offset_type new_offset, int whence, | |||||||
|  |  | ||||||
| 		assert(!ReadingFromBuffer() || | 		assert(!ReadingFromBuffer() || | ||||||
| 		       head == (size_t)offset); | 		       head == (size_t)offset); | ||||||
| 		assert(tail == (size_t)input->GetOffset()); | 		assert(tail == (size_t)input.GetOffset()); | ||||||
|  |  | ||||||
| 		head = (size_t)new_offset; | 		head = (size_t)new_offset; | ||||||
| 		offset = new_offset; | 		offset = new_offset; | ||||||
|  |  | ||||||
| 		return true; | 		return true; | ||||||
| 	} else { | 	} else { | ||||||
| 		bool success = input->Seek(new_offset, whence, error); |  | ||||||
| 		CopyAttributes(); |  | ||||||
|  |  | ||||||
| 		/* disable the buffer, because input has left the | 		/* disable the buffer, because input has left the | ||||||
| 		   buffered range now */ | 		   buffered range now */ | ||||||
| 		tail = 0; | 		tail = 0; | ||||||
|  |  | ||||||
| 		return success; | 		return ProxyInputStream::Seek(new_offset, whence, error); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann