1 /*
2 * Copyright 2003-2021 The Music Player Daemon Project
3 * http://www.musicpd.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "ProxyInputStream.hxx"
21 #include "tag/Tag.hxx"
22
23 #include <utility>
24
ProxyInputStream(InputStreamPtr _input)25 ProxyInputStream::ProxyInputStream(InputStreamPtr _input) noexcept
26 :InputStream(_input->GetURI(), _input->mutex),
27 input(std::move(_input))
28 {
29 assert(input);
30
31 input->SetHandler(this);
32 }
33
34 ProxyInputStream::~ProxyInputStream() noexcept = default;
35
36 void
SetInput(InputStreamPtr _input)37 ProxyInputStream::SetInput(InputStreamPtr _input) noexcept
38 {
39 assert(!input);
40 assert(_input);
41
42 input = std::move(_input);
43 input->SetHandler(this);
44
45 /* this call wakes up client threads if the new input is
46 ready */
47 CopyAttributes();
48
49 set_input_cond.notify_one();
50 }
51
52 void
CopyAttributes()53 ProxyInputStream::CopyAttributes()
54 {
55 assert(input);
56
57 if (input->IsReady()) {
58 if (!IsReady()) {
59 if (input->HasMimeType())
60 SetMimeType(input->GetMimeType());
61
62 size = input->KnownSize()
63 ? input->GetSize()
64 : UNKNOWN_SIZE;
65
66 seekable = input->IsSeekable();
67 SetReady();
68 }
69
70 offset = input->GetOffset();
71 }
72 }
73
74 void
Check()75 ProxyInputStream::Check()
76 {
77 if (input)
78 input->Check();
79 }
80
81 void
Update()82 ProxyInputStream::Update() noexcept
83 {
84 if (!input)
85 return;
86
87 input->Update();
88 CopyAttributes();
89 }
90
91 void
Seek(std::unique_lock<Mutex> & lock,offset_type new_offset)92 ProxyInputStream::Seek(std::unique_lock<Mutex> &lock,
93 offset_type new_offset)
94 {
95 set_input_cond.wait(lock, [this]{ return !!input; });
96
97 input->Seek(lock, new_offset);
98 CopyAttributes();
99 }
100
101 bool
IsEOF() const102 ProxyInputStream::IsEOF() const noexcept
103 {
104 return input && input->IsEOF();
105 }
106
107 std::unique_ptr<Tag>
ReadTag()108 ProxyInputStream::ReadTag() noexcept
109 {
110 if (!input)
111 return nullptr;
112
113 return input->ReadTag();
114 }
115
116 bool
IsAvailable() const117 ProxyInputStream::IsAvailable() const noexcept
118 {
119 return input && input->IsAvailable();
120 }
121
122 size_t
Read(std::unique_lock<Mutex> & lock,void * ptr,size_t read_size)123 ProxyInputStream::Read(std::unique_lock<Mutex> &lock,
124 void *ptr, size_t read_size)
125 {
126 set_input_cond.wait(lock, [this]{ return !!input; });
127
128 size_t nbytes = input->Read(lock, ptr, read_size);
129 CopyAttributes();
130 return nbytes;
131 }
132