InputStream.cxx 3.21 KB
Newer Older
1
/*
2
 * Copyright 2003-2016 The Music Player Daemon Project
3
 * http://www.musicpd.org
4 5 6 7 8 9 10 11 12 13
 *
 * 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.
14 15 16 17
 *
 * 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.
18 19
 */

Max Kellermann's avatar
Max Kellermann committed
20
#include "config.h"
21
#include "InputStream.hxx"
22
#include "thread/Cond.hxx"
23
#include "util/StringCompare.hxx"
24

25
#include <assert.h>
26

27 28 29 30
InputStream::~InputStream()
{
}

31
bool
32
InputStream::Check(gcc_unused Error &error)
33
{
34
	return true;
35 36
}

37
void
38
InputStream::Update()
39 40 41
{
}

42 43 44 45 46 47 48 49 50
void
InputStream::SetReady()
{
	assert(!ready);

	ready = true;
	cond.broadcast();
}

51
void
52
InputStream::WaitReady()
53 54
{
	while (true) {
55 56
		Update();
		if (ready)
57 58
			break;

59
		cond.wait(mutex);
60 61 62 63
	}
}

void
64
InputStream::LockWaitReady()
65
{
66 67
	const ScopeLock protect(mutex);
	WaitReady();
68 69
}

70 71 72 73 74 75 76 77 78
/**
 * Is seeking on resources behind this URI "expensive"?  For example,
 * seeking in a HTTP file requires opening a new connection with a new
 * HTTP request.
 */
gcc_pure
static bool
ExpensiveSeeking(const char *uri)
{
79 80
	return StringStartsWith(uri, "http://") ||
		StringStartsWith(uri, "https://");
81 82
}

83
bool
84
InputStream::CheapSeeking() const
85
{
86
	return IsSeekable() && !ExpensiveSeeking(uri.c_str());
87 88
}

89
bool
90
InputStream::Seek(gcc_unused offset_type new_offset,
91
		  gcc_unused Error &error)
Avuton Olrich's avatar
Avuton Olrich committed
92
{
93
	return false;
94 95
}

96
bool
97
InputStream::LockSeek(offset_type _offset, Error &error)
98
{
99
	const ScopeLock protect(mutex);
100
	return Seek(_offset, error);
101 102
}

103 104 105 106 107 108 109
bool
InputStream::LockSkip(offset_type _offset, Error &error)
{
	const ScopeLock protect(mutex);
	return Skip(_offset, error);
}

Max Kellermann's avatar
Max Kellermann committed
110
Tag *
111
InputStream::ReadTag()
112
{
113
	return nullptr;
114 115
}

Max Kellermann's avatar
Max Kellermann committed
116
Tag *
117
InputStream::LockReadTag()
118
{
119 120
	const ScopeLock protect(mutex);
	return ReadTag();
121 122 123
}

bool
124
InputStream::IsAvailable()
125
{
126
	return true;
127 128
}

129
size_t
130
InputStream::LockRead(void *ptr, size_t _size, Error &error)
131
{
132 133
#if !CLANG_CHECK_VERSION(3,6)
	/* disabled on clang due to -Wtautological-pointer-compare */
134
	assert(ptr != nullptr);
135
#endif
136
	assert(_size > 0);
137

138 139
	const ScopeLock protect(mutex);
	return Read(ptr, _size, error);
140 141
}

142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
bool
InputStream::ReadFull(void *_ptr, size_t _size, Error &error)
{
	uint8_t *ptr = (uint8_t *)_ptr;

	size_t nbytes_total = 0;
	while (_size > 0) {
		size_t nbytes = Read(ptr + nbytes_total, _size, error);
		if (nbytes == 0)
			return false;

		nbytes_total += nbytes;
		_size -= nbytes;
	}
	return true;
}

bool
InputStream::LockReadFull(void *ptr, size_t _size, Error &error)
{
#if !CLANG_CHECK_VERSION(3,6)
	/* disabled on clang due to -Wtautological-pointer-compare */
	assert(ptr != nullptr);
#endif
	assert(_size > 0);

	const ScopeLock protect(mutex);
	return ReadFull(ptr, _size, error);
}

172
bool
173
InputStream::LockIsEOF()
Avuton Olrich's avatar
Avuton Olrich committed
174
{
175 176
	const ScopeLock protect(mutex);
	return IsEOF();
177
}