Skip to content

Commit 04cebd1

Browse files
committed
libutil: Add RestartableSource
This is necessary to make seeking work with libcurl.
1 parent 2d76bd8 commit 04cebd1

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,4 +638,14 @@ struct FramedSink : nix::BufferedSink
638638
};
639639
};
640640

641+
/**
642+
* Source type that can be restarted.
643+
*/
644+
struct RestartableSource : Source
645+
{
646+
virtual void restart() = 0;
647+
};
648+
649+
std::unique_ptr<RestartableSource> restartableSourceFromFactory(std::function<std::unique_ptr<Source>()> factory);
650+
641651
} // namespace nix

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)