InputStream: make various methods abstract
Replace InputPlugin attributes.
This commit is contained in:
parent
82337dec44
commit
d4b625b48e
@ -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
|
||||
@ -205,12 +178,6 @@ InputStream::LockRead(void *ptr, size_t _size, Error &error)
|
||||
return Read(ptr, _size, error);
|
||||
}
|
||||
|
||||
bool
|
||||
InputStream::IsEOF()
|
||||
{
|
||||
return plugin.eof(this);
|
||||
}
|
||||
|
||||
bool
|
||||
InputStream::LockIsEOF()
|
||||
{
|
||||
|
@ -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()
|
||||
bool
|
||||
ThreadInputStream::IsEOF()
|
||||
{
|
||||
return eof;
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadInputStream::IsEOF(InputStream *is)
|
||||
{
|
||||
ThreadInputStream &tis = *(ThreadInputStream *)is;
|
||||
return tis.IsEOF2();
|
||||
}
|
||||
|
@ -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,34 +54,43 @@ 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;
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
bool Seek(InputStream::offset_type new_offset, int whence, Error &error) {
|
||||
uint64_t current_offset;
|
||||
int result = nfs_lseek(ctx, fh, new_offset, whence,
|
||||
¤t_offset);
|
||||
if (result < 0) {
|
||||
error.SetErrno(-result, "smbc_lseek() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
offset = current_offset;
|
||||
return true;
|
||||
}
|
||||
size_t Read(void *ptr, size_t size, Error &error) override;
|
||||
bool Seek(offset_type offset, int whence, Error &error) override;
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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,
|
||||
¤t_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 IsAvailable() {
|
||||
return input->IsAvailable();
|
||||
}
|
||||
|
||||
size_t Read(void *ptr, size_t size, Error &error);
|
||||
|
||||
bool IsEOF() {
|
||||
bool IsEOF() override {
|
||||
return !ReadingFromBuffer() && input->IsEOF();
|
||||
}
|
||||
|
||||
bool Seek(InputPlugin::offset_type offset, int whence, Error &error);
|
||||
Tag *ReadTag() override {
|
||||
return input->ReadTag();
|
||||
}
|
||||
|
||||
bool IsAvailable() override {
|
||||
return input->IsAvailable();
|
||||
}
|
||||
|
||||
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 {
|
||||
/* virtual methods from InputStream */
|
||||
|
||||
bool IsEOF() override {
|
||||
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;
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
static bool
|
||||
input_smbclient_eof(InputStream *is)
|
||||
bool
|
||||
SmbclientInputStream::Seek(InputStream::offset_type new_offset,
|
||||
int whence, Error &error)
|
||||
{
|
||||
SmbclientInputStream &s = *(SmbclientInputStream *)is;
|
||||
return s.IsEOF();
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
static bool
|
||||
input_smbclient_seek(InputStream *is,
|
||||
InputPlugin::offset_type offset, int whence,
|
||||
Error &error)
|
||||
{
|
||||
SmbclientInputStream &s = *(SmbclientInputStream *)is;
|
||||
return s.Seek(offset, whence, error);
|
||||
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,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user