input/proxy: allow input==nullptr
Allow implementations to install the "real" input later.
This commit is contained in:
parent
1ad21c27c9
commit
5148e229e0
@ -20,6 +20,9 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "ProxyInputStream.hxx"
|
#include "ProxyInputStream.hxx"
|
||||||
#include "tag/Tag.hxx"
|
#include "tag/Tag.hxx"
|
||||||
|
#include "thread/Cond.hxx"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
ProxyInputStream::ProxyInputStream(InputStreamPtr _input) noexcept
|
ProxyInputStream::ProxyInputStream(InputStreamPtr _input) noexcept
|
||||||
:InputStream(_input->GetURI(), _input->mutex, _input->cond),
|
:InputStream(_input->GetURI(), _input->mutex, _input->cond),
|
||||||
@ -30,9 +33,24 @@ ProxyInputStream::ProxyInputStream(InputStreamPtr _input) noexcept
|
|||||||
|
|
||||||
ProxyInputStream::~ProxyInputStream() noexcept = default;
|
ProxyInputStream::~ProxyInputStream() noexcept = default;
|
||||||
|
|
||||||
|
void
|
||||||
|
ProxyInputStream::SetInput(InputStreamPtr _input) noexcept
|
||||||
|
{
|
||||||
|
assert(!input);
|
||||||
|
assert(_input);
|
||||||
|
|
||||||
|
input = std::move(_input);
|
||||||
|
|
||||||
|
/* this call wakes up client threads if the new input is
|
||||||
|
ready */
|
||||||
|
CopyAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ProxyInputStream::CopyAttributes()
|
ProxyInputStream::CopyAttributes()
|
||||||
{
|
{
|
||||||
|
assert(input);
|
||||||
|
|
||||||
if (input->IsReady()) {
|
if (input->IsReady()) {
|
||||||
if (!IsReady()) {
|
if (!IsReady()) {
|
||||||
if (input->HasMimeType())
|
if (input->HasMimeType())
|
||||||
@ -53,12 +71,16 @@ ProxyInputStream::CopyAttributes()
|
|||||||
void
|
void
|
||||||
ProxyInputStream::Check()
|
ProxyInputStream::Check()
|
||||||
{
|
{
|
||||||
input->Check();
|
if (input)
|
||||||
|
input->Check();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ProxyInputStream::Update() noexcept
|
ProxyInputStream::Update() noexcept
|
||||||
{
|
{
|
||||||
|
if (!input)
|
||||||
|
return;
|
||||||
|
|
||||||
input->Update();
|
input->Update();
|
||||||
CopyAttributes();
|
CopyAttributes();
|
||||||
}
|
}
|
||||||
@ -66,6 +88,9 @@ ProxyInputStream::Update() noexcept
|
|||||||
void
|
void
|
||||||
ProxyInputStream::Seek(offset_type new_offset)
|
ProxyInputStream::Seek(offset_type new_offset)
|
||||||
{
|
{
|
||||||
|
while (!input)
|
||||||
|
cond.wait(mutex);
|
||||||
|
|
||||||
input->Seek(new_offset);
|
input->Seek(new_offset);
|
||||||
CopyAttributes();
|
CopyAttributes();
|
||||||
}
|
}
|
||||||
@ -73,24 +98,30 @@ ProxyInputStream::Seek(offset_type new_offset)
|
|||||||
bool
|
bool
|
||||||
ProxyInputStream::IsEOF() noexcept
|
ProxyInputStream::IsEOF() noexcept
|
||||||
{
|
{
|
||||||
return input->IsEOF();
|
return input && input->IsEOF();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Tag>
|
std::unique_ptr<Tag>
|
||||||
ProxyInputStream::ReadTag()
|
ProxyInputStream::ReadTag()
|
||||||
{
|
{
|
||||||
|
if (!input)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
return input->ReadTag();
|
return input->ReadTag();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ProxyInputStream::IsAvailable() noexcept
|
ProxyInputStream::IsAvailable() noexcept
|
||||||
{
|
{
|
||||||
return input->IsAvailable();
|
return input && input->IsAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
ProxyInputStream::Read(void *ptr, size_t read_size)
|
ProxyInputStream::Read(void *ptr, size_t read_size)
|
||||||
{
|
{
|
||||||
|
while (!input)
|
||||||
|
cond.wait(mutex);
|
||||||
|
|
||||||
size_t nbytes = input->Read(ptr, read_size);
|
size_t nbytes = input->Read(ptr, read_size);
|
||||||
CopyAttributes();
|
CopyAttributes();
|
||||||
return nbytes;
|
return nbytes;
|
||||||
|
@ -29,15 +29,25 @@ struct Tag;
|
|||||||
* An #InputStream that forwards all methods call to another
|
* An #InputStream that forwards all methods call to another
|
||||||
* #InputStream instance. This can be used as a base class to
|
* #InputStream instance. This can be used as a base class to
|
||||||
* override selected methods.
|
* override selected methods.
|
||||||
|
*
|
||||||
|
* The inner #InputStream instance may be nullptr initially, to be set
|
||||||
|
* later.
|
||||||
*/
|
*/
|
||||||
class ProxyInputStream : public InputStream {
|
class ProxyInputStream : public InputStream {
|
||||||
protected:
|
protected:
|
||||||
InputStreamPtr input;
|
InputStreamPtr input;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
gcc_nonnull_all
|
|
||||||
explicit ProxyInputStream(InputStreamPtr _input) noexcept;
|
explicit ProxyInputStream(InputStreamPtr _input) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an instance without an #InputStream instance.
|
||||||
|
* Once that instance becomes available, call SetInput().
|
||||||
|
*/
|
||||||
|
ProxyInputStream(const char *_uri,
|
||||||
|
Mutex &_mutex, Cond &_cond) noexcept
|
||||||
|
:InputStream(_uri, _mutex, _cond) {}
|
||||||
|
|
||||||
virtual ~ProxyInputStream() noexcept;
|
virtual ~ProxyInputStream() noexcept;
|
||||||
|
|
||||||
ProxyInputStream(const ProxyInputStream &) = delete;
|
ProxyInputStream(const ProxyInputStream &) = delete;
|
||||||
@ -53,6 +63,14 @@ public:
|
|||||||
size_t Read(void *ptr, size_t read_size) override;
|
size_t Read(void *ptr, size_t read_size) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/**
|
||||||
|
* If this instance was initialized without an input, this
|
||||||
|
* method can set it.
|
||||||
|
*
|
||||||
|
* Caller must lock the mutex.
|
||||||
|
*/
|
||||||
|
void SetInput(InputStreamPtr _input) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy public attributes from the underlying input stream to the
|
* Copy public attributes from the underlying input stream to the
|
||||||
* "rewind" input stream. This function is called when a method of
|
* "rewind" input stream. This function is called when a method of
|
||||||
|
Loading…
Reference in New Issue
Block a user