Commit d4b625b4 authored by Max Kellermann's avatar Max Kellermann

InputStream: make various methods abstract

Replace InputPlugin attributes.
parent 82337dec
......@@ -102,6 +102,10 @@ struct Bzip2InputStream final : public InputStream {
~Bzip2InputStream();
bool Open(Error &error);
/* virtual methods from InputStream */
bool IsEOF() override;
size_t Read(void *ptr, size_t size, Error &error) override;
};
extern const InputPlugin bz2_inputplugin;
......@@ -198,30 +202,26 @@ bz2_fillbuffer(Bzip2InputStream *bis, Error &error)
return true;
}
static size_t
bz2_is_read(InputStream *is, void *ptr, size_t length,
Error &error)
size_t
Bzip2InputStream::Read(void *ptr, size_t length, Error &error)
{
Bzip2InputStream *bis = (Bzip2InputStream *)is;
bz_stream *bzstream;
int bz_result;
size_t nbytes = 0;
if (bis->eof)
if (eof)
return 0;
bzstream = &bis->bzstream;
bzstream->next_out = (char *)ptr;
bzstream->avail_out = length;
bzstream.next_out = (char *)ptr;
bzstream.avail_out = length;
do {
if (!bz2_fillbuffer(bis, error))
if (!bz2_fillbuffer(this, error))
return 0;
bz_result = BZ2_bzDecompress(bzstream);
bz_result = BZ2_bzDecompress(&bzstream);
if (bz_result == BZ_STREAM_END) {
bis->eof = true;
eof = true;
break;
}
......@@ -230,20 +230,18 @@ bz2_is_read(InputStream *is, void *ptr, size_t length,
"BZ2_bzDecompress() has failed");
return 0;
}
} while (bzstream->avail_out == length);
} while (bzstream.avail_out == length);
nbytes = length - bzstream->avail_out;
is->offset += nbytes;
nbytes = length - bzstream.avail_out;
offset += nbytes;
return nbytes;
}
static bool
bz2_is_eof(InputStream *is)
bool
Bzip2InputStream::IsEOF()
{
Bzip2InputStream *bis = (Bzip2InputStream *)is;
return bis->eof;
return eof;
}
/* exported structures */
......@@ -258,13 +256,6 @@ const InputPlugin bz2_inputplugin = {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
bz2_is_read,
bz2_is_eof,
nullptr,
};
const ArchivePlugin bz2_archive_plugin = {
......
......@@ -162,7 +162,9 @@ public:
archive.Unref();
}
size_t Read(void *ptr, size_t size, Error &error);
/* virtual methods from InputStream */
bool IsEOF() override;
size_t Read(void *ptr, size_t size, Error &error) override;
};
InputStream *
......@@ -181,7 +183,7 @@ Iso9660ArchiveFile::OpenStream(const char *pathname,
statbuf);
}
inline size_t
size_t
Iso9660InputStream::Read(void *ptr, size_t read_size, Error &error)
{
int readed = 0;
......@@ -216,18 +218,10 @@ Iso9660InputStream::Read(void *ptr, size_t read_size, Error &error)
return readed;
}
static size_t
iso9660_input_read(InputStream *is, void *ptr, size_t size,
Error &error)
bool
Iso9660InputStream::IsEOF()
{
Iso9660InputStream *iis = (Iso9660InputStream *)is;
return iis->Read(ptr, size, error);
}
static bool
iso9660_input_eof(InputStream *is)
{
return is->offset == is->size;
return offset == size;
}
/* exported structures */
......@@ -242,13 +236,6 @@ const InputPlugin iso9660_input_plugin = {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
iso9660_input_read,
iso9660_input_eof,
nullptr,
};
const ArchivePlugin iso9660_archive_plugin = {
......
......@@ -123,6 +123,11 @@ struct ZzipInputStream final : public InputStream {
zzip_file_close(file);
archive->Unref();
}
/* virtual methods from InputStream */
bool IsEOF() override;
size_t Read(void *ptr, size_t size, Error &error) override;
bool Seek(offset_type offset, int whence, Error &error) override;
};
InputStream *
......@@ -142,41 +147,32 @@ ZzipArchiveFile::OpenStream(const char *pathname,
_file);
}
static size_t
zzip_input_read(InputStream *is, void *ptr, size_t size,
Error &error)
size_t
ZzipInputStream::Read(void *ptr, size_t read_size, Error &error)
{
ZzipInputStream *zis = (ZzipInputStream *)is;
int ret;
ret = zzip_file_read(zis->file, ptr, size);
int ret = zzip_file_read(file, ptr, read_size);
if (ret < 0) {
error.Set(zzip_domain, "zzip_file_read() has failed");
return 0;
}
is->offset = zzip_tell(zis->file);
offset = zzip_tell(file);
return ret;
}
static bool
zzip_input_eof(InputStream *is)
bool
ZzipInputStream::IsEOF()
{
ZzipInputStream *zis = (ZzipInputStream *)is;
return (InputPlugin::offset_type)zzip_tell(zis->file) == is->size;
return (InputPlugin::offset_type)zzip_tell(file) == size;
}
static bool
zzip_input_seek(InputStream *is, InputPlugin::offset_type offset,
int whence, Error &error)
bool
ZzipInputStream::Seek(offset_type new_offset, int whence, Error &error)
{
ZzipInputStream *zis = (ZzipInputStream *)is;
zzip_off_t ofs = zzip_seek(zis->file, offset, whence);
zzip_off_t ofs = zzip_seek(file, new_offset, whence);
if (ofs != -1) {
error.Set(zzip_domain, "zzip_seek() has failed");
is->offset = ofs;
offset = ofs;
return true;
}
return false;
......@@ -194,13 +190,6 @@ const InputPlugin zzip_input_plugin = {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
zzip_input_read,
zzip_input_eof,
zzip_input_seek,
};
const ArchivePlugin zzip_archive_plugin = {
......
......@@ -82,38 +82,6 @@ struct InputPlugin {
InputStream *(*open)(const char *uri,
Mutex &mutex, Cond &cond,
Error &error);
/**
* Check for errors that may have occurred in the I/O thread.
* May be unimplemented for synchronous plugins.
*
* @return false on error
*/
bool (*check)(InputStream *is, Error &error);
/**
* Update the public attributes. Call before access. Can be
* nullptr if the plugin always keeps its attributes up to date.
*/
void (*update)(InputStream *is);
Tag *(*tag)(InputStream *is);
/**
* Returns true if the next read operation will not block:
* either data is available, or end-of-stream has been
* reached, or an error has occurred.
*
* If this method is unimplemented, then it is assumed that
* reading will never block.
*/
bool (*available)(InputStream *is);
size_t (*read)(InputStream *is, void *ptr, size_t size,
Error &error);
bool (*eof)(InputStream *is);
bool (*seek)(InputStream *is, offset_type offset, int whence,
Error &error);
};
#endif
......@@ -45,10 +45,6 @@ InputStream::Open(const char *url,
is = plugin->open(url, mutex, cond, error);
if (is != nullptr) {
assert(is->plugin.read != nullptr);
assert(is->plugin.eof != nullptr);
assert(!is->seekable || is->plugin.seek != nullptr);
is = input_rewind_open(is);
return is;
......@@ -83,16 +79,14 @@ InputStream::OpenReady(const char *uri,
}
bool
InputStream::Check(Error &error)
InputStream::Check(gcc_unused Error &error)
{
return plugin.check == nullptr || plugin.check(this, error);
return true;
}
void
InputStream::Update()
{
if (plugin.update != nullptr)
plugin.update(this);
}
void
......@@ -130,20 +124,15 @@ InputStream::CheapSeeking() const
}
bool
InputStream::Seek(offset_type _offset, int whence, Error &error)
InputStream::Seek(gcc_unused offset_type new_offset, gcc_unused int whence,
gcc_unused Error &error)
{
if (plugin.seek == nullptr)
return false;
return plugin.seek(this, _offset, whence, error);
return false;
}
bool
InputStream::LockSeek(offset_type _offset, int whence, Error &error)
{
if (plugin.seek == nullptr)
return false;
const ScopeLock protect(mutex);
return Seek(_offset, whence, error);
}
......@@ -163,17 +152,12 @@ InputStream::LockRewind(Error &error)
Tag *
InputStream::ReadTag()
{
return plugin.tag != nullptr
? plugin.tag(this)
: nullptr;
return nullptr;
}
Tag *
InputStream::LockReadTag()
{
if (plugin.tag == nullptr)
return nullptr;
const ScopeLock protect(mutex);
return ReadTag();
}
......@@ -181,18 +165,7 @@ InputStream::LockReadTag()
bool
InputStream::IsAvailable()
{
return plugin.available != nullptr
? plugin.available(this)
: true;
}
size_t
InputStream::Read(void *ptr, size_t _size, Error &error)
{
assert(ptr != nullptr);
assert(_size > 0);
return plugin.read(this, ptr, _size, error);
return true;
}
size_t
......@@ -206,12 +179,6 @@ InputStream::LockRead(void *ptr, size_t _size, Error &error)
}
bool
InputStream::IsEOF()
{
return plugin.eof(this);
}
bool
InputStream::LockIsEOF()
{
const ScopeLock protect(mutex);
......
......@@ -166,13 +166,13 @@ public:
*
* @return false on error
*/
bool Check(Error &error);
virtual bool Check(Error &error);
/**
* Update the public attributes. Call before accessing attributes
* such as "ready" or "offset".
*/
void Update();
virtual void Update();
void SetReady();
......@@ -272,7 +272,7 @@ public:
* @param offset the relative offset
* @param whence the base of the seek, one of SEEK_SET, SEEK_CUR, SEEK_END
*/
bool Seek(offset_type offset, int whence, Error &error);
virtual bool Seek(offset_type offset, int whence, Error &error);
/**
* Wrapper for Seek() which locks and unlocks the mutex; the
......@@ -293,7 +293,7 @@ public:
* The caller must lock the mutex.
*/
gcc_pure
bool IsEOF();
virtual bool IsEOF() = 0;
/**
* Wrapper for IsEOF() which locks and unlocks the mutex; the
......@@ -311,7 +311,7 @@ public:
* nullptr if the tag has not changed since the last call
*/
gcc_malloc
Tag *ReadTag();
virtual Tag *ReadTag();
/**
* Wrapper for ReadTag() which locks and unlocks the mutex;
......@@ -328,7 +328,7 @@ public:
* The caller must lock the mutex.
*/
gcc_pure
bool IsAvailable();
virtual bool IsAvailable();
/**
* Reads data from the stream into the caller-supplied buffer.
......@@ -342,7 +342,7 @@ public:
* @return the number of bytes read
*/
gcc_nonnull_all
size_t Read(void *ptr, size_t size, Error &error);
virtual size_t Read(void *ptr, size_t size, Error &error) = 0;
/**
* Wrapper for Read() which locks and unlocks the mutex;
......
......@@ -116,8 +116,8 @@ ThreadInputStream::ThreadFunc(void *ctx)
tis.ThreadFunc();
}
inline bool
ThreadInputStream::Check2(Error &error)
bool
ThreadInputStream::Check(Error &error)
{
if (postponed_error.IsDefined()) {
error = std::move(postponed_error);
......@@ -128,27 +128,13 @@ ThreadInputStream::Check2(Error &error)
}
bool
ThreadInputStream::Check(InputStream *is, Error &error)
{
ThreadInputStream &tis = *(ThreadInputStream *)is;
return tis.Check2(error);
}
inline bool
ThreadInputStream::Available2()
ThreadInputStream::IsAvailable()
{
return !buffer->IsEmpty() || eof || postponed_error.IsDefined();
}
bool
ThreadInputStream::Available(InputStream *is)
{
ThreadInputStream &tis = *(ThreadInputStream *)is;
return tis.Available2();
}
inline size_t
ThreadInputStream::Read2(void *ptr, size_t read_size, Error &error)
ThreadInputStream::Read(void *ptr, size_t read_size, Error &error)
{
while (true) {
if (postponed_error.IsDefined()) {
......@@ -173,23 +159,8 @@ ThreadInputStream::Read2(void *ptr, size_t read_size, Error &error)
}
}
size_t
ThreadInputStream::Read(InputStream *is, void *ptr, size_t size,
Error &error)
{
ThreadInputStream &tis = *(ThreadInputStream *)is;
return tis.Read2(ptr, size, error);
}
inline bool
ThreadInputStream::IsEOF2()
{
return eof;
}
bool
ThreadInputStream::IsEOF(InputStream *is)
ThreadInputStream::IsEOF()
{
ThreadInputStream &tis = *(ThreadInputStream *)is;
return tis.IsEOF2();
return eof;
}
......@@ -82,6 +82,12 @@ public:
*/
InputStream *Start(Error &error);
/* virtual methods from InputStream */
bool Check(Error &error) override final;
bool IsEOF() override final;
bool IsAvailable() override final;
size_t Read(void *ptr, size_t size, Error &error) override final;
protected:
void SetMimeType(const char *_mime) {
assert(thread.IsInside());
......@@ -110,7 +116,7 @@ protected:
*
* @return 0 on end-of-file or on error
*/
virtual size_t Read(void *ptr, size_t size, Error &error) = 0;
virtual size_t ThreadRead(void *ptr, size_t size, Error &error) = 0;
/**
* Optional deinitialization before leaving the thread.
......@@ -130,19 +136,6 @@ protected:
private:
void ThreadFunc();
static void ThreadFunc(void *ctx);
bool Check2(Error &error);
bool Available2();
size_t Read2(void *ptr, size_t size, Error &error);
bool IsEOF2();
public:
/* InputPlugin callbacks */
static bool Check(InputStream *is, Error &error);
static bool Available(InputStream *is);
static size_t Read(InputStream *is, void *ptr, size_t size,
Error &error);
static bool IsEOF(InputStream *is);
};
#endif
......@@ -116,7 +116,13 @@ public:
static InputStream *Create(const char *uri, Mutex &mutex, Cond &cond,
Error &error);
bool Available() {
/* virtual methods from InputStream */
bool IsEOF() override {
return eof;
}
bool IsAvailable() override {
if (snd_pcm_avail(capture_handle) > frames_to_read)
return true;
......@@ -126,11 +132,7 @@ public:
return false;
}
size_t Read(void *ptr, size_t size, Error &error);
bool IsEOF() {
return eof;
}
size_t Read(void *ptr, size_t size, Error &error) override;
private:
static snd_pcm_t *OpenDevice(const char *device, int rate,
......@@ -181,7 +183,7 @@ AlsaInputStream::Create(const char *uri, Mutex &mutex, Cond &cond,
handle, frame_size);
}
inline size_t
size_t
AlsaInputStream::Read(void *ptr, size_t read_size, Error &error)
{
assert(ptr != nullptr);
......@@ -373,37 +375,9 @@ alsa_input_open(const char *uri, Mutex &mutex, Cond &cond, Error &error)
return AlsaInputStream::Create(uri, mutex, cond, error);
}
static bool
alsa_input_available(InputStream *is)
{
AlsaInputStream *ais = (AlsaInputStream *)is;
return ais->Available();
}
static size_t
alsa_input_read(InputStream *is, void *ptr, size_t size, Error &error)
{
AlsaInputStream *ais = (AlsaInputStream *)is;
return ais->Read(ptr, size, error);
}
static bool
alsa_input_eof(gcc_unused InputStream *is)
{
AlsaInputStream *ais = (AlsaInputStream *)is;
return ais->IsEOF();
}
const struct InputPlugin input_plugin_alsa = {
"alsa",
nullptr,
nullptr,
alsa_input_open,
nullptr,
nullptr,
nullptr,
alsa_input_available,
alsa_input_read,
alsa_input_eof,
nullptr,
};
......@@ -89,11 +89,4 @@ const InputPlugin input_plugin_archive = {
nullptr,
nullptr,
input_archive_open,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
};
......@@ -79,6 +79,11 @@ struct CdioParanoiaInputStream final : public InputStream {
if (cdio != nullptr)
cdio_destroy(cdio);
}
/* virtual methods from InputStream */
bool IsEOF() override;
size_t Read(void *ptr, size_t size, Error &error) override;
bool Seek(offset_type offset, int whence, Error &error) override;
};
static constexpr Domain cdio_domain("cdio");
......@@ -266,48 +271,44 @@ input_cdio_open(const char *uri,
return i;
}
static bool
input_cdio_seek(InputStream *is,
InputPlugin::offset_type offset, int whence, Error &error)
bool
CdioParanoiaInputStream::Seek(InputPlugin::offset_type new_offset,
int whence, Error &error)
{
CdioParanoiaInputStream *cis = (CdioParanoiaInputStream *)is;
/* calculate absolute offset */
switch (whence) {
case SEEK_SET:
break;
case SEEK_CUR:
offset += cis->offset;
new_offset += offset;
break;
case SEEK_END:
offset += cis->size;
new_offset += size;
break;
}
if (offset < 0 || offset > cis->size) {
if (new_offset < 0 || new_offset > size) {
error.Format(cdio_domain, "Invalid offset to seek %ld (%ld)",
(long int)offset, (long int)cis->size);
(long int)new_offset, (long int)size);
return false;
}
/* simple case */
if (offset == cis->offset)
if (new_offset == offset)
return true;
/* calculate current LSN */
cis->lsn_relofs = offset / CDIO_CD_FRAMESIZE_RAW;
cis->offset = offset;
lsn_relofs = new_offset / CDIO_CD_FRAMESIZE_RAW;
offset = new_offset;
cdio_paranoia_seek(cis->para, cis->lsn_from + cis->lsn_relofs, SEEK_SET);
cdio_paranoia_seek(para, lsn_from + lsn_relofs, SEEK_SET);
return true;
}
static size_t
input_cdio_read(InputStream *is, void *ptr, size_t length,
Error &error)
size_t
CdioParanoiaInputStream::Read(void *ptr, size_t length, Error &error)
{
CdioParanoiaInputStream *cis = (CdioParanoiaInputStream *)is;
size_t nbytes = 0;
int diff;
size_t len, maxwrite;
......@@ -319,20 +320,20 @@ input_cdio_read(InputStream *is, void *ptr, size_t length,
/* end of track ? */
if (cis->lsn_from + cis->lsn_relofs > cis->lsn_to)
if (lsn_from + lsn_relofs > lsn_to)
break;
//current sector was changed ?
if (cis->lsn_relofs != cis->buffer_lsn) {
rbuf = cdio_paranoia_read(cis->para, nullptr);
if (lsn_relofs != buffer_lsn) {
rbuf = cdio_paranoia_read(para, nullptr);
s_err = cdda_errors(cis->drv);
s_err = cdda_errors(drv);
if (s_err) {
FormatError(cdio_domain,
"paranoia_read: %s", s_err);
free(s_err);
}
s_mess = cdda_messages(cis->drv);
s_mess = cdda_messages(drv);
if (s_mess) {
free(s_mess);
}
......@@ -342,15 +343,15 @@ input_cdio_read(InputStream *is, void *ptr, size_t length,
return 0;
}
//store current buffer
memcpy(cis->buffer, rbuf, CDIO_CD_FRAMESIZE_RAW);
cis->buffer_lsn = cis->lsn_relofs;
memcpy(buffer, rbuf, CDIO_CD_FRAMESIZE_RAW);
buffer_lsn = lsn_relofs;
} else {
//use cached sector
rbuf = (int16_t*) cis->buffer;
rbuf = (int16_t *)buffer;
}
//correct offset
diff = cis->offset - cis->lsn_relofs * CDIO_CD_FRAMESIZE_RAW;
diff = offset - lsn_relofs * CDIO_CD_FRAMESIZE_RAW;
assert(diff >= 0 && diff < CDIO_CD_FRAMESIZE_RAW);
......@@ -364,8 +365,8 @@ input_cdio_read(InputStream *is, void *ptr, size_t length,
nbytes += len;
//update offset
cis->offset += len;
cis->lsn_relofs = cis->offset / CDIO_CD_FRAMESIZE_RAW;
offset += len;
lsn_relofs = offset / CDIO_CD_FRAMESIZE_RAW;
//update length
length -= len;
}
......@@ -373,12 +374,10 @@ input_cdio_read(InputStream *is, void *ptr, size_t length,
return nbytes;
}
static bool
input_cdio_eof(InputStream *is)
bool
CdioParanoiaInputStream::IsEOF()
{
CdioParanoiaInputStream *cis = (CdioParanoiaInputStream *)is;
return (cis->lsn_from + cis->lsn_relofs > cis->lsn_to);
return lsn_from + lsn_relofs > lsn_to;
}
const InputPlugin input_plugin_cdio_paranoia = {
......@@ -386,11 +385,4 @@ const InputPlugin input_plugin_cdio_paranoia = {
input_cdio_init,
nullptr,
input_cdio_open,
nullptr,
nullptr,
nullptr,
nullptr,
input_cdio_read,
input_cdio_eof,
input_cdio_seek,
};
......@@ -120,23 +120,6 @@ struct CurlInputStream final : public InputStream {
static InputStream *Open(const char *url, Mutex &mutex, Cond &cond,
Error &error);
bool Check(Error &error);
bool IsEOF() const {
return easy == nullptr && buffer.IsEmpty();
}
bool Seek(InputPlugin::offset_type offset, int whence, Error &error);
Tag *ReadTag();
bool IsAvailable() const {
return postponed_error.IsDefined() || easy == nullptr ||
!buffer.IsEmpty();
}
size_t Read(void *ptr, size_t size, Error &error);
bool InitEasy(Error &error);
/**
......@@ -180,6 +163,23 @@ struct CurlInputStream final : public InputStream {
* Runs in the I/O thread. The caller must not hold locks.
*/
void RequestDone(CURLcode result, long status);
/* virtual methods from InputStream */
bool Check(Error &error) override;
bool IsEOF() override {
return easy == nullptr && buffer.IsEmpty();
}
Tag *ReadTag() override;
bool IsAvailable() override {
return postponed_error.IsDefined() || easy == nullptr ||
!buffer.IsEmpty();
}
size_t Read(void *ptr, size_t size, Error &error) override;
bool Seek(offset_type offset, int whence, Error &error) override;
};
class CurlMulti;
......@@ -660,14 +660,7 @@ CurlInputStream::Check(Error &error)
return success;
}
static bool
input_curl_check(InputStream *is, Error &error)
{
CurlInputStream &c = *(CurlInputStream *)is;
return c.Check(error);
}
inline Tag *
Tag *
CurlInputStream::ReadTag()
{
Tag *result = tag;
......@@ -675,13 +668,6 @@ CurlInputStream::ReadTag()
return result;
}
static Tag *
input_curl_tag(InputStream *is)
{
CurlInputStream &c = *(CurlInputStream *)is;
return c.ReadTag();
}
inline bool
CurlInputStream::FillBuffer(Error &error)
{
......@@ -758,14 +744,7 @@ CurlInputStream::CopyIcyTag()
tag = new_tag;
}
static bool
input_curl_available(InputStream *is)
{
const CurlInputStream &c = *(const CurlInputStream *)is;
return c.IsAvailable();
}
inline size_t
size_t
CurlInputStream::Read(void *ptr, size_t read_size, Error &error)
{
size_t nbytes;
......@@ -797,21 +776,6 @@ CurlInputStream::Read(void *ptr, size_t read_size, Error &error)
return nbytes;
}
static size_t
input_curl_read(InputStream *is, void *ptr, size_t size,
Error &error)
{
CurlInputStream &c = *(CurlInputStream *)is;
return c.Read(ptr, size, error);
}
static bool
input_curl_eof(gcc_unused InputStream *is)
{
const CurlInputStream &c = *(const CurlInputStream *)is;
return c.IsEOF();
}
inline void
CurlInputStream::HeaderReceived(const char *name, std::string &&value)
{
......@@ -1091,15 +1055,6 @@ CurlInputStream::Seek(InputPlugin::offset_type new_offset, int whence,
return true;
}
static bool
input_curl_seek(InputStream *is, InputPlugin::offset_type offset,
int whence,
Error &error)
{
CurlInputStream &c = *(CurlInputStream *)is;
return c.Seek(offset, whence, error);
}
inline InputStream *
CurlInputStream::Open(const char *url, Mutex &mutex, Cond &cond,
Error &error)
......@@ -1136,11 +1091,4 @@ const struct InputPlugin input_plugin_curl = {
input_curl_init,
input_curl_finish,
input_curl_open,
input_curl_check,
nullptr,
input_curl_tag,
input_curl_available,
input_curl_read,
input_curl_eof,
input_curl_seek,
};
......@@ -66,13 +66,15 @@ public:
static InputStream *Open(const char *url, Mutex &mutex, Cond &cond,
Error &error);
bool IsEOF() const {
void Callback(int sig);
/* virtual methods from InputStream */
bool IsEOF() override {
return eof;
}
size_t Read(void *ptr, size_t size, Error &error);
Tag *ReadTag() {
Tag *ReadTag() override {
if (tag.IsEmpty())
return nullptr;
......@@ -81,7 +83,7 @@ public:
return result;
}
void Callback(int sig);
size_t Read(void *ptr, size_t size, Error &error) override;
private:
void FillBuffer();
......@@ -201,7 +203,7 @@ input_despotify_open(const char *url, Mutex &mutex, Cond &cond, Error &error)
return DespotifyInputStream::Open(url, mutex, cond, error);
}
inline size_t
size_t
DespotifyInputStream::Read(void *ptr, size_t read_size,
gcc_unused Error &error)
{
......@@ -217,39 +219,9 @@ DespotifyInputStream::Read(void *ptr, size_t read_size,
return to_cpy;
}
static size_t
input_despotify_read(InputStream *is, void *ptr, size_t size, Error &error)
{
DespotifyInputStream *ctx = (DespotifyInputStream *)is;
return ctx->Read(ptr, size, error);
}
static bool
input_despotify_eof(InputStream *is)
{
DespotifyInputStream *ctx = (DespotifyInputStream *)is;
return ctx->IsEOF();
}
static Tag *
input_despotify_tag(InputStream *is)
{
DespotifyInputStream *ctx = (DespotifyInputStream *)is;
return ctx->ReadTag();
}
const InputPlugin input_plugin_despotify = {
"despotify",
nullptr,
nullptr,
input_despotify_open,
nullptr,
nullptr,
input_despotify_tag,
nullptr,
input_despotify_read,
input_despotify_eof,
nullptr,
};
......@@ -56,6 +56,11 @@ struct FfmpegInputStream final : public InputStream {
~FfmpegInputStream() {
avio_close(h);
}
/* virtual methods from InputStream */
bool IsEOF() override;
size_t Read(void *ptr, size_t size, Error &error) override;
bool Seek(offset_type offset, int whence, Error &error) override;
};
static constexpr Domain ffmpeg_domain("ffmpeg");
......@@ -106,43 +111,35 @@ input_ffmpeg_open(const char *uri,
return new FfmpegInputStream(uri, mutex, cond, h);
}
static size_t
input_ffmpeg_read(InputStream *is, void *ptr, size_t size,
Error &error)
size_t
FfmpegInputStream::Read(void *ptr, size_t read_size, Error &error)
{
FfmpegInputStream *i = (FfmpegInputStream *)is;
int ret = avio_read(i->h, (unsigned char *)ptr, size);
int ret = avio_read(h, (unsigned char *)ptr, read_size);
if (ret <= 0) {
if (ret < 0)
error.Set(ffmpeg_domain, "avio_read() failed");
i->eof = true;
eof = true;
return false;
}
is->offset += ret;
offset += ret;
return (size_t)ret;
}
static bool
input_ffmpeg_eof(InputStream *is)
bool
FfmpegInputStream::IsEOF()
{
FfmpegInputStream *i = (FfmpegInputStream *)is;
return i->eof;
return eof;
}
static bool
input_ffmpeg_seek(InputStream *is, InputPlugin::offset_type offset,
int whence,
Error &error)
bool
FfmpegInputStream::Seek(offset_type new_offset, int whence, Error &error)
{
FfmpegInputStream *i = (FfmpegInputStream *)is;
int64_t ret = avio_seek(i->h, offset, whence);
int64_t ret = avio_seek(h, new_offset, whence);
if (ret >= 0) {
i->eof = false;
eof = false;
return true;
} else {
error.Set(ffmpeg_domain, "avio_seek() failed");
......@@ -155,11 +152,4 @@ const InputPlugin input_plugin_ffmpeg = {
input_ffmpeg_init,
nullptr,
input_ffmpeg_open,
nullptr,
nullptr,
nullptr,
nullptr,
input_ffmpeg_read,
input_ffmpeg_eof,
input_ffmpeg_seek,
};
......@@ -48,6 +48,15 @@ struct FileInputStream final : public InputStream {
~FileInputStream() {
close(fd);
}
/* virtual methods from InputStream */
bool IsEOF() override {
return GetOffset() >= GetSize();
}
size_t Read(void *ptr, size_t size, Error &error) override;
bool Seek(offset_type offset, int whence, Error &error) override;
};
static InputStream *
......@@ -89,56 +98,37 @@ input_file_open(const char *filename,
return new FileInputStream(filename, fd, st.st_size, mutex, cond);
}
static bool
input_file_seek(InputStream *is, InputPlugin::offset_type offset,
int whence,
Error &error)
bool
FileInputStream::Seek(InputPlugin::offset_type new_offset, int whence,
Error &error)
{
FileInputStream *fis = (FileInputStream *)is;
offset = (InputPlugin::offset_type)lseek(fis->fd, (off_t)offset, whence);
if (offset < 0) {
new_offset = (InputPlugin::offset_type)lseek(fd, (off_t)new_offset,
whence);
if (new_offset < 0) {
error.SetErrno("Failed to seek");
return false;
}
is->offset = offset;
offset = new_offset;
return true;
}
static size_t
input_file_read(InputStream *is, void *ptr, size_t size,
Error &error)
size_t
FileInputStream::Read(void *ptr, size_t read_size, Error &error)
{
FileInputStream *fis = (FileInputStream *)is;
ssize_t nbytes;
nbytes = read(fis->fd, ptr, size);
ssize_t nbytes = read(fd, ptr, read_size);
if (nbytes < 0) {
error.SetErrno("Failed to read");
return 0;
}
is->offset += nbytes;
offset += nbytes;
return (size_t)nbytes;
}
static bool
input_file_eof(InputStream *is)
{
return is->GetOffset() >= is->GetSize();
}
const InputPlugin input_plugin_file = {
"file",
nullptr,
nullptr,
input_file_open,
nullptr,
nullptr,
nullptr,
nullptr,
input_file_read,
input_file_eof,
input_file_seek,
};
......@@ -40,7 +40,8 @@ public:
protected:
virtual bool Open(gcc_unused Error &error) override;
virtual size_t Read(void *ptr, size_t size, Error &error) override;
virtual size_t ThreadRead(void *ptr, size_t size,
Error &error) override;
virtual void Close() {
mmsx_close(mms);
......@@ -89,7 +90,7 @@ input_mms_open(const char *url,
}
size_t
MmsInputStream::Read(void *ptr, size_t read_size, Error &error)
MmsInputStream::ThreadRead(void *ptr, size_t read_size, Error &error)
{
int nbytes = mmsx_read(nullptr, mms, (char *)ptr, read_size);
if (nbytes <= 0) {
......@@ -106,11 +107,4 @@ const InputPlugin input_plugin_mms = {
nullptr,
nullptr,
input_mms_open,
ThreadInputStream::Check,
nullptr,
nullptr,
ThreadInputStream::Available,
ThreadInputStream::Read,
ThreadInputStream::IsEOF,
nullptr,
};
......@@ -54,33 +54,42 @@ public:
nfs_destroy_context(ctx);
}
bool IsEOF() const {
/* virtual methods from InputStream */
bool IsEOF() override {
return offset >= size;
}
size_t Read(void *ptr, size_t read_size, Error &error) {
int nbytes = nfs_read(ctx, fh, read_size, (char *)ptr);
if (nbytes < 0) {
error.SetErrno(-nbytes, "nfs_read() failed");
nbytes = 0;
}
size_t Read(void *ptr, size_t size, Error &error) override;
bool Seek(offset_type offset, int whence, Error &error) override;
};
return nbytes;
size_t
NfsInputStream::Read(void *ptr, size_t read_size, Error &error)
{
int nbytes = nfs_read(ctx, fh, read_size, (char *)ptr);
if (nbytes < 0) {
error.SetErrno(-nbytes, "nfs_read() failed");
nbytes = 0;
}
bool Seek(InputStream::offset_type new_offset, int whence, Error &error) {
uint64_t current_offset;
int result = nfs_lseek(ctx, fh, new_offset, whence,
&current_offset);
if (result < 0) {
error.SetErrno(-result, "smbc_lseek() failed");
return false;
}
offset = current_offset;
return true;
return nbytes;
}
bool
NfsInputStream::Seek(offset_type new_offset, int whence, Error &error)
{
uint64_t current_offset;
int result = nfs_lseek(ctx, fh, new_offset, whence,
&current_offset);
if (result < 0) {
error.SetErrno(-result, "smbc_lseek() failed");
return false;
}
};
offset = current_offset;
return true;
}
/*
* InputPlugin methods
......@@ -148,40 +157,9 @@ input_nfs_open(const char *uri,
return new NfsInputStream(uri, mutex, cond, ctx, fh, st.st_size);
}
static size_t
input_nfs_read(InputStream *is, void *ptr, size_t size,
Error &error)
{
NfsInputStream &s = *(NfsInputStream *)is;
return s.Read(ptr, size, error);
}
static bool
input_nfs_eof(InputStream *is)
{
NfsInputStream &s = *(NfsInputStream *)is;
return s.IsEOF();
}
static bool
input_nfs_seek(InputStream *is,
InputPlugin::offset_type offset, int whence,
Error &error)
{
NfsInputStream &s = *(NfsInputStream *)is;
return s.Seek(offset, whence, error);
}
const InputPlugin input_plugin_nfs = {
"nfs",
nullptr,
nullptr,
input_nfs_open,
nullptr,
nullptr,
nullptr,
nullptr,
input_nfs_read,
input_nfs_eof,
input_nfs_seek,
};
......@@ -26,7 +26,12 @@
#include <string.h>
#include <stdio.h>
extern const InputPlugin rewind_input_plugin;
static const InputPlugin rewind_input_plugin = {
nullptr,
nullptr,
nullptr,
nullptr,
};
class RewindInputStream final : public InputStream {
InputStream *input;
......@@ -63,30 +68,31 @@ public:
delete input;
}
bool Check(Error &error) {
/* virtual methods from InputStream */
bool Check(Error &error) override {
return input->Check(error);
}
void Update() {
void Update() override {
if (!ReadingFromBuffer())
CopyAttributes();
}
Tag *ReadTag() {
return input->ReadTag();
bool IsEOF() override {
return !ReadingFromBuffer() && input->IsEOF();
}
bool IsAvailable() {
return input->IsAvailable();
Tag *ReadTag() override {
return input->ReadTag();
}
size_t Read(void *ptr, size_t size, Error &error);
bool IsEOF() {
return !ReadingFromBuffer() && input->IsEOF();
bool IsAvailable() override {
return input->IsAvailable();
}
bool Seek(InputPlugin::offset_type offset, int whence, Error &error);
size_t Read(void *ptr, size_t size, Error &error) override;
bool Seek(offset_type offset, int whence, Error &error) override;
private:
/**
......@@ -121,39 +127,7 @@ private:
}
};
static bool
input_rewind_check(InputStream *is, Error &error)
{
RewindInputStream *r = (RewindInputStream *)is;
return r->Check(error);
}
static void
input_rewind_update(InputStream *is)
{
RewindInputStream *r = (RewindInputStream *)is;
r->Update();
}
static Tag *
input_rewind_tag(InputStream *is)
{
RewindInputStream *r = (RewindInputStream *)is;
return r->ReadTag();
}
static bool
input_rewind_available(InputStream *is)
{
RewindInputStream *r = (RewindInputStream *)is;
return r->IsAvailable();
}
inline size_t
size_t
RewindInputStream::Read(void *ptr, size_t read_size, Error &error)
{
if (ReadingFromBuffer()) {
......@@ -193,23 +167,6 @@ RewindInputStream::Read(void *ptr, size_t read_size, Error &error)
}
}
static size_t
input_rewind_read(InputStream *is, void *ptr, size_t size,
Error &error)
{
RewindInputStream *r = (RewindInputStream *)is;
return r->Read(ptr, size, error);
}
static bool
input_rewind_eof(InputStream *is)
{
RewindInputStream *r = (RewindInputStream *)is;
return r->IsEOF();
}
inline bool
RewindInputStream::Seek(InputPlugin::offset_type new_offset, int whence,
Error &error)
......@@ -240,30 +197,6 @@ RewindInputStream::Seek(InputPlugin::offset_type new_offset, int whence,
}
}
static bool
input_rewind_seek(InputStream *is, InputPlugin::offset_type offset,
int whence,
Error &error)
{
RewindInputStream *r = (RewindInputStream *)is;
return r->Seek(offset, whence, error);
}
const InputPlugin rewind_input_plugin = {
nullptr,
nullptr,
nullptr,
nullptr,
input_rewind_check,
input_rewind_update,
input_rewind_tag,
input_rewind_available,
input_rewind_read,
input_rewind_eof,
input_rewind_seek,
};
InputStream *
input_rewind_open(InputStream *is)
{
......
......@@ -50,34 +50,14 @@ public:
smbclient_mutex.unlock();
}
bool IsEOF() const {
return offset >= size;
}
size_t Read(void *ptr, size_t read_size, Error &error) {
smbclient_mutex.lock();
ssize_t nbytes = smbc_read(fd, ptr, read_size);
smbclient_mutex.unlock();
if (nbytes < 0) {
error.SetErrno("smbc_read() failed");
nbytes = 0;
}
/* virtual methods from InputStream */
return nbytes;
bool IsEOF() override {
return offset >= size;
}
bool Seek(InputStream::offset_type new_offset, int whence, Error &error) {
smbclient_mutex.lock();
off_t result = smbc_lseek(fd, new_offset, whence);
smbclient_mutex.unlock();
if (result < 0) {
error.SetErrno("smbc_lseek() failed");
return false;
}
offset = result;
return true;
}
size_t Read(void *ptr, size_t size, Error &error) override;
bool Seek(offset_type offset, int whence, Error &error) override;
};
/*
......@@ -141,28 +121,34 @@ input_smbclient_open(const char *uri,
return new SmbclientInputStream(uri, mutex, cond, ctx, fd, st);
}
static size_t
input_smbclient_read(InputStream *is, void *ptr, size_t size,
Error &error)
size_t
SmbclientInputStream::Read(void *ptr, size_t read_size, Error &error)
{
SmbclientInputStream &s = *(SmbclientInputStream *)is;
return s.Read(ptr, size, error);
}
smbclient_mutex.lock();
ssize_t nbytes = smbc_read(fd, ptr, read_size);
smbclient_mutex.unlock();
if (nbytes < 0) {
error.SetErrno("smbc_read() failed");
nbytes = 0;
}
static bool
input_smbclient_eof(InputStream *is)
{
SmbclientInputStream &s = *(SmbclientInputStream *)is;
return s.IsEOF();
return nbytes;
}
static bool
input_smbclient_seek(InputStream *is,
InputPlugin::offset_type offset, int whence,
Error &error)
bool
SmbclientInputStream::Seek(InputStream::offset_type new_offset,
int whence, Error &error)
{
SmbclientInputStream &s = *(SmbclientInputStream *)is;
return s.Seek(offset, whence, error);
smbclient_mutex.lock();
off_t result = smbc_lseek(fd, new_offset, whence);
smbclient_mutex.unlock();
if (result < 0) {
error.SetErrno("smbc_lseek() failed");
return false;
}
offset = result;
return true;
}
const InputPlugin input_plugin_smbclient = {
......@@ -170,11 +156,4 @@ const InputPlugin input_plugin_smbclient = {
input_smbclient_init,
nullptr,
input_smbclient_open,
nullptr,
nullptr,
nullptr,
nullptr,
input_smbclient_read,
input_smbclient_eof,
input_smbclient_seek,
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment