diff --git a/utils/reusable_buffer.hh b/utils/reusable_buffer.hh index d0f75e1a79..c8040c0a6f 100644 --- a/utils/reusable_buffer.hh +++ b/utils/reusable_buffer.hh @@ -11,6 +11,7 @@ #include "utils/assert.hh" #include "utils/exception_container.hh" #include "utils/fragmented_temporary_buffer.hh" +#include "utils/managed_bytes.hh" #include "utils/result.hh" #include #include @@ -124,6 +125,22 @@ protected: return {out, bo.size()}; } + // Returns a linearized view onto the provided managed_bytes_view. + // If the input view is already linearized (single fragment), it is returned as-is. + // Otherwise the contents are copied to the reusable buffer + // and a view into the buffer is returned. + bytes_view get_linearized_view(managed_bytes_view mbv) & { + if (mbv.is_linearized()) { + return mbv.current_fragment(); + } + const auto out = get_temporary_buffer(mbv.size_bytes()).data(); + auto dst = out; + for (bytes_view fragment : fragment_range(mbv)) { + dst = std::copy(fragment.begin(), fragment.end(), dst); + } + return {out, mbv.size_bytes()}; + } + // Provides a contiguous buffer of size `maximum_length` to `fn`. // `fn` writes to the buffer and returns the number of bytes written. // A fragmented buffer containing the data written by `fn` is returned. @@ -332,6 +349,13 @@ public: return _buf.get_linearized_view(bo); } + // The result mustn't outlive `this`. + // No method of `this` may be called again. + bytes_view get_linearized_view(managed_bytes_view mbv) & { + mark_used(); + return _buf.get_linearized_view(mbv); + } + // The result mustn't outlive `this`. // No method of `this` may be called again. template