6#include "lix/libutil/charptr-cast.hh"
20 virtual void operator () (std::string_view data) = 0;
21 virtual bool good() {
return true; }
29 void operator () (std::string_view data)
override
36 virtual void finish() = 0;
44struct BufferedSink :
virtual Sink
46 size_t bufSize, bufPos;
47 std::unique_ptr<char[]> buffer;
49 BufferedSink(
size_t bufSize = 32 * 1024)
50 : bufSize(bufSize), bufPos(0), buffer(
nullptr) { }
52 void operator () (std::string_view data)
override;
58 virtual void writeUnbuffered(std::string_view data) = 0;
86 virtual size_t read(
char * data,
size_t len) = 0;
88 virtual bool good() {
return true; }
90 void drainInto(
Sink & sink);
102 size_t bufSize, bufPosIn, bufPosOut;
103 std::unique_ptr<char[]> buffer;
105 BufferedSource(
size_t bufSize = 32 * 1024)
106 : bufSize(bufSize), bufPosIn(0), bufPosOut(0), buffer(
nullptr) { }
108 size_t read(
char * data,
size_t len)
override;
123struct FdSink : BufferedSink
128 FdSink() : fd(-1) { }
129 FdSink(
int fd) : fd(fd) { }
130 FdSink(FdSink&&) =
default;
132 FdSink & operator=(FdSink && s)
143 void writeUnbuffered(std::string_view data)
override;
145 bool good()
override;
155struct FdSource : BufferedSource
162 std::string endOfFileError()
const;
164 FdSource() : fd(-1) { }
166 FdSource(FdSource &&) =
default;
168 FdSource & operator=(FdSource && s)
176 bool good()
override;
191 explicit StringSink(
const size_t reservedSize)
193 s.reserve(reservedSize);
195 StringSink(std::string && s) : s(std::move(s)) { };
196 void operator () (std::string_view data)
override;
207 StringSource(std::string_view s) : s(s), pos(0) { }
208 size_t read(
char * data,
size_t len)
override;
217 Sink & sink1, & sink2;
218 TeeSink(
Sink & sink1,
Sink & sink2) : sink1(sink1), sink2(sink2) { }
219 virtual void operator () (std::string_view data)
override
235 : orig(orig), sink(sink) { }
236 size_t read(
char * data,
size_t len)
override
238 size_t n = orig.read(data, len);
251 SizedSource(
Source & orig,
size_t size)
252 : orig(orig), remain(size) { }
253 size_t read(
char * data,
size_t len)
override
255 if (this->remain <= 0) {
256 throw EndOfFile(
"sized: unexpected end-of-file");
258 len = std::min(len, this->remain);
259 size_t n = this->orig.
read(data, len);
269 std::vector<char> buf(8192);
271 while (this->remain > 0) {
272 size_t n =
read(buf.data(), buf.size());
286 void operator () (std::string_view data)
override
288 length += data.size();
297 typedef std::function<void(std::string_view data)> lambda_t;
301 LambdaSink(
const lambda_t & lambda) : lambda(lambda) { }
303 void operator () (std::string_view data)
override
315 typedef std::function<size_t(
char *,
size_t)> lambda_t;
319 LambdaSource(
const lambda_t & lambda) : lambda(lambda) { }
321 size_t read(
char * data,
size_t len)
override
323 return lambda(data, len);
331 virtual size_t read(
char * data,
size_t len)
override
336 while (!buf.size()) {
337 if (
auto next = g.next()) {
340 throw EndOfFile(
"coroutine has finished");
344 len = std::min(len, buf.size());
345 memcpy(data, buf.data(), len);
346 buf = buf.subspan(len);
357 while (
auto buffer = g.next()) {
358 sink(std::string_view(buffer->data(), buffer->size()));
368 std::array<unsigned char, 8> buf;
370 Bytes operator()(uint64_t n)
373 buf[1] = (n >> 8) & 0xff;
374 buf[2] = (n >> 16) & 0xff;
375 buf[3] = (n >> 24) & 0xff;
376 buf[4] = (n >> 32) & 0xff;
377 buf[5] = (n >> 40) & 0xff;
378 buf[6] = (n >> 48) & 0xff;
379 buf[7] = (
unsigned char) (n >> 56) & 0xff;
380 return {charptr_cast<const char *>(buf.begin()), 8};
383 static Bytes padding(
size_t unpadded)
385 return Bytes(
"\0\0\0\0\0\0\0", unpadded % 8 ? 8 - unpadded % 8 : 0);
398 template<
typename Span>
399 requires std::same_as<Span, std::span<char>> || std::same_as<Span, std::span<const char>>
400 Bytes operator()(Span s)
404 WireFormatGenerator operator()(std::string_view s);
405 WireFormatGenerator operator()(
const Strings & s);
406 WireFormatGenerator operator()(
const StringSet & s);
407 WireFormatGenerator operator()(
const Error & s);
410void writePadding(
size_t len,
Sink & sink);
415inline Sink & operator<<(
Sink & sink, uint64_t u)
417 return sink << [&]() -> WireFormatGenerator {
co_yield u; }();
420inline Sink & operator<<(
Sink & sink, std::string_view s)
422 return sink << [&]() -> WireFormatGenerator {
co_yield s; }();
425inline Sink & operator<<(
Sink & sink,
const Strings & s)
427 return sink << [&]() -> WireFormatGenerator {
co_yield s; }();
430inline Sink & operator<<(
Sink & sink,
const StringSet & s)
432 return sink << [&]() -> WireFormatGenerator {
co_yield s; }();
435inline Sink & operator<<(
Sink & sink,
const Error & ex)
437 return sink << [&]() -> WireFormatGenerator {
co_yield ex; }();
441MakeError(SerialisationError, Error);
444T readNum(
Source & source);
446inline unsigned int readInt(
Source & source)
448 return readNum<unsigned int>(source);
452inline uint64_t readLongLong(
Source & source)
454 return readNum<uint64_t>(source);
458void readPadding(
size_t len,
Source & source);
459size_t readString(
char * buf,
size_t max,
Source & source);
460std::string readString(
Source & source,
size_t max = std::numeric_limits<size_t>::max());
461template<
class T> T readStrings(
Source & source);
475 b = readNum<uint64_t>(in);
479Error readError(
Source & source);
487 std::shared_ptr<std::basic_istream<char>> istream;
489 StreamToSourceAdapter(std::shared_ptr<std::basic_istream<char>> istream)
493 size_t read(
char * data,
size_t len)
override
495 if (!istream->read(data, len)) {
496 if (istream->eof()) {
497 if (istream->gcount() == 0)
498 throw EndOfFile(
"end of file");
500 throw Error(
"I/O error in StreamToSourceAdapter");
502 return istream->gcount();
519 std::vector<char> pending;
522 FramedSource(
Source & from) : from(from)
530 auto n = readInt(from);
532 std::vector<char> data(n);
533 from(data.data(), n);
537 ignoreExceptionInDestructor();
541 size_t read(
char * data,
size_t len)
override
543 if (eof)
throw EndOfFile(
"reached end of FramedSource");
545 if (pos >= pending.size()) {
546 size_t len = readInt(from);
551 pending = std::vector<char>(len);
553 from(pending.data(), len);
556 auto n = std::min(len, pending.size() - pos);
557 memcpy(data, pending.data() + pos, n);
572 std::exception_ptr & ex;
574 FramedSink(BufferedSink & to, std::exception_ptr & ex) : to(to), ex(ex)
583 ignoreExceptionInDestructor();
587 void writeUnbuffered(std::string_view data)
override
594 std::rethrow_exception(ex2);
604extern std::shared_ptr<void> (*create_coro_gc_hook)();
Definition serialise.hh:45
virtual size_t readUnbuffered(char *data, size_t len)=0
size_t read(char *data, size_t len) override
Definition serialise.cc:140
Definition serialise.hh:156
size_t readUnbuffered(char *data, size_t len) override
Definition serialise.cc:161
std::optional< std::string > specialEndOfFileError
Definition serialise.hh:160
Definition serialise.hh:35
size_t read(char *data, size_t len) override
Definition serialise.hh:541
virtual size_t read(char *data, size_t len) override
Definition serialise.hh:331
Definition generator.hh:236
size_t read(char *data, size_t len) override
Definition serialise.hh:321
Definition serialise.hh:283
Definition serialise.hh:28
Definition serialise.hh:18
size_t drainAll()
Definition serialise.hh:267
size_t read(char *data, size_t len) override
Definition serialise.hh:253
Definition serialise.hh:66
void operator()(char *data, size_t len)
Definition serialise.cc:108
virtual size_t read(char *data, size_t len)=0
size_t read(char *data, size_t len) override
Definition serialise.hh:493
size_t read(char *data, size_t len) override
Definition serialise.cc:186
size_t read(char *data, size_t len) override
Definition serialise.hh:236