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/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 | ||||
|  | ||||
|   | ||||
							
								
								
									
										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 "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); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann