forked from lix-project/lix
Create a new TeeSink abstraction
This is a bit complex because we want to expose extra functionality the wrapped class has. Perhaps there is some inheritancy trickery to do this nicer, but I don't know it, and this is the first thing we tried after a series of attempts that did build. This design is kind of like that of Rust's Writer, Reader, or Iter adapters, which impliment more traits based on what the inner type implements.
This commit is contained in:
parent
fb05a6adcf
commit
289b9b8dcf
|
@ -25,4 +25,16 @@ MakeError(UnknownCompressionMethod, Error);
|
|||
|
||||
MakeError(CompressionError, Error);
|
||||
|
||||
template<>
|
||||
struct TeeSink<ref<CompressionSink>> : CompressionSink
|
||||
{
|
||||
MAKE_TEE_SINK(ref<CompressionSink>);
|
||||
void finish() override {
|
||||
orig->finish();
|
||||
}
|
||||
void write(const unsigned char * data, size_t len) override {
|
||||
return orig->write(data, len);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -181,6 +181,28 @@ struct TeeSource : Source
|
|||
}
|
||||
};
|
||||
|
||||
#define MAKE_TEE_SINK(T) \
|
||||
T orig; \
|
||||
ref<std::string> data; \
|
||||
TeeSink(T && orig) \
|
||||
: orig(std::move(orig)), data(make_ref<std::string>()) { } \
|
||||
void operator () (const unsigned char * data, size_t len) { \
|
||||
this->data->append((const char *) data, len); \
|
||||
(*this->orig)(data, len); \
|
||||
} \
|
||||
void operator () (const std::string & s) \
|
||||
{ \
|
||||
*data += s; \
|
||||
(*this->orig)(s); \
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct TeeSink : Sink
|
||||
{
|
||||
MAKE_TEE_SINK(T);
|
||||
};
|
||||
|
||||
|
||||
/* A reader that consumes the original Source until 'size'. */
|
||||
struct SizedSource : Source
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue