Commit 5148e229 authored by Max Kellermann's avatar Max Kellermann

input/proxy: allow input==nullptr

Allow implementations to install the "real" input later.
parent 1ad21c27
...@@ -20,6 +20,9 @@ ...@@ -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),
...@@ -31,8 +34,23 @@ ProxyInputStream::ProxyInputStream(InputStreamPtr _input) noexcept ...@@ -31,8 +34,23 @@ ProxyInputStream::ProxyInputStream(InputStreamPtr _input) noexcept
ProxyInputStream::~ProxyInputStream() noexcept = default; ProxyInputStream::~ProxyInputStream() noexcept = default;
void 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
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() ...@@ -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 ...@@ -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) ...@@ -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; ...@@ -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;
...@@ -54,6 +64,14 @@ public: ...@@ -54,6 +64,14 @@ public:
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
* the underlying stream has returned, which may have modified these * the underlying stream has returned, which may have modified these
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment