mirror of
https://github.com/NixOS/nix.git
synced 2025-11-28 05:00:58 +01:00
libutil: Add RestartableSource
This is necessary to make seeking work with libcurl.
This commit is contained in:
parent
e947c895ec
commit
b8d7f551e4
2 changed files with 60 additions and 1 deletions
|
|
@ -230,10 +230,18 @@ struct StringSink : Sink
|
||||||
void operator()(std::string_view data) override;
|
void operator()(std::string_view data) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source type that can be restarted.
|
||||||
|
*/
|
||||||
|
struct RestartableSource : Source
|
||||||
|
{
|
||||||
|
virtual void restart() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A source that reads data from a string.
|
* A source that reads data from a string.
|
||||||
*/
|
*/
|
||||||
struct StringSource : Source
|
struct StringSource : RestartableSource
|
||||||
{
|
{
|
||||||
std::string_view s;
|
std::string_view s;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
|
|
@ -257,8 +265,22 @@ struct StringSource : Source
|
||||||
size_t read(char * data, size_t len) override;
|
size_t read(char * data, size_t len) override;
|
||||||
|
|
||||||
void skip(size_t len) override;
|
void skip(size_t len) override;
|
||||||
|
|
||||||
|
void restart() override
|
||||||
|
{
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a restartable Source from a factory function.
|
||||||
|
*
|
||||||
|
* @param factory Factory function that returns a fresh instance of the Source. Gets
|
||||||
|
* called for each source restart.
|
||||||
|
* @pre factory must return an equivalent source for each invocation.
|
||||||
|
*/
|
||||||
|
std::unique_ptr<RestartableSource> restartableSourceFromFactory(std::function<std::unique_ptr<Source>()> factory);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A sink that writes all incoming data to two other sinks.
|
* A sink that writes all incoming data to two other sinks.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -513,4 +513,41 @@ size_t ChainSource::read(char * data, size_t len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<RestartableSource> restartableSourceFromFactory(std::function<std::unique_ptr<Source>()> factory)
|
||||||
|
{
|
||||||
|
struct RestartableSourceImpl : RestartableSource
|
||||||
|
{
|
||||||
|
RestartableSourceImpl(decltype(factory) factory_)
|
||||||
|
: factory_(std::move(factory_))
|
||||||
|
, impl(this->factory_())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
decltype(factory) factory_;
|
||||||
|
std::unique_ptr<Source> impl = factory_();
|
||||||
|
|
||||||
|
size_t read(char * data, size_t len) override
|
||||||
|
{
|
||||||
|
return impl->read(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool good() override
|
||||||
|
{
|
||||||
|
return impl->good();
|
||||||
|
}
|
||||||
|
|
||||||
|
void skip(size_t len) override
|
||||||
|
{
|
||||||
|
return impl->skip(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void restart() override
|
||||||
|
{
|
||||||
|
impl = factory_();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return std::make_unique<RestartableSourceImpl>(std::move(factory));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace nix
|
} // namespace nix
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue