1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-08 19:46:02 +01:00

libutil: Add RestartableSource

This is necessary to make seeking work with libcurl.
This commit is contained in:
Sergei Zimmerman 2025-10-28 01:54:58 +03:00 committed by John Ericson
parent e947c895ec
commit b8d7f551e4
2 changed files with 60 additions and 1 deletions

View file

@ -230,10 +230,18 @@ struct StringSink : Sink
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.
*/
struct StringSource : Source
struct StringSource : RestartableSource
{
std::string_view s;
size_t pos;
@ -257,8 +265,22 @@ struct StringSource : Source
size_t read(char * data, 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.
*/

View file

@ -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