blob: 317eb30a5430c2b6b4f38957885c41795d17e487 [file] [log] [blame]
#pragma once
#include <stdplus/fd/intf.hpp>
#include <stdplus/raw.hpp>
#include <stdplus/types.hpp>
#include <utility>
namespace stdplus
{
namespace fd
{
namespace detail
{
void readExact(Fd& fd, span<std::byte> data);
void recvExact(Fd& fd, span<std::byte> data, RecvFlags flags);
void writeExact(Fd& fd, span<const std::byte> data);
void sendExact(Fd& fd, span<const std::byte> data, SendFlags flags);
span<std::byte> readAligned(Fd& fd, size_t align, span<std::byte> buf);
span<std::byte> recvAligned(Fd& fd, size_t align, span<std::byte> buf,
RecvFlags flags);
span<const std::byte> writeAligned(Fd& fd, size_t align,
span<const std::byte> data);
span<const std::byte> sendAligned(Fd& fd, size_t align,
span<const std::byte> data, SendFlags flags);
template <typename Fun, typename Container, typename... Args>
auto alignedOp(Fun&& fun, Fd& fd, Container&& c, Args&&... args)
{
using Data = raw::detail::dataType<Container>;
auto ret = fun(fd, sizeof(Data), raw::asSpan<std::byte>(c),
std::forward<Args>(args)...);
return span<Data>(std::begin(c), ret.size() / sizeof(Data));
}
} // namespace detail
template <typename Container>
inline auto read(Fd& fd, Container&& c)
{
return detail::alignedOp(detail::readAligned, fd,
std::forward<Container>(c));
}
template <typename Container>
inline auto recv(Fd& fd, Container&& c, RecvFlags flags)
{
return detail::alignedOp(detail::recvAligned, fd,
std::forward<Container>(c), flags);
}
template <typename Container>
inline auto write(Fd& fd, Container&& c)
{
return detail::alignedOp(detail::writeAligned, fd,
std::forward<Container>(c));
}
template <typename Container>
inline auto send(Fd& fd, Container&& c, SendFlags flags)
{
return detail::alignedOp(detail::sendAligned, fd,
std::forward<Container>(c), flags);
}
template <typename T>
inline void readExact(Fd& fd, T&& t)
{
detail::readExact(fd, raw::asSpan<std::byte>(t));
}
template <typename T>
inline void recvExact(Fd& fd, T&& t, RecvFlags flags)
{
detail::recvExact(fd, raw::asSpan<std::byte>(t), flags);
}
template <typename T>
inline void writeExact(Fd& fd, T&& t)
{
detail::writeExact(fd, raw::asSpan<std::byte>(t));
}
template <typename T>
inline void sendExact(Fd& fd, T&& t, SendFlags flags)
{
detail::sendExact(fd, raw::asSpan<std::byte>(t), flags);
}
inline size_t lseek(Fd& fd, off_t offset, Whence whence)
{
return fd.lseek(offset, whence);
}
inline void truncate(Fd& fd, off_t size)
{
return fd.truncate(size);
}
template <typename SockAddr>
inline void bind(Fd& fd, SockAddr&& sockaddr)
{
return fd.bind(raw::asSpan<std::byte>(sockaddr));
}
template <typename Opt>
inline void setsockopt(Fd& fd, SockLevel level, SockOpt optname, Opt&& opt)
{
return fd.setsockopt(level, optname, raw::asSpan<std::byte>(opt));
}
template <typename Data>
inline int constIoctl(const Fd& fd, unsigned long id, Data&& data)
{
return fd.constIoctl(id, raw::asSpan<std::byte>(data).data());
}
template <typename Data>
inline int ioctl(Fd& fd, unsigned long id, Data&& data)
{
return fd.ioctl(id, raw::asSpan<std::byte>(data).data());
}
inline FdFlags getFdFlags(const Fd& fd)
{
return fd.fcntlGetfd();
}
inline void setFdFlags(Fd& fd, FdFlags flags)
{
return fd.fcntlSetfd(flags);
}
inline FileFlags getFileFlags(const Fd& fd)
{
return fd.fcntlGetfl();
}
inline void setFileFlags(Fd& fd, FileFlags flags)
{
return fd.fcntlSetfl(flags);
}
} // namespace fd
} // namespace stdplus