StormByte-Buffer 2.0.0
C++26 buffer module of the StormByte suite
 
Loading...
Searching...
No Matches
generic.hxx
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024-2026 David C. Manuelda (StormBytePP)
3 *
4 * This file is part of StormByte-Buffer.
5 *
6 * StormByte-Buffer original source is dual-licensed:
7 *
8 * 1. GNU Lesser General Public License v3.0 (or later)
9 * You may redistribute and/or modify this file under the terms of the
10 * GNU Lesser General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option)
12 * any later version.
13 *
14 * 2. Commercial license
15 * Alternatively, this file may be used under the terms of a commercial
16 * license agreement with the copyright holder
17 * (David C. Manuelda <StormByte@gmail.com>).
18 *
19 * Both licenses apply only to original StormByte-Buffer source in this
20 * repository. They do not cover other StormByte modules or any third-party
21 * material shipped with this repository (including everything under
22 * thirdparty/, and in particular the bundled StormByte-Logger tree and
23 * the rest of the StormByte suite it vendors), which remains under its own
24 * license.
25 *
26 * Neither license grants any patent rights. Any patent licenses required
27 * to use this software or third-party components must be obtained separately
28 * from the patent holders.
29 *
30 * StormByte-Buffer is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU Lesser General Public License for more details.
34 *
35 * You should have received a copy of the GNU Lesser General Public License
36 * version 3 along with StormByte-Buffer. If not, see
37 * <https://www.gnu.org/licenses/lgpl-3.0.html>.
38 *
39 * SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-StormByte-Commercial
40 */
41
42#pragma once
43
47
48#include <algorithm>
49#include <cstdint>
50#include <iterator>
51#include <ranges>
52#include <span>
53#include <string_view>
54#include <type_traits>
55#include <utility>
56
61namespace StormByte {
66 namespace Buffer {
79 public:
88 Generic() noexcept = default;
89
94 Generic(const Generic& other) noexcept = default;
95
100 Generic(Generic&& other) noexcept = default;
101
105 virtual ~Generic() noexcept = 0;
106
112 Generic& operator=(const Generic& other) = default;
113
119 Generic& operator=(Generic&& other) noexcept = default;
120
134 virtual StormByte::ByteSize Size() const noexcept = 0;
135
140 protected:
152 template<Type::ByteInputRange Src>
153 static BinaryData DataConvert(const Src& src) noexcept {
154 BinaryData out;
155 if constexpr (requires { std::ranges::size(src); }) {
156 auto s = std::ranges::size(src);
157 if (s > 0)
158 out.reserve(StormByte::ByteSize{static_cast<std::size_t>(s)});
159 }
160 std::transform(std::ranges::begin(src), std::ranges::end(src), std::back_inserter(out),
161 [](auto&& e) noexcept { return static_cast<std::byte>(e); });
162 return out;
163 }
164
171 template<Type::ByteInputRange Src>
172 static BinaryData DataConvert(Src&& src) noexcept {
173 if constexpr (Type::SameAs<Src, BinaryData>) {
174 return std::move(src);
175 } else {
176 BinaryData out;
177 if constexpr (requires { std::ranges::size(src); }) {
178 auto s = std::ranges::size(src);
179 if (s > 0)
180 out.reserve(StormByte::ByteSize{static_cast<std::size_t>(s)});
181 }
182 std::transform(std::ranges::begin(src), std::ranges::end(src), std::back_inserter(out),
183 [](auto&& e) noexcept { return static_cast<std::byte>(e); });
184 return out;
185 }
186 }
187
193 static BinaryData DataConvert(std::string_view sv) noexcept {
194 BinaryData out;
195 if (!sv.empty())
196 out.reserve(StormByte::ByteSize{sv.size()});
197 std::transform(sv.begin(), sv.end(), std::back_inserter(out),
198 [](char c) noexcept { return static_cast<std::byte>(c); });
199 return out;
200 }
201
207 static BinaryData DataConvert(const char* s) noexcept {
208 if (!s)
209 return BinaryData{};
210 return DataConvert(std::string_view(s));
211 }
212
216 };
217
218 class WriteOnly;
219
229 public:
238 inline ReadOnly() noexcept: Generic() {}
239
244 ReadOnly(const ReadOnly& other) noexcept = default;
245
250 ReadOnly(ReadOnly&& other) noexcept = default;
251
255 virtual ~ReadOnly() noexcept;
256
262 ReadOnly& operator=(const ReadOnly& other) = default;
263
269 ReadOnly& operator=(ReadOnly&& other) noexcept = default;
270
284 virtual StormByte::ByteSize Available() const noexcept = 0;
285
290 virtual const BinaryData& Data() const noexcept = 0;
291
297 virtual bool Empty() const noexcept = 0;
298
303 virtual bool EoF() const noexcept = 0;
304
309 virtual bool IsReadable() const noexcept = 0;
310
324 virtual void Clean() noexcept = 0;
325
331 virtual void Clear() noexcept = 0;
332
339 virtual bool Drop(const StormByte::ByteSize& count) noexcept = 0;
340
348 virtual void Seek(const std::ptrdiff_t& offset, const Position& mode) const noexcept = 0;
349
365 inline virtual bool Extract(const StormByte::ByteSize& count, StormByte::BinaryData& outBuffer) noexcept = 0;
366
372 inline bool Extract(StormByte::BinaryData& outBuffer) noexcept {
373 return Extract(StormByte::ByteSize{0}, outBuffer);
374 }
375
382 inline virtual bool Extract(const StormByte::ByteSize& count, WriteOnly& outBuffer) noexcept = 0;
383
389 inline bool Extract(WriteOnly& outBuffer) noexcept {
390 return Extract(StormByte::ByteSize{0}, outBuffer);
391 }
392
398 virtual void ExtractUntilEoF(StormByte::BinaryData& outBuffer) noexcept = 0;
399
405 virtual void ExtractUntilEoF(WriteOnly& outBuffer) noexcept = 0;
406
424 virtual bool Peek(const StormByte::ByteSize& count, StormByte::BinaryData& outBuffer) const noexcept = 0;
425
433 virtual bool Peek(const StormByte::ByteSize& count, WriteOnly& outBuffer) const noexcept = 0;
434
450 virtual bool Read(const StormByte::ByteSize& count, StormByte::BinaryData& outBuffer) const noexcept = 0;
451
457 inline bool Read(StormByte::BinaryData& outBuffer) const noexcept {
458 return Read(StormByte::ByteSize{0}, outBuffer);
459 }
460
467 virtual bool Read(const StormByte::ByteSize& count, WriteOnly& outBuffer) const noexcept = 0;
468
474 inline bool Read(WriteOnly& outBuffer) const noexcept {
475 return Read(StormByte::ByteSize{0}, outBuffer);
476 }
477
483 virtual void ReadUntilEoF(StormByte::BinaryData& outBuffer) const noexcept = 0;
484
490 virtual void ReadUntilEoF(WriteOnly& outBuffer) const noexcept = 0;
491
495 };
496
506 public:
515 inline WriteOnly() noexcept: Generic() {}
516
521 WriteOnly(const WriteOnly& other) = default;
522
527 WriteOnly(WriteOnly&& other) noexcept = default;
528
532 virtual ~WriteOnly() noexcept;
533
539 WriteOnly& operator=(const WriteOnly& other) = default;
540
546 WriteOnly& operator=(WriteOnly&& other) noexcept = default;
547
561 virtual bool IsWritable() const noexcept = 0;
562
566 virtual void Close() noexcept = 0;
567
571 virtual void SetError() noexcept = 0;
572
589 virtual bool Write(const StormByte::ByteSize& count, const BinaryData& data) noexcept = 0;
590
598 virtual bool Write(const StormByte::ByteSize& count, BinaryData&& data) noexcept = 0;
599
607 virtual bool Write(const StormByte::ByteSize& count, const ReadOnly& data) noexcept = 0;
608
616 virtual bool Write(const StormByte::ByteSize& count, ReadOnly&& data) noexcept = 0;
617
632 inline bool Write(const ReadOnly& data) noexcept {
633 return Write(data.Available(), data);
634 }
635
641 inline bool Write(ReadOnly&& data) noexcept {
642 return Write(data.Available(), std::move(data));
643 }
644
659 bool Write(std::string_view sv) noexcept {
660 BinaryData tmp;
661 if (!sv.empty())
662 tmp.reserve(StormByte::ByteSize{sv.size()});
663 std::transform(sv.begin(), sv.end(), std::back_inserter(tmp),
664 [](char e) noexcept { return static_cast<std::byte>(e); });
665 return Write(tmp.size(), std::move(tmp));
666 }
667
673 bool Write(const char* s) noexcept {
674 if (!s)
675 return Write(BinaryData{});
676 return Write(std::string_view(s));
677 }
678
685 bool Write(const StormByte::ByteSize& count, std::string_view sv) noexcept {
686 const StormByte::ByteSize to_write = (count == StormByte::ByteSize{0})
687 ? StormByte::ByteSize{sv.size()}
688 : std::min(count, StormByte::ByteSize{sv.size()});
689 BinaryData tmp;
690 if (to_write > StormByte::ByteSize{0})
691 tmp.reserve(to_write);
692 std::transform(sv.begin(), sv.begin() + static_cast<std::ptrdiff_t>(static_cast<std::size_t>(to_write)),
693 std::back_inserter(tmp),
694 [](char e) noexcept { return static_cast<std::byte>(e); });
695 return Write(to_write, std::move(tmp));
696 }
697
704 bool Write(const StormByte::ByteSize& count, const char* s) noexcept {
705 if (!s)
706 return Write(count, BinaryData{});
707 return Write(count, std::string_view(s));
708 }
709
716 template<std::size_t N>
717 bool Write(const char (&s)[N]) noexcept {
718 if (N == 0)
719 return Write(BinaryData{});
720 return Write(std::string_view(s, (N > 0) ? (N - 1) : 0));
721 }
722
738 template<Type::ByteInputRange R>
739 bool Write(const R& r) noexcept {
740 BinaryData tmp;
741 if constexpr (requires { std::ranges::size(r); }) {
742 auto dist = std::ranges::size(r);
743 if (dist > 0)
744 tmp.reserve(StormByte::ByteSize{static_cast<std::size_t>(dist)});
745 }
746 std::transform(std::ranges::begin(r), std::ranges::end(r), std::back_inserter(tmp),
747 [](auto&& e) noexcept { return static_cast<std::byte>(e); });
748 return Write(tmp.size(), std::move(tmp));
749 }
750
758 template<Type::ByteInputRange Rw>
759 bool Write(const StormByte::ByteSize& count, const Rw& r) noexcept {
760 if (count == StormByte::ByteSize{0})
761 return Write(r);
762 BinaryData tmp;
763 tmp.reserve(count);
764 auto it = std::ranges::begin(r);
765 auto end = std::ranges::end(r);
766 StormByte::ByteSize written{0};
767 for (; it != end && written < count; ++it, written = written + StormByte::ByteSize{1})
768 tmp.push_back(static_cast<std::byte>(*it));
769 return Write(written, std::move(tmp));
770 }
771
779 template<Type::ByteInputRange Rrw>
780 bool Write(const StormByte::ByteSize& count, Rrw&& r) noexcept {
781 if (count == StormByte::ByteSize{0})
782 return Write(std::forward<Rrw>(r));
783 if constexpr (Type::SameAs<Rrw, BinaryData>) {
784 BinaryData tmp = std::move(r);
785 if (tmp.size() > count)
786 tmp.resize(count);
787 return Write(tmp.size(), std::move(tmp));
788 } else {
789 BinaryData tmp;
790 tmp.reserve(count);
791 auto it = std::ranges::begin(r);
792 auto end = std::ranges::end(r);
793 StormByte::ByteSize written{0};
794 for (; it != end && written < count; ++it, written = written + StormByte::ByteSize{1})
795 tmp.push_back(static_cast<std::byte>(*it));
796 return Write(written, std::move(tmp));
797 }
798 }
799
806 template<Type::ByteInputRange Rr>
807 bool Write(Rr&& r) noexcept {
808 if constexpr (Type::SameAs<Rr, BinaryData>) {
809 return Write(r.size(), std::move(r));
810 } else {
811 BinaryData tmp;
812 if constexpr (requires { std::ranges::size(r); }) {
813 auto dist = std::ranges::size(r);
814 if (dist > 0)
815 tmp.reserve(StormByte::ByteSize{static_cast<std::size_t>(dist)});
816 }
817 std::transform(std::ranges::begin(r), std::ranges::end(r), std::back_inserter(tmp),
818 [](auto&& e) noexcept { return static_cast<std::byte>(e); });
819 return Write(tmp.size(), std::move(tmp));
820 }
821 }
822
831 template<Type::ByteInputIterator I, typename S>
833 bool Write(I first, S last) noexcept {
834 BinaryData tmp;
835 std::transform(first, last, std::back_inserter(tmp),
836 [](auto&& e) noexcept { return static_cast<std::byte>(e); });
837 return Write(tmp.size(), std::move(tmp));
838 }
839
849 template<Type::ByteInputIterator I2, typename S2>
851 bool Write(const StormByte::ByteSize& count, I2 first, S2 last) noexcept {
852 if (count == StormByte::ByteSize{0})
853 return Write(first, last);
854 BinaryData tmp;
855 StormByte::ByteSize written{0};
856 for (; first != last && written < count; ++first, written = written + StormByte::ByteSize{1})
857 tmp.push_back(static_cast<std::byte>(*first));
858 return Write(written, std::move(tmp));
859 }
860
864 };
865
873 public:
882 inline ReadWrite() noexcept: Generic() {}
883
888 ReadWrite(const ReadWrite& other) noexcept = default;
889
894 ReadWrite(ReadWrite&& other) noexcept = default;
895
899 virtual ~ReadWrite() noexcept;
900
906 ReadWrite& operator=(const ReadWrite& other) = default;
907
913 ReadWrite& operator=(ReadWrite&& other) noexcept = default;
914
918 };
919
921 extern template BinaryData STORMBYTE_BUFFER_PUBLIC Generic::DataConvert<BinaryData>(const BinaryData&) noexcept;
922 extern template BinaryData STORMBYTE_BUFFER_PUBLIC Generic::DataConvert<BinaryData>(BinaryData&&) noexcept;
923 extern template BinaryData STORMBYTE_BUFFER_PUBLIC Generic::DataConvert<std::span<const std::byte>>(const std::span<const std::byte>&) noexcept;
924 extern template BinaryData STORMBYTE_BUFFER_PUBLIC Generic::DataConvert<std::span<std::byte>>(const std::span<std::byte>&) noexcept;
925 extern template BinaryData STORMBYTE_BUFFER_PUBLIC Generic::DataConvert<std::span<std::byte>>(std::span<std::byte>&&) noexcept;
926
927 extern template bool STORMBYTE_BUFFER_PUBLIC WriteOnly::Write<BinaryData>(const BinaryData&) noexcept;
928 extern template bool STORMBYTE_BUFFER_PUBLIC WriteOnly::Write<BinaryData>(BinaryData&&) noexcept;
929 extern template bool STORMBYTE_BUFFER_PUBLIC WriteOnly::Write<BinaryData>(const StormByte::ByteSize&, const BinaryData&) noexcept;
930 extern template bool STORMBYTE_BUFFER_PUBLIC WriteOnly::Write<BinaryData>(const StormByte::ByteSize&, BinaryData&&) noexcept;
931 extern template bool STORMBYTE_BUFFER_PUBLIC WriteOnly::Write<std::span<const std::byte>>(const std::span<const std::byte>&) noexcept;
932 extern template bool STORMBYTE_BUFFER_PUBLIC WriteOnly::Write<std::span<const std::byte>>(const StormByte::ByteSize&, const std::span<const std::byte>&) noexcept;
933 extern template bool STORMBYTE_BUFFER_PUBLIC WriteOnly::Write<std::span<std::byte>>(const std::span<std::byte>&) noexcept;
934 extern template bool STORMBYTE_BUFFER_PUBLIC WriteOnly::Write<std::span<std::byte>>(const StormByte::ByteSize&, const std::span<std::byte>&) noexcept;
935 extern template bool STORMBYTE_BUFFER_PUBLIC WriteOnly::Write<BinaryData::const_iterator, BinaryData::const_iterator>(BinaryData::const_iterator, BinaryData::const_iterator) noexcept;
936 extern template bool STORMBYTE_BUFFER_PUBLIC WriteOnly::Write<BinaryData::iterator, BinaryData::iterator>(BinaryData::iterator, BinaryData::iterator) noexcept;
937 extern template bool STORMBYTE_BUFFER_PUBLIC WriteOnly::Write<BinaryData::const_iterator, BinaryData::const_iterator>(const StormByte::ByteSize&, BinaryData::const_iterator, BinaryData::const_iterator) noexcept;
938 extern template bool STORMBYTE_BUFFER_PUBLIC WriteOnly::Write<BinaryData::iterator, BinaryData::iterator>(const StormByte::ByteSize&, BinaryData::iterator, BinaryData::iterator) noexcept;
940 }
941}
void reserve(const StormByte::ByteSize &new_cap)
void resize(const StormByte::ByteSize &new_size)
void push_back(std::byte value)
StormByte::ByteSize size() const noexcept
Abstract root of the byte-buffer interfaces.
Definition generic.hxx:78
static BinaryData DataConvert(const char *s) noexcept
Convert a C string to StormByte::BinaryData.
Definition generic.hxx:207
static BinaryData DataConvert(Src &&src) noexcept
Convert an rvalue input range to StormByte::BinaryData.
Definition generic.hxx:172
Generic() noexcept=default
Default constructor.
static BinaryData DataConvert(std::string_view sv) noexcept
Convert a string view to StormByte::BinaryData.
Definition generic.hxx:193
Buffer that can be read and not written.
Definition generic.hxx:228
virtual void ExtractUntilEoF(WriteOnly &outBuffer) noexcept=0
Extract until EoF into a WriteOnly.
ReadOnly(ReadOnly &&other) noexcept=default
Move constructor.
virtual void ReadUntilEoF(StormByte::BinaryData &outBuffer) const noexcept=0
Read until EoF into a StormByte::BinaryData.
virtual bool Extract(const StormByte::ByteSize &count, WriteOnly &outBuffer) noexcept=0
Extract bytes into a WriteOnly.
virtual bool Peek(const StormByte::ByteSize &count, WriteOnly &outBuffer) const noexcept=0
Peek into a WriteOnly.
bool Read(WriteOnly &outBuffer) const noexcept
Read all available bytes into a WriteOnly.
Definition generic.hxx:474
ReadOnly(const ReadOnly &other) noexcept=default
Copy constructor.
virtual bool Peek(const StormByte::ByteSize &count, StormByte::BinaryData &outBuffer) const noexcept=0
Peek into a StormByte::BinaryData.
virtual bool Read(const StormByte::ByteSize &count, WriteOnly &outBuffer) const noexcept=0
Read into a WriteOnly.
ReadOnly() noexcept
Default constructor.
Definition generic.hxx:238
bool Read(StormByte::BinaryData &outBuffer) const noexcept
Read all available bytes into a StormByte::BinaryData.
Definition generic.hxx:457
bool Extract(WriteOnly &outBuffer) noexcept
Extract all available bytes into a WriteOnly.
Definition generic.hxx:389
virtual void ExtractUntilEoF(StormByte::BinaryData &outBuffer) noexcept=0
Extract until EoF into a StormByte::BinaryData.
virtual ~ReadOnly() noexcept
Destructor.
virtual bool Read(const StormByte::ByteSize &count, StormByte::BinaryData &outBuffer) const noexcept=0
Read into a StormByte::BinaryData.
virtual void ReadUntilEoF(WriteOnly &outBuffer) const noexcept=0
Read until EoF into a WriteOnly.
Read and write interface.
Definition generic.hxx:872
ReadWrite() noexcept
Default constructor.
Definition generic.hxx:882
ReadWrite(const ReadWrite &other) noexcept=default
Copy constructor.
ReadWrite(ReadWrite &&other) noexcept=default
Move constructor.
virtual ~ReadWrite() noexcept
Destructor.
Buffer that can be written and not read.
Definition generic.hxx:505
bool Write(const char *s) noexcept
Write a C string.
Definition generic.hxx:673
WriteOnly(const WriteOnly &other)=default
Copy constructor.
virtual ~WriteOnly() noexcept
Destructor.
bool Write(const char(&s)[N]) noexcept
Write a string literal without the trailing NUL.
Definition generic.hxx:717
bool Write(ReadOnly &&data) noexcept
Append all available bytes from a ReadOnly (extract).
Definition generic.hxx:641
bool Write(Rr &&r) noexcept
Write all elements from an rvalue range.
Definition generic.hxx:807
bool Write(const StormByte::ByteSize &count, const Rw &r) noexcept
Write up to count elements from an input range.
Definition generic.hxx:759
bool Write(const StormByte::ByteSize &count, std::string_view sv) noexcept
Write up to count characters of a string view.
Definition generic.hxx:685
WriteOnly() noexcept
Default constructor.
Definition generic.hxx:515
bool Write(const StormByte::ByteSize &count, Rrw &&r) noexcept
Write up to count elements from an rvalue range.
Definition generic.hxx:780
WriteOnly(WriteOnly &&other) noexcept=default
Move constructor.
bool Write(const StormByte::ByteSize &count, const char *s) noexcept
Write up to count characters of a C string.
Definition generic.hxx:704
bool Write(std::string_view sv) noexcept
Write a string view.
Definition generic.hxx:659
bool Write(const StormByte::ByteSize &count, I2 first, S2 last) noexcept
Write up to count elements from an iterator pair.
Definition generic.hxx:851
bool Write(const R &r) noexcept
Write all elements from an input range.
Definition generic.hxx:739
bool Write(I first, S last) noexcept
Write all elements from an iterator pair.
Definition generic.hxx:833
Position
Forward declaration of the WriteOnly interface.
Definition typedefs.hxx:73
Root namespace of the StormByte C++ suite.
STL namespace.
#define STORMBYTE_BUFFER_PUBLIC
Definition visibility.h:54