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