io: add pwrite wrappers
This commit is contained in:
parent
825d359b9d
commit
bb812ba81c
79
io.hpp
79
io.hpp
@ -18,6 +18,8 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <streambuf>
|
#include <streambuf>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
|
||||||
#ifdef PLATFORM_WIN32
|
#ifdef PLATFORM_WIN32
|
||||||
#include "win32/windows.hpp"
|
#include "win32/windows.hpp"
|
||||||
@ -55,27 +57,80 @@ namespace cruft {
|
|||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
/// writes all data from the provided view into the file-like-object
|
/// Repeatedly calls FunctionT to transfer data from a supplied view to a
|
||||||
|
/// file-like-object.
|
||||||
///
|
///
|
||||||
/// writing will continually iterate until the entire buffer has been
|
/// FunctionT must return a view of the consumed data.
|
||||||
/// dispatched so as to avoid issues with partial writes. will block until
|
|
||||||
/// such time as the entire buffer has written.
|
|
||||||
///
|
///
|
||||||
/// an exception may be thrown in the event forward progress is impossible.
|
/// The operation will iterate until the entire view has been consumed and
|
||||||
/// in this event the progress may not be reported to the caller. in the
|
/// hence may block for an indefinate period.
|
||||||
/// future an exception member variable may expose the information.
|
///
|
||||||
|
/// An exception may be throw in the event forward progress is impossible
|
||||||
|
/// (depending on the supplied FunctionT).
|
||||||
|
template <
|
||||||
|
typename DstT,
|
||||||
|
typename FunctionT,
|
||||||
|
typename IteratorA,
|
||||||
|
typename IteratorB,
|
||||||
|
typename ...Args
|
||||||
|
>
|
||||||
|
[[nodiscard]] decltype(auto)
|
||||||
|
drain (
|
||||||
|
DstT &&dst,
|
||||||
|
FunctionT &&func,
|
||||||
|
cruft::view<IteratorA,IteratorB> const &src,
|
||||||
|
Args&& ...args
|
||||||
|
) {
|
||||||
|
static_assert (std::is_pointer_v<IteratorA>);
|
||||||
|
static_assert (std::is_pointer_v<IteratorB>);
|
||||||
|
|
||||||
|
auto cursor = reinterpret_cast<std::byte const*> (src.data ());
|
||||||
|
auto remain = src.size ();
|
||||||
|
|
||||||
|
while (remain) {
|
||||||
|
auto count = std::invoke (func, dst, cursor, remain, args...);
|
||||||
|
cursor += count;
|
||||||
|
remain -= count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Drains all data from the supplied view `src` to the file-like-object
|
||||||
|
/// `dst` by way of repeated calls to `write`.
|
||||||
|
///
|
||||||
|
/// Returns a view over the consumed data. This SHOULD always be identical
|
||||||
|
/// to `src`.
|
||||||
template <
|
template <
|
||||||
typename DstT,
|
typename DstT,
|
||||||
typename IteratorA,
|
typename IteratorA,
|
||||||
typename IteratorB
|
typename IteratorB
|
||||||
>
|
>
|
||||||
cruft::view<IteratorA,IteratorB>
|
decltype(auto)
|
||||||
write (DstT &&dst, const cruft::view<IteratorA, IteratorB> &src)
|
write (DstT &&dst, const cruft::view<IteratorA, IteratorB> &src)
|
||||||
{
|
{
|
||||||
auto remain = src;
|
constexpr auto func = &std::decay_t<DstT>::write;
|
||||||
while (!remain.empty ())
|
return drain (std::forward<DstT> (dst), func, src);
|
||||||
remain = remain.consume (dst.write (remain));
|
}
|
||||||
return src;
|
|
||||||
|
|
||||||
|
///------------------------------------------------------------------------
|
||||||
|
/// Drain the supplied data view into the destination object by calling
|
||||||
|
/// pwrite repeatedly.
|
||||||
|
///
|
||||||
|
/// Returns a view over the consumed data. This SHOULD always be identical
|
||||||
|
/// to `src`.
|
||||||
|
template <
|
||||||
|
typename DstT,
|
||||||
|
typename IteratorA,
|
||||||
|
typename IteratorB
|
||||||
|
>
|
||||||
|
decltype(auto)
|
||||||
|
pwrite (DstT &&dst, const cruft::view<IteratorA, IteratorB> &src, size_t offset)
|
||||||
|
{
|
||||||
|
return drain (std::forward<DstT> (dst), &std::decay_t<DstT>::pwrite, src, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user