input/InputStream: migrate from class Error to C++ exceptions
This commit is contained in:
@@ -78,16 +78,14 @@ AsyncInputStream::Resume()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AsyncInputStream::Check(Error &)
|
||||
void
|
||||
AsyncInputStream::Check()
|
||||
{
|
||||
if (postponed_exception) {
|
||||
auto e = std::move(postponed_exception);
|
||||
postponed_exception = std::exception_ptr();
|
||||
std::rethrow_exception(e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -97,15 +95,15 @@ AsyncInputStream::IsEOF()
|
||||
(!open && buffer.IsEmpty());
|
||||
}
|
||||
|
||||
bool
|
||||
AsyncInputStream::Seek(offset_type new_offset, Error &error)
|
||||
void
|
||||
AsyncInputStream::Seek(offset_type new_offset)
|
||||
{
|
||||
assert(IsReady());
|
||||
assert(seek_state == SeekState::NONE);
|
||||
|
||||
if (new_offset == offset)
|
||||
/* no-op */
|
||||
return true;
|
||||
return;
|
||||
|
||||
if (!IsSeekable())
|
||||
throw std::runtime_error("Not seekable");
|
||||
@@ -127,7 +125,7 @@ AsyncInputStream::Seek(offset_type new_offset, Error &error)
|
||||
}
|
||||
|
||||
if (new_offset == offset)
|
||||
return true;
|
||||
return;
|
||||
|
||||
/* no: ask the implementation to seek */
|
||||
|
||||
@@ -139,10 +137,7 @@ AsyncInputStream::Seek(offset_type new_offset, Error &error)
|
||||
while (seek_state != SeekState::NONE)
|
||||
cond.wait(mutex);
|
||||
|
||||
if (!Check(error))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
Check();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -177,15 +172,14 @@ AsyncInputStream::IsAvailable()
|
||||
}
|
||||
|
||||
size_t
|
||||
AsyncInputStream::Read(void *ptr, size_t read_size, Error &error)
|
||||
AsyncInputStream::Read(void *ptr, size_t read_size)
|
||||
{
|
||||
assert(!io_thread_inside());
|
||||
|
||||
/* wait for data */
|
||||
CircularBuffer<uint8_t>::Range r;
|
||||
while (true) {
|
||||
if (!Check(error))
|
||||
return 0;
|
||||
Check();
|
||||
|
||||
r = buffer.Read();
|
||||
if (!r.IsEmpty() || IsEOF())
|
||||
|
@@ -81,12 +81,12 @@ public:
|
||||
virtual ~AsyncInputStream();
|
||||
|
||||
/* virtual methods from InputStream */
|
||||
bool Check(Error &error) final;
|
||||
void Check() final;
|
||||
bool IsEOF() final;
|
||||
bool Seek(offset_type new_offset, Error &error) final;
|
||||
void Seek(offset_type new_offset) final;
|
||||
Tag *ReadTag() final;
|
||||
bool IsAvailable() final;
|
||||
size_t Read(void *ptr, size_t read_size, Error &error) final;
|
||||
size_t Read(void *ptr, size_t read_size) final;
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@@ -79,13 +79,13 @@ IcyInputStream::ReadTag()
|
||||
}
|
||||
|
||||
size_t
|
||||
IcyInputStream::Read(void *ptr, size_t read_size, Error &error)
|
||||
IcyInputStream::Read(void *ptr, size_t read_size)
|
||||
{
|
||||
if (!IsEnabled())
|
||||
return ProxyInputStream::Read(ptr, read_size, error);
|
||||
return ProxyInputStream::Read(ptr, read_size);
|
||||
|
||||
while (true) {
|
||||
size_t nbytes = ProxyInputStream::Read(ptr, read_size, error);
|
||||
size_t nbytes = ProxyInputStream::Read(ptr, read_size);
|
||||
if (nbytes == 0)
|
||||
return 0;
|
||||
|
||||
|
@@ -62,7 +62,7 @@ public:
|
||||
/* virtual methods from InputStream */
|
||||
void Update() override;
|
||||
Tag *ReadTag() override;
|
||||
size_t Read(void *ptr, size_t size, Error &error) override;
|
||||
size_t Read(void *ptr, size_t size) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -22,16 +22,17 @@
|
||||
#include "thread/Cond.hxx"
|
||||
#include "util/StringCompare.hxx"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
InputStream::~InputStream()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
InputStream::Check(gcc_unused Error &error)
|
||||
void
|
||||
InputStream::Check()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -86,25 +87,24 @@ InputStream::CheapSeeking() const
|
||||
return IsSeekable() && !ExpensiveSeeking(uri.c_str());
|
||||
}
|
||||
|
||||
bool
|
||||
InputStream::Seek(gcc_unused offset_type new_offset,
|
||||
gcc_unused Error &error)
|
||||
void
|
||||
InputStream::Seek(gcc_unused offset_type new_offset)
|
||||
{
|
||||
return false;
|
||||
throw std::runtime_error("Seeking is not implemented");
|
||||
}
|
||||
|
||||
bool
|
||||
InputStream::LockSeek(offset_type _offset, Error &error)
|
||||
void
|
||||
InputStream::LockSeek(offset_type _offset)
|
||||
{
|
||||
const ScopeLock protect(mutex);
|
||||
return Seek(_offset, error);
|
||||
Seek(_offset);
|
||||
}
|
||||
|
||||
bool
|
||||
InputStream::LockSkip(offset_type _offset, Error &error)
|
||||
void
|
||||
InputStream::LockSkip(offset_type _offset)
|
||||
{
|
||||
const ScopeLock protect(mutex);
|
||||
return Skip(_offset, error);
|
||||
Skip(_offset);
|
||||
}
|
||||
|
||||
Tag *
|
||||
@@ -127,7 +127,7 @@ InputStream::IsAvailable()
|
||||
}
|
||||
|
||||
size_t
|
||||
InputStream::LockRead(void *ptr, size_t _size, Error &error)
|
||||
InputStream::LockRead(void *ptr, size_t _size)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
@@ -136,28 +136,27 @@ InputStream::LockRead(void *ptr, size_t _size, Error &error)
|
||||
assert(_size > 0);
|
||||
|
||||
const ScopeLock protect(mutex);
|
||||
return Read(ptr, _size, error);
|
||||
return Read(ptr, _size);
|
||||
}
|
||||
|
||||
bool
|
||||
InputStream::ReadFull(void *_ptr, size_t _size, Error &error)
|
||||
void
|
||||
InputStream::ReadFull(void *_ptr, size_t _size)
|
||||
{
|
||||
uint8_t *ptr = (uint8_t *)_ptr;
|
||||
|
||||
size_t nbytes_total = 0;
|
||||
while (_size > 0) {
|
||||
size_t nbytes = Read(ptr + nbytes_total, _size, error);
|
||||
size_t nbytes = Read(ptr + nbytes_total, _size);
|
||||
if (nbytes == 0)
|
||||
return false;
|
||||
throw std::runtime_error("Unexpected end of file");
|
||||
|
||||
nbytes_total += nbytes;
|
||||
_size -= nbytes;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
InputStream::LockReadFull(void *ptr, size_t _size, Error &error)
|
||||
void
|
||||
InputStream::LockReadFull(void *ptr, size_t _size)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
@@ -166,7 +165,7 @@ InputStream::LockReadFull(void *ptr, size_t _size, Error &error)
|
||||
assert(_size > 0);
|
||||
|
||||
const ScopeLock protect(mutex);
|
||||
return ReadFull(ptr, _size, error);
|
||||
ReadFull(ptr, _size);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@@ -154,10 +154,9 @@ public:
|
||||
|
||||
/**
|
||||
* Check for errors that may have occurred in the I/O thread.
|
||||
*
|
||||
* @return false on error
|
||||
* Throws std::runtime_error on error.
|
||||
*/
|
||||
virtual bool Check(Error &error);
|
||||
virtual void Check();
|
||||
|
||||
/**
|
||||
* Update the public attributes. Call before accessing attributes
|
||||
@@ -271,36 +270,38 @@ public:
|
||||
*
|
||||
* The caller must lock the mutex.
|
||||
*
|
||||
* Throws std::runtime_error on error.
|
||||
*
|
||||
* @param offset the relative offset
|
||||
*/
|
||||
virtual bool Seek(offset_type offset, Error &error);
|
||||
virtual void Seek(offset_type offset);
|
||||
|
||||
/**
|
||||
* Wrapper for Seek() which locks and unlocks the mutex; the
|
||||
* caller must not be holding it already.
|
||||
*/
|
||||
bool LockSeek(offset_type offset, Error &error);
|
||||
void LockSeek(offset_type offset);
|
||||
|
||||
/**
|
||||
* Rewind to the beginning of the stream. This is a wrapper
|
||||
* for Seek(0, error).
|
||||
*/
|
||||
bool Rewind(Error &error) {
|
||||
return Seek(0, error);
|
||||
void Rewind() {
|
||||
Seek(0);
|
||||
}
|
||||
|
||||
bool LockRewind(Error &error) {
|
||||
return LockSeek(0, error);
|
||||
void LockRewind() {
|
||||
LockSeek(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip input bytes.
|
||||
*/
|
||||
bool Skip(offset_type _offset, Error &error) {
|
||||
return Seek(GetOffset() + _offset, error);
|
||||
void Skip(offset_type _offset) {
|
||||
Seek(GetOffset() + _offset);
|
||||
}
|
||||
|
||||
bool LockSkip(offset_type _offset, Error &error);
|
||||
void LockSkip(offset_type _offset);
|
||||
|
||||
/**
|
||||
* Returns true if the stream has reached end-of-file.
|
||||
@@ -351,38 +352,46 @@ public:
|
||||
*
|
||||
* The caller must lock the mutex.
|
||||
*
|
||||
* Throws std::runtime_error on error.
|
||||
*
|
||||
* @param ptr the buffer to read into
|
||||
* @param size the maximum number of bytes to read
|
||||
* @return the number of bytes read
|
||||
*/
|
||||
gcc_nonnull_all
|
||||
virtual size_t Read(void *ptr, size_t size, Error &error) = 0;
|
||||
virtual size_t Read(void *ptr, size_t size) = 0;
|
||||
|
||||
/**
|
||||
* Wrapper for Read() which locks and unlocks the mutex;
|
||||
* the caller must not be holding it already.
|
||||
*
|
||||
* Throws std::runtime_error on error.
|
||||
*/
|
||||
gcc_nonnull_all
|
||||
size_t LockRead(void *ptr, size_t size, Error &error);
|
||||
size_t LockRead(void *ptr, size_t size);
|
||||
|
||||
/**
|
||||
* Reads the whole data from the stream into the caller-supplied buffer.
|
||||
*
|
||||
* The caller must lock the mutex.
|
||||
*
|
||||
* Throws std::runtime_error on error.
|
||||
*
|
||||
* @param ptr the buffer to read into
|
||||
* @param size the number of bytes to read
|
||||
* @return true if the whole data was read, false otherwise.
|
||||
*/
|
||||
gcc_nonnull_all
|
||||
bool ReadFull(void *ptr, size_t size, Error &error);
|
||||
void ReadFull(void *ptr, size_t size);
|
||||
|
||||
/**
|
||||
* Wrapper for ReadFull() which locks and unlocks the mutex;
|
||||
* the caller must not be holding it already.
|
||||
*
|
||||
* Throws std::runtime_error on error.
|
||||
*/
|
||||
gcc_nonnull_all
|
||||
bool LockReadFull(void *ptr, size_t size, Error &error);
|
||||
void LockReadFull(void *ptr, size_t size);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -63,20 +63,11 @@ InputStream::OpenReady(const char *uri,
|
||||
{
|
||||
auto is = Open(uri, mutex, cond);
|
||||
|
||||
bool success;
|
||||
|
||||
{
|
||||
const ScopeLock protect(mutex);
|
||||
is->WaitReady();
|
||||
|
||||
Error error;
|
||||
success = is->Check(error);
|
||||
if (!success)
|
||||
throw std::runtime_error(error.GetMessage());
|
||||
is->Check();
|
||||
}
|
||||
|
||||
if (!success)
|
||||
is.reset();
|
||||
|
||||
return is;
|
||||
}
|
||||
|
@@ -49,10 +49,10 @@ ProxyInputStream::CopyAttributes()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ProxyInputStream::Check(Error &error)
|
||||
void
|
||||
ProxyInputStream::Check()
|
||||
{
|
||||
return input.Check(error);
|
||||
input.Check();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -62,12 +62,11 @@ ProxyInputStream::Update()
|
||||
CopyAttributes();
|
||||
}
|
||||
|
||||
bool
|
||||
ProxyInputStream::Seek(offset_type new_offset, Error &error)
|
||||
void
|
||||
ProxyInputStream::Seek(offset_type new_offset)
|
||||
{
|
||||
bool success = input.Seek(new_offset, error);
|
||||
input.Seek(new_offset);
|
||||
CopyAttributes();
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -89,9 +88,9 @@ ProxyInputStream::IsAvailable()
|
||||
}
|
||||
|
||||
size_t
|
||||
ProxyInputStream::Read(void *ptr, size_t read_size, Error &error)
|
||||
ProxyInputStream::Read(void *ptr, size_t read_size)
|
||||
{
|
||||
size_t nbytes = input.Read(ptr, read_size, error);
|
||||
size_t nbytes = input.Read(ptr, read_size);
|
||||
CopyAttributes();
|
||||
return nbytes;
|
||||
}
|
||||
|
@@ -43,13 +43,13 @@ public:
|
||||
ProxyInputStream &operator=(const ProxyInputStream &) = delete;
|
||||
|
||||
/* virtual methods from InputStream */
|
||||
bool Check(Error &error) override;
|
||||
void Check() override;
|
||||
void Update() override;
|
||||
bool Seek(offset_type new_offset, Error &error) override;
|
||||
void Seek(offset_type new_offset) override;
|
||||
bool IsEOF() override;
|
||||
Tag *ReadTag() override;
|
||||
bool IsAvailable() override;
|
||||
size_t Read(void *ptr, size_t read_size, Error &error) override;
|
||||
size_t Read(void *ptr, size_t read_size) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@@ -20,19 +20,12 @@
|
||||
#include "config.h"
|
||||
#include "Reader.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "Log.hxx"
|
||||
|
||||
size_t
|
||||
InputStreamReader::Read(void *data, size_t size)
|
||||
{
|
||||
Error error;
|
||||
size_t nbytes = is.LockRead(data, size, error);
|
||||
assert(nbytes == 0 || !error.IsDefined());
|
||||
assert(nbytes > 0 || error.IsDefined() || is.IsEOF());
|
||||
|
||||
if (gcc_unlikely(nbytes == 0 && error.IsDefined()))
|
||||
LogError(error);
|
||||
size_t nbytes = is.LockRead(data, size);
|
||||
assert(nbytes > 0 || is.IsEOF());
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
@@ -20,10 +20,11 @@
|
||||
#include "config.h"
|
||||
#include "TextInputStream.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "util/TextFile.hxx"
|
||||
#include "Log.hxx"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
TextInputStream::TextInputStream(InputStreamPtr &&_is)
|
||||
@@ -58,12 +59,12 @@ TextInputStream::ReadLine()
|
||||
character */
|
||||
--dest.size;
|
||||
|
||||
Error error;
|
||||
size_t nbytes = is->LockRead(dest.data, dest.size, error);
|
||||
if (nbytes > 0)
|
||||
buffer.Append(nbytes);
|
||||
else if (error.IsDefined()) {
|
||||
LogError(error);
|
||||
size_t nbytes;
|
||||
|
||||
try {
|
||||
nbytes = is->LockRead(dest.data, dest.size);
|
||||
} catch (const std::runtime_error &e) {
|
||||
LogError(e);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@@ -114,15 +114,13 @@ ThreadInputStream::ThreadFunc(void *ctx)
|
||||
tis.ThreadFunc();
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadInputStream::Check(Error &)
|
||||
void
|
||||
ThreadInputStream::Check()
|
||||
{
|
||||
assert(!thread.IsInside());
|
||||
|
||||
if (postponed_exception)
|
||||
std::rethrow_exception(postponed_exception);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -134,7 +132,7 @@ ThreadInputStream::IsAvailable()
|
||||
}
|
||||
|
||||
inline size_t
|
||||
ThreadInputStream::Read(void *ptr, size_t read_size, Error &)
|
||||
ThreadInputStream::Read(void *ptr, size_t read_size)
|
||||
{
|
||||
assert(!thread.IsInside());
|
||||
|
||||
|
@@ -83,10 +83,10 @@ public:
|
||||
void Start();
|
||||
|
||||
/* virtual methods from InputStream */
|
||||
bool Check(Error &error) override final;
|
||||
void Check() override final;
|
||||
bool IsEOF() override final;
|
||||
bool IsAvailable() override final;
|
||||
size_t Read(void *ptr, size_t size, Error &error) override final;
|
||||
size_t Read(void *ptr, size_t size) override final;
|
||||
|
||||
protected:
|
||||
void SetMimeType(const char *_mime) {
|
||||
|
@@ -98,8 +98,8 @@ class CdioParanoiaInputStream final : public InputStream {
|
||||
|
||||
/* virtual methods from InputStream */
|
||||
bool IsEOF() override;
|
||||
size_t Read(void *ptr, size_t size, Error &error) override;
|
||||
bool Seek(offset_type offset, Error &error) override;
|
||||
size_t Read(void *ptr, size_t size) override;
|
||||
void Seek(offset_type offset) override;
|
||||
};
|
||||
|
||||
static constexpr Domain cdio_domain("cdio");
|
||||
@@ -256,30 +256,26 @@ input_cdio_open(const char *uri,
|
||||
lsn_from, lsn_to);
|
||||
}
|
||||
|
||||
bool
|
||||
CdioParanoiaInputStream::Seek(offset_type new_offset, Error &error)
|
||||
void
|
||||
CdioParanoiaInputStream::Seek(offset_type new_offset)
|
||||
{
|
||||
if (new_offset > size) {
|
||||
error.Format(cdio_domain, "Invalid offset to seek %ld (%ld)",
|
||||
(long int)new_offset, (long int)size);
|
||||
return false;
|
||||
}
|
||||
if (new_offset > size)
|
||||
throw FormatRuntimeError("Invalid offset to seek %ld (%ld)",
|
||||
(long int)new_offset, (long int)size);
|
||||
|
||||
/* simple case */
|
||||
if (new_offset == offset)
|
||||
return true;
|
||||
return;
|
||||
|
||||
/* calculate current LSN */
|
||||
lsn_relofs = new_offset / CDIO_CD_FRAMESIZE_RAW;
|
||||
offset = new_offset;
|
||||
|
||||
cdio_paranoia_seek(para, lsn_from + lsn_relofs, SEEK_SET);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t
|
||||
CdioParanoiaInputStream::Read(void *ptr, size_t length, Error &error)
|
||||
CdioParanoiaInputStream::Read(void *ptr, size_t length)
|
||||
{
|
||||
size_t nbytes = 0;
|
||||
int diff;
|
||||
@@ -309,11 +305,9 @@ CdioParanoiaInputStream::Read(void *ptr, size_t length, Error &error)
|
||||
if (s_mess) {
|
||||
free(s_mess);
|
||||
}
|
||||
if (!rbuf) {
|
||||
error.Set(cdio_domain,
|
||||
"paranoia read error. Stopping.");
|
||||
return 0;
|
||||
}
|
||||
if (!rbuf)
|
||||
throw std::runtime_error("paranoia read error");
|
||||
|
||||
//store current buffer
|
||||
memcpy(buffer, rbuf, CDIO_CD_FRAMESIZE_RAW);
|
||||
buffer_lsn = lsn_relofs;
|
||||
|
@@ -61,8 +61,8 @@ struct FfmpegInputStream final : public InputStream {
|
||||
|
||||
/* virtual methods from InputStream */
|
||||
bool IsEOF() override;
|
||||
size_t Read(void *ptr, size_t size, Error &error) override;
|
||||
bool Seek(offset_type offset, Error &error) override;
|
||||
size_t Read(void *ptr, size_t size) override;
|
||||
void Seek(offset_type offset) override;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
@@ -103,15 +103,15 @@ input_ffmpeg_open(const char *uri,
|
||||
}
|
||||
|
||||
size_t
|
||||
FfmpegInputStream::Read(void *ptr, size_t read_size, Error &error)
|
||||
FfmpegInputStream::Read(void *ptr, size_t read_size)
|
||||
{
|
||||
auto result = avio_read(h, (unsigned char *)ptr, read_size);
|
||||
if (result <= 0) {
|
||||
if (result < 0)
|
||||
SetFfmpegError(error, result, "avio_read() failed");
|
||||
throw MakeFfmpegError(result, "avio_read() failed");
|
||||
|
||||
eof = true;
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset += result;
|
||||
@@ -124,19 +124,16 @@ FfmpegInputStream::IsEOF()
|
||||
return eof;
|
||||
}
|
||||
|
||||
bool
|
||||
FfmpegInputStream::Seek(offset_type new_offset, Error &error)
|
||||
void
|
||||
FfmpegInputStream::Seek(offset_type new_offset)
|
||||
{
|
||||
auto result = avio_seek(h, new_offset, SEEK_SET);
|
||||
|
||||
if (result < 0) {
|
||||
SetFfmpegError(error, result, "avio_seek() failed");
|
||||
return false;
|
||||
}
|
||||
if (result < 0)
|
||||
throw MakeFfmpegError(result, "avio_seek() failed");
|
||||
|
||||
offset = result;
|
||||
eof = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
const InputPlugin input_plugin_ffmpeg = {
|
||||
|
@@ -49,8 +49,8 @@ public:
|
||||
return GetOffset() >= GetSize();
|
||||
}
|
||||
|
||||
size_t Read(void *ptr, size_t size, Error &error) override;
|
||||
bool Seek(offset_type offset, Error &error) override;
|
||||
size_t Read(void *ptr, size_t size) override;
|
||||
void Seek(offset_type offset) override;
|
||||
};
|
||||
|
||||
InputStreamPtr
|
||||
@@ -84,26 +84,19 @@ input_file_open(gcc_unused const char *filename,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
FileInputStream::Seek(offset_type new_offset, Error &error)
|
||||
try {
|
||||
void
|
||||
FileInputStream::Seek(offset_type new_offset)
|
||||
{
|
||||
reader.Seek((off_t)new_offset);
|
||||
offset = new_offset;
|
||||
return true;
|
||||
} catch (const std::exception &e) {
|
||||
error.Set(std::current_exception());
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t
|
||||
FileInputStream::Read(void *ptr, size_t read_size, Error &error)
|
||||
try {
|
||||
FileInputStream::Read(void *ptr, size_t read_size)
|
||||
{
|
||||
size_t nbytes = reader.Read(ptr, read_size);
|
||||
offset += nbytes;
|
||||
return nbytes;
|
||||
} catch (const std::exception &e) {
|
||||
error.Set(std::current_exception());
|
||||
return 0;
|
||||
}
|
||||
|
||||
const InputPlugin input_plugin_file = {
|
||||
|
@@ -63,8 +63,8 @@ public:
|
||||
return !ReadingFromBuffer() && ProxyInputStream::IsEOF();
|
||||
}
|
||||
|
||||
size_t Read(void *ptr, size_t size, Error &error) override;
|
||||
bool Seek(offset_type offset, Error &error) override;
|
||||
size_t Read(void *ptr, size_t size) override;
|
||||
void Seek(offset_type offset) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -77,7 +77,7 @@ private:
|
||||
};
|
||||
|
||||
size_t
|
||||
RewindInputStream::Read(void *ptr, size_t read_size, Error &error)
|
||||
RewindInputStream::Read(void *ptr, size_t read_size)
|
||||
{
|
||||
if (ReadingFromBuffer()) {
|
||||
/* buffered read */
|
||||
@@ -96,7 +96,7 @@ RewindInputStream::Read(void *ptr, size_t read_size, Error &error)
|
||||
} else {
|
||||
/* pass method call to underlying stream */
|
||||
|
||||
size_t nbytes = input.Read(ptr, read_size, error);
|
||||
size_t nbytes = input.Read(ptr, read_size);
|
||||
|
||||
if (input.GetOffset() > (offset_type)sizeof(buffer))
|
||||
/* disable buffering */
|
||||
@@ -116,9 +116,8 @@ RewindInputStream::Read(void *ptr, size_t read_size, Error &error)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
RewindInputStream::Seek(offset_type new_offset,
|
||||
Error &error)
|
||||
void
|
||||
RewindInputStream::Seek(offset_type new_offset)
|
||||
{
|
||||
assert(IsReady());
|
||||
|
||||
@@ -131,14 +130,12 @@ RewindInputStream::Seek(offset_type new_offset,
|
||||
|
||||
head = (size_t)new_offset;
|
||||
offset = new_offset;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
/* disable the buffer, because input has left the
|
||||
buffered range now */
|
||||
tail = 0;
|
||||
|
||||
return ProxyInputStream::Seek(new_offset, error);
|
||||
ProxyInputStream::Seek(new_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -26,7 +26,6 @@
|
||||
#include "PluginUnavailable.hxx"
|
||||
#include "system/Error.hxx"
|
||||
#include "util/StringCompare.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <libsmbclient.h>
|
||||
|
||||
@@ -60,8 +59,8 @@ public:
|
||||
return offset >= size;
|
||||
}
|
||||
|
||||
size_t Read(void *ptr, size_t size, Error &error) override;
|
||||
bool Seek(offset_type offset, Error &error) override;
|
||||
size_t Read(void *ptr, size_t size) override;
|
||||
void Seek(offset_type offset) override;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -124,33 +123,28 @@ input_smbclient_open(const char *uri,
|
||||
}
|
||||
|
||||
size_t
|
||||
SmbclientInputStream::Read(void *ptr, size_t read_size, Error &error)
|
||||
SmbclientInputStream::Read(void *ptr, size_t read_size)
|
||||
{
|
||||
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;
|
||||
}
|
||||
if (nbytes < 0)
|
||||
throw MakeErrno("smbc_read() failed");
|
||||
|
||||
offset += nbytes;
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
bool
|
||||
SmbclientInputStream::Seek(offset_type new_offset, Error &error)
|
||||
void
|
||||
SmbclientInputStream::Seek(offset_type new_offset)
|
||||
{
|
||||
smbclient_mutex.lock();
|
||||
off_t result = smbc_lseek(fd, new_offset, SEEK_SET);
|
||||
smbclient_mutex.unlock();
|
||||
if (result < 0) {
|
||||
error.SetErrno("smbc_lseek() failed");
|
||||
return false;
|
||||
}
|
||||
if (result < 0)
|
||||
throw MakeErrno("smbc_lseek() failed");
|
||||
|
||||
offset = result;
|
||||
return true;
|
||||
}
|
||||
|
||||
const InputPlugin input_plugin_smbclient = {
|
||||
|
Reference in New Issue
Block a user