MPD  0.20.18
InputStream.hxx
Go to the documentation of this file.
1 /*
2  * Copyright 2003-2017 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 #ifndef MPD_INPUT_STREAM_HXX
21 #define MPD_INPUT_STREAM_HXX
22 
23 #include "check.h"
24 #include "Offset.hxx"
25 #include "Ptr.hxx"
26 #include "thread/Mutex.hxx"
27 #include "Compiler.h"
28 
29 #include <string>
30 
31 #include <assert.h>
32 
33 class Cond;
34 struct Tag;
35 
36 class InputStream {
37 public:
39 
40 private:
44  std::string uri;
45 
46 public:
56 
66 
67 protected:
72  bool ready;
73 
77  bool seekable;
78 
79  static constexpr offset_type UNKNOWN_SIZE = -1;
80 
84  offset_type size;
85 
89  offset_type offset;
90 
91 private:
95  std::string mime;
96 
97 public:
98  InputStream(const char *_uri, Mutex &_mutex, Cond &_cond)
99  :uri(_uri),
100  mutex(_mutex), cond(_cond),
101  ready(false), seekable(false),
102  size(UNKNOWN_SIZE), offset(0) {
103  assert(_uri != nullptr);
104  }
105 
111  virtual ~InputStream();
112 
127  static InputStreamPtr Open(const char *uri, Mutex &mutex, Cond &cond);
128 
134  static InputStreamPtr OpenReady(const char *uri,
135  Mutex &mutex, Cond &cond);
136 
142  const char *GetURI() const {
143  return uri.c_str();
144  }
145 
146  void Lock() {
147  mutex.lock();
148  }
149 
150  void Unlock() {
151  mutex.unlock();
152  }
153 
158  virtual void Check();
159 
164  virtual void Update();
165 
166  void SetReady();
167 
174  bool IsReady() const {
175  return ready;
176  }
177 
178  void WaitReady();
179 
184  void LockWaitReady();
185 
186  gcc_pure
187  bool HasMimeType() const noexcept {
188  assert(ready);
189 
190  return !mime.empty();
191  }
192 
193  gcc_pure
194  const char *GetMimeType() const noexcept {
195  assert(ready);
196 
197  return mime.empty() ? nullptr : mime.c_str();
198  }
199 
200  void ClearMimeType() noexcept {
201  mime.clear();
202  }
203 
205  void SetMimeType(const char *_mime) {
206  assert(!ready);
207 
208  mime = _mime;
209  }
210 
211  void SetMimeType(std::string &&_mime) {
212  assert(!ready);
213 
214  mime = std::move(_mime);
215  }
216 
217  gcc_pure
218  bool KnownSize() const noexcept {
219  assert(ready);
220 
221  return size != UNKNOWN_SIZE;
222  }
223 
224  gcc_pure
225  offset_type GetSize() const noexcept {
226  assert(ready);
227  assert(KnownSize());
228 
229  return size;
230  }
231 
232  void AddOffset(offset_type delta) noexcept {
233  assert(ready);
234 
235  offset += delta;
236  }
237 
238  gcc_pure
239  offset_type GetOffset() const noexcept {
240  assert(ready);
241 
242  return offset;
243  }
244 
245  gcc_pure
246  offset_type GetRest() const noexcept {
247  assert(ready);
248  assert(KnownSize());
249 
250  return size - offset;
251  }
252 
253  gcc_pure
254  bool IsSeekable() const noexcept {
255  assert(ready);
256 
257  return seekable;
258  }
259 
263  gcc_pure
264  bool CheapSeeking() const noexcept;
265 
276  virtual void Seek(offset_type offset);
277 
282  void LockSeek(offset_type offset);
283 
288  void Rewind() {
289  Seek(0);
290  }
291 
292  void LockRewind() {
293  LockSeek(0);
294  }
295 
299  void Skip(offset_type _offset) {
300  Seek(GetOffset() + _offset);
301  }
302 
303  void LockSkip(offset_type _offset);
304 
310  gcc_pure
311  virtual bool IsEOF() noexcept = 0;
312 
317  gcc_pure
318  bool LockIsEOF() noexcept;
319 
328  gcc_malloc
329  virtual Tag *ReadTag();
330 
335  gcc_malloc
336  Tag *LockReadTag();
337 
345  gcc_pure
346  virtual bool IsAvailable() noexcept;
347 
361  virtual size_t Read(void *ptr, size_t size) = 0;
362 
370  size_t LockRead(void *ptr, size_t size);
371 
384  void ReadFull(void *ptr, size_t size);
385 
393  void LockReadFull(void *ptr, size_t size);
394 };
395 
396 #endif
gcc_pure offset_type GetSize() const noexcept
gcc_nonnull_all void LockReadFull(void *ptr, size_t size)
Wrapper for ReadFull() which locks and unlocks the mutex; the caller must not be holding it already...
gcc_pure bool HasMimeType() const noexcept
static constexpr offset_type UNKNOWN_SIZE
Definition: InputStream.hxx:79
Mutex & mutex
A mutex that protects the mutable attributes of this object and its implementation.
Definition: InputStream.hxx:55
#define gcc_nonnull_all
Definition: Compiler.h:122
gcc_nonnull_all void SetMimeType(const char *_mime)
virtual gcc_pure bool IsAvailable() noexcept
Returns true if the next read operation will not block: either data is available, or end-of-stream ha...
gcc_malloc Tag * LockReadTag()
Wrapper for ReadTag() which locks and unlocks the mutex; the caller must not be holding it already...
virtual ~InputStream()
Close the input stream and free resources.
The meta information about a song file.
Definition: Tag.hxx:34
void AddOffset(offset_type delta) noexcept
gcc_pure bool KnownSize() const noexcept
gcc_pure bool CheapSeeking() const noexcept
Determines whether seeking is cheap.
void SetReady()
#define gcc_malloc
Definition: Compiler.h:112
::offset_type offset_type
Definition: InputStream.hxx:38
static gcc_nonnull_all InputStreamPtr OpenReady(const char *uri, Mutex &mutex, Cond &cond)
Just like Open(), but waits for the stream to become ready.
Definition: Cond.hxx:41
Definition: Mutex.hxx:43
offset_type size
the size of the resource, or UNKNOWN_SIZE if unknown
Definition: InputStream.hxx:84
virtual gcc_nonnull_all size_t Read(void *ptr, size_t size)=0
Reads data from the stream into the caller-supplied buffer.
virtual void Update()
Update the public attributes.
bool seekable
if true, then the stream is fully seekable
Definition: InputStream.hxx:77
gcc_pure offset_type GetOffset() const noexcept
InputStream(const char *_uri, Mutex &_mutex, Cond &_cond)
Definition: InputStream.hxx:98
gcc_pure const char * GetMimeType() const noexcept
offset_type offset
the current offset within the stream
Definition: InputStream.hxx:89
void SetMimeType(std::string &&_mime)
gcc_nonnull_all size_t LockRead(void *ptr, size_t size)
Wrapper for Read() which locks and unlocks the mutex; the caller must not be holding it already...
bool IsReady() const
Return whether the stream is ready for reading and whether the other attributes in this struct are va...
virtual gcc_pure bool IsEOF() noexcept=0
Returns true if the stream has reached end-of-file.
void Skip(offset_type _offset)
Skip input bytes.
virtual gcc_malloc Tag * ReadTag()
Reads the tag from the stream.
void Rewind()
Rewind to the beginning of the stream.
gcc_pure offset_type GetRest() const noexcept
void LockSeek(offset_type offset)
Wrapper for Seek() which locks and unlocks the mutex; the caller must not be holding it already...
std::unique_ptr< InputStream > InputStreamPtr
Definition: Ptr.hxx:25
void WaitReady()
virtual void Seek(offset_type offset)
Seeks to the specified position in the stream.
gcc_pure bool IsSeekable() const noexcept
void unlock()
Definition: PosixMutex.hxx:71
void LockSkip(offset_type _offset)
bool ready
indicates whether the stream is ready for reading and whether the other attributes in this struct are...
Definition: InputStream.hxx:72
uint64_t offset_type
A type for absolute offsets in a file.
Definition: Offset.hxx:30
const char * GetURI() const
The absolute URI which was used to open this stream.
static gcc_nonnull_all InputStreamPtr Open(const char *uri, Mutex &mutex, Cond &cond)
Opens a new input stream.
Cond & cond
A cond that gets signalled when the state of this object changes from the I/O thread.
Definition: InputStream.hxx:65
void LockRewind()
gcc_pure bool LockIsEOF() noexcept
Wrapper for IsEOF() which locks and unlocks the mutex; the caller must not be holding it already...
gcc_nonnull_all void ReadFull(void *ptr, size_t size)
Reads the whole data from the stream into the caller-supplied buffer.
#define gcc_pure
Definition: Compiler.h:116
void LockWaitReady()
Wrapper for WaitReady() which locks and unlocks the mutex; the caller must not be holding it already...
void lock()
Definition: PosixMutex.hxx:63
void ClearMimeType() noexcept
virtual void Check()
Check for errors that may have occurred in the I/O thread.