diff options
Diffstat (limited to 'src/libutil/serialise.hh')
-rw-r--r-- | src/libutil/serialise.hh | 63 |
1 files changed, 21 insertions, 42 deletions
diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh index 6c637bd35..612658b2d 100644 --- a/src/libutil/serialise.hh +++ b/src/libutil/serialise.hh @@ -1,16 +1,13 @@ #pragma once ///@file -#include <concepts> #include <memory> +#include "charptr-cast.hh" #include "generator.hh" -#include "strings.hh" #include "types.hh" #include "file-descriptor.hh" -namespace boost::context { struct stack_context; } - namespace nix { @@ -154,7 +151,10 @@ struct FdSource : BufferedSource { int fd; size_t read = 0; - BackedStringView endOfFileError{"unexpected end-of-file"}; + /** Defaults to "unexpected end-of-file" */ + std::optional<std::string> specialEndOfFileError; + + std::string endOfFileError() const; FdSource() : fd(-1) { } FdSource(int fd) : fd(fd) { } @@ -387,7 +387,7 @@ struct SerializingTransform buf[5] = (n >> 40) & 0xff; buf[6] = (n >> 48) & 0xff; buf[7] = (unsigned char) (n >> 56) & 0xff; - return {reinterpret_cast<const char *>(buf.begin()), 8}; + return {charptr_cast<const char *>(buf.begin()), 8}; } static Bytes padding(size_t unpadded) @@ -419,6 +419,9 @@ struct SerializingTransform void writePadding(size_t len, Sink & sink); +// NOLINTBEGIN(cppcoreguidelines-avoid-capturing-lambda-coroutines): +// These coroutines do their entire job before the semicolon and are not +// retained, so they live long enough. inline Sink & operator<<(Sink & sink, uint64_t u) { return sink << [&]() -> WireFormatGenerator { co_yield u; }(); @@ -443,23 +446,12 @@ inline Sink & operator<<(Sink & sink, const Error & ex) { return sink << [&]() -> WireFormatGenerator { co_yield ex; }(); } +// NOLINTEND(cppcoreguidelines-avoid-capturing-lambda-coroutines) MakeError(SerialisationError, Error); template<typename T> -T readNum(Source & source) -{ - unsigned char buf[8]; - source((char *) buf, sizeof(buf)); - - auto n = readLittleEndian<uint64_t>(buf); - - if (n > (uint64_t) std::numeric_limits<T>::max()) - throw SerialisationError("serialised integer %d is too large for type '%s'", n, typeid(T).name()); - - return (T) n; -} - +T readNum(Source & source); inline unsigned int readInt(Source & source) { @@ -542,13 +534,17 @@ struct FramedSource : Source ~FramedSource() { - if (!eof) { - while (true) { - auto n = readInt(from); - if (!n) break; - std::vector<char> data(n); - from(data.data(), n); + try { + if (!eof) { + while (true) { + auto n = readInt(from); + if (!n) break; + std::vector<char> data(n); + from(data.data(), n); + } } + } catch (...) { + ignoreException(); } } @@ -612,23 +608,6 @@ struct FramedSink : nix::BufferedSink }; }; -/** - * Stack allocation strategy for sinkToSource. - * Mutable to avoid a boehm gc dependency in libutil. - * - * boost::context doesn't provide a virtual class, so we define our own. - */ -struct StackAllocator { - virtual boost::context::stack_context allocate() = 0; - virtual void deallocate(boost::context::stack_context sctx) = 0; - - /** - * The stack allocator to use in sinkToSource and potentially elsewhere. - * It is reassigned by the initGC() method in libexpr. - */ - static StackAllocator *defaultAllocator; -}; - /* Disabling GC when entering a coroutine (without the boehm patch). mutable to avoid boehm gc dependency in libutil. */ |