Skip to content

Commit b8d7f55

Browse files
xokdviumEricson2314
authored andcommitted
libutil: Add RestartableSource
This is necessary to make seeking work with libcurl.
1 parent e947c89 commit b8d7f55

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

src/libutil/include/nix/util/serialise.hh

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,18 @@ struct StringSink : Sink
230230
void operator()(std::string_view data) override;
231231
};
232232

233+
/**
234+
* Source type that can be restarted.
235+
*/
236+
struct RestartableSource : Source
237+
{
238+
virtual void restart() = 0;
239+
};
240+
233241
/**
234242
* A source that reads data from a string.
235243
*/
236-
struct StringSource : Source
244+
struct StringSource : RestartableSource
237245
{
238246
std::string_view s;
239247
size_t pos;
@@ -257,8 +265,22 @@ struct StringSource : Source
257265
size_t read(char * data, size_t len) override;
258266

259267
void skip(size_t len) override;
268+
269+
void restart() override
270+
{
271+
pos = 0;
272+
}
260273
};
261274

275+
/**
276+
* Create a restartable Source from a factory function.
277+
*
278+
* @param factory Factory function that returns a fresh instance of the Source. Gets
279+
* called for each source restart.
280+
* @pre factory must return an equivalent source for each invocation.
281+
*/
282+
std::unique_ptr<RestartableSource> restartableSourceFromFactory(std::function<std::unique_ptr<Source>()> factory);
283+
262284
/**
263285
* A sink that writes all incoming data to two other sinks.
264286
*/

src/libutil/serialise.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,4 +513,41 @@ size_t ChainSource::read(char * data, size_t len)
513513
}
514514
}
515515

516+
std::unique_ptr<RestartableSource> restartableSourceFromFactory(std::function<std::unique_ptr<Source>()> factory)
517+
{
518+
struct RestartableSourceImpl : RestartableSource
519+
{
520+
RestartableSourceImpl(decltype(factory) factory_)
521+
: factory_(std::move(factory_))
522+
, impl(this->factory_())
523+
{
524+
}
525+
526+
decltype(factory) factory_;
527+
std::unique_ptr<Source> impl = factory_();
528+
529+
size_t read(char * data, size_t len) override
530+
{
531+
return impl->read(data, len);
532+
}
533+
534+
bool good() override
535+
{
536+
return impl->good();
537+
}
538+
539+
void skip(size_t len) override
540+
{
541+
return impl->skip(len);
542+
}
543+
544+
void restart() override
545+
{
546+
impl = factory_();
547+
}
548+
};
549+
550+
return std::make_unique<RestartableSourceImpl>(std::move(factory));
551+
}
552+
516553
} // namespace nix

0 commit comments

Comments
 (0)