23#include <StormByte/type_traits.hxx>
93 template<Type::ByteInputRange Src>
94 static
DataType DataConvert(const Src& src) noexcept {
96 if constexpr (
requires { std::ranges::size(src); }) {
97 auto s = std::ranges::size(src);
98 if (s > 0) out.reserve(
static_cast<typename DataType::size_type
>(s));
100 std::transform(std::ranges::begin(src), std::ranges::end(src), std::back_inserter(out),
101 [] (
auto&& e)
noexcept {
return static_cast<std::byte
>(e); });
111 template<Type::ByteInputRange Src>
113 if constexpr (Type::SameAs<Src, DataType>) {
114 return std::move(src);
117 if constexpr (
requires { std::ranges::size(src); }) {
118 auto s = std::ranges::size(src);
119 if (s > 0) out.reserve(
static_cast<typename DataType::size_type
>(s));
121 std::transform(std::ranges::begin(src), std::ranges::end(src), std::back_inserter(out),
122 [] (
auto&& e)
noexcept {
return static_cast<std::byte
>(e); });
134 if (!sv.empty()) out.reserve(
static_cast<typename DataType::size_type
>(sv.size()));
135 std::transform(sv.begin(), sv.end(), std::back_inserter(out),
136 [] (
char c)
noexcept { return static_cast<std::byte>(c); });
147 return DataConvert(std::string_view(s));
198 virtual std::
size_t AvailableBytes() const noexcept = 0;
211 virtual
bool Empty() const noexcept = 0;
217 virtual
bool EoF() const noexcept = 0;
223 virtual
bool IsReadable() const noexcept = 0;
230 virtual std::
size_t Size() const noexcept = 0;
243 virtual
void Clean() noexcept = 0;
250 virtual
void Clear() noexcept = 0;
258 virtual
bool Drop(const std::
size_t& count) noexcept = 0;
267 virtual
void Seek(const std::ptrdiff_t& offset, const
Position& mode) const noexcept = 0;
282 inline virtual
bool Extract(const std::
size_t& count,
DataType& outBuffer) noexcept = 0;
289 inline
bool Extract(
DataType& outBuffer) noexcept {
290 return Extract(0, outBuffer);
307 return Extract(0, outBuffer);
341 virtual bool Peek(
const std::size_t& count,
DataType& outBuffer)
const noexcept = 0;
352 virtual bool Peek(
const std::size_t& count,
WriteOnly& outBuffer)
const noexcept = 0;
367 virtual bool Read(
const std::size_t& count,
DataType& outBuffer)
const noexcept = 0;
375 return Read(0, outBuffer);
384 virtual bool Read(
const std::size_t& count,
WriteOnly& outBuffer)
const noexcept = 0;
392 return Read(0, outBuffer);
454 virtual
bool IsWritable() const noexcept = 0;
461 virtual
void Close() noexcept = 0;
467 virtual
void SetError() noexcept = 0;
483 virtual
bool Write(const std::
size_t& count, const
DataType& data) noexcept = 0;
492 virtual
bool Write(const std::
size_t& count,
DataType&& data) noexcept = 0;
501 virtual
bool Write(const std::
size_t& count, const
ReadOnly& data) noexcept = 0;
510 virtual
bool Write(const std::
size_t& count,
ReadOnly&& data) noexcept = 0;
525 return Write(data.AvailableBytes(), data);
534 return Write(data.AvailableBytes(), std::move(data));
551 bool Write(std::string_view sv)
noexcept {
553 if (!sv.empty()) tmp.reserve(
static_cast<typename DataType::size_type
>(sv.size()));
554 std::transform(sv.begin(), sv.end(), std::back_inserter(tmp),
555 [] (
char e)
noexcept { return static_cast<std::byte>(e); });
556 return Write(
static_cast<std::size_t
>(tmp.size()), std::move(tmp));
564 bool Write(
const char* s)
noexcept {
566 return Write(std::string_view(s));
575 bool Write(
const std::size_t& count, std::string_view sv)
noexcept {
576 size_t to_write = (count == 0) ?
static_cast<size_t>(sv.size())
577 : std::min(count,
static_cast<std::size_t
>(sv.size()));
579 if (to_write > 0) tmp.reserve(
static_cast<typename DataType::size_type
>(to_write));
580 std::transform(sv.begin(), sv.begin() + to_write, std::back_inserter(tmp),
581 [] (
char e)
noexcept { return static_cast<std::byte>(e); });
582 return Write(
static_cast<std::size_t
>(to_write), std::move(tmp));
591 bool Write(
const std::size_t& count,
const char* s)
noexcept {
592 if (!s)
return Write(count,
DataType{});
593 return Write(count, std::string_view(s));
602 template<std::
size_t N>
603 bool Write(
const char (&s)[N])
noexcept {
604 if (N == 0)
return Write(
DataType{});
605 return Write(std::string_view(s, (N > 0) ? (N - 1) : 0));
621 template<Type::ByteInputRange R>
624 if constexpr (
requires(
DataType& d,
typename DataType::size_type n) { d.reserve(n); }) {
625 auto dist = std::ranges::distance(r);
626 if (dist > 0) tmp.reserve(
static_cast<typename DataType::size_type
>(dist));
628 std::transform(std::ranges::begin(r), std::ranges::end(r), std::back_inserter(tmp),
629 [] (
auto&& e)
noexcept {
return static_cast<std::byte
>(e); });
630 return Write(
static_cast<std::size_t
>(tmp.size()), std::move(tmp));
640 template<Type::ByteInputRange Rw>
641 bool Write(
const std::size_t& count,
const Rw& r)
noexcept {
642 if (count == 0)
return Write(r);
644 if constexpr (
requires(
DataType& d,
typename DataType::size_type n) { d.reserve(n); }) {
645 auto dist = std::ranges::distance(r);
647 tmp.reserve(
static_cast<typename DataType::size_type
>(
648 std::min(dist,
static_cast<decltype(dist)
>(count))));
650 auto it = std::ranges::begin(r);
651 auto end = std::ranges::end(r);
652 std::size_t written = 0;
653 for (; it != end && written < count; ++it, ++written) {
654 tmp.push_back(
static_cast<std::byte
>(*it));
656 return Write(
static_cast<std::size_t
>(written), std::move(tmp));
666 template<Type::ByteInputRange Rrw>
667 bool Write(
const std::size_t& count, Rrw&& r)
noexcept {
668 if (count == 0)
return Write(std::forward<Rrw>(r));
669 if constexpr (Type::SameAs<Rrw, DataType>) {
671 if (tmp.size() > count) tmp.resize(count);
672 return Write(
static_cast<std::size_t
>(tmp.size()), std::move(tmp));
675 if constexpr (
requires(
DataType& d,
typename DataType::size_type n) { d.reserve(n); }) {
676 auto dist = std::ranges::distance(r);
678 tmp.reserve(
static_cast<typename DataType::size_type
>(
679 std::min(dist,
static_cast<decltype(dist)
>(count))));
681 auto it = std::ranges::begin(r);
682 auto end = std::ranges::end(r);
683 std::size_t written = 0;
684 for (; it != end && written < count; ++it, ++written) {
685 tmp.push_back(
static_cast<std::byte
>(*it));
687 return Write(
static_cast<std::size_t
>(written), std::move(tmp));
697 template<Type::ByteInputRange Rr>
699 if constexpr (Type::SameAs<Rr, DataType>) {
700 return Write(
static_cast<std::size_t
>(r.size()), std::move(r));
703 if constexpr (
requires(
DataType& d,
typename DataType::size_type n) { d.reserve(n); }) {
704 auto dist = std::ranges::distance(r);
705 if (dist > 0) tmp.reserve(
static_cast<typename DataType::size_type
>(dist));
707 std::transform(std::ranges::begin(r), std::ranges::end(r), std::back_inserter(tmp),
708 [] (
auto&& e)
noexcept {
return static_cast<std::byte
>(e); });
709 return Write(
static_cast<std::size_t
>(tmp.size()), std::move(tmp));
721 template<Type::ByteInputIterator I,
typename S>
722 requires Type::SentinelFor<S, I>
723 bool Write(I first, S last)
noexcept {
725 std::transform(first, last, std::back_inserter(tmp),
726 [] (
auto&& e)
noexcept {
return static_cast<std::byte
>(e); });
727 return Write(
static_cast<std::size_t
>(tmp.size()), std::move(tmp));
739 template<Type::ByteInputIterator I2,
typename S2>
740 requires Type::SentinelFor<S2, I2>
741 bool Write(
const std::size_t& count, I2 first, S2 last)
noexcept {
742 if (count == 0)
return Write(first, last);
744 std::size_t written = 0;
745 for (; first != last && written < count; ++first, ++written) {
746 tmp.push_back(
static_cast<std::byte
>(*first));
748 return Write(
static_cast<std::size_t
>(written), std::move(tmp));
Pure abstract root of the buffer interface hierarchy.
Definition generic.hxx:48
static DataType DataConvert(Src &&src) noexcept
Convert an rvalue input range to DataType (moves when already DataType).
Definition generic.hxx:112
static DataType DataConvert(const char *s) noexcept
Convert a null-terminated C string to DataType.
Definition generic.hxx:145
Generic() noexcept=default
Default construct.
static DataType DataConvert(std::string_view sv) noexcept
Convert a string view to DataType (no trailing NUL).
Definition generic.hxx:132
Pure interface for a buffer that can be read but not written.
Definition generic.hxx:164
ReadOnly(ReadOnly &&) noexcept=default
Move construct.
virtual void ExtractUntilEoF(WriteOnly &outBuffer) noexcept=0
Extract until EoF into a WriteOnly.
virtual bool Extract(const std::size_t &count, WriteOnly &outBuffer) noexcept=0
Extract bytes into a WriteOnly.
virtual void ExtractUntilEoF(DataType &outBuffer) noexcept=0
Extract until EoF into a DataType.
ReadOnly(const ReadOnly &) noexcept=default
Copy construct.
virtual bool Read(const std::size_t &count, WriteOnly &outBuffer) const noexcept=0
Read into a WriteOnly.
virtual bool Read(const std::size_t &count, DataType &outBuffer) const noexcept=0
Read into a DataType.
bool Read(WriteOnly &outBuffer) const noexcept
Read all available bytes into a WriteOnly.
Definition generic.hxx:391
bool Read(DataType &outBuffer) const noexcept
Read all available bytes into a DataType.
Definition generic.hxx:374
ReadOnly() noexcept
Default construct.
Definition generic.hxx:171
bool Extract(WriteOnly &outBuffer) noexcept
Extract all available bytes into a WriteOnly.
Definition generic.hxx:306
virtual void ReadUntilEoF(DataType &outBuffer) const noexcept=0
Read until EoF into a DataType.
virtual bool Peek(const std::size_t &count, WriteOnly &outBuffer) const noexcept=0
Peek into a WriteOnly without advancing the read position.
virtual bool Peek(const std::size_t &count, DataType &outBuffer) const noexcept=0
Peek into a DataType without advancing the read position.
virtual void ReadUntilEoF(WriteOnly &outBuffer) const noexcept=0
Read until EoF into a WriteOnly.
Pure interface combining ReadOnly and WriteOnly.
Definition generic.hxx:762
ReadWrite() noexcept
Default construct.
Definition generic.hxx:769
ReadWrite(const ReadWrite &other) noexcept=default
Copy construct.
ReadWrite(ReadWrite &&other) noexcept=default
Move construct.
virtual ~ReadWrite() noexcept
Virtual destructor.
Pure interface for a buffer that can be written but not read.
Definition generic.hxx:420
WriteOnly(const WriteOnly &)=default
Copy construct.
bool Write(const std::size_t &count, const char *s) noexcept
Write up to count characters from a C string.
Definition generic.hxx:591
bool Write(const char *s) noexcept
Write a null-terminated C string.
Definition generic.hxx:564
bool Write(const std::size_t &count, std::string_view sv) noexcept
Write up to count characters from a string view.
Definition generic.hxx:575
bool Write(const std::size_t &count, I2 first, S2 last) noexcept
Write up to count elements from an iterator pair.
Definition generic.hxx:741
bool Write(const char(&s)[N]) noexcept
Write a string literal without the trailing NUL.
Definition generic.hxx:603
bool Write(const std::size_t &count, Rrw &&r) noexcept
Write up to count elements from an rvalue range.
Definition generic.hxx:667
bool Write(ReadOnly &&data) noexcept
Append all available bytes from a ReadOnly (move path).
Definition generic.hxx:533
bool Write(Rr &&r) noexcept
Write all elements from an rvalue range.
Definition generic.hxx:698
WriteOnly() noexcept
Default construct.
Definition generic.hxx:427
WriteOnly(WriteOnly &&) noexcept=default
Move construct.
bool Write(std::string_view sv) noexcept
Write a string view (no trailing NUL).
Definition generic.hxx:551
bool Write(const std::size_t &count, const Rw &r) noexcept
Write up to count elements from an input range.
Definition generic.hxx:641
bool Write(const R &r) noexcept
Write all elements from an input range.
Definition generic.hxx:622
bool Write(I first, S last) noexcept
Write all elements from an iterator pair.
Definition generic.hxx:723
Buffer module of the StormByte suite.
std::vector< std::byte > DataType
Primary byte storage type used throughout the buffer API.
Definition typedefs.hxx:62
Position
Forward declaration of the WriteOnly interface.
Definition typedefs.hxx:50
#define STORMBYTE_BUFFER_PUBLIC
Definition visibility.h:28